Repository navigation
fix(#1712): blank decompress range fields = omitted; stop advertising range args where CCR cannot arm - #1713
Conversation
📦 Built Package ArtifactBranch: Option A — Install this exact build (recommended)npm install -g billion-context@0.0.1668-pr.1713.6a644b3This exact version is immutable and reproducible. The rolling Option B — Download artifact
tar xzf billion-context-pr1713.tgz
npm install -g packageInstall instructions are refreshed on each push. |
…rtising range args where CCR cannot arm - resolveDecompress/resolveDerivedDecompress: blank or whitespace-only startId/endId now mean unspecified (whole-block restore) instead of entering the range path and failing 'given together'; one-sided non-blank still fails, with guidance to omit both. - plugin-mode CCR-off error replaced (the old 'proxy-mode only' text was stale since #1271/#1345 and steered callers into filling unsupported params): now points at the working call shape {"blockId":"<id>"}. - decompress schema surface (#1192 conservative rule): new *_NO_RANGE tool arrays without startId/endId. Proxy wire injection serves them while the session is not CCR-armed; the plugin manifest advertises range args only on anthropic/openai when base config enables CCR — never on responses (plugin mode structurally disarms CCR there, #1271). - param descriptions document omit-both / empty-counts-as-omitted. - goldens regenerated via scripts/update-wire-contract-goldens.ts (manifest-default loses the two props; manifest-optin keeps them on anthropic/openai only; bili.json description text). - tests/decompress-empty-range.test.ts: 9 regression tests (execution semantics + schema surface + manifest).
f30259f to
75e23c1
Compare
[bot] 🏷 Review complete — mergeable. All 13 CI checks green on the rebased head ① Direction (issue audit)Root-cause analysis in the PR holds up, verified against the code: two independent defects, both fixed at their source (the decision point and the producer), not masked:
② Regression inventory (existing behaviors touched)
③ Code review
④ Test validityThe 9 new tests exercise the real kernel core + real ⑤ Base freshness, diff, CI
Chinese summary: 修复了 decompress 空 range 参数被当成"已提供"而报 "given together"、填了真值又撞过时的 "proxy-mode only" 死循环的缺陷——根因在参数判定(空白=未指定)与工具面无条件广告(改为按 CCR 实际可武装性收敛)两处,均已从源头修复;分支已 rebase 到最新 master(无冲突)、本地与 CI 全绿,可以合并。 |
Rebased onto master (post #1713 NO_RANGE manifest locals, post #1745): goldens now reflect zero-injection manifests — every conversation_id param block removed (routing param, search_context cross-session param, one tool left with empty properties). Regenerated via scripts/update-wire-contract-goldens.ts; manifest arrays keep the NO_RANGE-aware locals instead of the pre-rebase plain BILI_ACP_TOOLS_* arrays.
Rebased onto master (post #1713 NO_RANGE manifest locals, post #1745): goldens now reflect zero-injection manifests — every conversation_id param block removed (routing param, search_context cross-session param, one tool left with empty properties). Regenerated via scripts/update-wire-contract-goldens.ts; manifest arrays keep the NO_RANGE-aware locals instead of the pre-rebase plain BILI_ACP_TOOLS_* arrays.
Closes #1712
Problem
In OMP native plugin mode,
decompresswith blankstartId/endId(""or whitespace) entered the range-restore branch (typeof === "string"check only) and failed withstartId and endId must be given together. Following that hint, filling real ranges then hitrange restore … is proxy-mode only — plugin mode owns its folds natively— a dead end that sent the model into a fill-the-params / unsupported retry loop (16 observed failures vs 10 successes when the fields were simply omitted).Root cause is two-fold:
startId/endIdunconditionally on every wire and in the plugin manifest, while execution requires CCR to be armed ([Feature] CCR v2: message-ID coverage in block summaries, range-level decompress, ID-returning search_context #1179). Plugin mode arms CCR only on anthropic/openai with base-config enabled ([Feature] CCR enablement switch on every host lane: acp_retrieve tool + config surface, one aligned schema across three repos #1271/bug(ccr): plugin manifest tool name can diverge from the route/model-resolved CCR tool name #1345), so for most plugin sessions — including the reporter's OMP-on-Responses case, where CCR never arms at all — the advertised params can never work. The old error text ("proxy-mode only") was also stale since [Feature] CCR enablement switch on every host lane: acp_retrieve tool + config surface, one aligned schema across three repos #1271.Changes
Execution semantics (
src/decompress-shared.ts):hasRangeArgs(): a call asks for a range restore only when at least one field carries a non-blank value. Both blank/whitespace/missing → whole-block restore (the bug's repro now succeeds).…must be given together — pass both mNNNNN refs, or omit both to restore the whole block.[decompress FAILED: range restore (startId/endId) requires CCR, which this plugin-mode session does not have — omit startId/endId and restore the whole block: {"blockId":"<id>"}](replaces the stale "proxy-mode only" text).Schema surface — #1192 conservative rule applied to decompress (
src/compress-tool.ts,src/plugin.ts,src/server.ts):BILI_ACP_TOOLS_*_NO_RANGEarrays: identical except decompress lacksstartId/endId.acp_retrieveon each wire); CCR-armed sessions get the full schema as before.PLUGIN_CCR_WIRESexcludes it, mirroring howccrToolsis never spread into the responses array).Behavior changes (old → new)
decompressexec, both fields blank/whitespace[decompress FAILED: startId and endId must be given together]decompressexec, one-sided non-blank…must be given together— pass both mNNNNN refs, or omit both to restore the whole blockdecompressexec, plugin mode w/o CCRrange restore (startId/endId) is proxy-mode only — plugin mode owns its folds nativelyrequires CCR, which this plugin-mode session does not have — omit startId/endId … {"blockId":"<id>"}startId/endIdstartId/endId)No new config fields/env vars/CLI flags — the config surface is untouched. No change to what CCR-armed sessions can do: range restore behaves exactly as before wherever it could already run.
Golden regeneration
tests/golden/wire-contract/{bili,manifest-default,manifest-optin}.jsonregenerated vianode --import tsx scripts/update-wire-contract-goldens.ts. Justification: the diff IS the intended behavior change above — manifest-default loses the two props from all three wires' decompress; manifest-optin keeps them on anthropic/openai only (responses loses them); bili.json carries only the updated param description text. kernel.json unchanged.Tests
New
tests/decompress-empty-range.test.ts(9 tests): blank/whitespace/one-missing → whole-block restore; one-sided → paired-error with omit guidance; plugin CCR-off → copy-pasteable guidance (and no more "proxy-mode only"); proxy CCR-off → enable-CCR error; with-range vs NO_RANGE array parity (drop exactly startId/endId, tool set identical, search_context keeps conversation_id); manifest default/optin per-wire assertions.Pre-flight (all green on this head):
npm run typecheck✅npm test— 3241 pass / 0 fail / 12 skipped ✅npm run build✅E2E: local upstream (127.0.0.1:8199) unreachable from this sandbox, so the codex e2e suite runs via CI (
ci-e2e.ymlauto-triggers on this diff —src/server.tsis a hot file).中文摘要:修复了 OMP 插件模式下 decompress 传空字符串范围参数导致的反复失败重试——空白参数现在按"未指定"处理直接整块恢复,且不再向无法启用 CCR 的会话/清单暴露 startId/endId(错误提示改为给出可直接复制的成功调用形式)。