Skip to content

fix(session): surface empty aborted turns - #17909

Closed
dzianisv wants to merge 37 commits into
anomalyco:devfrom
dzianisv:issue-17895-aborted-empty-turn
Closed

dzianisv wants to merge 37 commits into
anomalyco:devfrom
dzianisv:issue-17895-aborted-empty-turn

Conversation

@dzianisv

Copy link
Copy Markdown

Summary

  • persist structured abort provenance on MessageAbortedError
  • mark restart-recovered orphan assistant turns as aborted instead of only force-completing them
  • render completed aborted assistant turns with no visible output as an explicit interruption card in the web UI
  • add focused regression coverage for abort provenance, recovery, and zero-part aborted turn rendering

Changes

  • extend MessageAbortedError with optional structured source
  • propagate structured abort reasons through prompt cancellation and restart teardown
  • update Session.recover() to persist server_restart abort state for orphan assistant messages
  • add a dedicated SessionTurn interruption card for completed aborted zero-part assistant turns
  • keep the abort-card visibility helper aligned with actual UI renderability so structural-only parts still show the interruption state
  • regenerate SDK v2 types after the schema change

Testing

  • cd packages/opencode && bun test test/session/message-v2.test.ts test/session/session.test.ts
  • cd packages/ui && bun test src/components/session-turn.test.ts src/components/message-file.test.ts src/components/scroll-view.test.ts
  • cd packages/opencode && bun typecheck
  • cd packages/ui && bun typecheck
  • cd packages/sdk/js && bun typecheck
  • cd packages/app && bun typecheck

Closes #17895

engineer and others added 30 commits March 14, 2026 21:40
…n, external watchdog

- MCP shared map now tracks lastUsed timestamp; periodic sweep closes
  idle clients after OPENCODE_MCP_IDLE_MS (default 10 min)
- Instance disposal force-closes MCP clients immediately
- Session sweep in serve mode archives sessions idle beyond
  OPENCODE_SESSION_IDLE_MS (default 30 min)
- SIGTERM/SIGINT in serve mode captures final memory snapshot
- External watchdog script + launchd plist for crash-surviving
  process-tree RSS monitoring

Addresses child-process memory accumulation that caused overnight
macOS kernel watchdog panic (8.5 GB tree RSS, 238 active sessions).
Primary leak source identified as chrome-devtools-mcp --autoConnect
growing ~13 MB/min.

Ref: anomalyco#16697

Co-authored-by: Copilot <[email protected]>
Shutdown handler was missing Instance.disposeAll() and MCP.closeAll(),
causing MCP child processes (chrome-devtools-mcp, etc.) to become
orphans on SIGTERM/SIGINT. Now the shutdown sequence is:

1. Stop session sweep
2. Capture final memory snapshot
3. Stop memory monitor
4. Dispose all instances (triggers force-release of MCP refs)
5. Close any remaining shared MCP clients
6. Stop HTTP server

Also added MCP.stopMcpSweep() and MCP.closeAll() exports.

Co-authored-by: Copilot <[email protected]>
Question tool and permission ask() both use Deferred.await() which
blocks indefinitely with no timeout or abort handling. When the AI
SDK issues multiple tool calls in a single step, one stuck tool
(e.g., unanswered question, unapproved permission) blocks the
entire stream, preventing the cleanup code from marking tools as
errored.

Fix: race both Question.ask() and PermissionNext.ask() against the
abort signal from the AI SDK. This ensures tool execution unblocks
when the session is cancelled, allowing the processor cleanup to
mark stuck tools as errored.

Co-authored-by: Copilot <[email protected]>
When the server restarts while tools are executing, their parts remain
stuck in "running" or "pending" state forever. Session.recover() runs
at startup and marks all such parts as "error" with a descriptive
message, unblocking affected sessions.

Co-authored-by: Copilot <[email protected]>
- Add GET /global/session endpoint using Session.listGlobal()
- Create Recent page component with search, project labels, diff stats
- Add /recent route and navigation button on Home page

Co-authored-by: Copilot <[email protected]>
Adds a status icon in the sidebar bottom section so the dashboard
is accessible from any project view, not just the home page.

Co-authored-by: Copilot <[email protected]>
- New rename tool lets the agent set a descriptive session title
- System prompt instructs agents to rename early once task is understood
- No permission required — lightweight metadata update

Co-authored-by: Copilot <[email protected]>
When packages/app/dist exists, serve static files from it directly.
Falls back to proxy to app.opencode.ai if local build is missing.
Enables local web UI customizations without cloud deployment.

Co-authored-by: Copilot <[email protected]>
Use same Button components, typography tokens, and layout patterns
as the Home page for a consistent native look.

Co-authored-by: Copilot <[email protected]>
engineer and others added 7 commits March 15, 2026 17:40
The fork publish creates @vibetechnologies/opencode-{os}-{arch} packages
but bin/opencode and postinstall.mjs hardcoded unscoped names, so
binary resolution failed after `bun add -g @vibetechnologies/opencode`.

Now publish-fork.ts patches both files to use the @VibeTechnologies scope
when looking up platform-specific binary packages in node_modules.

Co-authored-by: Copilot <[email protected]>
30-minute default was archiving all sessions, hiding them from sidebar.

Co-authored-by: Copilot <[email protected]>
Assistant messages without time.completed cause permanent spinner
in sidebar after server restart. Now Session.recover() also completes
these orphaned messages, matching the existing tool part recovery.

Co-authored-by: Copilot <[email protected]>
When session status is idle, the pending memo now returns undefined
instead of searching for incomplete assistant messages. This prevents
permanent Thinking spinners caused by:
- Orphaned messages from interrupted streams
- Stale in-memory store data after server-side recovery

Fixes anomalyco#17680

Co-authored-by: Copilot <[email protected]>
@dzianisv
dzianisv requested a review from adamdotdevin as a code owner March 17, 2026 05:13
@github-actions github-actions Bot added the needs:compliance This means the issue will auto-close after 2 hours. label Mar 17, 2026
@github-actions

Copy link
Copy Markdown
Contributor

This PR doesn't fully meet our contributing guidelines and PR template.

What needs to be fixed:

  • PR description is missing required template sections. Please use the PR template.

Please edit this PR description to address the above within 2 hours, or it will be automatically closed.

If you believe this was flagged incorrectly, please let a maintainer know.

@github-actions

Copy link
Copy Markdown
Contributor

This pull request has been automatically closed because it was not updated to meet our contributing guidelines within the 2-hour window.

Feel free to open a new pull request that follows our guidelines.

@github-actions github-actions Bot removed the needs:compliance This means the issue will auto-close after 2 hours. label Mar 17, 2026
@github-actions github-actions Bot closed this Mar 17, 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.

Completed aborted assistant message with zero parts renders as blank/stuck in web UI

1 participant