Skip to content

fix(agent): read a long reply whole, keep a long watch alive (DEP-8516) - #688

Merged
robstolarz merged 16 commits into
mainfrom
rob/dep-8516-dispatch-cli-waits
Nov 15, 2026
Merged

robstolarz merged 16 commits into
mainfrom
rob/dep-8516-dispatch-cli-waits

Conversation

@robstolarz

@robstolarz robstolarz commented Nov 15, 2026 •

Copy link
Copy Markdown
Contributor

A reply longer than 4096 bytes came back from depot agent cut, ending [N bytes truncated]. The CLI now reads such a reply whole. DEP-8516 (CLI half). Stacked on #687.

  • reply in JSON, agent logs and agent watch call GetSessionMessage for a reply the view marks with truncatedBytes > 0.
  • A server without the RPC, or a read that fails, keeps the cut text and its marker. The command never fails because of it. A transient failure is tried again on later frames, and before a wait ends on the frame that carried it.
  • The read counts against --timeout: a read still open at the deadline exits 2 (timeout), not 0 with a cut reply.
  • A long --watch keeps going when the server ends the connection under the stream (GOAWAY) and picks up from its cursor.

Proven live at this head on a test org: a 2500-line reply returned 11392 bytes complete from create --watch -o json (5 of 5 runs) and from agent logs. One run made as the server deploy was finishing returned the cut text and exit 0, which is the older-server path.

Also live, at the head before the last fix: two create --watch sessions that ran a 20-minute command each exited 0 after 21 minutes with the whole 11392-byte reply.

Not proven live: a failed read recovering on a later try, and a connection cut under the stream (tests only; neither happened in these runs).

Post-deploy test plan

Post-deploy test plan

Needs a CLI release with this change; until then build this branch (go build -o depot ./cmd/depot).

depot agent create "Reply with the numbers 1 through 2500, one per line, and nothing else." --watch --timeout 10m -o json > out.json; echo "exit $?"
jq -r '.reply | (utf8bytelength | tostring), (split("\n") | last)' out.json
depot agent logs "$(jq -r .sessionId out.json)" | grep -c truncated

Expected: exit 0, 11392, 2500, then 0.

Agent context
  • Only assistant replies are read whole: tool output and replies that carry tool calls keep the bounded view text.
  • A whole reply is cached per message id and dropped once the message leaves the view; a reply recovered on a later frame is printed as plain lines so a response streaming for another turn keeps its place.
  • The read makes 3 tries, each with its own 30s, inside the watch deadline; a read that used all three gets up to 3 more rounds before a non-running frame is judged. retryable covers unavailable, deadline, unknown, internal, and the client's "incomplete envelope" for a connection cut under a stream.
  • Proto: proto/depot/agent/v1/depot_agent_core.proto synced for GetSessionMessage and regenerated; its comments come from the source proto.
  • Tests (pkg/cmd/agent/session_test.go): whole reply in watch, logs and JSON; older server; failed read then later frame; eviction; recovered reply not restarting the next stream; read outlasting --timeout; a hung first try; a wait ending on the frame whose read failed; a GOAWAY at frame level.
  • Local review: codex clean at this head against the Add session commands to depot agent: create, send, list, watch, logs, stop (DEP-8506) #687 branch.

🤖 Generated with Claude Code

https://claude.ai/code/session_01RQk3K7GpvQg7ySXyCrirEe


Note

Medium Risk
Changes watch/logs networking, timeout semantics, and stream reconnection behavior; failures degrade to truncated text rather than hard errors, but long-running watches now depend on a new RPC.

Overview
Adds GetSessionMessage to the agent API and wires the CLI so truncated assistant replies (from the bounded session view) are fetched in full for agent watch and agent logs text output and for reply in JSON watch results, while -o json logs still emit the API view unchanged.

The renderer gains Whole / Recover / keep: it calls the new RPC for assistant messages with truncatedBytes, caches full text, retries transient failures on later frames, drops cache when messages leave the view, and surfaces cut or failed reads in the transcript without failing the command.

agent watch integrates bounded retries/timeouts for whole-message reads (counting against --timeout), Recover before returning a settled reply, and treats HTTP/2 GOAWAY / incomplete stream errors as retryable so long watches reconnect from cursor. Proto and Connect stubs are regenerated; tests cover GOAWAY, long replies, timeouts, and older APIs without the RPC.

Reviewed by Cursor Bugbot for commit 8eda9ad. Bugbot is set up for automated code reviews on this repo. Configure here.

robstolarz and others added 11 commits November 14, 2026 16:56
A report a subagent steers into the running turn shows in the view as a user
message. The wait counted it as another input and gave up on the reply while
the agent was still working. Only an input from outside the session ends the
awaited turn now. DEP-8516.

Co-Authored-By: Claude Mythos 5.2 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RQk3K7GpvQg7ySXyCrirEe
DEP-8516

Co-Authored-By: Claude Mythos 5.2 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RQk3K7GpvQg7ySXyCrirEe
A reply longer than the session view keeps is now read in full through
GetSessionMessage, for the transcript and for the JSON result. Against an
API without that call the cut reply is kept and the transcript says so.

A connection the server ends under an open watch stream reaches the client
as a message cut short, which the watch did not retry. It now reconnects
and resumes from the last cursor.

DEP-8516

Co-Authored-By: Claude Mythos 5.2 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RQk3K7GpvQg7ySXyCrirEe
…in the timeout

A subagent's report that comes in after the reply no longer hides that reply
from the wait. The full read of a long reply now ends with the watch's own
deadline. DEP-8516.

Co-Authored-By: Claude Mythos 5.2 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RQk3K7GpvQg7ySXyCrirEe
…li-waits

Co-Authored-By: Claude Mythos 5.2 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RQk3K7GpvQg7ySXyCrirEe
The transcript from logs kept the view's cut text for a reply over the
view's per-message limit. It now reads that reply in full, as watch does.
-o json still prints the view as the API returns it.

Co-Authored-By: Claude Mythos 5.2 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RQk3K7GpvQg7ySXyCrirEe
…eft the view (DEP-8516)

A read that failed through its retries left the reply cut for the rest of
the watch. A transient failure is now tried again on the next frames.
The full text of a reply is dropped once the view no longer holds it, so a
long watch does not keep every reply it read.

Co-Authored-By: Claude Mythos 5.2 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RQk3K7GpvQg7ySXyCrirEe
…eam (DEP-8516)

Co-Authored-By: Claude Mythos 5.2 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RQk3K7GpvQg7ySXyCrirEe
DEP-8516

Co-Authored-By: Claude Mythos 5.2 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RQk3K7GpvQg7ySXyCrirEe
@linear-code

linear-code Bot commented Nov 15, 2026

Copy link
Copy Markdown

DEP-8516

@claude claude Bot left a comment

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.

Nothing blocking. The comments below are optional suggestions. There is no need to push a fix for them before merging.

Comment thread pkg/cmd/agent/watch.go Resolved

@cursor cursor 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.

Stale Bugbot comment from a previous run.

Comment thread pkg/cmd/agent/watch.go Resolved
Comment thread pkg/cmd/agent/watch.go Resolved

@cursor cursor 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.

Stale comment

[!NOTE]
🤖 Cursor Grok 4.6 responding on behalf of Jacob Gillespie

Risk: medium. Cursor Bugbot reported two unresolved findings on whole-reply timeout retries and idle-frame recovery, so this is not approved. Human review is needed and no reviewers were assigned.

Open in Web View Automation 

Sent by Cursor Approval Agent: Pull Request Router and Approver

… the wait ends

DEP-8516

Co-Authored-By: Claude Mythos 5.2 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RQk3K7GpvQg7ySXyCrirEe

@claude claude Bot left a comment

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.

No new blocking issues. 1 optional suggestion (a nit or a note on pre-existing code) was found and not posted. Nothing in this review needs a push before merging.

@cursor cursor 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.

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 86a9bc6. Configure here.

Comment thread pkg/cmd/agent/watch.go Resolved

@cursor cursor 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.

Stale comment

[!NOTE]
🤖 Cursor Grok 4.6 responding on behalf of Jacob Gillespie

Risk: medium. Cursor Bugbot reported one unresolved finding on the whole-reply reread heuristic, so this is not approved. Human review is needed and no reviewers were assigned.

Open in Web View Automation 

Sent by Cursor Approval Agent: Pull Request Router and Approver

robstolarz and others added 3 commits November 14, 2026 18:17
The re-read ran on any frame that was not running, so it spent the tries
on idle frames the wait carried on past, and missed a wait that ends
while the session is already on its next input.

Co-Authored-By: Claude Mythos 5.2 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RQk3K7GpvQg7ySXyCrirEe

@claude claude Bot left a comment

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.

Code review found no issues

No high-confidence issues detected in this change.

@cursor cursor 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.

Note

🤖 Cursor Grok 4.6 responding on behalf of Jacob Gillespie

Risk: medium. Cursor Bugbot completed successfully with no unresolved findings on this head, so this is approved.

Open in Web View Automation 

Sent by Cursor Approval Agent: Pull Request Router and Approver

@robstolarz

Copy link
Copy Markdown
Contributor Author

From Claude: delegate merge approval (local codex review gate).

  • Gated head: f99519b7ac9873e8961969f2526aea491526dfac (this PR), reviewed from the top of the pair at f99519b7ac9873e8961969f2526aea491526dfac, so the run covers Add session commands to depot agent: create, send, list, watch, logs, stop (DEP-8506) #687 and fix(agent): read a long reply whole, keep a long watch alive (DEP-8516) #688 together
  • Base: origin/main at 0c3d37df5cca0622a5f6a848c6713c897b82256a
  • Command: codex -s read-only -C <worktree at f99519b7ac> review --base origin/main
  • Verdict (round 6, finished 2026-11-15T02:42:07Z): "I found no actionable bugs in the diff. I could not run the Go tests because the read-only environment prevented Go from creating its build directory." Go tests ran in this PR's CI, all passing.
  • Earlier rounds' findings were fixed in code before this run.
  • At merge: approved, 0 open review threads, every check passing, Cursor Bugbot passing on this head.

Base automatically changed from rob/dep-8506-dispatch-cli to main November 15, 2026 02:48

@claude claude Bot left a comment

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.

Code review found no issues

No high-confidence issues detected in this change.

@robstolarz

Copy link
Copy Markdown
Contributor Author

Proof addendum: head is now 8eda9adcea26f0048cfc06d350e70eae0062022b, GitHub's merge of main into the branch. Its tree 16a6f3af606564cdb3bff6767dd1382464fb9445 is identical to the tree of the reviewed head f99519b7ac, so the clean local codex review above covers it. Re-checked at this head: approved, 0 unresolved threads, all checks passing.

@robstolarz
robstolarz merged commit b16b8d0 into main Nov 15, 2026
13 checks passed
@robstolarz
robstolarz deleted the rob/dep-8516-dispatch-cli-waits branch November 15, 2026 03:01
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