Skip to content

feat: recover from prompt-too-long errors by compacting and retrying - #48

Open
kyletser wants to merge 3 commits into
LiuMengxuan04:mainfrom
kyletser:feat/ptl-recovery
Open

feat: recover from prompt-too-long errors by compacting and retrying#48
kyletser wants to merge 3 commits into
LiuMengxuan04:mainfrom
kyletser:feat/ptl-recovery

Conversation

@kyletser

@kyletser kyletser commented Aug 20, 2026

Copy link
Copy Markdown

What

Implements prompt-too-long recovery from the context-management roadmap in #1. Recognized HTTP 400 context-length errors trigger deterministic transcript compaction and a bounded retry.

Behavior

  • Preserve HTTP status in ModelRequestError and recognize context-length error wording from Anthropic-compatible endpoints.
  • Use snip compaction, not an additional model summarization request, and retry at most LIMITS.PTL_MAX_RETRIES (2).
  • Await the existing onSnipCompact callback with the complete snip result before retrying, preserving boundary persistence and avoiding another regular snip in the same turn.
  • Propagate unrelated errors, errors where nothing can be compacted, and errors after retry exhaustion through the existing turn outcome handling.
  • Rebuild plan/runtime context for each model request without persisting those temporary system messages. Keep the upstream abortable model wrapper, including cancellation while a retry is waiting.
  • Document behavior in English and Chinese usage guides. Image-size recovery is out of scope.

Verification

Synced with upstream main and validated at 7d71c41:

  • npm run check: passed.
  • npm run lint: passed.
  • npm test: 279 passed, no failures or skips.
  • test/prompt-too-long.test.ts: 9 cases covering recognition, bounded retries, failure propagation, complete snip metadata, awaited persistence, fresh ephemeral context, and cancellation during a blocked retry.
  • Mutation checks confirmed that persisting temporary context breaks the new isolation test, and bypassing the abortable model wrapper prevents the cancellation test from completing.

Refs #1

Copilot AI lite review requested due to automatic review settings August 20, 2026 11:16

Copilot AI 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.

Pull request overview

Adds deterministic “prompt too long” (HTTP 400) recovery to the agent’s model request path so long sessions can compact the transcript and retry instead of aborting the turn.

Changes:

  • Introduces ModelRequestError (with HTTP status) and isPromptTooLongError() detection for Anthropic-compatible 400 PTL responses.
  • Adds requestWithPromptTooLongRecovery() to snip-compact and retry up to LIMITS.PTL_MAX_RETRIES.
  • Wires the agent loop to use the recovery helper and adds a dedicated test suite covering the retry/rethrow behaviors.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
test/prompt-too-long.test.ts Adds unit tests for PTL detection + compact-and-retry behavior.
src/utils/errors.ts Introduces ModelRequestError and PTL message matching.
src/prompt-too-long.ts Implements the compact-and-retry recovery helper around model.next().
src/anthropic-adapter.ts Throws ModelRequestError on non-2xx responses (status-aware errors).
src/agent-loop.ts Wraps the model request with PTL recovery and keeps transcript/stats in sync.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/prompt-too-long.ts Outdated
Comment thread src/agent-loop.ts Outdated
When the model API rejects the request as prompt too long (HTTP 400),
the agent loop now deterministically snip-compacts the transcript (no
extra model call) and retries, up to PTL_MAX_RETRIES times. Previously
the whole turn aborted on such errors, wasting the work done so far.

- Add ModelRequestError carrying the HTTP status, thrown by the
  Anthropic adapter on non-2xx responses.
- Add isPromptTooLongError() matching Anthropic-compatible 400 wording.
- Add requestWithPromptTooLongRecovery() helper and wire it into the
  agent loop request path; if nothing can be freed, the original error
  is rethrown untouched.

Part of the model-aware context management roadmap (LiuMengxuan04#1).
@kyletser

Copy link
Copy Markdown
Author

Addressed both review points in 0117192. The recovery callback now receives the full SnipCompactResult and awaits the existing onSnipCompact path before retrying, so the snip boundary is persisted and session save state is reset. Recovery also marks the turn as already snipped. Added tests for awaited metadata delivery and agent-loop persistence wiring. Verification: npm run check, npm run lint, and npm test (235/235) all pass.

@LiuMengxuan04

Copy link
Copy Markdown
Owner

感谢你的PR,我们正在进行版本升级,请等我们近期升级完成之后集中处理PR请求

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.

3 participants