Skip to content

feat: add slash commands for agent switching#2790

Open
dgageot wants to merge 6 commits into
docker:mainfrom
dgageot:feat/agent-switching-commands
Open

feat: add slash commands for agent switching#2790
dgageot wants to merge 6 commits into
docker:mainfrom
dgageot:feat/agent-switching-commands

Conversation

@dgageot
Copy link
Copy Markdown
Member

@dgageot dgageot commented May 13, 2026

Summary

Adds support for slash commands that switch the active agent. For example, declaring /plan in the agent config makes the planner sub-agent take over the conversation when the user types /plan.

Usage

A new agent: field can be set on a command in agent.yaml:

agents:
  root:
    sub_agents: [planner, reviewer]
    commands:
      plan:
        description: Hand off to the planner
        agent: planner
      review:
        description: Hand off to the reviewer
        agent: reviewer

When the user types /plan, the active agent is switched to planner. Anything typed after the command (e.g. /plan add a logout button) is forwarded to the target agent as the first user message.

agent: can be combined with instruction: to switch and send a fixed prompt; on its own it acts as a pure handoff.

A complete example lives in examples/agent_switching_commands.yaml.

Changes

  • pkg/config/types/commands.go — new Agent field on Command; YAML parser accepts the agent key.
  • pkg/runtime/commands.go — new LookupCommand helper; ResolveCommand forwards trailing args verbatim for agent-only commands.
  • pkg/app/app.go — exposes App.LookupCommand.
  • pkg/tui/handlers.gohandleAgentCommand switches the active agent before sending the resolved message.
  • pkg/cli/runner.goPrepareUserMessage does the same for the non-TUI flow.
  • agent-schema.json — documents the new agent property.
  • examples/agent_switching_commands.yaml — full example with /plan, /review, /back.
  • pkg/runtime/commands_test.go — unit tests for the new behavior.

Validation

  • task lint clean.
  • task test passes for all changed packages.
  • task build succeeds.

@dgageot dgageot requested a review from a team as a code owner May 13, 2026 14:01
trungutt
trungutt previously approved these changes May 13, 2026
docker-agent

This comment was marked as outdated.

Comment thread pkg/cli/runner.go
Comment thread agent-schema.json
Comment thread pkg/tui/handlers.go
Comment thread pkg/cli/runner.go
Comment thread pkg/config/types/commands.go
@dgageot dgageot force-pushed the feat/agent-switching-commands branch from 7df0e5a to 7e3d57d Compare May 18, 2026 08:41
@dgageot
Copy link
Copy Markdown
Member Author

dgageot commented May 18, 2026

/review

docker-agent

This comment was marked as outdated.

dgageot added a commit to dgageot/cagent that referenced this pull request May 18, 2026
This commit addresses all review feedback from PR docker#2790:

**Critical fixes (blocking issues):**

1. **Fix SetCurrentAgent error handling in CLI and TUI** (runner.go, handlers.go)
   - If SetCurrentAgent fails, we now return an empty message instead of
     proceeding to send the message to the wrong agent
   - Added checked type assertion in TUI to prevent potential panics
   - Both CLI and TUI now properly handle agent switch failures

2. **Add unit tests for PrepareUserMessage and agent switching** (runner_test.go)
   - Added comprehensive tests for agent-switching commands
   - Tests cover success cases, failure cases, and edge cases
   - Tests verify that empty messages are returned on switch failures
   - Tests verify that agent-only commands (no instruction) work correctly

**Non-blocking improvements:**

3. **Update agent-schema.json** (agent-schema.json)
   - Changed description from 'must be reachable from sub-agent graph' to
     'must be defined in team configuration' to match runtime behavior
   - The runtime validates agent existence but doesn't enforce graph reachability

4. **Add explanatory comment for fallback logic** (commands.go)
   - Added comment explaining why description falls back to instruction
   - Clarifies the shorthand command definition behavior

5. **Improve code quality**
   - Fixed unchecked type assertion in TUI handlers
   - Used slog.WarnContext instead of slog.Warn for proper context propagation
   - All linters pass, all tests pass

Addresses feedback from @aheritier and docker-agent bot.
@dgageot dgageot requested a review from aheritier May 18, 2026 08:59
docker-agent

This comment was marked as outdated.

dgageot added 5 commits May 18, 2026 14:28
Add support for commands that switch the active agent via a new 'agent:' field
in the commands section of agent.yaml. Users can now use /plan to switch to a
planner sub-agent, /review to switch to a reviewer, etc. Trailing arguments
after the command are forwarded to the target agent as the first prompt.
Wires the new agent-switching slash command feature into the built-in coder agent:
- Adds a planner sub-agent with read-only tools (filesystem, fetch, todo, user_prompt)
- Adds /plan command on root agent to switch to plan mode
- Adds symmetric /back command on planner agent to hand work back
- Updates root instruction to mention the /plan command
Addresses review feedback from docker-agent bot:

1. In pkg/cli/runner.go (PrepareUserMessage):
   - Moved ResolveCommand call BEFORE SetCurrentAgent
   - This ensures the command is looked up in the original agent's command table
   - Prevents raw slash-command strings from being sent to target agents when
     the target agent doesn't have the command defined

2. In pkg/tui/handlers.go (handleAgentCommand):
   - Added switchSucceeded flag to track whether agent switch was successful
   - Only send resolved message if the agent switch succeeded
   - Prevents messages from being sent to the wrong agent when switching fails
This commit addresses all review feedback from PR docker#2790:

**Critical fixes (blocking issues):**

1. **Fix SetCurrentAgent error handling in CLI and TUI** (runner.go, handlers.go)
   - If SetCurrentAgent fails, we now return an empty message instead of
     proceeding to send the message to the wrong agent
   - Added checked type assertion in TUI to prevent potential panics
   - Both CLI and TUI now properly handle agent switch failures

2. **Add unit tests for PrepareUserMessage and agent switching** (runner_test.go)
   - Added comprehensive tests for agent-switching commands
   - Tests cover success cases, failure cases, and edge cases
   - Tests verify that empty messages are returned on switch failures
   - Tests verify that agent-only commands (no instruction) work correctly

**Non-blocking improvements:**

3. **Update agent-schema.json** (agent-schema.json)
   - Changed description from 'must be reachable from sub-agent graph' to
     'must be defined in team configuration' to match runtime behavior
   - The runtime validates agent existence but doesn't enforce graph reachability

4. **Add explanatory comment for fallback logic** (commands.go)
   - Added comment explaining why description falls back to instruction
   - Clarifies the shorthand command definition behavior

5. **Improve code quality**
   - Fixed unchecked type assertion in TUI handlers
   - Used slog.WarnContext instead of slog.Warn for proper context propagation
   - All linters pass, all tests pass

Addresses feedback from @aheritier and docker-agent bot.
Address critical review feedback from docker-agent bot:

**CLI (runner.go) fixes:**
1. Resolve command content BEFORE switching agents - Previously,
   SetCurrentAgent was called before ResolveCommand, causing the
   command lookup to run against the new agent's command table instead
   of the original agent's. This resulted in raw slash-command strings
   being sent to the target agent when the command wasn't re-declared.

2. Return explicit error on agent-switch failure - Previously returned
   an empty UserMessage that was unconditionally added to the session,
   silently corrupting conversation history. Now returns (nil, "", error)
   so callers can handle the failure properly.

3. Handle agent-only commands with no trailing args - When a command
   like /plan has no instruction and no trailing text, return
   (nil, "", nil) to signal successful agent switch with no message
   to send, preventing empty messages from being forwarded to the LLM.

**TUI (handlers.go) fixes:**
Already implemented in the current code:
- Check if agent switch succeeded before sending resolved message
- Use comma-ok form for type assertion to prevent panics

**Test updates:**
- Update PrepareUserMessage signature to return error
- Fix test expectations to match new nil-message behavior
- Add expectError and expectNilMessage flags to test cases

All linters and tests passing.
@dgageot dgageot force-pushed the feat/agent-switching-commands branch from a8dfd3a to 68b8555 Compare May 18, 2026 12:38
@dgageot
Copy link
Copy Markdown
Member Author

dgageot commented May 18, 2026

/review

@docker-agent
Copy link
Copy Markdown

PR Review Failed — The review agent encountered an error and could not complete the review. View logs.

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.

4 participants