Repository navigation
Replies: 1 comment
|
The arithmetic here checks out, and one measured detail decides which of the levers can work — worth stating before the adapter is patched. The reserve only moves the threshold above a threshold of its own. with Measured on the shipped rc.3 (
Two consequences.
On fix 1, a semantic note. On fix 3 as a third-party plugin. I began building one and stopped, on two findings. The reserve is already a per-model operator knob — |
Uh oh!
There was an error while loading. Please reload this page.
Summary
On
0.1.7-rc.1, a session on a catalog-backed pi-ai provider (opencode-go) dies permanently at ~664k tokens, with no compaction and no warning.compaction-basicalready contains the555b664b08threshold fix:But
reservedCompletionTokensis 0 for this route, because the adapter never reports the value it actually sends. The threshold therefore lands at 800,000 while the provider's real input ceiling is 664,576 — a 135,424-token blind zone that the session must cross before compaction would ever fire. It cannot: crossing it is what kills the session.Environment
0.1.7-rc.1opencode-go / deepseek-v4.1-flash,api: openai-completions, baseURLhttps://opencode.ai/zen/go/v1apiKeyEnv: OPENCODE_GO_API_KEYonly — nomodels[].maxTokens, nomodelOverrides(the ordinary catalog case)dsh-compaction-basic@0.1.7-rc.1,dsh-llm-pi-ai@0.1.7-rc.1,dsh-token-meter@0.1.7-rc.1headroomTokenspresent?lib/index.js:21,63-64) → the fixed formula is in this buildActual vs expected
Upstream's own message (captured from a different session on the same route):
A concrete crash, reconstructed from the session journal (
session.v4.jsonl.zstd):inputTokens 456 + cacheReadTokens 663,680 = 664,136665,256(previous completion 844 folded back + 246 tokens of tool output + envelope)Root cause
dsh-compaction-basicresolves the reservation as:dsh-llm-pi-aionly populatesdefaultMaxTokenswhen the provider profile explicitly declaresmodels[].maxTokens(dsh-llm-pi-ai, model-info path). In the ordinary catalog case it reports nothing.Meanwhile the sender side does use the catalog value: pi-ai sends
max_tokens = options?.maxTokens ?? model.maxTokens, i.e. 384,000 for this model.So the two halves disagree: the request reserves 384,000 tokens of the window, the budgeter assumes 0.
With
O = 384,000reported, the threshold would bemin(800,000, 550,464) = 550,464— which would work.Journal confirms the consequence: zero
compaction/*events in a 1,617-event session, and nocontextPressurealert before the crash.Secondary defect (why the safety net also misses)
The provider returned an opaque 400 body,
{"error": {"model": "deepseek-v4.1-flash"}}. The openai SDK renders it as400 {"model":"deepseek-v4.1-flash"}. That string matches none of the context-overflow patterns, so the failure is classifiedINVALID_REQUESTrather thanCONTEXT_WINDOW_EXCEEDED— andcompaction-basic's overflow-recovery listener never runs.Even when the same provider does return recognisable wording (another session got the full message above and was correctly classified
CONTEXT_WINDOW_EXCEEDED), the turn still ended in error, so recovery is not a reliable fallback here either (see also #23 —retainTokens = 0in the overflow branch).Workaround that works
Give the route an explicit
maxTokensso the request envelope carries it:Effect:
max_tokenssentOThis matches the design note's wording — "
Ois taken from the effective envelope'smaxTokens" — so the envelope is the intended knob.Suggested fixes
dsh-llm-pi-ai: report the catalogmaxTokensasdefaultMaxTokenseven when the profile does not declare it. The adapter already sends that value, so it owns it.dsh-compaction-basic: clampOto what the adapter actually sends for the route, instead of treating "unknown" as 0.contextWindow − O − headroomTokensagainst the adapter's real per-requestmax_tokens; fail loudly when the threshold would sit above the provider's admission limit.References
.agents/notes/implemented/architecture/2026-07-20-routed-model-context-and-compaction-policy.zh.md(statesOsemantics)555b664b08; this report is the residual)(Posting here because the repository has no issue tracker.)
All reactions