Skip to content

fix(box): a chat agent resumed with no prompt shows as idle, not working - #217

Open
tinhthanh wants to merge 4 commits into
cosscom:mainfrom
tinhthanh:fix/idle-after-resume
Open

tinhthanh wants to merge 4 commits into
cosscom:mainfrom
tinhthanh:fix/idle-after-resume

Conversation

@tinhthanh

@tinhthanh tinhthanh commented Nov 4, 2026 •

Copy link
Copy Markdown
Contributor

Bug: A structured (stream-json) agent that is started again without a new prompt lists as running forever: the app shows it working with a timer counting up, until someone sends it something. This happens after its agent exits and the session is resumed, or after the box restarts and its conversation is opened in a new session. Seen on a real box: the last turn ended normally (end_turn), the box rebooted, the conversation was resumed at its prompt, and the session showed "working" for over 90 minutes with berth session turns reporting no turns.

Cause:

  • The host writes its started entry before berthd starts following the log. follow() reads entries already in the log without saying anything (live=false), so the driver's Ready for that start is never sent.
  • reconcile() only corrects running/waiting → Finished. With the turn state empty or exited, nothing is sent.
  • enrich then defaults the session to running (tasks.go).

Fix: Each driver notes when its agent last said it was ready, whether the log was read live or not: Claude when its host started; Codex and ACP when their thread or session opened. The note clears when the host starts again or exits. In reconcile(), a new case: not busy, nothing pending, the agent at its prompt, and turn state "" or exited → send Ready. The turn tracker makes that idle (only when no turn is open). A new session whose host hasn't started yet gets nothing from the catch-up, as before. An earlier version sent Ready there too: that moved its first prompt sooner, and TestATurnClaudeStartsByItselfShowsAsWorking then missed the first turn's short running (17/30 runs). It passes 30/30 now.

Test: TestAResumedConversationWithNoPromptIsIdle, with the stand-in stream Claude. It covers three cases:

  1. The agent stops and the session is resumed: the session lists as idle.
  2. The session is deleted and the conversation is resumed in a new one: it lists as idle.
  3. A prompt there still starts and finishes a turn.

It fails before the fix (AgentState: running with the turn state exited) and passes 10/10 with -race after; TestATurnClaudeStartsByItselfShowsAsWorking passes 30/30. go test -race ./... passes, except TestAttachPassesShiftEnter, which also fails on main without this change. Changelog bullet added under Unreleased.

🤖 Generated with Claude Code

Its host says it started before berthd reads the log, so the catch-up read
says nothing, and a session with no turn state lists as running: after a
box restarted or a conversation was opened again, the app showed it
working, its timer counting up, until someone sent it something. The
catch-up now says the agent is ready when nothing else did.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@vercel

vercel Bot commented Nov 4, 2026

Copy link
Copy Markdown

@tinhthanh is attempting to deploy a commit to the seanbrydonio's projects Team on Vercel.

A member of the Team first needs to authorize it.

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

All reported issues were addressed across 5 files

Reply with feedback, questions, or to request a fix.

View guided diff | Re-trigger cubic

Comment thread internal/box/claudedriver_test.go Resolved
Comment thread docs/changelog.mdx Resolved
tinhthanh and others added 2 commits November 5, 2026 01:37
… start; changelog says it needs the box upgraded

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ts host starts

The catch-up said Ready for any agent not busy with no turn state, also a
new session whose host hadn't started: the app then sent its first prompt
sooner, and that turn could end before anything saw it running. Each
driver now notes when its agent last said it was ready (Claude: its host
started; Codex and ACP: their thread or session opened) and the catch-up
says Ready only then.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

All reported issues were addressed across 3 files (changes from recent commits).

Reply with feedback, questions, or to request a fix.

View guided diff | Re-trigger cubic

Comment thread internal/box/codexdriver.go Resolved
Comment thread internal/box/codexdriver.go Resolved
Codex said Ready only for a new thread id, so a session resumed on its
own thread stayed exited and listed as working. It now says Ready each
time a thread opens, live, and reads the result once (a result that
fails to decode changes nothing). The Codex driver test checks the
resumed session lists as idle.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
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