Repository navigation
fix(claude-code): stop re-sending file reads in full after they were trimmed - #92
Merged
trancefornow merged 2 commits intoSep 30, 2026
Conversation
…requests The tool_payload_trim pass sends a file read in full when its path was already disclosed, taking it as the model asking for the whole file again. The Claude Code gateway persisted every disclosed path and passed them all back in on the next request. Claude Code resends the whole history, so the pass saw the same read as a repeat of itself and sent it untrimmed: a probe showed a Read result trimmed to 2,830 chars on one request going out at 36,580 chars on the next, which also breaks the prompt cache from that point on. The session snapshot now records which tool_use_id disclosed each path (disclosedReadOwners). A path is carried into the next request only when that read is no longer in the history, so a genuine re-read after compaction still comes back in full. Snapshots from before this change (paths without owners) are ignored rather than carried. Tests: tests/reduction-disclosed-reads.test.ts (O1-O3, D1-D4, C1) and a gateway test for the same read staying trimmed. D1, D3 and the gateway test fail against the previous behaviour. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01S6it2Si8k8XNGMF8RdyMQz
boxabirds
pushed a commit
to boxabirds/LightRSI
that referenced
this pull request
Sep 30, 2026
Applies the refinement made to the Claude Code fix in zjunlp#92 (eb1eb2c) to Codex: - a path's owner must be a `read`/`file_read` result that tool_payload_trim actually trimmed in this request, not merely the first tool result with that path (a write to the same file, or an untrimmed read, can no longer own it); - owners are rebuilt from the pass's bounded reported path set instead of accumulating. Tests O4, O5 and D5 mirror the Claude Code ones; O4 and D5 fail without the new ownership filter. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01S6it2Si8k8XNGMF8RdyMQz
boxabirds
pushed a commit
to boxabirds/LightRSI
that referenced
this pull request
Oct 1, 2026
Adds an in-process OpenCode v1 server plugin (`components/adapters/opencode`) plus the host glue it uses (`components/adapters/shared/canonical`), built on the shared packages and mirroring the Claude Code adapter. Refs zjunlp#93. - Stabilizer: `experimental.chat.system.transform` (developer target; the user target is not possible in 1.18.33 because messages are transformed first). - Reduction: request-time in `experimental.chat.messages.transform`, through the shared `@lightrsi/reduction` pipeline over a canonical envelope. - Recovery: the shared recovery MCP server, registered in `opencode.json`. - Eviction (opt-in, needs taskStateEstimator settings): the shared canonical-surface cycle, applied as a durable per-session overlay. - Repeat-read rule: as in zjunlp#92, a disclosed path is carried into the next request only when the trimmed read that disclosed it has left the history; the record is saved per session so restarts keep it. - Reversible install with backups (jsonc configs are printed, never rewritten); never writes credentials; every hook fails open and logs to `<stateDir>/tokenpilot/adapter.log`. Tests: 189 in the package. The shared glue (config, reduction, memo store, before-call, eviction, logger) has one test file per module, each listing the cases it covers; plus runtime, codec/overlay, install/doctor and registration tests. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01S6it2Si8k8XNGMF8RdyMQz
This was referenced Oct 2, 2026
Xubqpanda
pushed a commit
that referenced
this pull request
Oct 3, 2026
Adds an in-process extension for the pi coding agent (`@earendil-works/pi-coding-agent`, verified on 0.87.1) in `components/adapters/pi`, built on the shared host glue from the OpenCode adapter (`components/adapters/shared/canonical`). Refs #97. - Stabilizer: `before_agent_start` system-prompt sections, so pi appends a section delta instead of replacing the prompt. - Reduction: request-time in the `context` hook, through the shared `@lightrsi/reduction` pipeline over a canonical envelope. - Recovery: a native `memory_fault_recover` tool with the shared MCP tool's name, description and schema (pi has no MCP). - Eviction (opt-in, needs taskStateEstimator settings): the shared canonical-surface cycle, applied as native `context_edit` entries at `turn_end`, before pi's own threshold compaction. - Repeat-read rule: the shared disclosed-read memo, as in #92 and the OpenCode adapter, saved per session so `pi -p` / `--continue` restarts keep it. - Reversible install with backups; never writes credentials; every hook fails open and logs to `<stateDir>/tokenpilot/adapter.log`. Tests: 86 in the package (runtime, codec, install/doctor, registration). The shared glue is already covered by the OpenCode package's suites. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01S6it2Si8k8XNGMF8RdyMQz
boxabirds
pushed a commit
to boxabirds/LightRSI
that referenced
this pull request
Oct 3, 2026
Applies the refinement made to the Claude Code fix in zjunlp#92 (eb1eb2c) to Codex: - a path's owner must be a `read`/`file_read` result that tool_payload_trim actually trimmed in this request, not merely the first tool result with that path (a write to the same file, or an untrimmed read, can no longer own it); - owners are rebuilt from the pass's bounded reported path set instead of accumulating. Tests O4, O5 and D5 mirror the Claude Code ones; O4 and D5 fail without the new ownership filter. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01S6it2Si8k8XNGMF8RdyMQz
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
TokenPilot shortens large file reads before Claude Code sends them to the model. Because of a bug, the next request sent the same file in full again. That undid the saving and broke the prompt cache from that point on. This PR keeps a file shortened for as long as that same read is in the conversation.
In a local probe through the gateway's reduction path, a
Readresult trimmed to 2,830 characters went out at its full 36,580 characters on the very next request.What was going wrong
tool_payload_trimhas a deliberate rule: if the model reads a file it has already seen in shortened form, it probably wants the whole file this time, so that second read is left in full.To apply the rule, the gateway saves every path it has shortened (
disclosedReadPaths) and passes the list back in on the next request. But Claude Code resends the entire conversation on every request, so the first read is sent again too. The pass then mistook that same old read for a new re-read and sent it in full.The fix
The session snapshot now also records which read first disclosed each path, keyed by its
tool_use_id(disclosedReadOwners). A path is carried into the next request only when that read is no longer in the conversation.The last row is a one-off cost after upgrading: a deliberate re-read in an existing session may come back shortened once.
Files changed:
src/reduction.ts: owner tracking, and the carry rule above.src/session-state.tsandsrc/gateway-runtime.ts: persist the new field alongsidedisclosedReadPaths.src/context-cleaner/session-catalog.ts: validates the new field.Tests
New file
tests/reduction-disclosed-reads.test.ts:In
tests/gateway-runtime.test.ts, a new test sends two requests through the real gateway with the same read in both. The existing test for genuine re-reads passes unchanged.Checks run:
pnpm build,pnpm typecheckandcheck:boundariespass.Prepared with help from Claude Code; the commit is marked
Co-Authored-By: Claude.