Files
coyote/docs/restful-api/testing/plans/11-sub-agent-spawning.md
T

4.9 KiB

Test Plan: Sub-Agent Spawning

Feature description

Agents with can_spawn_agents=true can spawn child agents that run in parallel as background tokio tasks. Children communicate results back to the parent via collect/check. Escalation allows children to request user input through the parent.

Behaviors to test

Spawn

  • agent__spawn creates child agent in background (requires agent config on disk)
  • Child gets own RequestContext with incremented depth (new_for_child)
  • Child starts with empty scope (new_for_child)
  • Child gets shared root_escalation_queue (new_for_child)
  • Child gets inbox for teammate messaging (new_for_child)
  • Child inherits parent_supervisor (new_for_child)
  • Child MCP servers acquired if configured (requires live MCP)
  • Max concurrent agents enforced (Supervisor.register)
  • Max depth enforced (Supervisor.register)
  • Agent not found → error (requires agent config on disk)
  • can_spawn_agents=false → no spawn tools available (requires agent init)

Collect/Check

  • agent__check returns PENDING for running agent
  • agent__check returns error for unknown agent
  • agent__collect blocks until done, returns output (requires real child completion)
  • Output summarization when exceeds threshold (requires LLM client)
  • Summarization uses configured model (requires LLM client)

Task queue (handler integration tests)

  • handle_task_create creates tasks (simple, with deps, with dispatch_agent)
  • handle_task_create errors when agent set without prompt
  • handle_task_complete unblocks dependents
  • handle_task_list shows all tasks
  • handle_task_fail marks failed and reports blocked dependents
  • handle_task_fail returns error for missing task

Escalation (handler integration tests)

  • handle_reply_escalation delivers reply via oneshot channel
  • handle_reply_escalation errors for missing escalation_id
  • handle_reply_escalation errors when no queue
  • Pending summary contains correct fields
  • Reply reaches receiver via oneshot channel
  • Escalation timeout → fallback message (requires tokio timeout)

Teammate messaging (handler integration tests)

  • handle_send_message delivers to registered agent's inbox
  • handle_send_message errors for unknown agent
  • handle_check_inbox returns messages with count
  • handle_check_inbox returns empty when no inbox
  • handle_check_inbox returns empty for empty inbox

Cancel/List (handler integration tests)

  • handle_list returns empty for fresh supervisor
  • handle_list returns registered agents
  • handle_list errors when no supervisor
  • handle_cancel removes agent and signals abort
  • handle_cancel errors for unknown agent
  • handle_cancel errors when no supervisor

Dispatch routing

  • Unknown action → error with "Unknown supervisor action"
  • agent__list routes to handle_list
  • agent__task_list routes to handle_task_list

Child agent lifecycle

  • run_child_agent loops (requires LLM client)
  • Child uses before/after_chat_completion (requires LLM client)
  • Child tool calls evaluated (requires LLM client)
  • Child exits cleanly (requires LLM client)

Context switching scenarios

  • Parent spawns child with MCP (requires live MCP + agent config)
  • Parent exits agent → all children cancelled (requires agent init)
  • Multiple children share escalation queue (new_for_child + ensure_root_escalation_queue)

Additional behaviors tested (not in original plan)

  • EscalationQueue: default, submit, take, take_nonexistent, has_pending
  • EscalationQueue: pending_summary with/without options, empty
  • EscalationQueue: reply via oneshot channel
  • new_escalation_id: prefix and uniqueness
  • Inbox: new/default empty, deliver+drain, drain empties, multiple deliveries
  • Inbox: clone preserves messages, clone is independent
  • Supervisor: new defaults, register count, take removes, take nonexistent
  • Supervisor: inbox accessor, list_agents, task_queue accessible
  • Supervisor: register allows at max_depth boundary
  • AgentExitStatus: equality/inequality
  • TaskQueue: fail sets status, get missing returns None
  • TaskQueue: dispatch_agent/prompt stored, claim blocked fails
  • TaskQueue: list sorted by id, default empty
  • TaskQueue: dependency on nonexistent errors, complete nonexistent
  • TaskNode: is_runnable when pending+unblocked, not when blocked

Integration handler tests added

  • All handle_* functions tested via handler integration tests (36 tests)
  • new_for_child: depth, id, inbox, escalation queue, parent supervisor, empty scope
  • ensure_root_escalation_queue: lazy init, same Arc on repeated calls
  • AppState::test_default() helper added for cross-module test construction

Old code reference

  • src/function/supervisor.rs — all handler functions
  • src/supervisor/ — Supervisor, EscalationQueue, Inbox, TaskQueue