Repository navigation
fix: resolve relay model windows via registry + panel + variant + bidirectional self-heal (#392) - #424
Conversation
…irectional self-heal (#393) Claude Opus 5 behind a relay (Anthropic /v1/messages, --upstream mode) was served the static-table 200K window instead of its real 1M window. Four independent defects compounded: 1. models.dev lookup was gated on a parsed host that is only present in MITM / /bili/<absURL> mode, so plain --upstream relays always fell through to the static table. Removed the host gate: peekRegistryContext and the async contextFromRegistry now run unconditionally (a relay host resolves via the */<model> suffix scan). 2. The status panel hardcoded a 200K fallback and effectiveContextLimit was only written for plugin sessions, so wire-mode panels always showed 200K. effectiveContextLimit is now recorded in every mode (post self-heal + output-headroom), and the panel shows 0 (honest) instead of a fake 200K. 3. Inference suffixes like -thinking did not match the base model's entry. registryLookup now tries modelVariants (progressive suffix strip) so claude-opus-5-thinking resolves to the base model's 1M window. 4. Self-heal only corrected downward (from overflows). Added an upward path: when a low-confidence fallback window is in effect and a prior successful turn's input exceeded the window it was measured under, raise the window to that input and persist it per-model. Also classify GET /models as a known discovery path so omp's model enumeration no longer logs a warn-level "unrecognized path".
📦 Built Package ArtifactBranch: Option A — Install from npm PR tag (recommended)npm install -g billion-context@pr-424Each push to this PR publishes a new version under the Option B — Download artifact
tar xzf billion-context-pr424.tgz
npm install -g packageThis comment is automatically updated on each push. |
[bot] 🏷 PR #424 独立复核(checkout 分支后重跑全部预检 + 逐条核对代码) 结论:LGTM,无阻塞问题。 四项根因 + 次级问题均正确修复,测试覆盖到位。 预检(全绿)
逐条核对
测试 6 个新用例与四项修复一一对应( 合并前建议跑一次 E2E(AGENTS.md §3) 本 PR 动了 关于 #416 误链 同意判断:#416 正文 不合并 —— 合并是人工操作。你过目后(最好先跑上面的 E2E)即可合并。 |
… variant loop from #393 Conflict resolution in registry.ts registryLookup: each variant's relay suffix scan now takes Math.max across */<name> matches (warn once per name on distinct values) and returns before falling through to the next stripped variant; zero valid matches still falls through. Known-provider hosts do not cross-provider scan but their stripped variants keep the exact-key chance. Adds combined-semantics test (variant conflict resolves to max, not the base name's window).
Review: ✅ 方向正确,冲突已解,可合并(已推送到 PR 分支 7e4a781)结论四个根因的定位和修复都对,测试覆盖了关键路径。有两点小观察(不阻塞):
与 master(#490)的冲突已解决并推送到本 PR 分支master 上的 #490(minCompressRange 单位修复)同时改了
验证
|
[bot] 🏷 复核更新后的分支 拉取最新状态、本地分支重置到 冲突解决核对(
预检(在
那 1 个失败非本 PR 引入(已在 master 复现)
你的两点观察我都同意
结论:LGTM。 逻辑、注释、组合语义测试都对,冲突正确合并,预存失败已排除。CI 绿即可合并。 不合并 —— 合并是人工操作。 |
Summary
Fixes #392 — Claude Opus 5 behind a relay (Anthropic
/v1/messages,--upstreammode) was served the static-table 200K window instead of its real 1M window. Four independent defects compounded, plus one secondary logging issue.Root causes & fixes
models.dev lookup bypassed by a host gate.
peekRegistryContext/contextFromRegistrywere gated on a parsedhostthat only exists in MITM //bili/<absURL>mode, so plain--upstreamrelays always fell through to the static table (/^claude-/→ 200K). Removed the gate — both now run unconditionally; a relay host (not inHOST_TO_PROVIDER) resolves via the existing*/<model>suffix scan. The bundled snapshot already containedanthropic/claude-opus-5→ 1,000,000.Panel hardcoded a 200K fallback +
effectiveContextLimitonly written in plugin mode. Wire-mode sessions never gotmetadata.effectiveContextLimit, so the panel always showed 200K. NoweffectiveContextLimitis recorded in every mode (post self-heal + output-headroom), and the panel shows0(honest0% (x / 0)) instead of a fabricated 200K when there is genuinely no value.Inference-suffix variant mismatch.
claude-opus-5-thinkingis not a registry key (only the baseclaude-opus-5is).registryLookupnow triesmodelVariants(name)— progressive strip of-thinking/-reasoning/-high/-medium/-low/-fast/-extended/-interleaved-thinking(longest-first) — so the variant resolves to the base model's window. Known-provider hosts keep the old no-suffix-scan behavior.Self-heal only corrected downward. An overflow only proves the window is smaller; a too-small fallback never overflows (we compress early), so it was never raised. Added an upward path: when a low-confidence fallback (
nativeFromFallback) is in effect and a prior successful turn's reported input exceeded the window it was measured under (lastTurnWindow), raise the window to that input and persist it per-model inlearnedContextLimits. A context that merely fit inside a larger (e.g. beta) window is not evidence (theprevInput > prevWindowguard).Secondary:
GET /models(omp'sopenai-models-listdiscovery) was logged as a warn-level "unrecognized path". Now classified as a known discovery path.Tests
New
tests/issue-393-registry-window.test.ts(6 tests):modelVariantssuffix-strip unit testbundledSnapshotLookupresolves the-thinkingvariant to the base model's 1M window--upstreammode (no/bili/prefix,host === undefined) resolvesclaude-opus-5andclaude-opus-5-thinking→ 1,000,000 (acceptance fix: keep system prompt byte-stable for prefix cache #1)x-bili-plugin) recordseffectiveContextLimit(acceptance fix: address all code review findings (condense, routing, session-id, dead code) #2)tests/e2e-overflow-selfheal.test.ts)GET /modelsemits no warn-level unrecognized-path log (control asserts an unknown path still does)Pre-flight
npm run typecheck✅npm test✅ 874 pass / 0 fail (868 existing + 6 new)npm run build✅tests/e2e/e2e-codex.test.ts): skipped in this environment — thecodexCLI binary is not installed here (spawn codex ENOENT). All changed code paths are covered by the new unit/integration tests above.Note on the #416 mis-link
Cross-link corrections (2026-09-01): this PR fixes #392 (relay window defects). #393 is the omp plugin install/remove idempotency issue and belongs to PR #416, whose
Fixesline has been corrected accordingly. The batch cross-links were fixed together: #415→#391, #416→#393, #418→#413.