fix: bridge SendMessage bypasses orchestration routing for multi-agent groups#297
fix: bridge SendMessage bypasses orchestration routing for multi-agent groups#297
Conversation
PR #297 Review -- 5-Model Consensus ReportPR: fix: bridge SendMessage bypasses orchestration routing for multi-agent groups Findings🔴 HIGH -- Thread-unsafe read of Organization.Sessions in GetOrchestratorGroupId (2+ models)WsBridgeServer.cs / CopilotService.Organization.cs -- GetOrchestratorGroupId() reads Organization.Sessions (plain List) on the WebSocket background thread. Organization.Sessions is UI-thread-only. Concurrent enumeration + mutation throws InvalidOperationException or corrupts internal array. Fix: Marshal the call to UI thread via InvokeOnUIAsync, or take a .ToArray() snapshot under lock, or cache the orchestrator group ID at session creation time. 🔴 HIGH -- SendToMultiAgentGroupAsync reads Organization state from thread pool (2+ models)CopilotService.Organization.cs -- SendToMultiAgentGroupAsync is called from Task.Run (via WsBridgeServer). It reads Organization.Groups and Organization.Sessions without marshaling to UI thread. Same thread-safety issue as above. Fix: Marshal the entire method body to the UI thread, or snapshot the needed data (group members list) on the UI thread before dispatching to background. 🟡 MEDIUM -- Silent orchestration bypass when images are present (2+ models)When imagePaths is non-empty, the code silently falls back to direct SendPromptAsync instead of routing through the orchestrator. No user feedback is shown -- the message just goes to the wrong session. Users sending images in a multi-agent group won't understand why the orchestrator didn't route their message. Fix: Show a toast/system message like 'Images sent directly (orchestration routing does not support images yet)' so users understand the behavior. Recommended Action:
|
PR #297 Re-Review — 5-Model Consensus ReportPR: fix: bridge SendMessage bypasses orchestration routing for multi-agent groups Previous Findings — All 3 Confirmed STILL PRESENT (5/5 models)🔴 HIGH — Thread-unsafe read of
|
b3348dd to
90e6d86
Compare
PR #297 — Re-Review Round 3 (5-Model Consensus)Commit: Previous Findings Status
Required FixMarshal Verdict:
|
…t groups When a mobile client sent a message to an orchestrator session via the WebSocket bridge, WsBridgeServer.HandleClientMessage called SendPromptAsync directly, bypassing the multi-agent dispatch pipeline. The orchestrator responded as a normal chat session instead of planning and dispatching tasks to workers. Root cause: WsBridgeServer had no awareness of orchestrator sessions. All bridge sends went through SendPromptAsync regardless of session role. Fix: - WsBridgeServer now calls GetOrchestratorGroupId before sending. If the target session is an orchestrator, routes through SendToMultiAgentGroupAsync. - CreateSessionAsync queue drain also checks for orchestrator routing. - Fix pre-existing RightClickContextMenuTests failure (proximity threshold). Evidence from diagnostics: successful orchestrator sends ran on thread=1 (UI thread, via Dashboard.razor). Failed sends at 02:00/02:04 ran on thread=44/65 (background, from Task.Run in WsBridgeServer) with no DISPATCH-ROUTE or DISPATCH logs — orchestration pipeline never executed. Tests: 7 new tests (4 unit + 3 integration), all 2066 passing. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- WsBridgeServer: Replace Task.Run with InvokeOnUIAsync so GetOrchestratorGroupId + SendToMultiAgentGroupAsync run atomically on UI thread (fixes thread-unsafe Organization reads and TOCTOU race) - Dashboard.razor + CopilotService.cs: Add system message warning when orchestrator has images and falls back to direct send - agentMode is now correctly forwarded on the non-orchestrator path Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…and create-drain paths Mirror Dashboard.razor's AutoStartReflectionIfNeeded behavior in WsBridgeServer and the CreateSessionAsync queue-drain path. Previously, messages to OrchestratorReflect groups via the mobile bridge silently fell back to single-pass Orchestrator mode because StartGroupReflection was never called (no ReflectionState was initialized). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
90e6d86 to
8b76099
Compare
PR #297 — Final Re-Review (Round 4, 3-Model Consensus)Commit: \8b76099\ (3rd commit — fix StartGroupReflection for OrchestratorReflect) All Previous Findings — Status
New Findings (3-model consensus)None. The fix is clean and complete. One model (Gemini) flagged thread-safety issues at WsBridgeServer.cs:612 (\MultiAgentBroadcast) and :621 (\MultiAgentCreateGroup) — but these are pre-existing code paths not modified by this PR, and no other model agreed (1/3 models, below the 2-model consensus threshold). Summary of Applied Fixes
Verdict: ✅ Ready to mergeAll 7 previously-reported findings are resolved. The fix correctly routes bridge sends through the multi-agent orchestration pipeline with proper thread safety, image fallback feedback, TOCTOU elimination, and OrchestratorReflect support. |
…t groups (PureWeen#297) ## Problem When sending a message to an orchestrator session from the **mobile app** (via WebSocket bridge), the message went directly to instead of through the multi-agent dispatch pipeline. The orchestrator responded as a normal chat session — no worker dispatch, no task planning, no synthesis. This was the root cause of the PR Review Squad orchestrator not working after the latest deploy. ## Root Cause `WsBridgeServer.HandleClientMessage` called `SendPromptAsync` directly via `Task.Run`, completely bypassing the orchestration routing that exists in `Dashboard.razor`. The bridge had no awareness of orchestrator sessions. **Evidence from diagnostics:** - Successful orchestrator sends: thread=1 (UI thread, via Dashboard.razor → orchestration pipeline) - Failed sends at 02:00/02:04: thread=44/65 (background, from `Task.Run` in WsBridgeServer) - No `[DISPATCH-ROUTE]` or `[DISPATCH]` logs — orchestration pipeline never executed ## Fix 1. **`WsBridgeServer.cs`** — Now calls `GetOrchestratorGroupId()` before sending. If the target session is an orchestrator, routes through `SendToMultiAgentGroupAsync` instead of direct `SendPromptAsync`. 2. **`CopilotService.cs`** (CreateSessionAsync queue drain) — Same pattern for newly created orchestrator sessions. 3. **`RightClickContextMenuTests.cs`** — Fix pre-existing test failure (proximity threshold too tight after new attributes were added to the session-item div). ## Tests - 4 new unit tests in `MultiAgentRegressionTests.cs` (Bug PureWeen#8 region) - 3 new integration tests in `WsBridgeIntegrationTests.cs` (bridge orchestration routing) - Fix for 1 pre-existing test failure - **All 2066 tests passing** --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Problem
When sending a message to an orchestrator session from the mobile app (via WebSocket bridge), the message went directly to instead of through the multi-agent dispatch pipeline. The orchestrator responded as a normal chat session — no worker dispatch, no task planning, no synthesis.
This was the root cause of the PR Review Squad orchestrator not working after the latest deploy.
Root Cause
WsBridgeServer.HandleClientMessagecalledSendPromptAsyncdirectly viaTask.Run, completely bypassing the orchestration routing that exists inDashboard.razor. The bridge had no awareness of orchestrator sessions.Evidence from diagnostics:
Task.Runin WsBridgeServer)[DISPATCH-ROUTE]or[DISPATCH]logs — orchestration pipeline never executedFix
WsBridgeServer.cs— Now callsGetOrchestratorGroupId()before sending. If the target session is an orchestrator, routes throughSendToMultiAgentGroupAsyncinstead of directSendPromptAsync.CopilotService.cs(CreateSessionAsync queue drain) — Same pattern for newly created orchestrator sessions.RightClickContextMenuTests.cs— Fix pre-existing test failure (proximity threshold too tight after new attributes were added to the session-item div).Tests
MultiAgentRegressionTests.cs(Bug Fix Android crash and safe area insets, update MAUI to 10.0.31 #8 region)WsBridgeIntegrationTests.cs(bridge orchestration routing)