Skip to content

feat: add team tools, HTTP routes, and tool registry integration#12731

Open
ugoenyioha wants to merge 6 commits intoanomalyco:devfrom
ugoenyioha:feature/team-tools
Open

feat: add team tools, HTTP routes, and tool registry integration#12731
ugoenyioha wants to merge 6 commits intoanomalyco:devfrom
ugoenyioha:feature/team-tools

Conversation

@ugoenyioha
Copy link

@ugoenyioha ugoenyioha commented Feb 8, 2026

Summary

Adds the tool and API layer for agent teams (Fixes #12711). Depends on #12730 — merge that first.

This is PR 2/3. It exposes the Team namespace from PR 1 as 9 MCP tools the LLM can call, plus HTTP routes for TUI consumption. All tools are conditionally registered behind the OPENCODE_EXPERIMENTAL_AGENT_TEAMS feature flag.

What's included

Business logic in Team namespace (team/index.ts — +333 lines over PR 1)

Core team operations live in the Team namespace, not the tool layer. Tools are thin wrappers that handle authorization checks and format output.

New Team functions:

  • Team.resolveModel() — Model resolution with priority chain: explicit provider/model param → agent config → lead's last model → global default. Validates against configured providers with fuzzy suggestions on miss.
  • Team.spawnMember() — Creates child session, registers member (with orphaned session cleanup on addMember failure), constructs teammate context message, launches fire-and-forget prompt loop. Sync-throw guard on SessionPrompt.loop().
  • Team.approvePlan() — Removes plan-approval deny rules from teammate session, updates plan state, notifies teammate via team message.
  • Team.autoCleanup() — Subscribes to TeamEvent.MemberStatusChanged. When all members reach "shutdown", auto-cleans the team. Safety net that doesn't depend on the LLM remembering to call team_cleanup.
  • Team.onCleanedRestorePermissions() — Subscribes to TeamEvent.Cleaned. Restores lead session permissions when a delegate-mode team is cleaned up. Decouples cleanup from direct Session imports.
  • Private notifyLead() — Sends idle/error notification to lead when a teammate's prompt loop finishes. Uses setMemberStatus with { guard: true } to prevent overwriting "shutdown" (TOCTOU prevention).

Team tools (tool/team.ts — 557 lines)

9 MCP tools, each a thin wrapper over Team namespace methods with authorization checks and formatted output:

Tool Description
team_create Create a new team. Caller becomes lead. Optional delegate mode restricts lead to coordination-only. Optional initial task list. Prevents nested teams.
team_spawn Spawn a teammate via Team.spawnMember(). Configurable agent type, model, initial prompt, auto-claim task, and optional require_plan_approval. Wraps spawnMember in try/catch for proper error reporting.
team_message Send a directed message to a specific teammate or "lead".
team_broadcast Send a message to all active teammates.
team_tasks View, add, complete, or replace the shared task list.
team_claim Atomically claim a pending task. Checks dependency resolution before allowing claim.
team_approve_plan Lead-only. Approve (unlocks write tools) or reject (keep read-only) a teammate's plan via Team.approvePlan().
team_shutdown Request graceful shutdown of a teammate.
team_cleanup Lead-only. Remove team resources. Reports delegate restriction removal.

Security & authorization:

  • Teammates are denied team_create, team_spawn, team_shutdown, team_cleanup, team_approve_plan via session permission rules
  • Reserved name "lead" rejected on spawn
  • Plan approval uses tagged deny patterns (*:plan-approval) distinct from delegate deny patterns (*) so they can be independently managed
  • Delegate mode adds write-tool deny rules (bash, write, edit, multiedit, apply_patch) to the lead session

Teammate system prompt design

Teammates always receive the full provider-specific system prompt for their model (e.g. PROMPT_ANTHROPIC for Claude, PROMPT_BEAST for GPT-4/o1/o3, PROMPT_GEMINI for Gemini, PROMPT_CODEX for GPT-5/Codex). This matches Claude Code's behavior where sub-agents get the same system prompt as standalone sessions.

How it works: Teammate sessions are marked with session.teammate = true. In llm.ts, system prompt construction becomes additive for teammates:

// Teammate (additive):   provider prompt + agent prompt + input.system
// Non-teammate (existing): agent prompt OR provider prompt + input.system

Empty-provider fallback: if SystemPrompt.provider(model) returns empty for a teammate, falls back to SystemPrompt.instructions().

For Codex teammates, options.instructions is always set (API requirement).

The team-specific context (role identity, available tools, communication rules) is injected as a user message, not a system prompt — keeping it separate from the provider behavioral guidance.

Event-based decoupling

Team.cleanup() no longer imports Session directly. Instead it publishes TeamEvent.Cleaned with leadSessionID and delegate fields. The onCleanedRestorePermissions() listener (wired in bootstrap) subscribes to this event and handles the Session.update to remove delegate deny rules. This keeps the team module decoupled from session internals.

HTTP routes (server/routes/team.ts — 130 lines)

Routes use hono-openapi with describeRoute, validator, and resolver middleware for OpenAPI metadata, request validation, and consistent error responses:

  • GET /team — List all teams
  • GET /team/:name — Get team by name
  • GET /team/:name/tasks — Get team's task list
  • GET /team/by-session/:sessionID — Find team context for a session (team info + tasks + role)
  • POST /team/:name/delegate — Toggle delegate mode (validates body with Zod schema)

Bootstrap wiring (project/bootstrap.ts)

  • Team.onCleanedRestorePermissions() — wired before recovery
  • Team.recover() — marks stale teammates as interrupted
  • Team.autoCleanup() — wired after recovery completes

Registry integration (tool/registry.ts)

  • Conditional import + registration of all 9 team tools when Flag.OPENCODE_EXPERIMENTAL_AGENT_TEAMS is enabled

Server integration (server/server.ts)

  • Mounts TeamRoutes() at /team path — single 2-line change

Tests

11 test files, 134 tests covering:

Test file Coverage
team.test.ts Core tool execution, auto-cleanup behavior, constraints
team-spawn.test.ts Spawn validation — agent resolution, model validation, permission rules, plan mode, session.teammate flag
team-e2e.test.ts Full lifecycle — create → spawn → work → message → complete → shutdown → cleanup
team-edge-cases.test.ts Error paths — invalid names, missing teams, double create, nested team prevention, cleanup with active members
team-scenarios.test.ts Real-world patterns — multi-agent code review, parallel implementation, research → implement pipeline
team-plan-approval.test.ts Plan approval flow — pending → approved (unlocks tools), pending → rejected (stays read-only)
team-delegate-cleanup.test.ts Delegate mode — lead permission denial, cleanup restores permissions via event (no sleeps — Bus.publish awaits subscribers)
team-integration.ts Integration patterns — team + task tool interaction, concurrent operations
team-multi-model.ts Multi-model teams — different providers per teammate, model resolution priority chain
team-scenarios-integration.ts Cross-cutting scenarios — error recovery, message ordering, task dependency chains

Files changed

File Change
src/tool/team.ts New — 9 MCP tools (thin wrappers)
src/team/index.ts Modified — +333 lines (resolveModel, spawnMember, approvePlan, notifyLead, autoCleanup, onCleanedRestorePermissions)
src/server/routes/team.ts New — hono-openapi routes with validation
src/project/bootstrap.ts Modified — wire event listeners and auto-cleanup
src/session/llm.ts Modified — additive system prompt for teammates, empty-provider fallback
src/session/index.ts Modified — add teammate flag to Session.Info
src/session/prompt.ts Modified — pass teammate + sessionPermission to LLM
src/tool/registry.ts Modified — conditional registration
src/server/server.ts Modified — mount routes
test/team/*.test.ts New — 11 test files, 134 tests
Total +8,198 / −11

Stack

PR 2/3 — merge in order:

  1. feat: add agent team core — Team namespace, messaging, recovery, and events #12730 — Core team primitives
  2. This PR — Tools + routes + prompting + lifecycle
  3. feat: add team TUI integration — sidebar, header, sync, and team dialog #12732 — TUI integration

@github-actions
Copy link
Contributor

github-actions bot commented Feb 8, 2026

Thanks for your contribution!

This PR doesn't have a linked issue. All PRs must reference an existing issue.

Please:

  1. Open an issue describing the bug/feature (if one doesn't exist)
  2. Add Fixes #<number> or Closes #<number> to this PR description

See CONTRIBUTING.md for details.

@github-actions
Copy link
Contributor

github-actions bot commented Feb 8, 2026

The following comment was made by an LLM, it may be inaccurate:

Based on my search, I found two related PRs that are part of the same feature stack:

  1. PR feat: add agent team core — Team namespace, messaging, recovery, and events #12730feat: add agent team core — Team namespace, messaging, recovery, and events

  2. PR feat: add team TUI integration — sidebar, header, sync, and team dialog #12732feat: add team TUI integration — sidebar, header, sync, and team dialog

These are not duplicates but rather sequential dependencies in a 3-part feature implementation for agent teams. PR #12731 is the middle piece that adds the tool layer and API routes between the core primitives (#12730) and the UI integration (#12732).

…tative

- Set shutdown_requested BEFORE sending message (fixes autoWake race)
- Remove force:true from shutdown transition (prevent resurrection)
- Fallback to direct shutdown if message delivery fails
- Make shutdown authoritative: updated description and message text
@ugoenyioha ugoenyioha marked this pull request as ready for review February 10, 2026 23:06
… test

- Update tool/team.ts with shutdown race condition fix
- Update server routes, tool registry to latest dev
- Add task-team-isolation test
- Sync team core deps (events, index, messaging)
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.

[DESIGN]: Agent Teams — flat teams with named messaging, multi-model support, and TUI integration

2 participants

Comments