Skip to content

feat: add probing service and update mobile adapter#652

Open
yuerqiqi wants to merge 2 commits intoUbiquitousLearning:mainfrom
yuerqiqi:main
Open

feat: add probing service and update mobile adapter#652
yuerqiqi wants to merge 2 commits intoUbiquitousLearning:mainfrom
yuerqiqi:main

Conversation

@yuerqiqi
Copy link
Contributor

@yuerqiqi yuerqiqi commented Mar 14, 2026

This PR introduces several updates for the probing service and mobile adaptation:

  • Added probing service core logic in mllm engine.
  • Updated mllm-cli with a new mobile adapter and server logic.
  • Synchronized mllm-chat submodule to support latest UI changes.

Summary by CodeRabbit

Release Notes

  • New Features

    • Added probing session support for model optimization across CLI and mobile server
    • Added --probe-path CLI flag for probing configuration
    • Added mobile server launcher functionality
  • Improvements

    • Enhanced message history handling to remove hallucination artifacts
  • Chores

    • Updated Go toolchain to version 1.25 and dependencies

@yuerqiqi yuerqiqi requested a review from chenghuaWang as a code owner March 14, 2026 09:49
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 14, 2026

📝 Walkthrough

Walkthrough

This pull request introduces a new probing session feature for Qwen3 models across multiple layers: C API and C++ runtime implementation, Go bindings, CLI argument handling, and mobile server integration. It adds conditional probing session creation based on configuration flags, sanitizes message history in probing sessions, updates dependencies, and changes HTTP response handling and threading synchronization.

Changes

Cohort / File(s) Summary
Submodule Update
mllm-chat
Updates submodule pointer to a new commit; metadata-only change.
C API Probing Session Layer
mllm/c_api/Runtime.h, mllm/c_api/Runtime.cpp
Adds new public C API function createQwen3ProbingSession(const char* model_path, const char* probe_path) to initialize probing sessions with probe path configuration and loading.
C++ Probing Session Implementation
mllm/models/qwen3/modeling_qwen3_probing_service.hpp
Sanitizes message history by removing assistant messages containing "early_exit_hallucination" and preceding user messages in probing session preprocessing.
Go Bindings for Probing
mllm-cli/mllm/c.go
Adds NewProbingSession(modelPath, probePath) function and updates session lifecycle management with finalizers for probing session cleanup.
CLI Server Probing Flag
mllm-cli/cmd/mllm-server/main.go
Introduces --probe-path CLI flag to conditionally create probing sessions via NewProbingSession() when flag is set.
Mobile Server Integration
mllm-cli/mobile_adapter/mobile_server.go
Adds StartServer() function that orchestrates probing session creation for mobile platform with conditional probing based on directory existence and enableProbing parameter.
HTTP Response Handling
mllm-cli/cmd/mllm-client/main.go
Moves from deferred resp.Body.Close() to explicit closes in error-handling and post-streaming branches for precise control-flow handling.
Dependencies and Build
mllm-cli/go.mod
Updates Go toolchain from 1.23.0 to 1.25.0 and refreshes indirect dependencies including golang.org/x/sync and golang.org/x/sys.
Service Threading
mllm/engine/service/Service.cpp
Changes ResponsePool::push notification from notify_one to notify_all to wake all waiting threads when responses are enqueued.

Sequence Diagram

sequenceDiagram
    participant CLI as CLI Server
    participant Go as Go Runtime
    participant C as C API
    participant CPP as C++ Runtime
    participant Service as Service

    CLI->>Go: StartServer(modelPath, probePath, enableProbing)
    Go->>Go: Check probes_linear directory
    alt enableProbing && probes exist
        Go->>C: createQwen3ProbingSession(modelPath, probePath)
    else
        Go->>C: createQwen3Session(modelPath)
    end
    C->>CPP: createQwen3ProbingSession (C++)
    CPP->>CPP: Initialize Qwen3ProbingSession
    CPP->>CPP: Load probes from probePath
    CPP-->>C: Return session handle
    C-->>Go: Return Session object
    Go->>Service: RegisterSession(sessionID, session)
    Service-->>Go: Success
    Go->>Service: StartService()
    Service-->>Go: Service started
    Go->>Go: Launch HTTP server on 127.0.0.1:8080
    Go-->>CLI: Return success message
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

enhancement

Suggested reviewers

  • chenghuaWang
  • oreomaker
  • yirongjie
  • liang1232018

Poem

🐰 A probe hops through the garden of models,
Testing paths where hallucinations fall,
From C to Go, the session bells ring,
Early exits whisper, and probes take wing!

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 7.14% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ❓ Inconclusive The description provides a high-level overview of changes but lacks specifics about implementation details, testing, and migration steps expected by the template guidelines. Expand the description with implementation details, testing approach, and any migration or breaking change information to align with contribution guidelines.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat: add probing service and update mobile adapter' accurately summarizes the main changes: addition of probing service functionality and mobile adapter updates.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
📝 Coding Plan
  • Generate coding plan for human review comments

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Tip

You can enable review details to help with troubleshooting, context usage and more.

Enable the reviews.review_details setting to include review details such as the model used, the time taken for each step and more in the review comments.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

🧹 Nitpick comments (4)
mllm/c_api/Runtime.h (1)

45-46: Add documentation for the new public API function.

Per coding guidelines, public APIs should have clear comments explaining purpose, parameters, return values, and error conditions. Consider adding a brief docstring:

📝 Suggested documentation
 MllmCAny createQwen3Session(const char* model_path);

+/**
+ * Creates a Qwen3 session with probing capabilities enabled.
+ * `@param` model_path Path to the model directory containing model.mllm and config.json.
+ * `@param` probe_path Path to the directory containing probe .mllm files.
+ * `@return` MllmCAny with kCustomObject type on success, kRetCode with -1 on failure.
+ */
 MllmCAny createQwen3ProbingSession(const char* model_path, const char* probe_path);

As per coding guidelines: "Ensure public APIs, classes, and functions have clear docstrings or comments explaining purpose, parameters, returns, and errors."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@mllm/c_api/Runtime.h` around lines 45 - 46, Add a concise doc comment above
the public function declaration createQwen3ProbingSession(const char*
model_path, const char* probe_path) that states its purpose (create and
initialize a Qwen3 probing session), documents parameters (model_path: path to
model artifact; probe_path: path to probe data or config), describes the return
value (what MllmCAny represents and ownership/lifetime expectations) and lists
error conditions/behaviour (what is returned on failure, e.g., null/invalid
handle, and whether callers must free the result). Keep it short and follow
existing header comment style used for other public APIs in Runtime.h.
mllm/c_api/Runtime.cpp (1)

95-123: Consider making probing parameters configurable.

The probing thresholds and default layers are hardcoded:

  • prefill_stop_threshold = 0.7f
  • decode_stop_threshold = 0.8f
  • pos_threshold = 0.9f
  • default_prefill_layers = {27, 30}

While these may be sensible defaults, consider exposing them as parameters or loading from a config file to allow tuning without recompilation.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@mllm/c_api/Runtime.cpp` around lines 95 - 123, The probing thresholds and
default layers are hardcoded in createQwen3ProbingSession; make them
configurable by changing createQwen3ProbingSession to accept either a
ProbingArgs struct (or individual parameters) or a config-file path, parse those
inputs and populate mllm::models::qwen3_probing::ProbingArgs instead of
hardcoding values, then call qwen3_session->setProbingArgs(p_args) and
qwen3_session->loadProbes(probe_path, p_args) as before; ensure you still apply
the current values as sensible defaults when the caller does not provide
overrides and keep the existing exception handling.
mllm-cli/mobile_adapter/mobile_server.go (1)

17-84: Consider adding a StopServer function for graceful shutdown.

The StartServer function launches an HTTP server in a goroutine but provides no way to stop it. For mobile apps that may need to release resources or restart the server, a corresponding shutdown mechanism would be beneficial.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@mllm-cli/mobile_adapter/mobile_server.go` around lines 17 - 84, StartServer
currently launches the HTTP server in a goroutine with server.NewServer(...) and
s.Start() but offers no way to stop it; add a complementary StopServer function
and a package-level reference to the running server (e.g., a variable srv
*server.Server protected by a mutex) so StartServer assigns srv =
server.NewServer(...) and StopServer can safely call srv.Stop() or
srv.Shutdown(context) to gracefully stop listening and wait for handlers to
finish; after shutting the HTTP server, StopServer should also call
mllm.StopService() (or the appropriate teardown API) and deregister/close any
registered sessions from the pkgmllm.Service (use
Service.RegisterSession/session.Insert identifiers to locate and close sessions)
and return a status string so mobile callers can release resources and restart
the server cleanly.
mllm-cli/mllm/c.go (1)

58-109: Constructor/finalizer wiring is duplicated across three factories.

NewSession, NewProbingSession, and NewDeepseekOCRSession repeat the same lifecycle scaffolding (CString/free, handle check, Session build, finalizer setup). Extracting a shared helper will reduce drift and keep future lifecycle fixes consistent.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@mllm-cli/mllm/c.go` around lines 58 - 109, The three constructors NewSession,
NewProbingSession, and NewDeepseekOCRSession duplicate CString allocation/free,
handle validation, Session creation and finalizer setup; extract a small helper
(e.g., createSessionHelper or newSessionFromHandle) that centralizes: converting
strings to C.CString and deferring C.free, invoking the appropriate C create
function (C.createQwen3Session, C.createQwen3ProbingSession,
C.createDeepseekOCRSession) via a passed-in callback or closure, checking
isOk(handle), returning the *Session with runtime.SetFinalizer (single canonical
finalizer message and C.freeSession call), and use that helper from each of the
three factory functions to remove the repeated lifecycle scaffolding.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@mllm-cli/mllm/c.go`:
- Around line 44-47: StartService currently passes an int workerThreads directly
to C.startService allowing negatives; add a defensive check at the top of
StartService to clamp or reject negative values (e.g., if workerThreads < 0 set
to 0 or return false) before calling C.startService, then call C.startService
with the sanitized value and return isOk(result); update references to
workerThreads in StartService and ensure the conversion C.size_t(...) uses the
sanitized variable.
- Around line 111-117: The Close method on *Session dereferences the receiver
without nil-checking which can panic if Close is called on a nil *Session; add
an early guard at the top of Session.Close that returns immediately if s == nil
(and also treat s.cHandle == nil as a no-op) before calling
C.MllmCAny_get_v_custom_ptr, C.freeSession or runtime.SetFinalizer to make Close
nil-safe while keeping the existing cleanup logic intact.

In `@mllm-cli/mobile_adapter/mobile_server.go`:
- Around line 77-81: The goroutine starts the HTTP server with server.NewServer
and calls s.Start() but drops any returned error; change the goroutine to
capture s.Start()'s error and propagate/log it (e.g., send error on a startup
channel or log via log.Println/processLogger) before returning so callers know
if binding failed; specifically update the anonymous func that calls s.Start()
to send success/err over a channel and handle that channel result in the caller
instead of immediately returning "Success".
- Around line 68-70: session.Insert(sessionID) return value is not checked for
the OCR session; update the OCR session creation to check the return value of
session.Insert (same pattern as the Qwen session), and if the insert failed do
not call service.RegisterSession(sessionID, session) — instead log or return the
error. Specifically, after computing sessionID from ocrPath and before calling
service.RegisterSession, inspect the result of session.Insert(sessionID) (e.g.,
if err != nil or if !ok) and handle the failure by returning the error or
logging and aborting registration.
- Around line 57-59: The code calls session.Insert(sessionID) but ignores its
return value, which can lead to a registered session that wasn't actually
inserted; update the flow around session.Insert in mobile_server.go to check its
boolean (or error) return just like the pattern in
mllm-cli/cmd/mllm-server/main.go: capture the return from
session.Insert(sessionID), and if insertion fails, avoid calling
service.RegisterSession(sessionID, session) and handle the failure (log and
return/error-out) so session registration and insertion remain consistent for
the given sessionID derived from filepath.Base(modelPath).

In `@mllm/c_api/Runtime.cpp`:
- Line 13: Replace the deprecated C header by including the C++-style header and
update uses to the std namespace: change the include of <string.h> to <cstring>
in Runtime.cpp and update any calls to strncpy to std::strncpy (or qualify other
string.h symbols with std::) so the code uses the C++ <cstring> header and
symbols in the std namespace.

---

Nitpick comments:
In `@mllm-cli/mllm/c.go`:
- Around line 58-109: The three constructors NewSession, NewProbingSession, and
NewDeepseekOCRSession duplicate CString allocation/free, handle validation,
Session creation and finalizer setup; extract a small helper (e.g.,
createSessionHelper or newSessionFromHandle) that centralizes: converting
strings to C.CString and deferring C.free, invoking the appropriate C create
function (C.createQwen3Session, C.createQwen3ProbingSession,
C.createDeepseekOCRSession) via a passed-in callback or closure, checking
isOk(handle), returning the *Session with runtime.SetFinalizer (single canonical
finalizer message and C.freeSession call), and use that helper from each of the
three factory functions to remove the repeated lifecycle scaffolding.

In `@mllm-cli/mobile_adapter/mobile_server.go`:
- Around line 17-84: StartServer currently launches the HTTP server in a
goroutine with server.NewServer(...) and s.Start() but offers no way to stop it;
add a complementary StopServer function and a package-level reference to the
running server (e.g., a variable srv *server.Server protected by a mutex) so
StartServer assigns srv = server.NewServer(...) and StopServer can safely call
srv.Stop() or srv.Shutdown(context) to gracefully stop listening and wait for
handlers to finish; after shutting the HTTP server, StopServer should also call
mllm.StopService() (or the appropriate teardown API) and deregister/close any
registered sessions from the pkgmllm.Service (use
Service.RegisterSession/session.Insert identifiers to locate and close sessions)
and return a status string so mobile callers can release resources and restart
the server cleanly.

In `@mllm/c_api/Runtime.cpp`:
- Around line 95-123: The probing thresholds and default layers are hardcoded in
createQwen3ProbingSession; make them configurable by changing
createQwen3ProbingSession to accept either a ProbingArgs struct (or individual
parameters) or a config-file path, parse those inputs and populate
mllm::models::qwen3_probing::ProbingArgs instead of hardcoding values, then call
qwen3_session->setProbingArgs(p_args) and qwen3_session->loadProbes(probe_path,
p_args) as before; ensure you still apply the current values as sensible
defaults when the caller does not provide overrides and keep the existing
exception handling.

In `@mllm/c_api/Runtime.h`:
- Around line 45-46: Add a concise doc comment above the public function
declaration createQwen3ProbingSession(const char* model_path, const char*
probe_path) that states its purpose (create and initialize a Qwen3 probing
session), documents parameters (model_path: path to model artifact; probe_path:
path to probe data or config), describes the return value (what MllmCAny
represents and ownership/lifetime expectations) and lists error
conditions/behaviour (what is returned on failure, e.g., null/invalid handle,
and whether callers must free the result). Keep it short and follow existing
header comment style used for other public APIs in Runtime.h.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 5cd9e705-9aae-49d0-bf19-2491c4f91fd3

📥 Commits

Reviewing files that changed from the base of the PR and between 10d3d6a and a0f74c1.

⛔ Files ignored due to path filters (1)
  • mllm-cli/go.sum is excluded by !**/*.sum
📒 Files selected for processing (10)
  • mllm-chat
  • mllm-cli/cmd/mllm-client/main.go
  • mllm-cli/cmd/mllm-server/main.go
  • mllm-cli/go.mod
  • mllm-cli/mllm/c.go
  • mllm-cli/mobile_adapter/mobile_server.go
  • mllm/c_api/Runtime.cpp
  • mllm/c_api/Runtime.h
  • mllm/engine/service/Service.cpp
  • mllm/models/qwen3/modeling_qwen3_probing_service.hpp

Comment on lines 44 to 47
func StartService(workerThreads int) bool {
result := C.startService(C.size_t(workerThreads))
return isOk(result)
result := C.startService(C.size_t(workerThreads))
return isOk(result)
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify whether callers can pass unchecked/derived values into StartService.
rg -nP --type=go -C3 '\bStartService\s*\('
rg -nP --type=go -C3 '\bworkerThreads\b'

Repository: UbiquitousLearning/mllm

Length of output: 1586


Add defensive check for negative workerThreads parameter.

The function parameter accepts int, which can be negative. While all current callers (in main.go and mobile_server.go) pass the literal value 1, a defensive check would prevent accidental misuse if the API is called with untrusted input in the future.

💡 Suggested improvement
 func StartService(workerThreads int) bool {
+	if workerThreads <= 0 {
+		return false
+	}
 	result := C.startService(C.size_t(workerThreads))
 	return isOk(result)
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
func StartService(workerThreads int) bool {
result := C.startService(C.size_t(workerThreads))
return isOk(result)
result := C.startService(C.size_t(workerThreads))
return isOk(result)
}
func StartService(workerThreads int) bool {
if workerThreads <= 0 {
return false
}
result := C.startService(C.size_t(workerThreads))
return isOk(result)
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@mllm-cli/mllm/c.go` around lines 44 - 47, StartService currently passes an
int workerThreads directly to C.startService allowing negatives; add a defensive
check at the top of StartService to clamp or reject negative values (e.g., if
workerThreads < 0 set to 0 or return false) before calling C.startService, then
call C.startService with the sanitized value and return isOk(result); update
references to workerThreads in StartService and ensure the conversion
C.size_t(...) uses the sanitized variable.

Comment on lines 111 to +117
func (s *Session) Close() {
if C.MllmCAny_get_v_custom_ptr(s.cHandle) != nil {
fmt.Println("[Go Close] Mllm Session manually closed.")
C.freeSession(s.cHandle)
s.cHandle = C.MllmCAny_set_v_custom_ptr_null(s.cHandle)
runtime.SetFinalizer(s, nil)
}
if C.MllmCAny_get_v_custom_ptr(s.cHandle) != nil {
fmt.Println("[Go Close] Mllm Session manually closed.")
C.freeSession(s.cHandle)
s.cHandle = C.MllmCAny_set_v_custom_ptr_null(s.cHandle)
runtime.SetFinalizer(s, nil)
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

# Check if the file exists and read the Close() function
find . -name "c.go" -path "*mllm-cli*" | head -5

Repository: UbiquitousLearning/mllm

Length of output: 87


🏁 Script executed:

# Read the specific lines from the file
sed -n '105,120p' ./mllm-cli/mllm/c.go

Repository: UbiquitousLearning/mllm

Length of output: 426


🏁 Script executed:

# Check if Close() is used in deferred/cleanup contexts
rg "defer.*\.Close\(\)" ./mllm-cli --type go -A 2 -B 2 | head -30

Repository: UbiquitousLearning/mllm

Length of output: 291


🏁 Script executed:

# Search for Session.Close() usage patterns
rg "Session.*Close\(\)" ./mllm-cli --type go -B 3 -A 2 | head -50

Repository: UbiquitousLearning/mllm

Length of output: 348


🏁 Script executed:

# Check where Close() is actually called or if it's used as a callback
rg "\.Close" ./mllm-cli/mllm --type go -B 2 -A 2

Repository: UbiquitousLearning/mllm

Length of output: 49


🏁 Script executed:

# Broader search for Close usage in mllm-cli
rg "Close" ./mllm-cli --type go | head -20

Repository: UbiquitousLearning/mllm

Length of output: 738


🏁 Script executed:

# Check the actual calls to session.Close() in the service and main files
rg -B 5 -A 2 "session\.Close\(\)" ./mllm-cli --type go

Repository: UbiquitousLearning/mllm

Length of output: 1612


Add nil-safety check to Close() method to prevent panic on nil receiver.

The function dereferences s.cHandle immediately without checking if the receiver is nil. While current code paths pass non-nil receivers, calling Close() on a nil *Session will panic. This is a defensive Go pattern that should be adopted:

Proposed fix
 func (s *Session) Close() {
+	if s == nil {
+		return
+	}
 	if C.MllmCAny_get_v_custom_ptr(s.cHandle) != nil {
 		fmt.Println("[Go Close] Mllm Session manually closed.")
 		C.freeSession(s.cHandle)
 		s.cHandle = C.MllmCAny_set_v_custom_ptr_null(s.cHandle)
 		runtime.SetFinalizer(s, nil)
 	}
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@mllm-cli/mllm/c.go` around lines 111 - 117, The Close method on *Session
dereferences the receiver without nil-checking which can panic if Close is
called on a nil *Session; add an early guard at the top of Session.Close that
returns immediately if s == nil (and also treat s.cHandle == nil as a no-op)
before calling C.MllmCAny_get_v_custom_ptr, C.freeSession or
runtime.SetFinalizer to make Close nil-safe while keeping the existing cleanup
logic intact.

Comment on lines +57 to +59
sessionID := filepath.Base(modelPath)
session.Insert(sessionID)
service.RegisterSession(sessionID, session)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Check return value of session.Insert() for consistency.

Unlike mllm-cli/cmd/mllm-server/main.go (Lines 54-57) which checks the Insert return value and handles failures, this code ignores it. If insertion fails, the session is registered but not properly inserted into the service layer.

🔧 Proposed fix
 sessionID := filepath.Base(modelPath)
-session.Insert(sessionID)
+if !session.Insert(sessionID) {
+	session.Close()
+	return "Error: Failed to insert Qwen session with ID: " + sessionID
+}
 service.RegisterSession(sessionID, session)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
sessionID := filepath.Base(modelPath)
session.Insert(sessionID)
service.RegisterSession(sessionID, session)
sessionID := filepath.Base(modelPath)
if !session.Insert(sessionID) {
session.Close()
return "Error: Failed to insert Qwen session with ID: " + sessionID
}
service.RegisterSession(sessionID, session)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@mllm-cli/mobile_adapter/mobile_server.go` around lines 57 - 59, The code
calls session.Insert(sessionID) but ignores its return value, which can lead to
a registered session that wasn't actually inserted; update the flow around
session.Insert in mobile_server.go to check its boolean (or error) return just
like the pattern in mllm-cli/cmd/mllm-server/main.go: capture the return from
session.Insert(sessionID), and if insertion fails, avoid calling
service.RegisterSession(sessionID, session) and handle the failure (log and
return/error-out) so session registration and insertion remain consistent for
the given sessionID derived from filepath.Base(modelPath).

Comment on lines +68 to +70
sessionID := filepath.Base(ocrPath)
session.Insert(sessionID)
service.RegisterSession(sessionID, session)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Check return value of session.Insert() for OCR session as well.

Same issue as the Qwen session - the Insert() return value should be checked to ensure proper error handling.

🔧 Proposed fix
 sessionID := filepath.Base(ocrPath)
-session.Insert(sessionID)
+if !session.Insert(sessionID) {
+	session.Close()
+	return "Error: Failed to insert OCR session with ID: " + sessionID
+}
 service.RegisterSession(sessionID, session)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
sessionID := filepath.Base(ocrPath)
session.Insert(sessionID)
service.RegisterSession(sessionID, session)
sessionID := filepath.Base(ocrPath)
if !session.Insert(sessionID) {
session.Close()
return "Error: Failed to insert OCR session with ID: " + sessionID
}
service.RegisterSession(sessionID, session)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@mllm-cli/mobile_adapter/mobile_server.go` around lines 68 - 70,
session.Insert(sessionID) return value is not checked for the OCR session;
update the OCR session creation to check the return value of session.Insert
(same pattern as the Qwen session), and if the insert failed do not call
service.RegisterSession(sessionID, session) — instead log or return the error.
Specifically, after computing sessionID from ocrPath and before calling
service.RegisterSession, inspect the result of session.Insert(sessionID) (e.g.,
if err != nil or if !ok) and handle the failure by returning the error or
logging and aborting registration.

Comment on lines +77 to +81
go func() {
s := server.NewServer("127.0.0.1:8080", service)
log.Println("[GoMobile] HTTP Server listening on 8080")
s.Start()
}()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

HTTP server errors are silently dropped.

The server runs in a goroutine without capturing or logging errors from s.Start(). If the server fails to bind to port 8080 (e.g., port already in use), the caller receives "Success" but the server isn't actually running.

🔧 Suggested improvement
 go func() {
 	s := server.NewServer("127.0.0.1:8080", service)
 	log.Println("[GoMobile] HTTP Server listening on 8080")
-	s.Start()
+	if err := s.Start(); err != nil {
+		log.Printf("[GoMobile] HTTP Server error: %v", err)
+	}
 }()

Note: For a more robust solution, consider using a channel to communicate startup success/failure back to the caller before returning.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
go func() {
s := server.NewServer("127.0.0.1:8080", service)
log.Println("[GoMobile] HTTP Server listening on 8080")
s.Start()
}()
go func() {
s := server.NewServer("127.0.0.1:8080", service)
log.Println("[GoMobile] HTTP Server listening on 8080")
if err := s.Start(); err != nil {
log.Printf("[GoMobile] HTTP Server error: %v", err)
}
}()
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@mllm-cli/mobile_adapter/mobile_server.go` around lines 77 - 81, The goroutine
starts the HTTP server with server.NewServer and calls s.Start() but drops any
returned error; change the goroutine to capture s.Start()'s error and
propagate/log it (e.g., send error on a startup channel or log via
log.Println/processLogger) before returning so callers know if binding failed;
specifically update the anonymous func that calls s.Start() to send success/err
over a channel and handle that channel result in the caller instead of
immediately returning "Success".

#include <vector>
#include <map>
#include <string.h> // for strncpy
#include <string.h> // for strncpy
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Use modern C++ header <cstring> instead of deprecated <string.h>.

Static analysis flagged this as a modernize-deprecated-headers issue. In C++ code, prefer <cstring> which places symbols in the std namespace.

🔧 Proposed fix
-#include <string.h>  // for strncpy
+#include <cstring>  // for strncpy
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
#include <string.h> // for strncpy
`#include` <cstring> // for strncpy
🧰 Tools
🪛 Clang (14.0.6)

[error] 13-13: inclusion of deprecated C++ header 'string.h'; consider using 'cstring' instead

(modernize-deprecated-headers,-warnings-as-errors)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@mllm/c_api/Runtime.cpp` at line 13, Replace the deprecated C header by
including the C++-style header and update uses to the std namespace: change the
include of <string.h> to <cstring> in Runtime.cpp and update any calls to
strncpy to std::strncpy (or qualify other string.h symbols with std::) so the
code uses the C++ <cstring> header and symbols in the std namespace.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant