From f9f63f12a135dac3002a11e9460c6f4103cbc2c1 Mon Sep 17 00:00:00 2001 From: viettranx Date: Fri, 27 Mar 2026 10:43:29 +0700 Subject: [PATCH] docs: update agent teams Section 7 to match task dispatch flow Replace outdated spawn+team_task_id delegation docs with current team_tasks(create, assignee) + dispatchTaskToAgent() auto-dispatch model. --- docs/11-agent-teams.md | 93 +++++++++++++++++++++++------------------- 1 file changed, 50 insertions(+), 43 deletions(-) diff --git a/docs/11-agent-teams.md b/docs/11-agent-teams.md index 1dedd59b..43be2726 100644 --- a/docs/11-agent-teams.md +++ b/docs/11-agent-teams.md @@ -406,70 +406,77 @@ File tools use this context to resolve workspace paths and auto-link files to ta --- -## 7. Delegation Integration +## 7. Task Dispatch Integration -Teams integrate deeply with the delegation system. The mandatory workflow ensures every piece of delegated work is tracked. +Teams use a task-board-driven dispatch model. The lead creates tasks with an assignee; the system auto-dispatches to the assigned member agent via the message bus. The legacy `spawn(agent=..., team_task_id=...)` flow has been removed — `spawn` now only supports self-clone subagents. ```mermaid flowchart TD - LEAD["Lead receives user request"] --> CREATE["1. Create task on board
team_tasks action=create
→ returns task_id"] - CREATE --> SPAWN["2. Delegate to member
spawn agent=member,
team_task_id=task_id"] - SPAWN --> INJECT["Inject team workspace context
WithToolTeamID
WithToolTeamWorkspace
WithTeamTaskID"] - INJECT --> LANE["Scheduled through
team lane"] - LANE --> MEMBER["Member agent executes
in isolated session
with workspace access"] - MEMBER --> COMPLETE["3. Task auto-completed
with delegation result"] - COMPLETE --> DISPATCH["Files auto-linked to task
Comments/events recorded"] - DISPATCH --> CLEANUP["Session cleaned up"] + LEAD["Lead receives user request"] --> CREATE["1. Create task on board
team_tasks(action='create',
assignee='member')"] + CREATE --> QUEUE["2. Task queued for
post-turn dispatch
(PendingTeamDispatchFromCtx)"] + QUEUE --> ASSIGN["3. AssignTask
(pending → in_progress)"] + ASSIGN --> DISPATCH["4. dispatchTaskToAgent
publishes to message bus
(teammate:dashboard sender)"] + DISPATCH --> CONSUMER["Gateway consumer
routes to team lane"] + CONSUMER --> MEMBER["Member agent executes
in isolated session
with workspace access"] + MEMBER --> COMPLETE["5. Member calls
team_tasks(action='complete')"] + COMPLETE --> UNBLOCK["DispatchUnblockedTasks
auto-dispatches
dependent tasks"] - subgraph "Parallel Delegation" - SPAWN2["spawn member_A, task_id=1"] --> RUN_A["Member A works
with workspace"] - SPAWN3["spawn member_B, task_id=2"] --> RUN_B["Member B works
with workspace"] - RUN_A --> COLLECT["Results collected"] - RUN_B --> COLLECT - COLLECT --> ANNOUNCE["4. Single combined
announcement to lead"] + subgraph "Parallel Dispatch" + CREATE2["create task #1
assignee=member_A"] --> DISPATCH_A["dispatchTaskToAgent
→ Member A"] + CREATE3["create task #2
assignee=member_B"] --> DISPATCH_B["dispatchTaskToAgent
→ Member B"] + DISPATCH_A --> RUN_A["Member A works"] + DISPATCH_B --> RUN_B["Member B works"] end ``` -### Task ID Enforcement +### Dispatch Mechanism -When a team member delegates work, the system requires a valid `team_task_id`: +Task dispatch uses `dispatchTaskToAgent()` (`team_tool_dispatch.go`) which publishes an inbound message via the message bus: -- **Missing task ID**: Delegation is rejected with an error explaining the requirement. The error includes a list of pending tasks to help the LLM self-correct. -- **Invalid task ID**: If the LLM hallucinates a UUID that doesn't exist, the error includes pending tasks as a hint. -- **Cross-team task ID**: If the task belongs to a different team, the delegation is rejected. -- **Auto-claim**: When delegation starts, the linked task is automatically claimed (status: pending → in_progress). +- **Post-turn dispatch** (default): Tasks created during a lead's turn are queued via `PendingTeamDispatchFromCtx` and dispatched after the turn ends. This avoids race conditions with `blocked_by` setup. +- **Fallback dispatch**: If no post-turn hook is available (e.g., HTTP API context), the task is assigned and dispatched immediately. +- **Routing**: Uses `task.Channel`/`task.ChatID` as primary source, falling back to context values for initial dispatch. + +### Spawn Rejection + +The `spawn` tool no longer accepts an `agent` parameter. If an LLM attempts `spawn(agent="member")`, it receives an error directing it to use `team_tasks(action="create", assignee="member")` instead. + +### Dispatch Safety + +- **Lead self-dispatch guard**: Tasks assigned to the lead agent are auto-failed (prevents dual-session loop). +- **Circuit breaker**: Tasks auto-fail after 3 dispatch attempts (`maxTaskDispatches`). Prevents infinite loops when agents can't complete a task. +- **Dispatch count tracking**: Each dispatch increments `metadata.dispatch_count`. ### Auto-Completion -When a delegation finishes (success or failure): +When a member calls `team_tasks(action="complete")`: -1. The linked task is marked as `completed` with the delegation result +1. Task marked as `completed` with result summary 2. Files created during execution are auto-linked to the task -3. Workspace events are recorded (modified/created file events) -4. A team message audit record is created (from member → lead) -5. The delegation session is cleaned up (deleted) -6. Delegation history is saved with team context (team_id, team_task_id, trace_id) +3. Workspace events recorded (modified/created file events) +4. `DispatchUnblockedTasks` runs — pending tasks with satisfied blockers are auto-dispatched +5. Only one task per owner dispatched per round (priority-ordered) to prevent cancellation bugs -### Parallel Delegation Batching +### Unblocked Task Dispatch -When the lead delegates to multiple members simultaneously: +`DispatchUnblockedTasks()` runs after task completion/cancellation: -- Each delegation runs independently in the team lane -- Intermediate completions accumulate their results (artifacts) -- When the **last** sibling delegation finishes, all accumulated results are collected -- A single combined announcement is delivered to the lead with all results -- Each individual task is still auto-completed independently — the batching only affects the announcement +- Finds pending tasks with assigned owners (ordered by priority DESC) +- Dispatches highest-priority task per owner (one at a time) +- Appends completed blocker results and recent comments to dispatch content +- Restores leader's trace context from task metadata for proper trace linking +- Remaining tasks stay pending until the current one completes -### Announcement Format +### Dispatch Content -The combined announcement includes: +Each dispatched task includes in its message to the member: -- Results from each member agent, separated clearly -- Deliverables and media files (auto-delivered) -- Elapsed time statistics -- Guidance for the lead: present results to user, delegate follow-ups, or ask for revisions - -If all delegations failed, the lead receives a friendly error notification with guidance to retry or handle it directly. The announcement also asks the lead to notify the user of the hiccup before retrying. +- Task number, ID, subject, and description +- Team workspace path (if configured) +- List of attached files (from task metadata) +- Instructions for available actions: progress, comment, blocker, complete +- Completed blocker results (for unblocked tasks) +- Recent comments (for re-dispatched tasks after reject/retry) ---