Skip to content

fix(desktop): Chat toggle attaches to the chat a terminal id already runs (SUPER-2635) - #8625

Draft
superset-app[bot] wants to merge 1 commit into
mainfrom
superset/super-2635-chat-reuses-run-session
Draft

superset-app[bot] wants to merge 1 commit into
mainfrom
superset/super-2635-chat-reuses-run-session

Conversation

@superset-app

@superset-app superset-app Bot commented Oct 18, 2026 •

Copy link
Copy Markdown
Contributor

Related to SUPER-2635, but does not fix what that issue reports (see "Verification"). It fixes a real duplicate-session path that comes from the SUPER-2825 bug.

What this fixes

With acp-chat on, automation dispatch calls agents.run with surface: "chat". The host starts a chat session (launchChatAgent) and binds it to a fresh terminal id that has no PTY. The run row stores that terminal id.

Several desktop paths treat that terminal id as a PTY and open a bare terminal pane for it (#8626 fixes those paths). That pane looks up the id's agent binding, which terminalAgents.listByWorkspace returns for chats too. So it shows the CLI/Chat toggle. Clicking Chat ran switchSurface("acp"), which:

  1. killed the (non-existent) terminal. terminal.killSession succeeds for an unknown id, so the switch continues, and
  2. replaced the pane with a chat-v3 pane with sessionId: null.

AcpChatPane creates a session whenever sessionId is null (createSession({ terminalId, resume })), and the chat runtime does not deduplicate by terminal id. So the same agent conversation is resumed in a second chat session while the run's session keeps running.

Change

  • useAgentSurfaceSwitch: when the terminal id already has a chat binding (binding.chatSessionId), the new chat pane carries that session id. Nothing is killed, because there is no PTY. Plain terminal agents keep the old behaviour (kill the PTY, then start a chat that resumes the agent session).
  • useAgentSurface: offers the toggle for a chat binding even before the agent has reported its own session id.

Verification

This path: reproduced on main (0e0c87f), fixed on this branch. A hook-level repro renders the real useAgentSurfaceSwitch against a real @superset/panes store. Only the host is faked: terminal id T1 has a chat binding (chatSessionId: chat-session-1) and no PTY. It calls switchSurface(ctx, "acp", agent) on a bare terminal pane for T1.

  • main: ❌ the new chat-v3 pane has sessionId: null, so AcpChatPane starts a second session, and terminal.killSession is called.
  • this branch: ✅ the pane has sessionId: "chat-session-1", and killSession is not called.

The repro is not committed (it has to mock.module @superset/workspace-client). useAgentSurfaceSwitch.test.ts is the committed regression test.

SUPER-2635 as reported: a different root cause, already fixed on main by #8242.

  • The issue was filed at 2026-10-06 16:49 UTC. Chat-surface automation runs did not exist yet: feat(chat): a chat pane of its own, host-started chats, and no leaked chat agents #8242 (host-started chats, surface: "chat" dispatch, continueChatAgent) was opened at 22:54 UTC that day and merged at 01:30 UTC on 10-07. So the path above cannot be what the reporter hit.
  • On the reporter's build (66e170b), automations ran Claude in a terminal. With "continue the agent session", the next run delivered the prompt only into the previous run's PTY (continueTerminalAgent). Switching that agent to Chat kills its PTY and starts a chat on the same terminal id. A host-level repro on 66e170b (real TerminalAgentStore and continuationTarget, with the chat binding recorded as the chat bridge does) shows the next run accept T1 as the target. The send then goes to a PTY that no longer exists, so continueTerminalAgent returns null and agents.run launches a new agent on every run. That matches the screenshot: 16 Claude agents in the "Email Triage" workspace. The send failing on a disposed PTY comes from reading the code, not from running it.
  • The same repro on main delivers into the chat (chatContinuationTarget returns chat-2), so this direction is fixed.
  • Still broken on main, not fixed by this PR: the reverse direction. A chat run switched to CLI gets its conversation resumed in a new terminal T2, but the next continue-run still names T1. Neither the chat nor the terminal continuation finds it, so a new agent launches. Shown by the same host repro on main. Needs a separate change (for example, continuation following the resumed successor).
  • I could not confirm whether the reporter's automation had "continue the agent session" on. Without it, a new agent per run is by design.

Also run: bun test over v2-workspace (752 pass); bun run typecheck in apps/desktop; biome. This branch merges cleanly with #8626, and the repro passes on the merged tree.

Not verified in the running desktop app. This cloud workspace has no signed-in desktop session, no acp-chat host, and no Claude credentials.

Tests

  • useAgentSurfaceSwitch.test.ts: a chat-bound terminal maps to its existing chat session. A terminal agent still gets sessionId: null.

Summary by cubic

Fixes the CLI/Chat toggle in a terminal pane creating a duplicate chat session for automation runs that already run a chat.

When a chat-surface automation run binds to a terminal id that has no PTY, switching that pane to Chat now opens the existing chat session instead of killing the (non-existent) terminal and starting a second session that resumes the same agent conversation. Plain terminal agents keep the old behavior: the PTY is killed and a new chat session is started.

Also makes the CLI/Chat toggle appear for chat bindings even before the agent has reported its own session id.

Written for commit e2e6c64. Summary will update on new commits.

View guided diff Turn on auto-fix

…runs (SUPER-2635)

A chat-surface automation run starts a host chat session bound to a
terminal id that has no PTY. When that id ended up in a terminal pane, the
pane offered the CLI/Chat toggle from the chat's binding, and "Chat"
replaced it with a chat pane whose sessionId was null. AcpChatPane then
created a second session resuming the same agent conversation, so the
user's message went to a new agent while the run's session kept running.

The switch now reads the terminal's binding: a terminal that already runs
a chat gets a chat pane on that chat session, and no terminal is killed,
since there is none. The toggle is offered for a chat binding even before
the agent has reported its own session id.
@coderabbitai

coderabbitai Bot commented Oct 18, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Bot user detected.

To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration
  • Configuration used: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: c50978c5-343f-48e8-81c8-bb5268ccbf89

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

Copy link
Copy Markdown
Contributor

🚀 Preview Deployment

🔗 Preview Links

Service Status Link
Neon Database (Neon) ✅ View Branch
Vercel API (Vercel) ✅ Open Preview
Vercel Web (Vercel) ✅ Open Preview
Vercel Marketing (Vercel) ✅ Open Preview
Vercel Docs (Vercel) ✅ Open Preview

Preview updates automatically with new commits

@greptile-apps

greptile-apps Bot commented Oct 18, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerView in GreptileConfidence Score: 4/5

[Medium impact] Chat toggle logic for terminal panes.

The PR appears safe to merge, with a non-blocking request to test the no-kill behavior.

Findings

  1. P2 No-kill behavior remains untested ▶
Fix with agent prompt
### Issue 1
apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/usePaneRegistry/components/AgentTerminalPane/hooks/useAgentSurfaceSwitch/useAgentSurfaceSwitch.test.ts:7-14
These tests check only `chatPaneDataForTerminal`, so they would still pass if `switchSurface` killed a chat-bound terminal. Add a test that calls `switchSurface` with a chat binding and checks that it preserves the session without calling `killSession`. Also cover a binding without `agentSessionId`, since this PR now offers the toggle in that case.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Summary

The Chat toggle now attaches to the chat already bound to a terminal ID instead of starting another chat.

  • The Chat toggle reuses the chat already tied to a terminal.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[User selects Chat] --> B{Existing chat binding?}
    B -->|Yes| C[Keep existing chat session ID]
    B -->|No| D[Stop terminal process]
    D --> E[Create chat pane without a session ID]
    C --> F[Attach to existing chat]
    E --> G[Start chat and resume agent conversation]
Loading

Reviews (1) · Last reviewed commit: "fix(desktop): Chat toggle attaches to th..." · Reviewed by Greptile

Comment on lines +7 to +14
it("attaches to the chat already running on the terminal", () => {
expect(
chatPaneDataForTerminal({
terminalId: "terminal-1",
agent,
binding: { chatSessionId: "chat-1" },
}),
).toEqual({ terminalId: "terminal-1", sessionId: "chat-1", agent });

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 No-kill behavior remains untested

These tests check only chatPaneDataForTerminal, so they would still pass if switchSurface killed a chat-bound terminal. Add a test that calls switchSurface with a chat binding and checks that it preserves the session without calling killSession. Also cover a binding without agentSessionId, since this PR now offers the toggle in that case.

Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/usePaneRegistry/components/AgentTerminalPane/hooks/useAgentSurfaceSwitch/useAgentSurfaceSwitch.test.ts
Line: 7-14

Comment:
**No-kill behavior remains untested**

These tests check only `chatPaneDataForTerminal`, so they would still pass if `switchSurface` killed a chat-bound terminal. Add a test that calls `switchSurface` with a chat binding and checks that it preserves the session without calling `killSession`. Also cover a binding without `agentSessionId`, since this PR now offers the toggle in that case.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

This branch was previously deployed

1 inactive deployment
preview — e2e6c644 Deployed Oct 18, 2026 by superset-app[bot] via Deploy Marketing #12175
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