Skip to content

Fix/proxy fold - #23

Open
s-horna wants to merge 9 commits into
mainfrom
fix/proxy-fold
Open

s-horna wants to merge 9 commits into
mainfrom
fix/proxy-fold

Conversation

@s-horna

@s-horna s-horna commented Oct 16, 2026

Copy link
Copy Markdown
  • fix cache_control bug
  • sd_retrieve returns full transcript, not summary
  • fixed the request to /summarization/abstractive
  • fixed compaction threshold
  • invalid key error
  • no false MCP warning on re-run
  • fixed status line to reflect session stats instead of machine wide + better hint to make users use the proxy

s-horna and others added 9 commits October 15, 2026 15:22
… id in marker

- Count cache_control breakpoints on message blocks as well as system/tools
  before marking the folded summary. Claude Code marks recent messages, so
  the summary's breakpoint made a fifth and every turn after the first fold
  failed with "A maximum of 4 blocks with cache_control may be provided".
- Persist the sd_retrieve id of the full transcript stored at a fold and
  reuse it in the marker on later requests. Previously every later request
  re-stored the summary under a new id, so sd_retrieve returned the summary
  the model already had instead of the original turns.
- Document SCALEDOWN_PROXY_CACHE_CONTROL_DISABLE.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
With `messages` present, /summarization/abstractive skips the model
(latency_ms: 0) and only strips tool results, so a fold returned the
transcript almost verbatim (24,426 chars for a 24,586-char transcript) and
saved ~0 tokens. The flattened text alone gets a real summary.

Kept as a separate commit so it can be dropped if the backend behaviour
changes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The session key was a hash of the system prompt + first message only, so two
conversations that open the same way shared compaction state and the second
was sent the first one's summary in place of its own turns (21 messages -> 1).

- Key state on Claude Code's session id (x-claude-code-session-id header, or
  session_id in metadata.user_id) plus the existing hash, which still
  separates the main thread from subagents within one session.
- Store a fingerprint of the folded prefix at each fold and reset instead of
  applying the summary when the incoming messages don't match it. This covers
  clients that send no session id. The fingerprint ignores cache_control and
  thinking blocks, which clients rewrite between requests. State saved before
  this change has no fingerprint and is trusted as before.
- Record proxy savings under Claude Code's session id, the key the hooks
  already use, so per-session stats line up.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Setup only treated 401 as an invalid key, but ScaleDown returns 403 for a bad
or empty key. The bad key was saved and every later hook call and proxy fold
failed. Treat 401 and 403 as invalid (exit 1, key not saved); network errors
and 5xx still warn and continue.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
registerMcp only removed the pre-rename `scaledown` id, so re-running setup
(the README's way to change your key) hit "already exists" on `claude mcp add`
and printed a false "Could not register MCP server" warning. Remove the
`dietcode` id first too (best-effort) before adding it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`dietcode claude` sets CLAUDE_AUTOCOMPACT_PCT_OVERRIDE=95 so the proxy owns
compaction, but only when the variable was unset, and setup exports 50 in the
shell rc. Setup also writes 50 into settings.json `env`, which overrides the
environment Claude Code is started with: inside `dietcode claude`, Claude Code
2.1.301 sees 50, so its own compaction can fire before the proxy folds.

Pass the threshold with --settings, which outranks the settings files (checked
live: settings env 50 + process env 95 -> 50; adding --settings 95 -> 95), and
always set the env var in the wrapper. A user-supplied --settings is left alone.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The status line showed global totals and the context size whichever session
wrote last, so a brand-new session showed the same "94.5K saved · 39 reqs" and
30% bar as every other one.

- Savings come from stats.sessions[session_id]. Since the proxy now records
  under Claude Code's session id, proxy savings show up in the session that
  earned them.
- Requests are counted per session too (new sessionRequests map; the proxy
  passes its session id, other callers are unchanged).
- The context bar uses Claude Code's own context_window.used_percentage from
  the status line input; it is hidden until Claude Code reports one. In a
  proxy session this is the size of the compacted request.
- The off-proxy nudge now says how to turn compaction on.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The comments still described the aged chunk being sent as structured
`messages` alongside the flattened text. The proxy's summarize drops them
since "proxy: stop sending structured messages to the summarize endpoint";
point there instead of rewriting the comments, so dropping that commit
restores the old behaviour with no other edits.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.

1 participant