Skip to content

fix: improve Claude Code cascade context reuse#36

Merged
dwgx merged 3 commits into
dwgx:masterfrom
baily-zhang:fix-claude-code-context-reuse
Apr 23, 2026
Merged

fix: improve Claude Code cascade context reuse#36
dwgx merged 3 commits into
dwgx:masterfrom
baily-zhang:fix-claude-code-context-reuse

Conversation

@baily-zhang
Copy link
Copy Markdown
Contributor

Summary

  • make Cascade conversation reuse robust against Claude Code system prompt churn
  • include tool-result turns in the stable reuse fingerprint
  • make Cascade history replay budget configurable, with a larger default for 1m models
  • allow local LS data directory override via LS_DATA_DIR for non-/opt deployments

Verification

  • node --check src/langserver.js
  • node --check src/conversation-pool.js
  • node --check src/client.js
  • local /v1/messages non-stream validation: conversation pool hits increased and the second turn recovered the nonce
  • local /v1/messages stream validation: service logs showed cascade reuse HIT and reuse=1

@dwgx dwgx merged commit aa54f20 into dwgx:master Apr 23, 2026
@dwgx
Copy link
Copy Markdown
Owner

dwgx commented Apr 23, 2026

谢谢你

dwgx added a commit that referenced this pull request Apr 23, 2026
…路 sanitize

#24 根因:Claude Code 每轮往 user 消息里注入 <system-reminder> / <command-*>
      等动态 meta tag(cwd / todo state / timestamp),canonicalise 把这
      些内容也拉进 hash,fingerprint 每轮都漂移,reuse 永远 MISS(即使
      PR #36 已经不 hash system/assistant 也救不了)。修法:在 canonicalise
      前 stripMetaTags,只对稳定用户文本算指纹。E2E 验证:三轮注入动态
      timestamp 的请求,T2/T3 都 reuse HIT 同一个 cascade。

#38 根因:反代给 LS 的 workspace path 是 /home/user/projects/workspace-{hash}
      的沙盒格式,Cascade 把它塞进模型 system context,模型于是在 tool
      调用里建议 file_path = /home/user/projects/workspace-x/foo.py。
      反代 text 流过 PathSanitizeStream 会改写,但 tool_use 结构的 input
      字段走 JSON 通道不过流,Claude Code 收到的就是原始沙盒路径,试
      着 Read 本地 → ENOENT。修法:
        1. sanitize.js PATTERNS 加 /home/user/projects/workspace-* → .
        2. sanitizeToolCall 扩展支持 input 对象(之前只管 argumentsJson/
           result 两个 legacy carrier)
        3. chat.js 流式 emit tool_call 前用 sanitizeToolCall 处理
      E2E 验证:用户说 "Read /home/user/projects/workspace-abc/main.py",
      模型走 tool_use,Claude Code 收到 input={file_path: './main.py'}。
dwgx pushed a commit that referenced this pull request Apr 25, 2026
Merge baily-zhang's third major contribution. Two-pronged Opus 4.7 fix:

The blast radius. Claude Code routes through the proxy with tools[] +
images. The proxy was packing the entire Claude Code system prompt
(billing header included), tool fallback preamble, image base64 blobs
and reuse fingerprint inputs onto the user-message channel. Successive
image turns inflated history geometrically and tripped Opus 4.7's
prompt-injection heuristics, resulting in tool refusal cascades.

The fix.
- Image / binary content blocks become text-history placeholders
  instead of base64 dumps.
- Big Claude Code system prompts get compressed (billing header
  dropped, only proxy-relevant context kept).
- Opus 4.7 multimodal tool calls bypass the user-message tool fallback
  entirely (the proto-level section override carries the schema).
- Opus 4.7 tool turns get strict-account-bound narrow cascade reuse
  so retries don't replay full history into a different account.
- Conversation reuse fingerprint stops hashing image base64.
- Regression coverage on every angle (tool fallback, image
  desensitization, system-prompt compression, Opus 4.7 reuse policy).

CI green, npm test 105/105.

baily-zhang's prior surgical work on cascade reuse (PR #36, PR #45)
is what made this diagnosis possible — they own the fingerprint /
trajectory-offset machinery this PR extends.
dwgx added a commit that referenced this pull request Apr 25, 2026
…ly-zhang to S+

- baily-zhang PR #61 (Opus 4.7 multimodal context bloat) — third major
  contribution after #36 and #45, now de-facto maintainer of the
  reuse-fingerprint / trajectory-offset machinery
- abwuge PR #58 (docker/nginx deploy fix) — first-time contributor,
  +3/-2 surgical, unblocked the docker-compose Restart loop
- aict666 PR #54 (tool preamble slimming + redact marker 6th-gen U+2026
  ellipsis + identity coverage extension) — fourth major contribution
- aict666 PR #53 (redact marker shell-safety regression) — second
  contribution, was missing from the prior credits update
- baily-zhang upgraded from S to S+ (parity with aict666)
dwgx added a commit that referenced this pull request Apr 25, 2026
The Pages site at dwgx.github.io/WindsurfAPI/ had only 4 names listed
in the footer (dd373156, colin1112a, motto1, youfak). 8 contributors
were missing from the public site even though most of them landed
S+/S level fixes (aict666 #44/#51/#53/#54, baily-zhang #36/#45/#61,
smeinecke #43, abwuge #58).

Adds a dedicated `#contributors` section before the footer with one
card per contributor: avatar, GitHub link, weight badge (S+/S/A+/A/B+),
PR list, and a one-paragraph 繁體中文 description of what each fix
actually solved. Cards reuse the existing panel-card warm/coral
palette to fit the site's aesthetic.

Footer one-liner is also expanded to all 8 names ordered by weight,
with a "完整名單 ↑" anchor back to the new section.

CSS additions: contrib-grid, contrib-card, contrib-avatar,
contrib-weight + 5 weight-tier classes (-S-plus, -S, -A-plus, -A,
-B-plus). All gradient/hover behaviour matches the existing
panel-card styling.
dwgx pushed a commit that referenced this pull request Apr 25, 2026
Critical hotfix: my own credits commit (60fcd5a) shipped over-escaped
single quotes (`Codeium\'s Cascade`) inside the inline single-quoted
JS strings of dashboard CONTRIBUTORS, breaking the entire main script
parse. Result: dashboard pages opened but every panel rendered empty
because App.init() never ran.

baily-zhang spotted it within hours, fixed the literal, and added
test/dashboard-syntax.test.js — a regression that statically parses
the inline `<script>` blocks of src/dashboard/index.html with the V8
parser. Future copy/escape regressions in dashboard inline JS will
now break `npm test` instead of silently bricking the live UI.

baily-zhang's fourth landed PR (#36 / #45 / #61 / #62), entirely on
issues created by other people / by me. Adding to the dashboard credits
in a follow-up commit.
dwgx added a commit that referenced this pull request Apr 25, 2026
baily-zhang's fourth landed PR (#36 / #45 / #61 / #62) — adding the
PR #62 entry to the dashboard credits panel as a separate card so
the inline-script regression-test win is visible alongside the
cascade-reuse machinery work.

v2.0.5 covers everything since 2.0.4:
- aict666 #54 tool preamble slim + redact U+2026
- abwuge #58 docker/nginx deploy fix
- baily #61 Opus 4.7 multimodal context bloat
- baily #62 dashboard escape regression
- own commits: empty-message validator, internal_error backoff,
  upstream_transient_error category, Opus 4.6 reuse widening,
  /v1/responses endpoint for Codex CLI compatibility (#56, #63)
huanchen pushed a commit to huanchen/WindsurfAPI that referenced this pull request May 3, 2026
…euse

fix: improve Claude Code cascade context reuse
huanchen pushed a commit to huanchen/WindsurfAPI that referenced this pull request May 3, 2026
… path 全链路 sanitize

dwgx#24 根因:Claude Code 每轮往 user 消息里注入 <system-reminder> / <command-*>
      等动态 meta tag(cwd / todo state / timestamp),canonicalise 把这
      些内容也拉进 hash,fingerprint 每轮都漂移,reuse 永远 MISS(即使
      PR dwgx#36 已经不 hash system/assistant 也救不了)。修法:在 canonicalise
      前 stripMetaTags,只对稳定用户文本算指纹。E2E 验证:三轮注入动态
      timestamp 的请求,T2/T3 都 reuse HIT 同一个 cascade。

dwgx#38 根因:反代给 LS 的 workspace path 是 /home/user/projects/workspace-{hash}
      的沙盒格式,Cascade 把它塞进模型 system context,模型于是在 tool
      调用里建议 file_path = /home/user/projects/workspace-x/foo.py。
      反代 text 流过 PathSanitizeStream 会改写,但 tool_use 结构的 input
      字段走 JSON 通道不过流,Claude Code 收到的就是原始沙盒路径,试
      着 Read 本地 → ENOENT。修法:
        1. sanitize.js PATTERNS 加 /home/user/projects/workspace-* → .
        2. sanitizeToolCall 扩展支持 input 对象(之前只管 argumentsJson/
           result 两个 legacy carrier)
        3. chat.js 流式 emit tool_call 前用 sanitizeToolCall 处理
      E2E 验证:用户说 "Read /home/user/projects/workspace-abc/main.py",
      模型走 tool_use,Claude Code 收到 input={file_path: './main.py'}。
huanchen pushed a commit to huanchen/WindsurfAPI that referenced this pull request May 3, 2026
Merge baily-zhang's third major contribution. Two-pronged Opus 4.7 fix:

The blast radius. Claude Code routes through the proxy with tools[] +
images. The proxy was packing the entire Claude Code system prompt
(billing header included), tool fallback preamble, image base64 blobs
and reuse fingerprint inputs onto the user-message channel. Successive
image turns inflated history geometrically and tripped Opus 4.7's
prompt-injection heuristics, resulting in tool refusal cascades.

The fix.
- Image / binary content blocks become text-history placeholders
  instead of base64 dumps.
- Big Claude Code system prompts get compressed (billing header
  dropped, only proxy-relevant context kept).
- Opus 4.7 multimodal tool calls bypass the user-message tool fallback
  entirely (the proto-level section override carries the schema).
- Opus 4.7 tool turns get strict-account-bound narrow cascade reuse
  so retries don't replay full history into a different account.
- Conversation reuse fingerprint stops hashing image base64.
- Regression coverage on every angle (tool fallback, image
  desensitization, system-prompt compression, Opus 4.7 reuse policy).

CI green, npm test 105/105.

baily-zhang's prior surgical work on cascade reuse (PR dwgx#36, PR dwgx#45)
is what made this diagnosis possible — they own the fingerprint /
trajectory-offset machinery this PR extends.
huanchen pushed a commit to huanchen/WindsurfAPI that referenced this pull request May 3, 2026
…nel; promote baily-zhang to S+

- baily-zhang PR dwgx#61 (Opus 4.7 multimodal context bloat) — third major
  contribution after dwgx#36 and dwgx#45, now de-facto maintainer of the
  reuse-fingerprint / trajectory-offset machinery
- abwuge PR dwgx#58 (docker/nginx deploy fix) — first-time contributor,
  +3/-2 surgical, unblocked the docker-compose Restart loop
- aict666 PR dwgx#54 (tool preamble slimming + redact marker 6th-gen U+2026
  ellipsis + identity coverage extension) — fourth major contribution
- aict666 PR dwgx#53 (redact marker shell-safety regression) — second
  contribution, was missing from the prior credits update
- baily-zhang upgraded from S to S+ (parity with aict666)
huanchen pushed a commit to huanchen/WindsurfAPI that referenced this pull request May 3, 2026
The Pages site at dwgx.github.io/WindsurfAPI/ had only 4 names listed
in the footer (dd373156, colin1112a, motto1, youfak). 8 contributors
were missing from the public site even though most of them landed
S+/S level fixes (aict666 dwgx#44/dwgx#51/dwgx#53/dwgx#54, baily-zhang dwgx#36/dwgx#45/dwgx#61,
smeinecke dwgx#43, abwuge dwgx#58).

Adds a dedicated `#contributors` section before the footer with one
card per contributor: avatar, GitHub link, weight badge (S+/S/A+/A/B+),
PR list, and a one-paragraph 繁體中文 description of what each fix
actually solved. Cards reuse the existing panel-card warm/coral
palette to fit the site's aesthetic.

Footer one-liner is also expanded to all 8 names ordered by weight,
with a "完整名單 ↑" anchor back to the new section.

CSS additions: contrib-grid, contrib-card, contrib-avatar,
contrib-weight + 5 weight-tier classes (-S-plus, -S, -A-plus, -A,
-B-plus). All gradient/hover behaviour matches the existing
panel-card styling.
huanchen pushed a commit to huanchen/WindsurfAPI that referenced this pull request May 3, 2026
Critical hotfix: my own credits commit (0376901) shipped over-escaped
single quotes (`Codeium\'s Cascade`) inside the inline single-quoted
JS strings of dashboard CONTRIBUTORS, breaking the entire main script
parse. Result: dashboard pages opened but every panel rendered empty
because App.init() never ran.

baily-zhang spotted it within hours, fixed the literal, and added
test/dashboard-syntax.test.js — a regression that statically parses
the inline `<script>` blocks of src/dashboard/index.html with the V8
parser. Future copy/escape regressions in dashboard inline JS will
now break `npm test` instead of silently bricking the live UI.

baily-zhang's fourth landed PR (dwgx#36 / dwgx#45 / dwgx#61 / dwgx#62), entirely on
issues created by other people / by me. Adding to the dashboard credits
in a follow-up commit.
huanchen pushed a commit to huanchen/WindsurfAPI that referenced this pull request May 3, 2026
baily-zhang's fourth landed PR (dwgx#36 / dwgx#45 / dwgx#61 / dwgx#62) — adding the
PR dwgx#62 entry to the dashboard credits panel as a separate card so
the inline-script regression-test win is visible alongside the
cascade-reuse machinery work.

v2.0.5 covers everything since 2.0.4:
- aict666 dwgx#54 tool preamble slim + redact U+2026
- abwuge dwgx#58 docker/nginx deploy fix
- baily dwgx#61 Opus 4.7 multimodal context bloat
- baily dwgx#62 dashboard escape regression
- own commits: empty-message validator, internal_error backoff,
  upstream_transient_error category, Opus 4.6 reuse widening,
  /v1/responses endpoint for Codex CLI compatibility (dwgx#56, dwgx#63)
dwgx pushed a commit that referenced this pull request May 9, 2026
Merge baily-zhang's third major contribution. Two-pronged Opus 4.7 fix:

The blast radius. Claude Code routes through the proxy with tools[] +
images. The proxy was packing the entire Claude Code system prompt
(billing header included), tool fallback preamble, image base64 blobs
and reuse fingerprint inputs onto the user-message channel. Successive
image turns inflated history geometrically and tripped Opus 4.7's
prompt-injection heuristics, resulting in tool refusal cascades.

The fix.
- Image / binary content blocks become text-history placeholders
  instead of base64 dumps.
- Big Claude Code system prompts get compressed (billing header
  dropped, only proxy-relevant context kept).
- Opus 4.7 multimodal tool calls bypass the user-message tool fallback
  entirely (the proto-level section override carries the schema).
- Opus 4.7 tool turns get strict-account-bound narrow cascade reuse
  so retries don't replay full history into a different account.
- Conversation reuse fingerprint stops hashing image base64.
- Regression coverage on every angle (tool fallback, image
  desensitization, system-prompt compression, Opus 4.7 reuse policy).

CI green, npm test 105/105.

baily-zhang's prior surgical work on cascade reuse (PR #36, PR #45)
is what made this diagnosis possible — they own the fingerprint /
trajectory-offset machinery this PR extends.
dwgx added a commit that referenced this pull request May 9, 2026
…ly-zhang to S+

- baily-zhang PR #61 (Opus 4.7 multimodal context bloat) — third major
  contribution after #36 and #45, now de-facto maintainer of the
  reuse-fingerprint / trajectory-offset machinery
- abwuge PR #58 (docker/nginx deploy fix) — first-time contributor,
  +3/-2 surgical, unblocked the docker-compose Restart loop
- aict666 PR #54 (tool preamble slimming + redact marker 6th-gen U+2026
  ellipsis + identity coverage extension) — fourth major contribution
- aict666 PR #53 (redact marker shell-safety regression) — second
  contribution, was missing from the prior credits update
- baily-zhang upgraded from S to S+ (parity with aict666)
dwgx added a commit that referenced this pull request May 9, 2026
The Pages site at dwgx.github.io/WindsurfAPI/ had only 4 names listed
in the footer (dd373156, colin1112a, motto1, youfak). 8 contributors
were missing from the public site even though most of them landed
S+/S level fixes (aict666 #44/#51/#53/#54, baily-zhang #36/#45/#61,
smeinecke #43, abwuge #58).

Adds a dedicated `#contributors` section before the footer with one
card per contributor: avatar, GitHub link, weight badge (S+/S/A+/A/B+),
PR list, and a one-paragraph 繁體中文 description of what each fix
actually solved. Cards reuse the existing panel-card warm/coral
palette to fit the site's aesthetic.

Footer one-liner is also expanded to all 8 names ordered by weight,
with a "完整名單 ↑" anchor back to the new section.

CSS additions: contrib-grid, contrib-card, contrib-avatar,
contrib-weight + 5 weight-tier classes (-S-plus, -S, -A-plus, -A,
-B-plus). All gradient/hover behaviour matches the existing
panel-card styling.
dwgx pushed a commit that referenced this pull request May 9, 2026
Critical hotfix: my own credits commit (60fcd5a) shipped over-escaped
single quotes (`Codeium\'s Cascade`) inside the inline single-quoted
JS strings of dashboard CONTRIBUTORS, breaking the entire main script
parse. Result: dashboard pages opened but every panel rendered empty
because App.init() never ran.

baily-zhang spotted it within hours, fixed the literal, and added
test/dashboard-syntax.test.js — a regression that statically parses
the inline `<script>` blocks of src/dashboard/index.html with the V8
parser. Future copy/escape regressions in dashboard inline JS will
now break `npm test` instead of silently bricking the live UI.

baily-zhang's fourth landed PR (#36 / #45 / #61 / #62), entirely on
issues created by other people / by me. Adding to the dashboard credits
in a follow-up commit.
dwgx added a commit that referenced this pull request May 9, 2026
baily-zhang's fourth landed PR (#36 / #45 / #61 / #62) — adding the
PR #62 entry to the dashboard credits panel as a separate card so
the inline-script regression-test win is visible alongside the
cascade-reuse machinery work.

v2.0.5 covers everything since 2.0.4:
- aict666 #54 tool preamble slim + redact U+2026
- abwuge #58 docker/nginx deploy fix
- baily #61 Opus 4.7 multimodal context bloat
- baily #62 dashboard escape regression
- own commits: empty-message validator, internal_error backoff,
  upstream_transient_error category, Opus 4.6 reuse widening,
  /v1/responses endpoint for Codex CLI compatibility (#56, #63)
MYMDO added a commit to MYMDO/WindsurfAPI that referenced this pull request May 14, 2026
Operational/navigation links updated to MYMDO/WindsurfAPI:
- package.json: homepage, repository.url, bugs.url
- install-ls.sh: OUR_RELEASE
- update.sh: RELEASE_URL
- docker-compose.yml: ghcr.io/mymdo/windsurf-api:latest (lowercased per GHCR)
- SECURITY.md: 2x security advisory URLs
- .github/ISSUE_TEMPLATE/config.yml: security advisory URL
- .github/workflows/release.yml: comment
- README.{md,en,ua,zh}.md: clone URLs, GitHub Pages catalog, Issues/PR CTAs
- docs/index.html: nav GitHub, hero CTA, deploy clone, contributors CTA, footer (GitHub/Releases/Issues/Security/READMEs/CONTRIBUTING)
- src/dashboard/index.html + index-sketch.html: Issue/PR CTA buttons, RELEASE_NOTES blob link

KEPT at dwgx (intentional):
- Historical PR references (PR dwgx#1, dwgx#13, dwgx#36, dwgx#43, dwgx#44, dwgx#45) — they exist only in dwgx/WindsurfAPI
- @dwgx profile link in footer (attribution)
- (c) 2026 dwgx (copyright attribution per MIT)
- package.json author field (original creator)
- bydwgx1337 brand strings in dashboard UI / server provider / version BRAND
- contributors.json (login + historical narrative)
- test fixtures and code comments referencing dwgx
- docs/releases/RELEASE_NOTES_*.md (historical archives)
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.

2 participants