Skip to content

fix: 修复 Opus 4.7 Claude Code 上下文爆炸#61

Merged
dwgx merged 1 commit into
dwgx:masterfrom
baily-zhang:fix/opus47-context-bloat
Apr 25, 2026
Merged

fix: 修复 Opus 4.7 Claude Code 上下文爆炸#61
dwgx merged 1 commit into
dwgx:masterfrom
baily-zhang:fix/opus47-context-bloat

Conversation

@baily-zhang
Copy link
Copy Markdown
Contributor

解决的问题

Claude Code 通过 WindsurfAPI 调用 Opus 4.7 时,带图片和 tools 的请求会把完整 Claude Code system prompt、billing header、工具 fallback 以及图片 base64 混进 Cascade 的用户文本通道。连续图片 turn 会导致历史快速膨胀,并触发 Opus 4.7 的 prompt injection 判断。

修改内容

  • 图片和二进制 content block 在文本历史里只保留占位符,不再序列化 base64。
  • 压缩 Claude Code 大 system prompt,移除 billing header,只保留必要的代理上下文和环境事实。
  • Opus 4.7 多模态工具请求禁用 user-message tool fallback,避免把工具提示和图片数组拼成用户文本。
  • 对 Opus 4.7 工具请求启用窄范围 cascade reuse 和严格账号绑定,减少失败重试时的整段历史重放。
  • conversation reuse fingerprint 不再纳入原始图片 base64。
  • 增加回归测试覆盖多模态工具 fallback、图片历史脱敏、system prompt 压缩和 Opus 4.7 reuse 策略。

验证

  • node --check src/client.js
  • node --check src/handlers/chat.js
  • node --check src/handlers/tool-emulation.js
  • npm test,105/105 通过

避免 Claude Code 图片请求在 Cascade 文本通道里重复携带 base64、billing header 和完整 system prompt。

对 Opus 4.7 工具调用启用窄范围 cascade reuse 与严格绑定,减少限流失败后的上下文重放。

新增回归测试覆盖多模态 tool fallback、system prompt 压缩和图片历史脱敏。
@dwgx
Copy link
Copy Markdown
Owner

dwgx commented Apr 25, 2026

baily-zhang 感谢。。

@dwgx dwgx merged commit 54b42f1 into dwgx:master Apr 25, 2026
2 checks passed
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
Copy link
Copy Markdown
Owner

dwgx commented Apr 25, 2026

合了 部到 US 主 VPS 了 v2.0.4 + commit 54b42f1

@baily-zhang 这是第三次了 PR #36 → PR #45 → PR #61 一条线下来 cascade reuse 这套机器(fingerprint / trajectory offset / Opus 4.7 多模态分支)你已经是实质 maintainer 信任级在 dashboard credits 升到 S+ 跟 aict666 平级了

这次的 multimodal 处理特别精彩 —— 把图片 base64 排除在 fingerprint 之外这一笔 我之前没意识到 把图片塞进 reuse hash 等于每张图都生成新 cascade_id 复用瞬间归零 这条线索藏得有点深

下次再来直接审合 不用绕了

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 added a commit that referenced this pull request Apr 25, 2026
zhqsuo (#59) reproduced multi-turn tool-context loss on Opus 4.6 +
Claude Code that mirrors the Opus 4.7 problem PR #61 already
addressed. The strict-reuse / multimodal-tool-fallback gates were
keyed on `isOpus47Model` (regex `^claude-opus-4-7`) which excluded
4.6 (`claude-opus-4.6` / `claude-opus-4-6-high` etc.).

Rename `isOpus47Model` → `isToolSensitiveOpusModel` and widen the
regex to `^claude-opus-4(?:[.-]6|[.-]7)(?:[-.]|$)` to cover both
versions and both label formats (dotted `4.6` / dashed `4-7-high`).
Behaviour is unchanged for 4.7; 4.6 now gets:

- Tool-emulated cascade_id reuse (preserves Cascade-side context
  across <tool_call>/<tool_result> turns instead of replaying full
  history each time)
- Strict reuse (preserves cascade across rate-limit retries on the
  same account, returning 429 instead of switching accounts and
  losing context)
- Disabled user-message tool fallback when the request carries
  multimodal content (avoids re-injecting tools into user channel
  on top of the proto-level SectionOverride, which was triggering
  Opus's prompt-injection heuristic)

Five call sites updated; env-var names (OPUS47_TOOL_EMULATED_REUSE,
OPUS47_STRICT_REUSE) intentionally retained for compatibility with
existing deployments.

105/105 tests pass.
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)
dwgx added a commit that referenced this pull request May 2, 2026
…r + upstream transparency + GOD/MR/LR rarity)

User asked for everything in one shot:

1. Logs export — POST /dashboard/api/logs/export?type=api|system|all
   &format=jsonl|txt&level=... so issue reporters can attach logs.
   Dashboard logs panel got a 3-way type select + format select +
   download button using fetch+blob (so the X-Dashboard-Password
   header travels with the request).

2. Chart hover crosshair — _paintChart now reads _chartCursorIdx,
   draws a dashed vertical line and a highlight ring on the bucket
   under the cursor. _bindChartHover sets the index on mousemove and
   triggers a single repaint when it changes. Empty buckets (drought
   periods) get a small baseline marker so users see "this hour really
   had no traffic". Skips while entry animation runs.

3. Local-windsurf import availability preflight — new GET
   /dashboard/api/accounts/import-local-availability returns
   {available, reason, hint}. loadWindsurfLogin() now disables the
   import button + surfaces a friendly 中文 hint on public binds
   instead of letting users click and get a confusing 403
   ERR_LOCAL_IMPORT_NOT_AVAILABLE_PUBLIC_BIND.

4. Upstream endpoint transparency — new GET
   /dashboard/api/upstream-endpoints lists primary + fallback hosts
   for every Windsurf RPC (RegisterUser / PostAuth / OneTimeToken /
   CheckUserLoginMethod / GetUserStatus / GetCascadeModelConfigs +
   Firebase). Confirms v2.0.57 migration is wired and explains that
   GetUserStatus already covers wam-bundle's GetPlanStatus payload.

5. Contributor rarity ladder — added GOD (animated rainbow gradient
   for project creator), MR (Mythic Rare cyan→purple→pink for
   accumulated S+ contributors like aict666 ×4), LR (Legendary Rare
   purple→indigo→cyan for single-PR architectural leaps like
   baily-zhang's #61 Opus 4.7 multimodal rescue), and an explicit R
   tier so the badge stops being empty for B-grade. weightRank table
   updated so sort order respects the new ceiling.

Tests: 639 / 639 still green (pure dashboard + 3 new GET endpoints).
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
…helper)

zhqsuo (dwgx#59) reproduced multi-turn tool-context loss on Opus 4.6 +
Claude Code that mirrors the Opus 4.7 problem PR dwgx#61 already
addressed. The strict-reuse / multimodal-tool-fallback gates were
keyed on `isOpus47Model` (regex `^claude-opus-4-7`) which excluded
4.6 (`claude-opus-4.6` / `claude-opus-4-6-high` etc.).

Rename `isOpus47Model` → `isToolSensitiveOpusModel` and widen the
regex to `^claude-opus-4(?:[.-]6|[.-]7)(?:[-.]|$)` to cover both
versions and both label formats (dotted `4.6` / dashed `4-7-high`).
Behaviour is unchanged for 4.7; 4.6 now gets:

- Tool-emulated cascade_id reuse (preserves Cascade-side context
  across <tool_call>/<tool_result> turns instead of replaying full
  history each time)
- Strict reuse (preserves cascade across rate-limit retries on the
  same account, returning 429 instead of switching accounts and
  losing context)
- Disabled user-message tool fallback when the request carries
  multimodal content (avoids re-injecting tools into user channel
  on top of the proto-level SectionOverride, which was triggering
  Opus's prompt-injection heuristic)

Five call sites updated; env-var names (OPUS47_TOOL_EMULATED_REUSE,
OPUS47_STRICT_REUSE) intentionally retained for compatibility with
existing deployments.

105/105 tests pass.
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 added a commit that referenced this pull request May 9, 2026
zhqsuo (#59) reproduced multi-turn tool-context loss on Opus 4.6 +
Claude Code that mirrors the Opus 4.7 problem PR #61 already
addressed. The strict-reuse / multimodal-tool-fallback gates were
keyed on `isOpus47Model` (regex `^claude-opus-4-7`) which excluded
4.6 (`claude-opus-4.6` / `claude-opus-4-6-high` etc.).

Rename `isOpus47Model` → `isToolSensitiveOpusModel` and widen the
regex to `^claude-opus-4(?:[.-]6|[.-]7)(?:[-.]|$)` to cover both
versions and both label formats (dotted `4.6` / dashed `4-7-high`).
Behaviour is unchanged for 4.7; 4.6 now gets:

- Tool-emulated cascade_id reuse (preserves Cascade-side context
  across <tool_call>/<tool_result> turns instead of replaying full
  history each time)
- Strict reuse (preserves cascade across rate-limit retries on the
  same account, returning 429 instead of switching accounts and
  losing context)
- Disabled user-message tool fallback when the request carries
  multimodal content (avoids re-injecting tools into user channel
  on top of the proto-level SectionOverride, which was triggering
  Opus's prompt-injection heuristic)

Five call sites updated; env-var names (OPUS47_TOOL_EMULATED_REUSE,
OPUS47_STRICT_REUSE) intentionally retained for compatibility with
existing deployments.

105/105 tests pass.
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)
dwgx added a commit that referenced this pull request May 9, 2026
…r + upstream transparency + GOD/MR/LR rarity)

User asked for everything in one shot:

1. Logs export — POST /dashboard/api/logs/export?type=api|system|all
   &format=jsonl|txt&level=... so issue reporters can attach logs.
   Dashboard logs panel got a 3-way type select + format select +
   download button using fetch+blob (so the X-Dashboard-Password
   header travels with the request).

2. Chart hover crosshair — _paintChart now reads _chartCursorIdx,
   draws a dashed vertical line and a highlight ring on the bucket
   under the cursor. _bindChartHover sets the index on mousemove and
   triggers a single repaint when it changes. Empty buckets (drought
   periods) get a small baseline marker so users see "this hour really
   had no traffic". Skips while entry animation runs.

3. Local-windsurf import availability preflight — new GET
   /dashboard/api/accounts/import-local-availability returns
   {available, reason, hint}. loadWindsurfLogin() now disables the
   import button + surfaces a friendly 中文 hint on public binds
   instead of letting users click and get a confusing 403
   ERR_LOCAL_IMPORT_NOT_AVAILABLE_PUBLIC_BIND.

4. Upstream endpoint transparency — new GET
   /dashboard/api/upstream-endpoints lists primary + fallback hosts
   for every Windsurf RPC (RegisterUser / PostAuth / OneTimeToken /
   CheckUserLoginMethod / GetUserStatus / GetCascadeModelConfigs +
   Firebase). Confirms v2.0.57 migration is wired and explains that
   GetUserStatus already covers wam-bundle's GetPlanStatus payload.

5. Contributor rarity ladder — added GOD (animated rainbow gradient
   for project creator), MR (Mythic Rare cyan→purple→pink for
   accumulated S+ contributors like aict666 ×4), LR (Legendary Rare
   purple→indigo→cyan for single-PR architectural leaps like
   baily-zhang's #61 Opus 4.7 multimodal rescue), and an explicit R
   tier so the badge stops being empty for B-grade. weightRank table
   updated so sort order respects the new ceiling.

Tests: 639 / 639 still green (pure dashboard + 3 new GET endpoints).
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