Request Flow¶
A message through the ReAct loop — reason, act, observe, repeat — and the decisions made along the way.
The run sequence¶
What happens when a user sends a message to a running team: the client POSTs to a controller, the orchestrator picks the topology and enqueues an LLM call through the scheduler, tool calls route through the router, and every event streams back over SignalR.
sequenceDiagram
participant U as User
participant C as React Client
participant H as SignalR Hub
participant API as Controller
participant O as OrchestratorService
participant S as ModelScheduler
participant L as LM Studio
participant R as McpToolRouter
participant T as MCP Server<br/>(e.g. WorkspaceTools)
U->>C: type message, press send
C->>API: POST /api/orchestrator/...
API->>O: dispatch to topology
O->>S: enqueue LLM call
S->>L: /v1/chat/completions
L-->>S: response + tool_calls
S-->>O: ChatDetailedResponse
O->>R: route tool call
R->>T: invoke tool method
T-->>R: tool result
R-->>O: result
O->>S: next LLM turn (loop)
O->>H: stream tokens + events
H-->>C: SignalR push
C-->>U: rendered response
Push-dispatched delegation¶
In a Hierarchical team the supervisor's LLM makes every delegation decision (delegate, push). Workers run what they're assigned and reply. Peer messaging (send_message_to) is a transport shortcut between workers — it moves messages, not the authority to delegate.
graph TB
User([User request])
subgraph decision["Decision layer — the supervisor's LLM decides"]
Sup[Supervisor]
end
subgraph exec["Execution layer — workers run assigned tasks"]
W1[Worker A]
W2[Worker B]
end
User --> Sup
Sup -->|"delegate (push)"| W1
Sup -->|"delegate (push)"| W2
W1 -->|reply| Sup
W2 -->|reply| Sup
W1 -.->|"send_message_to (transport only)"| W2
Sup -->|synthesized response| User
→ §17 — Architecture Decisions (ADR 2)
The MCP session lifecycle¶
Each tool call rides a session context. The turn assembles the context, filters the catalog to what the agent may see, and for every tool call sets the ambient context, runs the gates, dispatches, then clears the context and writes an audit entry — in a finally, so cleanup happens whether the call succeeds or throws.
flowchart TB
Begin([Agent turn begins]):::ext --> Build[Assemble McpSessionContext<br/>project · agent · workspace ·<br/>authorized servers · allowed domains]
Build --> Filter[Filter tool catalog<br/>connection + capability layers]
Filter --> Q{Agent emits<br/>a tool call?}
Q -- no --> Done([Turn ends]):::ext
Q -- yes --> Set[Set ambient context<br/>via McpSessionProvider]
Set --> Gate[Tier gate + egress/DLP + approval]
Gate --> Dispatch[Dispatch to MCP server class method]
Dispatch --> Clear[Clear context · write audit entry]
Clear --> Q
classDef ext fill:#D5C3B0,stroke:#2D2D2D,stroke-width:1.5px,color:#1A1A1A
classDef gate fill:#B87333,stroke:#2D2D2D,stroke-width:2px,color:#FFFFFF
Which model runs the turn¶
Before a turn, the Engine resolves the model through a fallthrough chain and takes the first tier that yields a usable local model. At every tier, a candidate that is empty, "default", or cloud-prefixed is skipped.
flowchart TB
N[1 · Node model_id]:::step
R[2 · Registry routing<br/>best model for agent_type]:::step
Wk[3 · AI_WorkerModelId<br/>workers only]:::step
TD[4 · Team default chain<br/>AI_ModelId → team.config.model<br/>→ loaded model → local-model]:::step
OUT([Resolved local model]):::ext
G[Skip-rule applied at every tier:<br/>empty · default · cloud-prefixed<br/>gpt- claude- o1- o3- gemini-]:::gate
N --> R
R --> Wk
Wk --> TD
TD --> OUT
G -.-> N
classDef step fill:#8FA68A,stroke:#2D2D2D,stroke-width:1.5px,color:#1A1A1A
classDef gate fill:#B87333,stroke:#2D2D2D,stroke-width:2px,color:#FFFFFF
classDef ext fill:#D5C3B0,stroke:#2D2D2D,stroke-width:1.5px,color:#1A1A1A
→ §09 — Configuration · keys in the Config Reference