Skip to content

feat: add switch_agent tool for model-initiated agent switching#262

Open
marius-kilocode wants to merge 2 commits intodevfrom
feat/switch-agent-tool
Open

feat: add switch_agent tool for model-initiated agent switching#262
marius-kilocode wants to merge 2 commits intodevfrom
feat/switch-agent-tool

Conversation

@marius-kilocode
Copy link
Collaborator

Summary

  • Adds a switch_agent tool that allows the AI model to request switching between primary agents (code, plan, debug, orchestrator) during a conversation
  • Uses the existing permission system (ctx.ask) so users can configure it as ask (default, prompts user), allow (auto-approve), or deny (block) in their opencode.json
  • Fixes TUI agent indicator not updating when a mid-turn agent switch occurs via synthetic user message

How it works

  1. The tool dynamically lists available agents in its description (same pattern as the task tool listing subagents)
  2. When invoked, it validates the target agent, asks for permission via ctx.ask(), then creates a synthetic user message with the new agent name
  3. The existing session loop picks up the new agent from lastUser.agent - no loop changes needed
  4. The TUI now reactively tracks lastUserMessage().id to update the agent indicator on mid-turn switches

Files changed

File Change
packages/opencode/src/tool/switch-agent.ts New tool implementation
packages/opencode/src/tool/switch-agent.txt Tool description template with {agents} placeholder
packages/opencode/src/tool/registry.ts Register SwitchAgentTool
packages/opencode/src/agent/agent.ts Add switch_agent permission: deny default, ask for code/plan/debug/orchestrator
packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx Reactive agent sync on mid-turn switch
packages/opencode/test/agent/switch-agent.test.ts 9 permission tests

User configuration

{
  "agent": {
    "code": {
      "permission": {
        "switch_agent": "allow"
      }
    }
  }
}

Allow the AI model to request switching between primary agents (code,
plan, debug, orchestrator) during a conversation. Uses the existing
permission system (ctx.ask) so users can configure it as ask/allow/deny.

Creates a synthetic user message with the new agent name, which the
session loop picks up naturally. The TUI agent indicator now also
reactively updates when a mid-turn switch occurs.
await ctx.ask({
permission: "switch_agent",
patterns: [params.agent],
always: ["*"],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WARNING: always: ["*"] makes "Always allow" approval apply to all future agent switches

For switch_agent, approving "always" effectively allows switching to any agent without prompting, which can act like a permission escalation path. Scoping the persisted approval to the requested agent name keeps the UX ("always allow this") while reducing blast radius.

Suggested change
always: ["*"],
always: [params.agent],

@kiloconnect
Copy link
Contributor

kiloconnect bot commented Feb 12, 2026

Code Review Summary

Status: 1 Issues Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 1
SUGGESTION 0
Issue Details (click to expand)

WARNING

File Line Issue
packages/opencode/src/tool/switch-agent.ts 76 always: ["*"] scopes "always allow" too broadly for agent switching
Other Observations (not in diff)

Issues found in unchanged code that cannot receive inline comments:

File Line Issue
Files Reviewed (5 files)
  • packages/opencode/src/agent/agent.ts - 0 issues
  • packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx - 0 issues
  • packages/opencode/src/tool/registry.ts - 0 issues
  • packages/opencode/src/tool/switch-agent.ts - 1 issue
  • packages/opencode/test/agent/switch-agent.test.ts - 0 issues

Fix these issues in Kilo Cloud

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.

1 participant