feat(cursor): commit tool-suspended checkpoints for external models - #2652
Conversation
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. 🗂️ Base branches to auto review (2)
Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
✅ Deterministic PR hygiene checks passed. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: eda8380c36
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| // A tool-suspended checkpoint is only usable by the immediate trailing-toolResult | ||
| // continuation; the request-builder guard keys on checkpointUsable=false for that. | ||
| checkpointUsable: !toolSuspendedCommit, | ||
| checkpointRef, |
There was a problem hiding this comment.
Persist the suspended-only restriction with the checkpoint
The checkpointUsable: false restriction exists only in the returned continuation metadata, while the committed snapshot is also added to the generic prefix index without that restriction. For a stable client thread that sends full history without previous_response_id, lookupPrefixSnapshot can therefore recover this tool-suspended snapshot with no cursorState; if the next request ends in a user message rather than the immediate tool result, the guard at request-builder.ts:427 is bypassed and the request resumes from pending-tool state without appending the uncovered transcript. Store the suspended kind on the snapshot and enforce it for both ref and prefix lookup, or exclude such snapshots from generic prefix recovery.
AGENTS.md reference: src/AGENTS.md:L19-L19
Useful? React with 👍 / 👎.
| if (message.type === "tool_call_end") emittedClientTool = true; | ||
| const captured = capturedCursorCheckpointBytes(activeTransport); | ||
| if (captured) lastTransport = { captured }; | ||
| if (captured) { | ||
| if (captured !== lastTransport?.captured) capturedAfterClientTool = emittedClientTool; |
There was a problem hiding this comment.
Require a checkpoint after the final emitted tool call
With multiple client tool calls, a checkpoint captured after the first tool_call_end sets capturedAfterClientTool permanently true; a later second call does not reset it, so done can commit the earlier snapshot even when no checkpoint arrived after the second call. Cursor explicitly supports sequential and late sibling calls, and resuming that snapshot with results for all emitted calls can omit the later pending call or trigger an invalid continuation. Reset the ordering proof for every newly emitted tool call and require a newer capture after the last one before committing.
AGENTS.md reference: src/AGENTS.md:L19-L19
Useful? React with 👍 / 👎.
리뷰 · 우선순위 55 / 80설명 이 풀 리퀘스트는 Cursor 경로가 도구를 한 번 호출할 때마다 대화 전체를 다시 보내는 이유를 고치려 합니다. 지금 새 규칙은 세 가지가 동시에 맞을 때만 저장합니다. 모델이 외부 와이어 모델이고( 네이티브 composer 모델은 예전처럼 거절합니다. 위험은 저장본의 뜻입니다. 지금 이 PR도 지금 src/adapters/cursor.ts:153 - 지금 메인테이너의 판단이 필요한 지점
너의 추천 #2650과 #2651이 이 댓글은 grok-bot이 작성했습니다 |
2b80c8b to
bbee907
Compare
eda8380 to
81628b6
Compare
bbee907 to
dbcc82c
Compare
81628b6 to
9de5682
Compare
9de5682 to
69a0b71
Compare
4d85df3 to
fdd406e
Compare
fix(cursor): quarantine catalog models whose runs always fail upstream
Summary
emittedClientTool=trueandcommitCapturedCheckpointrefused to commit ANY checkpoint, so the next trailing-toolResult request always fell back to full flattened-text replay (live probe: input_tokens 268 → 10,383 across one tool boundary; every agentic session pays this on every round).checkpointUsable:falseso only the immediate covered-prefix + trailing-toolResult continuation (existing request-builder path, already tested) can consume it. Native composer models keep the old refusal; pre-tool captures are refused by the ordering guard.Stacked on #2651. Design: 050_checkpoint_continuity.md (research disproved the earlier trailing_tool_result hypothesis).
Verification
bun test tests/cursor-tool-suspended-checkpoint.test.ts— 3 pass (external commit w/ usable=false, native refusal, ordering guard).bun test tests/cursor-adapter.test.ts tests/cursor-request-builder.test.ts tests/responses-state.test.ts tests/cursor-live-transport.test.ts— 205 pass 0 fail.bun x tsc --noEmit— clean.Checklist