fix: switching from plan to implementation#8897
fix: switching from plan to implementation#8897assagman wants to merge 5 commits intoanomalyco:devfrom
Conversation
|
Thanks for your contribution! This PR doesn't have a linked issue. All PRs must reference an existing issue. Please:
See CONTRIBUTING.md for details. |
|
The following comment was made by an LLM, it may be inaccurate: No duplicate PRs found |
|
please check out #6315 . but your PR is better ! |
There was a problem hiding this comment.
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()andAgent.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.
| const target = await resolveImplementationAgent() | ||
| // explore is subagent, so it should fallback to myimpl or plan | ||
| expect(["myimpl", "plan"]).toContain(target) |
There was a problem hiding this comment.
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".
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 |
|
Thats fair.
My solution is very limited in scope..it just adds a way for opencode to
drop out of plan mode.
User defined agents is very nice....but as you said, i wasnt sure if the
devs agree with that direction!
If your approach gets approved...it will definitely be better !
…On Sat, 17 Jan, 2026, 17:06 Sercan Sagman, ***@***.***> wrote:
*assagman* left a comment (anomalyco/opencode#8897)
<#8897 (comment)>
please check out #6315 <#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 <https://github.com/rekram1-node> @thdxr
<https://github.com/thdxr>
—
Reply to this email directly, view it on GitHub
<#8897 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAASYU2QI2YIEU7OTYZKTTD4HINDBAVCNFSM6AAAAACR5SF7Q6VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZTONRTGE4DINJSGU>
.
You are receiving this because you commented.Message ID:
***@***.***>
|
5eb6c07 to
9240c25
Compare
|
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:
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>
9240c25 to
1647af2
Compare
00637c0 to
71e0ba2
Compare
f1ae801 to
08fa7f7
Compare
|
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 |

Fixes: #9055