You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Native Cursor (cursor / cursor-cli-oauth) rejects long sessions with 0-token resource_exhausted because the wire payload still contains verbatim toolResult bodies (often hundreds of KB–MB). Compaction does not fix this:
findCutPoint cannot cut at toolResult, so the last tool turn is kept whole.
After a successful compact, AgentSession replaces agent.state.messages from sessionManager.buildSessionContext(), which reloads those full bodies from jsonl.
The retry then sends the same payload. A second compact often throws Nothing to compact (session too small) and the TUI shows Pre-prompt compaction failed / Retry failed after 2 attempts.
Mid-turn compact skip (#984) is still correct (it poisons conversationId). The missing piece is Cursor-only truncation of toolResult text at admission and again after compact reload, plus remint.
Evidence (session 01a01a3e)
Compact reported tokensBefore: 99166 then saved ~11%; Cursor still RE.
jsonl toolResult bodies stayed >2k chars (66 of them); truncation was in-memory only and wiped on reload.
After overflow compact 31818 → 4306 on the session.log meter, jsonl still had the original bodies.
Proposed fix
Export truncateToolResultBodies(messages, 2000) and apply it on Cursor compactBeforeNextAdmissionbefore the Cursor compaction during a live turn poisons conversationId #984 skip return, returning true when messages changed so prepareNextTurn uses agent.state.messages.
Call the same helper after compact applies sessionContext.messages and in _restoreAgentMessagesFromSession.
Remint (allowConversationRotate) when truncated.
Do not persist truncated bodies to jsonl; do not change x.ai / other providers.
Why not an extension
Admission and compact reload are private AgentSession paths. There is no hook after buildSessionContext() replaces agent messages.
Summary
Native Cursor (
cursor/cursor-cli-oauth) rejects long sessions with 0-tokenresource_exhaustedbecause the wire payload still contains verbatimtoolResultbodies (often hundreds of KB–MB). Compaction does not fix this:findCutPointcannot cut attoolResult, so the last tool turn is kept whole.agent.state.messagesfromsessionManager.buildSessionContext(), which reloads those full bodies from jsonl.Nothing to compact (session too small)and the TUI showsPre-prompt compaction failed/Retry failed after 2 attempts.Mid-turn compact skip (#984) is still correct (it poisons
conversationId). The missing piece is Cursor-only truncation oftoolResulttext at admission and again after compact reload, plus remint.Evidence (session 01a01a3e)
tokensBefore: 99166then saved ~11%; Cursor still RE.31818 → 4306on the session.log meter, jsonl still had the original bodies.Proposed fix
truncateToolResultBodies(messages, 2000)and apply it on CursorcompactBeforeNextAdmissionbefore the Cursor compaction during a live turn poisons conversationId #984 skip return, returningtruewhen messages changed soprepareNextTurnusesagent.state.messages.sessionContext.messagesand in_restoreAgentMessagesFromSession.allowConversationRotate) when truncated.Why not an extension
Admission and compact reload are private AgentSession paths. There is no hook after
buildSessionContext()replaces agent messages.