Skip to content

fix: switching from plan to implementation#8897

Closed
assagman wants to merge 5 commits intoanomalyco:devfrom
assagman:fix/plan-to-build
Closed

fix: switching from plan to implementation#8897
assagman wants to merge 5 commits intoanomalyco:devfrom
assagman:fix/plan-to-build

Conversation

@assagman
Copy link
Contributor

@assagman assagman commented Jan 16, 2026

Fixes: #9055

@github-actions
Copy link
Contributor

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

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

No duplicate PRs found

@sandys
Copy link

sandys commented Jan 17, 2026

please check out #6315 . but your PR is better !

@assagman assagman marked this pull request as ready for review January 17, 2026 08:50
Copilot AI review requested due to automatic review settings January 17, 2026 08:50
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes the hardcoded "build" agent reference in the plan_exit tool to dynamically resolve the appropriate implementation agent based on configuration and availability. The change enables better support for custom agent configurations where "build" may be disabled or unavailable.

Changes:

  • Added Agent.getOrDefault() and Agent.isPrimaryVisible() helper functions for consistent agent resolution
  • Implemented resolveImplementationAgent() to intelligently select the target agent when exiting plan mode
  • Updated documentation to clarify that invalid default_agent configurations will now error instead of silently falling back

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
packages/sdk/js/src/v2/gen/types.gen.ts Updated documentation for default_agent to clarify error behavior
packages/opencode/src/config/config.ts Updated schema description to match types.gen.ts documentation
packages/opencode/src/agent/agent.ts Added isPrimaryVisible() helper and getOrDefault() for graceful agent resolution with fallback
packages/opencode/src/tool/plan.ts Added resolveImplementationAgent() function and updated plan_exit/plan_enter tools to use dynamic agent resolution and store agent in metadata
packages/opencode/src/session/prompt.ts Replaced Agent.get() with Agent.getOrDefault() in three locations to gracefully handle missing agents
packages/opencode/src/session/processor.ts Updated doom loop detection to use Agent.getOrDefault() for resilience
packages/opencode/src/cli/cmd/github.ts Updated comment to document new fallback behavior
packages/opencode/src/cli/cmd/tui/routes/session/index.tsx Updated TUI to read target agent from tool metadata instead of hardcoding
packages/opencode/src/cli/cmd/tui/context/local.tsx Refactored to use Agent.isPrimaryVisible() helper for consistency
packages/opencode/src/acp/agent.ts Refactored to use Agent.isPrimaryVisible() helper for consistency
packages/opencode/test/tool/plan.test.ts Added comprehensive test coverage for resolveImplementationAgent()
packages/opencode/test/agent/agent.test.ts Added test coverage for new Agent.getOrDefault() function

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +94 to +96
const target = await resolveImplementationAgent()
// explore is subagent, so it should fallback to myimpl or plan
expect(["myimpl", "plan"]).toContain(target)
Copy link

Copilot AI Jan 17, 2026

Choose a reason for hiding this comment

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

The test assertion is too permissive. Given the logic in resolveImplementationAgent, when build is disabled and myimpl exists as a primary agent, the function will deterministically return "myimpl" (line 33-34 of plan.ts finds the first visible primary agent that is not "plan"). The test should expect exactly "myimpl" rather than accepting either "myimpl" or "plan".

Copilot uses AI. Check for mistakes.
@assagman
Copy link
Contributor Author

please check out #6315 . but your PR is better !

yes, I experienced a kind of looping behavior too, but apparently we followed too different approaches.

I think the core issue here is that all the existing implementation heavily depends on hardcoded "build" agent. However, opencode config does allow users to mutate the "build" agent. This situation is conflicting. Either the build agent must be immutable or codebase should be eliminated from these assumptions. I think all of the default agents can be replaceable by user-defined agents, even plan, compaction, renaming etc.. I'm not sure if this idea aligns with the team or not, needs more discussion.

cc: @rekram1-node @thdxr

@sandys
Copy link

sandys commented Jan 17, 2026 via email

@rwese
Copy link
Contributor

rwese commented Jan 22, 2026

I was just starting to implement this in a similar way, after playing a bit with claude.

My approach, for picking the agent to exit to, would be:

  1. a configuration option "default plan execution agent", which should be noted in the prompt.. "Exit plan mode and switch to ..."
  2. a choice list of all primary agents, except the current one, usually "plan".. "Exit plan mode, pick agent to execute..."

if either of those are to anyones liking, i can provide the changes.

…agent

Users with custom agents who disabled the default 'build' agent experienced
a crash when completing a plan and accepting the switch prompt. The session
would crash with 'undefined is not an object (evaluating agent.steps)'.

Now plan_exit dynamically resolves the target agent: prefers 'build' if
available, falls back to default_agent config, then first visible primary
agent. Defensive guards added throughout session handling to prevent similar
crashes when an agent becomes unavailable.

Signed-off-by: assagman <ahmetsercansagman@gmail.com>
Extract repeated fallback logic into Agent.getOrFallback() to follow
style guide preference for const over let with reassignment.

Signed-off-by: assagman <ahmetsercansagman@gmail.com>
…aram

Allow callers to omit agent name, defaulting to the configured fallback.
Simplifies call sites by removing redundant fallback logic.

Signed-off-by: assagman <ahmetsercansagman@gmail.com>
Cover all branches: existing agent, undefined name, nonexistent agent,
custom default_agent config, and error when no fallback exists.

Signed-off-by: assagman <ahmetsercansagman@gmail.com>
…ead of silently falling back

Signed-off-by: assagman <ahmetsercansagman@gmail.com>
@assagman
Copy link
Contributor Author

I was just starting to implement this in a similar way, after playing a bit with claude.

My approach, for picking the agent to exit to, would be:

  1. a configuration option "default plan execution agent", which should be noted in the prompt.. "Exit plan mode and switch to ..."
  2. a choice list of all primary agents, except the current one, usually "plan".. "Exit plan mode, pick agent to execute..."

if either of those are to anyones liking, i can provide the changes.

Yes it's a decision point, like an extra feature. Here, the main problem is that I disabled build agent and opencode has assumptions regarding using build agent few places automatically. This causes errors/unexpected behaviors. So I decided to manage default agent behavior with introducing "primary visible" concept to make it easy to manage.

Here you can see that after planning is completed, it suggest user to use NULL agent which is my main agent locally. This SS was taken from the opencode instance opened bun run dev in this branch

Screenshot 2026-01-22 at 17 10 44

@assagman
Copy link
Contributor Author

apparently this issue has been tried to be resolved by both the opencode team and the community. different thoughts, different approaches are flying around.

closing this one. may open a new one if needed

@assagman assagman closed this Jan 30, 2026
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.

[bug] switching from plan mode to build agent

3 participants