#18498 · @Haohao-end · opened Mar 21, 2026 at 8:11 AM UTC · last updated Mar 21, 2026 at 8:33 AM UTC

fix(tui): prevent subagent sessions from overwriting the selected agent

tuifix
70
+322 files

Score breakdown

Impact

8.0

Clarity

8.0

Urgency

8.0

Ease Of Review

8.0

Guidelines

6.0

Readiness

7.0

Size

10.0

Trust

5.0

Traction

4.0

Summary

This PR addresses a critical bug in the TUI where subagent sessions incorrectly overwrite the primary agent, leading to identity swapping and dysfunctional tool calls. The change prevents this by restricting agent switching logic to root sessions. However, thorough local validation was not performed, raising concerns.

Open in GitHub

Description

Summary

Fixes #18404

Prevent child/subagent sessions from mutating the globally selected primary agent in the TUI.

This change gates both:

  • prompt-state restore
  • tool-driven plan/build agent switching

to root sessions only (!session.parentID).

As a result, subagent sessions no longer overwrite the selected primary agent after tool activity, while existing root-session behavior remains unchanged.

Testing

  • Verified the change is limited to the TUI agent-selection paths in:
    • packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx
    • packages/opencode/src/cli/cmd/tui/routes/session/index.tsx
  • CI bun typecheck currently fails in packages/app, not in the files touched by this PR.
  • I was not able to run the repo’s normal Bun/tsgo validation locally in the original shell used for development because those tools were unavailable there.

Linked Issues

#18404 Subagent identity swapping after first tool call

View issue

Comments

PR comments

Haohao-end

Updated the PR description to use the template and linked the issue with Fixes #18404.

Also, the current bun typecheck failure appears to be in packages/app:

  • src/components/dialog-connect-provider.tsx
  • src/components/dialog-custom-provider.tsx

Those files are unrelated to this PR’s TUI-only changes.

Changed Files

packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx

+22
@@ -154,13 +154,13 @@ export function Prompt(props: PromptProps) {
createEffect(() => {
const sessionID = props.sessionID
const msg = lastUserMessage()
const info = sessionID ? sync.session.get(sessionID) : undefined
if (sessionID !== syncedSessionID) {
if (!sessionID || !msg) return
if (!sessionID || !msg || !info || info.parentID) return
syncedSessionID = sessionID
// Only set agent if it's a primary agent (not a subagent)
const isPrimaryAgent = local.agent.list().some((x) => x.name === msg.agent)
if (msg.agent && isPrimaryAgent) {
local.agent.set(msg.agent)

packages/opencode/src/cli/cmd/tui/routes/session/index.tsx

+10
@@ -219,6 +219,7 @@ export function Session() {
const part = evt.properties.part
if (part.type !== "tool") return
if (part.sessionID !== route.sessionID) return
if (session()?.parentID) return
if (part.state.status !== "completed") return
if (part.id === lastSwitch) return