[stack 8/8] fix(runtime): bound transcript and autonomous recovery - #1165
[stack 8/8] fix(runtime): bound transcript and autonomous recovery#1165sethkarten wants to merge 5 commits into
Conversation
e234355 to
23945e2
Compare
| ): number | undefined { | ||
| const messages = this.agent.state.messages; | ||
| if (compactionTimestamp !== undefined && assistantMessage.timestamp <= compactionTimestamp) { | ||
| return messages.reduce((tokens, message) => tokens + estimateTokens(message), 0); |
There was a problem hiding this comment.
🟠 High core/agent-session.ts:7962
The stale-usage fallback at line 7962 sums estimateTokens(message) across all messages, but estimateTokens counts only text blocks for user messages and assigns zero tokens to image attachments. After compaction, when the only post-compaction input is a user message with images, the fallback produces a near-zero token estimate, so threshold compaction is skipped even though the images occupy real context — causing repeated context-limit errors instead of compaction. The fallback should account for image blocks (as estimateTokens already does for toolResult and custom messages) or use a complete context estimator.
🚀 Reply "fix it for me" or copy this AI Prompt for your agent:
In file @packages/coding-agent/src/core/agent-session.ts around line 7962:
The stale-usage fallback at line 7962 sums `estimateTokens(message)` across all messages, but `estimateTokens` counts only text blocks for `user` messages and assigns zero tokens to image attachments. After compaction, when the only post-compaction input is a user message with images, the fallback produces a near-zero token estimate, so threshold compaction is skipped even though the images occupy real context — causing repeated context-limit errors instead of compaction. The fallback should account for image blocks (as `estimateTokens` already does for `toolResult` and `custom` messages) or use a complete context estimator.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 23945e2. Configure here.
| content: [{ type: "text", text: "No result provided" }], | ||
| isError: true, | ||
| timestamp: Date.now(), | ||
| }); |
There was a problem hiding this comment.
Tool results emitted out of order
High Severity
Hoisted tool results are appended in look-ahead discovery order, then missing synthetics follow in toolCalls order. When only some results exist after an interrupt, the emitted sequence can disagree with the assistant toolCall order. Providers that pack consecutive toolResult messages into one user turn (notably Anthropic) can reject that transcript with a 400.
Reviewed by Cursor Bugbot for commit 23945e2. Configure here.
| if (foundReasoningField) { | ||
| const delta = deltaFields[foundReasoningField]; | ||
| if (typeof delta === "string" && delta.length > 0) { | ||
| const repetition = repetitionGuard?.push(delta); |
There was a problem hiding this comment.
Nice catch on the degenerate repetition issue. The repetitionGuard is a solid safety net — detecting and throwing StreamFailureError on degenerate output is the right defensive measure.
One suggestion: consider also adding anti-repetition guidance to the system prompt as a complementary layer. The guard catches repetition after it starts (wasting tokens in the process), while prompt-level
instructions can prevent it from starting.
Claude Code's system prompt includes explicit anti-repetition directives like:
Do NOT read this resource again unless you think it may have changed.
Do not re-select memories you already returned for an earlier query.
When you already know which part of the file you need, only read that part.
Something similar in buildRlmPrompt() (e.g. in rlm.ts) would reduce how often the guard triggers:
Do not re-run the same tool call with identical arguments unless the underlying data may have changed.
If you find yourself repeating the same action with the same result, stop and reconsider your approach.
Do not re-read files or re-execute commands whose results you already have in context.
This way the prompt prevents most repetition, and the repetitionGuard catches the rest. Neither alone is sufficient — prompts can't guarantee compliance, and code-level detection without prompt guidance means
the guard fires frequently and degrades UX.


Stack 8/8 — fix(runtime): bound transcript and autonomous recovery
Base:
stack/external-07-providersReview order: merge only after the preceding stack layer is accepted. This PR is not intended to merge independently out of order.
Stack navigation
Summary
Validation
npm run check; focused compaction/autonomy suites 76 passed with 2 credential-gated skips; final adversarial review cleared.Provenance
upstream/mainusing issue reports and PR descriptions/comments only.Linked-item disposition
Fixed on merge
Independently superseded pull requests
Partial/distinct overlap — remains open
Reviewer notes
main, to avoid cumulative duplicate diffs.