fix(coding-agent): seven session and IO correctness defects - #2037
Open
snimu wants to merge 7 commits into
Open
Conversation
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 ce12e55. Configure here.
The bash executor's inline spill copy is folded into a shared OutputSpill with exactly two terminal states: a COMPLETE advertised file (finalize resolves its path after the flush settles) or a DEGRADED spill (failure at open, write, or final flush) whose path is cleared everywhere and whose tool call still succeeds with the in-memory tail. closeTempFile never rejects for spill reasons; results are built only after finalize; the bash formatter never prints 'Full output: undefined'. snapshot's persistIfTruncated option is deleted - append/finish already open the spill on a strict superset of its condition.
…truthful rescue metadata A degraded spill best-effort unlinks its partial file after the stream closes (the leak squatted on the very disk pressure that caused the degrade). The retry-continue rejection path marks captured provider auth failures stale before clearing them, like every other terminal retry path. The tail rescue keeps trailing blank lines in the output (their newlines charged to the byte budget) so line metadata describes the real file, and the bash label names the partial line by its actual number, omitting a zero-byte line size.
Trailing blank lines kept by the rescue now fit WITHIN maxBytes (at most maxBytes-1 of them, their join newlines charged to the budget; excess blanks are dropped), so truncateTail's byte cap holds for every input. Property pin sweeps a blank-shape corpus across small budgets.
…ry callbacks The degraded-spill unlink runs in a 'close' event handler where an EACCES/EBUSY/ENOTDIR would kill the process (force only suppresses ENOENT); cleanup is now genuinely best-effort. A retry-generation token (bumped by every retry resolution) fences the scheduled continue's rejection callback, so an aborted retry's parked continue can no longer clear a newer retry's state or emit its end event.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Summary
Seven small, unrelated session/IO correctness defects, each with a regression pin:
findCutPointfell back to the first cut point — keeping essentially the whole history and making the compaction a no-op exactly when the session most needed shrinking. The fallback now keeps only the final turn. Fixes the defect reported in discussion findCutPoint silently keeps the whole window when a turn's tool results exceed keepRecentTokens, so compaction becomes a no-op #1555.agent.continue()swallowed every rejection; a continue that never starts (busy,nothing-to-continue) leftisRetryingstuck true and every retry waiter parked forever. The rejection now ends the retry (auto_retry_end, state reset, waiters released). Fixes the defect reported in discussion [Bug] fix(coding-agent): auto-retry leaves isRetrying stuck when agent.continue() fails #1812.parentSessionPath; a session withrlmDepth > 0whose parent edge was reconciliation-dropped was presented as top-level. Depth now decides, with the path as legacy fallback. Fixes the defect reported in discussion [Bug] Top-level forked sessions are nested as subagents in Agents View #1635.truncateTailsplits on\n, so newline-terminated output contributes a trailing empty line that defeated the oversized-line rescue (outputLinesArr.length === 0) — returning empty output instead of the line's tail. The rescue now fires when only empty lines have been collected. Fixes the defect reported in discussion truncateTail returns empty content when the last line exceeds the byte budget, so long single-line output reaches the model as (no output) #1551.OutputAccumulatorand an inline copy in the bash executor), both created write streams with noerrorlistener — an ENOSPC/unwritable tmpdir emitted an unhandlederrorevent, killing the process mid-command — and neither had a terminal contract: a failed final flush could rejectcloseTempFile()(turning a degraded spill into a tool failure), the executor returned before its flush settled (advertising a partial file), and the formatter printedFull output: undefinedafter a cleared path. Both paths now share oneOutputSpillwith exactly two terminal states: a complete advertised file (results are built only afterfinalize()settles) or a degraded spill — any failure at open, write, or final flush clears the path everywhere and the tool call still succeeds with the truncated in-memory tail. The redundantpersistIfTruncatedsnapshot option is deleted (append/finish already open the spill on a strict superset of its condition). Fixes the defect reported in discussion Temp-file open failure kills the process: createWriteStream has no error listener in either output path #1552 and the three review findings on its first round.echo data | prime-agent -p "summarize"joined the parts with an empty string, welding the last stdin line to the first instruction word. Parts join with a blank line. Fixes the defect reported in discussion [Bug] Piped stdin and the CLI instruction are concatenated without a separator #1396.---made the shared parser (skills, prompts, themes) silently treat the whole file as body. The parser's normalization strips a leading BOM, fixing all call sites at once. Fixes the defect reported in discussion [Bug] UTF-8 BOM prevents SKILL.md frontmatter from loading #1397.Validation
compaction(29),agent-session-retry-events(29),agents-view-state(75),initial-message(3),frontmatter(9),bash-tool,suite/agent-session-compaction, plus newtruncateandoutput-accumulatorpins — 185 tests, 0 failures, sanitized envnpm run checkpasses via the pre-commit hookLOC
Total src: +142/−90 (net +52); tests: +258/−7 (net +251).
Src +59/−17 (round 1, point fixes) + 94/−101 (round 2 spill consolidation — net src −7: one lifecycle instead of two copies plus a deleted redundant option). Tests +122/−3 and +62/−1 (three acceptance pins for the terminal contract, each verified fail-unfixed: never-rejecting close, complete-file-only advertisement, no
Full output: undefined). Mechanism split: round 2 is consolidation —OutputSpillreplaces two divergent inline lifecycles.Linear: RES-1266 https://linear.app/primeintellect/issue/RES-1266
Note
Medium Risk
Touches compaction cut logic, retry lifecycle, and bash output paths used during tool execution; changes are localized with regression tests but affect long-session behavior and error recovery.
Overview
Bundles seven unrelated correctness fixes across compaction, retries, agents UI, bash/output handling, CLI prompts, and frontmatter parsing.
Compaction now defaults to the final turn when the keep-recent token budget is exceeded inside trailing tool results (no cut point at/after that index), instead of falling back to the first cut point and effectively keeping the whole history.
Auto-retry bumps a
_retryGenerationon resolve and, if the deferredagent.continue()rejects while still the active retry, emits a failedauto_retry_end, clears retry state, and releases waiters—stale continue callbacks from aborted retries are ignored.Bash / tool output consolidates temp-file spilling into shared
OutputSpill: stream errors are handled (no process crash),finalize()never rejects, full-output paths are advertised only after the file is complete, and degraded spills omit the path andFull output: undefinedmessaging.truncateTailagain rescues oversized final lines when output ends with newline-induced blank lines.CLI joins piped stdin, file text, and the first message with
\n\ninstead of empty-string concatenation. Frontmatter strips a leading UTF-8 BOM before---matching. Agents view treats archived saved sessions withrlmDepth > 0as subagents even whenparentSessionPathis missing.Reviewed by Cursor Bugbot for commit 41b5d72. Bugbot is set up for automated code reviews on this repo. Configure here.
Note
Fix seven session and IO correctness defects in
coding-agentAgentSessionretry lifecycle: rejected scheduled continuations now terminate the retry, emit a failedauto-retry-endevent, and clear retry state. Stale continuations are ignored.OutputSpillmanager for bash command output. Temp file failures degrade to an undefined path without rejecting finalization. The bash tool only advertises a full-output path after the file settles.compaction.findCutPointfalls back to the final valid cut point when the budget is crossed in trailing tool results, instead of retaining the entire history.truncateTailpreserves the end of an oversized final line with trailing blank lines within the byte budget.agents-view.summaryForUnifiedRecorduses positiverlmDepthfor subagent classification.utils.normalizeNewlinesstrips a leading UTF-8 BOM.cli.buildInitialMessageseparates prompt parts with blank lines.OutputSpillreplaces direct temp stream management incore.executeBashWithOperationsandtools.createBashToolDefinition; check spill finalization paths to ensure temp files are cleaned up and bash output paths are not lost.Macroscope summarized 41b5d72.