@linxiraos/pi-catalog 1.2.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +79 -0
- package/README.md +4 -2
- package/THIRD-PARTY-NOTICES.txt +55 -5
- package/dist/types/build.d.ts +3 -2
- package/dist/types/compat/auth-ids.d.ts +2 -2
- package/dist/types/compat/axes.d.ts +1 -1
- package/dist/types/compat/behavior.d.ts +5 -0
- package/dist/types/compat/catalog-endpoint.d.ts +8 -0
- package/dist/types/compat/image-tokenization.d.ts +9 -1
- package/dist/types/compat/judgment-images.d.ts +25 -0
- package/dist/types/compat/provider-ids.d.ts +1 -1
- package/dist/types/compat/request-compression.d.ts +23 -0
- package/dist/types/compat/request-size.d.ts +12 -3
- package/dist/types/compat/thinking-replay.d.ts +9 -0
- package/dist/types/compat/types.d.ts +4 -0
- package/dist/types/discovery/antigravity.d.ts +7 -0
- package/dist/types/model-cache.d.ts +7 -0
- package/dist/types/model-manager.d.ts +6 -0
- package/dist/types/model-thinking.d.ts +11 -1
- package/dist/types/models.d.ts +16 -1
- package/dist/types/pricing.d.ts +37 -1
- package/dist/types/provider-models/openai-compat.d.ts +18 -46
- package/dist/types/types.d.ts +63 -12
- package/dist/types/wire/codex.d.ts +2 -0
- package/package.json +6 -6
- package/src/build.d.ts +3 -2
- package/src/build.ts +159 -80
- package/src/compat/auth-ids.ts +2 -0
- package/src/compat/axes.d.ts +1 -1
- package/src/compat/axes.ts +129 -4
- package/src/compat/behavior.d.ts +5 -0
- package/src/compat/behavior.ts +9 -1
- package/src/compat/cascade.ts +4 -1
- package/src/compat/catalog-endpoint.ts +43 -0
- package/src/compat/image-tokenization.ts +28 -10
- package/src/compat/judgment-images.ts +83 -0
- package/src/compat/provider-ids.d.ts +1 -1
- package/src/compat/provider-ids.ts +1 -0
- package/src/compat/request-compression.ts +43 -0
- package/src/compat/request-size.ts +20 -5
- package/src/compat/resolve.ts +90 -53
- package/src/compat/rules/README.md +32 -3
- package/src/compat/rules/auth/_order.kdl +1 -1
- package/src/compat/rules/auth/google-antigravity.kdl +1 -1
- package/src/compat/rules/auth/sambanova.kdl +9 -0
- package/src/compat/rules/auth/stencil.kdl +1 -1
- package/src/compat/rules/classes/anthropic.kdl +42 -2
- package/src/compat/rules/classes/deepseek.kdl +4 -0
- package/src/compat/rules/classes/gemini.kdl +46 -2
- package/src/compat/rules/classes/meta.kdl +7 -0
- package/src/compat/rules/classes/minimax.kdl +11 -1
- package/src/compat/rules/classes/openai.kdl +34 -3
- package/src/compat/rules/classes/xai.kdl +26 -0
- package/src/compat/rules/providers/amazon-bedrock.kdl +1 -0
- package/src/compat/rules/providers/anthropic.kdl +23 -0
- package/src/compat/rules/providers/azure.kdl +2 -0
- package/src/compat/rules/providers/cerebras.kdl +3 -0
- package/src/compat/rules/providers/cline-pass.kdl +16 -0
- package/src/compat/rules/providers/commandcode.kdl +10 -0
- package/src/compat/rules/providers/cursor.kdl +50 -1
- package/src/compat/rules/providers/deepinfra.kdl +3 -1
- package/src/compat/rules/providers/devin.kdl +117 -6
- package/src/compat/rules/providers/factory-droid.kdl +6 -0
- package/src/compat/rules/providers/firepass.kdl +15 -0
- package/src/compat/rules/providers/fireworks.kdl +26 -0
- package/src/compat/rules/providers/github-copilot.kdl +24 -0
- package/src/compat/rules/providers/google-antigravity.kdl +37 -0
- package/src/compat/rules/providers/google-gemini-cli.kdl +1 -0
- package/src/compat/rules/providers/google-vertex.kdl +5 -0
- package/src/compat/rules/providers/google.kdl +1 -0
- package/src/compat/rules/providers/image-tokenization.kdl +2 -1
- package/src/compat/rules/providers/local.kdl +8 -1
- package/src/compat/rules/providers/meta.kdl +16 -0
- package/src/compat/rules/providers/moonshot.kdl +2 -0
- package/src/compat/rules/providers/muse-code.kdl +49 -0
- package/src/compat/rules/providers/native-tools.kdl +3 -0
- package/src/compat/rules/providers/ollama-cloud.kdl +10 -0
- package/src/compat/rules/providers/openai-codex.kdl +29 -5
- package/src/compat/rules/providers/openai.kdl +1 -0
- package/src/compat/rules/providers/opencode-go.kdl +35 -0
- package/src/compat/rules/providers/opencode-zen.kdl +4 -0
- package/src/compat/rules/providers/openrouter.kdl +19 -0
- package/src/compat/rules/providers/sambanova.kdl +60 -0
- package/src/compat/rules/providers/tool-call-names.kdl +37 -0
- package/src/compat/rules/providers/typesafe.kdl +11 -0
- package/src/compat/rules/providers/umans.kdl +7 -0
- package/src/compat/rules/providers/venice.kdl +7 -0
- package/src/compat/rules/providers/xai-oauth.kdl +16 -6
- package/src/compat/rules/providers/xai.kdl +3 -0
- package/src/compat/rules/providers/zai.kdl +5 -0
- package/src/compat/rules/runtime/behavior.kdl +128 -8
- package/src/compat/rules/taxonomy/_collapse.kdl +11 -0
- package/src/compat/rules/taxonomy/gemma.kdl +1 -0
- package/src/compat/rules/taxonomy/meta.kdl +7 -0
- package/src/compat/rules/taxonomy/openai.kdl +2 -0
- package/src/compat/rules.json +1 -1
- package/src/compat/thinking-replay.ts +33 -0
- package/src/compat/types.d.ts +4 -0
- package/src/compat/types.ts +4 -0
- package/src/discovery/antigravity.d.ts +7 -0
- package/src/discovery/antigravity.ts +13 -0
- package/src/discovery/codex.ts +0 -4
- package/src/discovery/cursor.ts +28 -20
- package/src/discovery/devin.ts +7 -8
- package/src/model-cache.d.ts +7 -0
- package/src/model-cache.ts +8 -0
- package/src/model-manager.d.ts +6 -0
- package/src/model-manager.ts +41 -21
- package/src/model-thinking.d.ts +80 -0
- package/src/model-thinking.ts +13 -1
- package/src/model-tokenizer.ts +7 -1
- package/src/models.d.ts +16 -1
- package/src/models.json +1 -1
- package/src/models.ts +26 -12
- package/src/pricing.d.ts +37 -1
- package/src/pricing.ts +123 -12
- package/src/provider-models/bundled-references.ts +5 -2
- package/src/provider-models/cache-provider-id.ts +1 -1
- package/src/provider-models/descriptors.ts +2 -0
- package/src/provider-models/google.ts +7 -1
- package/src/provider-models/openai-compat.d.ts +18 -46
- package/src/provider-models/openai-compat.ts +188 -104
- package/src/provider-models/special.ts +1 -0
- package/src/types.d.ts +63 -12
- package/src/types.ts +71 -9
- package/src/wire/codex.d.ts +2 -0
- package/src/wire/codex.ts +17 -0
|
@@ -196,6 +196,8 @@ An `on-api` nested inside `on` under a class requires both the selected provider
|
|
|
196
196
|
|
|
197
197
|
A `models` string without `*` is an exact, case-sensitive match against the provider-relative model identifier. A string containing `*` is an anchored, ASCII-case-insensitive wildcard match. Prefer taxonomy ranks; retain exact/glob lists only when they isolate the census member set exactly, and keep a `// residue:` comment explaining why ranks do not.
|
|
198
198
|
|
|
199
|
+
A row whose own id classifies as `unknown` but whose `requestModelId` does not resolves under the wire id: classification and `models` matching both use it, so the model the row sends gets its own rules. Devin Fusion pairings (`fusion-<lead>-sidekick-*`) resolve as their lead this way.
|
|
200
|
+
|
|
199
201
|
`priority=N` is an optional signed integer property on the block that owns axis assignments. Its default is zero. Use it only to resolve an intentional equal-specificity overlap; do not use it to encode declaration order.
|
|
200
202
|
|
|
201
203
|
`buildDiscoveredModel(spec, providerType)` resolves the catalog `discovery-api` axis before materializing compatibility. It preserves the credential-bearing provider ID and records `providerType` as the backend used for provider selectors on subsequent rebuilds. Ordinary `buildModel` preserves its input API. This lets custom-named llama.cpp deployments reuse the same rules without model-specific discovery code.
|
|
@@ -213,16 +215,36 @@ The three value shapes are:
|
|
|
213
215
|
- **Object**: no arguments and a child block, including an empty block. Child names are kebab-case: an axis-directive spelling compiles to its resolved axis key (`template-reasoning-effort` → `qwenTemplateReasoningEffort`), anything else converts mechanically (`input-threshold` → `inputThreshold`); camelCase names are a compile error. `extra-body` payloads (top-level or nested) are the exception — their child names are literal wire JSON keys copied verbatim (`enable_thinking`). Each child is either one scalar or another object; arrays are not representable inside an object payload.
|
|
214
216
|
|
|
215
217
|
A rule cannot assign the same resolved axis twice in one block.
|
|
216
|
-
One object axis carries a computed form: `long-context-cost` accepts either the absolute rates (`input-threshold` + `input`/`output`/`cache-read`/`cache-write`) or `input-threshold` + `multiplier` (with optional `input-threshold-inclusive`), which derives the tier from the row's base price at build time, after `cost-patch` and `cost-fallback`, so the rule tracks upstream list-price updates (xAI's SuperGrok 200K tier). Rows without a token price carry no tier. An empty `long-context-cost {}` adds no tier; a more specific rule uses it to opt a host out of a broader rule's band (GitHub Copilot's Haiku 5.5 rows, whose long tier is the `-1m` sibling).
|
|
218
|
+
One object axis carries a computed form: `long-context-cost` accepts either the absolute rates (`input-threshold` + `input`/`output`/`cache-read`/`cache-write`) or `input-threshold` + `multiplier` (with optional `input-threshold-inclusive`, and `output-multiplier` when the tier raises output by a different factor than the other legs), which derives the tier from the row's base price at build time, after `cost-patch` and `cost-fallback`, so the rule tracks upstream list-price updates (xAI's SuperGrok 200K tier). Rows without a token price carry no tier. An empty `long-context-cost {}` adds no tier; a more specific rule uses it to opt a host out of a broader rule's band (GitHub Copilot's Haiku 5.5 rows, whose long tier is the `-1m` sibling).
|
|
219
|
+
|
|
220
|
+
`cost-patch` and `cost-fallback` accept an optional `effective-rates` block of named dated cards, each with a distinct ISO UTC `effective-from` (`YYYY-MM-DDTHH:mm:ssZ` or with three fractional-second digits) and any of `input`/`output`/`cache-read`/`cache-write` as nonnegative rates; a malformed card fails `buildModel` rather than leaving the old price in force. A card overwrites those legs from its date: for `cost-patch` over whatever upstream reports, for `cost-fallback` only when it seeded the row. A patch may carry the dated cards alone, leaving the upstream price in place until the first one starts; pin the current price beside them when upstream may later report the new one, or a row built after that loses the earlier period (Gemini 4 Argon's 2026-12-01 list-price increase in [`classes/gemini.kdl`](classes/gemini.kdl) pins both). `buildModel` sets the row's legs to the card due when it is built, and compiles every price period into `ModelCost.timeBased.effectiveRates` (complete cards, long-context tier and cache-rate derivations included, with a leading card for the price before the first change) under a schedule with no peak windows and a 1x off-peak multiplier. Requests are therefore priced at the card in force when they were made, even on rows built before a change (bundles, caches, long sessions); price displays read `getEffectiveTokenCost`, which selects the same card, and such a schedule reports no peak/off-peak period. Rebuilding a row that already carries such a schedule (dynamic merges, overrides) starts from the card due at the rebuild, and Cursor lanes priced from a sibling slug's card keep that card's schedule, scaled by the lane's multiplier. Cards that leave the price unchanged (a fallback the upstream price outranks) add no schedule. A rule cannot combine these cards with `time-based-cost` `effective-rates`; it may add them to a recurring `time-based-cost` tariff without its own.
|
|
217
221
|
|
|
218
222
|
`context-window-authoritative #true` preserves a host's supplied context window through runtime model selection instead of applying inferred expansion or reference-price-tier caps. Explicit user context overrides still apply afterward. It applies to rows materialized through `buildModel` (discovery and regenerated bundles). See [`providers/factory-droid.kdl`](providers/factory-droid.kdl).
|
|
219
223
|
|
|
220
|
-
`
|
|
224
|
+
`long-context-window-uncapped #true` keeps a model's `long-context-cost` tier from capping its runtime context window while extended context is off: the coding agent normally lowers the window to the tier's input threshold so compaction fires before a request crosses into premium pricing. Use it where the tier is an API-equivalent estimate on a subscription host (`xai-oauth`) or where the model is served at its full window regardless (GPT-5.4, except on GitHub Copilot). `buildModel` materializes it as `Model.longContextWindowUncapped`; explicit user context overrides still apply.
|
|
225
|
+
|
|
226
|
+
`max-tokens-fallback` seeds `maxTokens` only when the row reports none, and `max-tokens-ceiling` lowers a larger reported `maxTokens` to the host's output cap (an unknown budget stays unknown unless a fallback seeded it). Both apply in `buildModel` after `limits-patch`, so discovery mappers pass upstream output budgets through verbatim. See the Kimi rules in [`providers/fireworks.kdl`](providers/fireworks.kdl).
|
|
227
|
+
|
|
228
|
+
`inline-image-byte-budget` caps retained base64 image characters for a deployment's request body. It leaves room for tool schemas and text beneath the provider's body-size limit; the coding agent reads it through `resolveInlineImageByteBudget` before sending live history, and snapcompact gives its archive frames half of it (`frameDataBytesBudget`). The budget applies only while the request reaches the official endpoint (the Anthropic API, first-party OpenAI, or the Codex backend at its default URL), which callers decide with pi-ai's `reachesOfficialEndpoint`: `compat.officialEndpoint` for the configured `baseUrl`, and for first-party Anthropic models also the `ANTHROPIC_BASE_URL` or Foundry `FOUNDRY_BASE_URL` reroute applied at request time. A custom or rerouted endpoint imposes its own body limit.
|
|
229
|
+
|
|
230
|
+
`image-count-budget` is the most images one request may carry, archive frames, screenshots and imaged tool results combined. The coding agent reads it through `resolveImageCountBudget`, drops the oldest images past it, and caps snapcompact frames at it; unassigned hosts get a floor of 5. `official-image-count-budget` replaces it while the request reaches the official endpoint (same gate as `inline-image-byte-budget`), for limits established on the host's own endpoint (Anthropic: 600, 100 on 200k-window models; Codex: 2,000); a custom or rerouted endpoint keeps `image-count-budget` (Anthropic 90, Codex 200).
|
|
231
|
+
|
|
232
|
+
`endpoint-hosts` lists the HTTPS hostnames a provider serves besides its bundled base URL's host, such as Copilot's per-plan `api.<plan>.githubcopilot.com` hosts. That host plus these define the provider's own endpoint (`isCatalogEndpointUrl`), which separates first-party traffic from a custom model or provider override that keeps a catalog provider id but points `baseUrl` at a gateway, proxy, or local server. Connection prewarming and request compression act only on the provider's own endpoint.
|
|
233
|
+
|
|
234
|
+
`request-encodings` lists the `Content-Encoding`s (`zstd`, `gzip`) a provider's own endpoint decodes on request bodies, most preferred first; pi-ai's `wrapFetchForRequestCompression` reads them through `resolveRequestCompression` and compresses bodies of 1 KiB or more. A proxy, relay, or `ANTHROPIC_BASE_URL` reroute never receives bytes it cannot read. `request-encoding-rejection` is a regular expression for the JSON 400/415 error body the host returns when it cannot decode the body; unassigned, every JSON 400/415 is re-checked with an uncompressed resend. A 400/403/415 whose body is not JSON (empty included) is presumed to come from a proxy in front of the host, such as a TLS-inspecting gateway that refuses compressed uploads, and is re-checked either way, until the uncompressed resend draws the same status from that host. A rejected encoding is dropped for that host only after the uncompressed resend succeeds. Assign them only from a live probe of every endpoint host: a compressed body, the same plain JSON mislabeled as compressed (a decoding host must reject it), and a real request.
|
|
221
235
|
|
|
222
236
|
`judgment-questions-max` is the most questions one System One judgment request may carry (razorback16/openjev: 256; Cloudflare Clef on Workers AI and through OpenRouter Decisions: 64; unidentified `*openjev*` deployments: 16). The coding agent reads it through `resolveJudgmentQuestionsMax` and `NativeJudge` splits larger requests into parallel chunks; unassigned means the endpoint takes any batch size. [`providers/judgment-questions.kdl`](providers/judgment-questions.kdl) lists the servers verified uncapped or not isolatable.
|
|
223
237
|
|
|
238
|
+
`judgment-image-input` assigns model-specific native judgment image bounds, read through `resolveJudgmentImageInput`. Its object accepts `mime-types` as a comma-separated lowercase MIME list and positive integer `max-count`, `max-bytes`, `max-total-bytes`, `min-pixels`, `max-pixels`, `min-side`, and `max-side`; byte limits count decoded data. `NativeJudge` enforces these alongside its wire's encoding constraints without resizing, and candidate filtering skips models whose bounds reject the images. Unassigned adds no model-specific bounds. The Jev selectors in [`providers/typesafe.kdl`](providers/typesafe.kdl) and [`providers/openrouter.kdl`](providers/openrouter.kdl) own Jev's limits rather than imposing them on every model using those APIs.
|
|
239
|
+
|
|
224
240
|
`prompt-cache-lookback` is how many block positions back from a cache breakpoint the model's prompt cache looks for an earlier request's entry (Claude: 20, counting the breakpoint; a run of consecutive `tool_use` or `tool_result` blocks is one position). The coding agent reads it through `resolvePromptCacheLookback` and keeps warm-cache tool-result pruning inside the window; unassigned means no known bound.
|
|
225
241
|
|
|
242
|
+
`task-sibling-prompt-cache #true` lets Task children use an automatically derived sibling cache key on the matching request model. Missing or `#false` keeps the provider's per-child default; explicit cache keys still win. The session resolves this catalog policy against the actual model for primary turns, handoff, and ephemeral requests that reuse the live context, including model changes, without sharing conversation IDs or response state. The automatic candidate is persisted separately from explicit keys and survives full forks, `/tan`, and session reopening; new and partial sessions discard it. A fork carrying an automatic candidate uses its own conversation ID on unsupported models, and re-enables the candidate when returning to an eligible model. Ordinary forks without an automatic candidate keep their existing inherited cache routing. Conventional compaction keeps its existing cache routing because its serialized summary prompt differs from the primary context. The opt-in covers Muse Code's `muse-spark-1.3`, `muse-spark-1.3-contributor`, `muse-wonder-1.0`, `muse-wonder-1.0-contributor`, `muse-wonder-full-1.0`, and `muse-wonder-full-1.0-contributor` over `openai-responses`. Meta documents shared-prefix `prompt_cache_key` routing for Responses. Warmed sibling cache reuse was measured on Spark 1.3 Contributor; the standard Spark variant shares this scope following maintainer guidance. A bounded synthetic probe observed cache reuse on all four Wonder variants; it does not establish production or latency benefits. Auxiliary-request latency has not been measured. Provider selectors also match custom providers that declare the same `providerType`; no benefit is established for custom endpoints.
|
|
243
|
+
|
|
244
|
+
`image-max-edge` is the longest image edge, in pixels, a host passes to the model; it downscales larger images to fit first (Cursor: 1024 for Claude and GPT). Snapcompact reads it through `resolveImageMaxEdge` and renders frames no wider, so their glyphs reach the model at the size they were drawn; unassigned means the host keeps the image's size.
|
|
245
|
+
|
|
246
|
+
`snapcompact-image-reads #true` opts a reader in to getting a fresh `read` result as snapcompact frames when `snapcompact.toolResults` is on. Frames collapse whitespace, so snapcompact draws each row's leading indentation as a count bracket (`[»2]`, `[·4]`) and keeps the `[path#TAG]` header as text beside them. On 3–4 frame reads Opus 5.5 then made exact first edits from frames within one of text (38 vs 39 of 40), so Opus 5.5+ opts in ([`classes/anthropic.kdl`](classes/anthropic.kdl)); Sonnet 5.5 (37 vs 40) and Haiku 5.5 (35 vs 40) still miscounted deep tab indents. Unassigned: `read` results stay text; other tools' results are imaged either way.
|
|
247
|
+
|
|
226
248
|
The routed-subscription registry axes (`upstream-rotation`, `region-upstreams-global|us|eu`, `region-limits-eu`, `credit-rates`, `list-price-from`, `routing-family`, `policy-aliases`, `entitlement`, `default-reasoning-off`) describe a gateway whose proxy fans one model out to several upstreams. They are read through `src/compat/factory-droid.ts` by Factory Droid discovery and its request provider, not materialized by `buildModel`. A provider-wide `region-upstreams-*` rule is the upstream serving table and a model rule replaces it for that region. `list-price-from "<provider>" ["<id>"]` shows a bundled row's list price beside the subscription's own billing; unlike seed values it is resolved at runtime and degrades to the seed's zero cost when the row is gone. See [`providers/factory-droid.kdl`](providers/factory-droid.kdl), whose wire and billing pool per model are `api-routes` and `quota-tiers` rules in `runtime/behavior.kdl`.
|
|
227
249
|
|
|
228
250
|
### Time-based pricing
|
|
@@ -280,7 +302,7 @@ The highest-ranked matching assignment wins for that axis. Two distinct rules th
|
|
|
280
302
|
|
|
281
303
|
### Capability gating
|
|
282
304
|
|
|
283
|
-
Wire axes are considered for every matching target. Thinking axes require `reasoning`, except that an exact model selector declaring `thinking-efforts` opens the gate for reviewed corrections. A winning `thinking-upgrade-neutral #true` scoped to a recognized class, family, revision, or model selector also opens it when a matching effort ladder exists; provider-wide opt-in alone does not. Materializing a neutral spec as reasoning-capable requires that opt-in and no explicit thinking vocabulary. Family and revision selectors never match targets missing that rank. An unmatched target resolves to empty maps; the cascade does not infer negative capabilities from absence.
|
|
305
|
+
Wire axes are considered for every matching target. Thinking axes require `reasoning`, except that an exact model selector declaring `thinking-efforts` opens the gate for reviewed corrections. A winning `thinking-upgrade-neutral #true` scoped to a recognized class, family, revision, or model selector also opens it when a matching effort ladder exists; provider-wide opt-in alone does not. Materializing a neutral spec as reasoning-capable requires that opt-in and no explicit thinking vocabulary. A winning `thinking-unverified #true` (scoped `class "unknown"` on hosts whose model list carries no capability metadata) instead offers an unclassified neutral spec its ladder as `ThinkingConfig.unverified`: off until the user picks an effort, and sent as non-reasoning without one; it never changes compat. Family and revision selectors never match targets missing that rank. An unmatched target resolves to empty maps; the cascade does not infer negative capabilities from absence.
|
|
284
306
|
|
|
285
307
|
## Runtime behavior grammar
|
|
286
308
|
|
|
@@ -313,11 +335,17 @@ behavior {
|
|
|
313
335
|
pricing-peer provider="google-antigravity" peers="google" "google-vertex" {
|
|
314
336
|
alias "gemini-3-pro" peer-id="gemini-3-pro-preview"
|
|
315
337
|
}
|
|
338
|
+
role-defaults "smol" {
|
|
339
|
+
model "claude-haiku-5-5"
|
|
340
|
+
model "openai-codex/gpt-5.3-codex-spark"
|
|
341
|
+
}
|
|
316
342
|
}
|
|
317
343
|
```
|
|
318
344
|
|
|
319
345
|
`exclude-discovery-modes` takes one or more exact, case-sensitive upstream mode strings plus `provider=`; discovery mappers preserve missing, malformed, and unknown modes unless the provider policy explicitly lists them. Matcher properties on `route` / `exclude-models` / `tier` nodes are `exact=` / `prefix=` / `substring=` / `glob=`, repeatable. `strip-prefix=#true` on a prefix route strips the matched prefix off the wire id. Values are copied verbatim from the TS constants they replaced; runtime accessors live in `src/compat/behavior.ts`.
|
|
320
346
|
|
|
347
|
+
`role-defaults "<role>"` declares one agent role's built-in default model selector chain, one `model "<selector>"` child per entry, most preferred first. Selectors are copied verbatim (`provider/id`, bare ids, fuzzy fragments such as `-mini`, and `@role` references); duplicates within a role and repeated roles are compile errors. `roleDefaultModels()` returns every chain keyed by role in declaration order.
|
|
348
|
+
|
|
321
349
|
## Auth grammar
|
|
322
350
|
|
|
323
351
|
Every provider has exactly one `auth "<id>" { … }` node under `auth/`; `auth/_order.kdl` holds a single `login-order "id" …` node pinning the `/login` roster order (every provider with a `login` and `show-in-login-list` unset/true must appear; providers without a login sort alphabetically after it). Runtime accessors live in `src/compat/auth.ts`; the id unions in the generated `src/compat/auth-ids.ts`. Every provider in `provider-models/descriptors.ts` needs an auth node (`@linxiraos/pi-ai` type-checks this).
|
|
@@ -446,6 +474,7 @@ provider "sakana" {
|
|
|
446
474
|
dynamic-models-authoritative #true // discovery replaces bundled rows
|
|
447
475
|
allow-unauthenticated #true // runtime manager without a key
|
|
448
476
|
skip-cross-provider-reference-fills #true // generator never backfills from same-id rows elsewhere
|
|
477
|
+
keep-bundled-names #true // discovery never renames a bundled row
|
|
449
478
|
discovery label="Sakana AI" oauth-provider="sakana" allow-unauthenticated=#true {
|
|
450
479
|
env "SAKANA_GEN_KEY" // generation-time keys; defaults to the provider env
|
|
451
480
|
}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
login-order "openai-codex" "anthropic" "zai" "zai-coding-plan" "kimi-code" "openrouter" "github-copilot" \
|
|
5
5
|
"cursor" "devin" "google-antigravity" "google-gemini-cli" "openai-codex-device" "xai" "xai-oauth" \
|
|
6
6
|
"gitlab-duo" "gitlab-duo-agent" "alibaba-coding-plan" "alibaba-token-plan" "aiand" "abliteration" "zhipu-coding-plan" \
|
|
7
|
-
"umans" "qwen-portal" "sakana" "minimax-code" "minimax-code-cn" "xiaomi" "xiaomi-token-plan-sgp" \
|
|
7
|
+
"umans" "qwen-portal" "sakana" "sambanova" "minimax-code" "minimax-code-cn" "xiaomi" "xiaomi-token-plan-sgp" \
|
|
8
8
|
"xiaomi-token-plan-ams" "xiaomi-token-plan-cn" "firepass" "cline-pass" "factory-droid" "commandcode" "charm-hyper" "deepseek" "stepfun" "muse-code" "meta" "moonshot" \
|
|
9
9
|
"cerebras" "baseten" "helmcode" "fireworks" "together" "nvidia" "novita" "deepinfra" "huggingface" "perplexity" \
|
|
10
10
|
"qianfan" "venice" "siliconflow" "siliconflow-cn" "synthetic" "nanogpt" "wafer-serverless" "coreweave" \
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
auth "google-antigravity" {
|
|
2
|
-
name "Antigravity (Gemini
|
|
2
|
+
name "Google Antigravity (Gemini, Claude, GPT-OSS)"
|
|
3
3
|
login "oauth-code" {
|
|
4
4
|
// Antigravity uses different Google OAuth credentials for its additional models.
|
|
5
5
|
client-id "MTA3MTAwNjA2MDU5MS10bWhzc2luMmgyMWxjcmUyMzV2dG9sb2poNGc0MDNlcC5hcHBzLmdvb2dsZXVzZXJjb250ZW50LmNvbQ==" encoding="base64"
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
auth "sambanova" {
|
|
2
|
+
name "SambaNova"
|
|
3
|
+
login "api-key" {
|
|
4
|
+
auth-url "https://cloud.sambanova.ai/apis"
|
|
5
|
+
instructions "Copy your API key from the SambaNova Cloud dashboard"
|
|
6
|
+
prompt "Paste your SambaNova API key" placeholder="..."
|
|
7
|
+
validate "models-endpoint" label="SambaNova" url="https://api.sambanova.ai/v1/models"
|
|
8
|
+
}
|
|
9
|
+
}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
// Two hosts: the Stencil API at api.stencil.so (`{base}`, STENCIL_BASE_URL)
|
|
5
5
|
// and the OIDC issuer at auth.stencil.so (`{auth}`, STENCIL_AUTH_URL) which
|
|
6
6
|
// serves the PKCE-mandatory authorization codes under /oauth/* and mints
|
|
7
|
-
// ES256 access tokens. The public client id `
|
|
7
|
+
// ES256 access tokens. The public client id `zetacode` is code-defined in the
|
|
8
8
|
// issuer with a port-flexible 127.0.0.1 loopback callback.
|
|
9
9
|
auth "stencil" {
|
|
10
10
|
name "Stencil (invite only)"
|
|
@@ -14,10 +14,25 @@
|
|
|
14
14
|
// consecutive tool_use or tool_result blocks is one position. Warm-cache
|
|
15
15
|
// tool-result pruning keeps its rewrites inside this window.
|
|
16
16
|
// https://platform.claude.com/docs/en/build-with-claude/prompt-caching
|
|
17
|
+
// A replayed signed thinking block bills the full reasoning its signature
|
|
18
|
+
// carries (the server rebuilds it from the signature), at the size its turn
|
|
19
|
+
// billed as output, not the signature's bytes. Thinking a request drops bills
|
|
20
|
+
// nothing (earlier turns on lines that strip it: Opus before 4.5, Sonnet
|
|
21
|
+
// before 4.6, Haiku before 5.5; turns before a compaction or prune on
|
|
22
|
+
// prefix-bound lines; another model's blocks the reader cannot read), so
|
|
23
|
+
// those turns count high.
|
|
24
|
+
// https://platform.claude.com/docs/en/build-with-claude/context-windows#the-context-window-with-thinking
|
|
25
|
+
// https://platform.claude.com/docs/en/build-with-claude/preserved-thinking#switching-models
|
|
17
26
|
class "anthropic" {
|
|
18
27
|
prompt-cache-lookback 20
|
|
28
|
+
// Claude's input classifier refuses requests that quote earlier reasoning
|
|
29
|
+
// back as text (`reasoning_extraction`, issue #6093).
|
|
30
|
+
classifier-cot-extraction #true
|
|
31
|
+
thinking-replay-tokens "output"
|
|
32
|
+
// verified: billing matched this formula on Opus 4.7+ and Fable 5.1.
|
|
19
33
|
image-tokenization {
|
|
20
34
|
regime "anthropic-patch"
|
|
35
|
+
verified #true
|
|
21
36
|
max-edge 2576
|
|
22
37
|
max-tokens 4784
|
|
23
38
|
}
|
|
@@ -37,21 +52,39 @@ class "anthropic" {
|
|
|
37
52
|
}
|
|
38
53
|
}
|
|
39
54
|
}
|
|
55
|
+
// Standard tier. verified: billing matched it on Sonnet 4.6 only; older
|
|
56
|
+
// Sonnet lines keep the floor until measured.
|
|
40
57
|
family "sonnet" {
|
|
41
|
-
revision "<4.
|
|
58
|
+
revision "<4.6" {
|
|
42
59
|
image-tokenization {
|
|
43
60
|
regime "anthropic-patch"
|
|
44
61
|
max-edge 1568
|
|
45
62
|
max-tokens 1568
|
|
46
63
|
}
|
|
47
64
|
}
|
|
48
|
-
revision ">=
|
|
65
|
+
revision ">=4.6 <4.7" {
|
|
66
|
+
image-tokenization {
|
|
67
|
+
regime "anthropic-patch"
|
|
68
|
+
verified #true
|
|
69
|
+
max-edge 1568
|
|
70
|
+
max-tokens 1568
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
revision ">=10 <46" {
|
|
49
74
|
image-tokenization {
|
|
50
75
|
regime "anthropic-patch"
|
|
51
76
|
max-edge 1568
|
|
52
77
|
max-tokens 1568
|
|
53
78
|
}
|
|
54
79
|
}
|
|
80
|
+
revision ">=46 <47" {
|
|
81
|
+
image-tokenization {
|
|
82
|
+
regime "anthropic-patch"
|
|
83
|
+
verified #true
|
|
84
|
+
max-edge 1568
|
|
85
|
+
max-tokens 1568
|
|
86
|
+
}
|
|
87
|
+
}
|
|
55
88
|
}
|
|
56
89
|
family "haiku" {
|
|
57
90
|
revision "<4.7" {
|
|
@@ -87,6 +120,13 @@ class "anthropic" {
|
|
|
87
120
|
supports-sampling-params #false
|
|
88
121
|
}
|
|
89
122
|
}
|
|
123
|
+
// Opus 5.5 edits from imaged `read` results within one miss of text; Sonnet
|
|
124
|
+
// and Haiku 5.5 miscount deep tab indents (measurements: rules/README.md).
|
|
125
|
+
family "opus" {
|
|
126
|
+
revision ">=5.5 <10" {
|
|
127
|
+
snapcompact-image-reads #true
|
|
128
|
+
}
|
|
129
|
+
}
|
|
90
130
|
family "sonnet" {
|
|
91
131
|
revision ">=5 <10" {
|
|
92
132
|
supports-sampling-params #false
|
|
@@ -59,6 +59,10 @@ class "deepseek" {
|
|
|
59
59
|
on "alibaba-token-plan" "deepseek" {
|
|
60
60
|
supports-developer-role #false
|
|
61
61
|
}
|
|
62
|
+
// Replaces the provider-keyed leaked chat-template special-token strip.
|
|
63
|
+
on "nvidia" "deepseek" {
|
|
64
|
+
strip-deepseek-special-tokens #true
|
|
65
|
+
}
|
|
62
66
|
on "deepseek" "opencode-go" {
|
|
63
67
|
family "pro" {
|
|
64
68
|
max-tokens-field "max_tokens"
|
|
@@ -66,13 +66,15 @@ class "gemini" {
|
|
|
66
66
|
}
|
|
67
67
|
}
|
|
68
68
|
}
|
|
69
|
-
// Gemini 3.7+ Flash native thinkingLevel does not accept
|
|
70
|
-
// (400 THINKING_LEVEL_MINIMAL; observed on 3.7 and 3.8
|
|
69
|
+
// Gemini 3.7+ Flash and Gemini 4 Argon native thinkingLevel does not accept
|
|
70
|
+
// `minimal` (400 THINKING_LEVEL_MINIMAL; observed on Flash 3.7 and 3.8, and
|
|
71
|
+
// documented for Argon and Argon Cyber Permissive). Only the direct
|
|
71
72
|
// google-level transports emit `thinkingLevel` on the wire, so the tier is
|
|
72
73
|
// dropped there; budget (anthropic-messages) and reasoning_effort resellers
|
|
73
74
|
// never send the rejected value and keep the four-tier ladder. The collapsed
|
|
74
75
|
// google-antigravity / google-gemini-cli variants remap minimal -> LOW and
|
|
75
76
|
// carry their own explicit ladder, so they are unaffected.
|
|
77
|
+
// https://docs.cloud.google.com/gemini-enterprise-agent-platform/models/gemini/4-argon
|
|
76
78
|
// https://ai.google.dev/gemini-api/docs/generate-content/thinking#thinking-levels
|
|
77
79
|
on "google" "google-vertex" "opencode-zen" {
|
|
78
80
|
family "flash" {
|
|
@@ -80,6 +82,41 @@ class "gemini" {
|
|
|
80
82
|
thinking-efforts "low" "medium" "high"
|
|
81
83
|
}
|
|
82
84
|
}
|
|
85
|
+
// Exact ids: a revision-wide rule would tie with the Pro low/high ladder.
|
|
86
|
+
// Gemini API discovery has no bundled Argon reference and infers
|
|
87
|
+
// `reasoning: false` from the id; repair it so the ladder is selectable.
|
|
88
|
+
models "gemini-4-argon" "gemini-4-argon-cyber-permissive" {
|
|
89
|
+
thinking-upgrade-neutral #true
|
|
90
|
+
thinking-efforts "low" "medium" "high"
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
// Gemini 4 Argon's introductory list price ($2/$10, $0.10 cached) ends
|
|
94
|
+
// 2026-11-30; from 2026-12-01 Google bills $4/$20, $0.20 cached, on the
|
|
95
|
+
// Gemini API and Vertex global endpoint alike. Cloud Billing days start at
|
|
96
|
+
// midnight US Pacific. Both cards are pinned over whatever stencil.so or
|
|
97
|
+
// the bundled pricing peer reports: the switch needs no regeneration, and
|
|
98
|
+
// a row built after upstream catches up still prices earlier requests at
|
|
99
|
+
// the introductory rate.
|
|
100
|
+
// https://ai.google.dev/gemini-api/docs/pricing
|
|
101
|
+
// https://cloud.google.com/vertex-ai/generative-ai/pricing
|
|
102
|
+
on "google" "google-vertex" "google-antigravity" {
|
|
103
|
+
models "gemini-4-argon" {
|
|
104
|
+
cost-patch {
|
|
105
|
+
input 2
|
|
106
|
+
output 10
|
|
107
|
+
cache-read 0.1
|
|
108
|
+
cache-write 0
|
|
109
|
+
effective-rates {
|
|
110
|
+
list-price {
|
|
111
|
+
effective-from "2026-12-01T08:00:00Z"
|
|
112
|
+
input 4
|
|
113
|
+
output 20
|
|
114
|
+
cache-read 0.2
|
|
115
|
+
cache-write 0
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
83
120
|
}
|
|
84
121
|
|
|
85
122
|
revision ">=3" {
|
|
@@ -88,6 +125,13 @@ class "gemini" {
|
|
|
88
125
|
// Replaces the Gemini 3+ mandatory-reasoning fallback.
|
|
89
126
|
thinking-requires-effort #true
|
|
90
127
|
}
|
|
128
|
+
// Gemini 3+ takes `thinkingLevel` on the native Google transports; Gemini 4
|
|
129
|
+
// rejects `thinkingBudget` outright (400 "Use thinking level instead").
|
|
130
|
+
on-api "google-generative-ai" "google-gemini-cli" "google-vertex" {
|
|
131
|
+
revision ">=3" {
|
|
132
|
+
thinking-mode "google-level"
|
|
133
|
+
}
|
|
134
|
+
}
|
|
91
135
|
// Public Gemini requires the bypass sentinel on every unsigned call and
|
|
92
136
|
// supports function-part ids. Scope by adapter so custom providers using
|
|
93
137
|
// the same wire protocol inherit both contracts. The Cloud Code Assist
|
|
@@ -9,6 +9,13 @@ class "meta" {
|
|
|
9
9
|
thinking-efforts "minimal" "low" "medium" "high" "xhigh" "max"
|
|
10
10
|
thinking-mode "effort"
|
|
11
11
|
}
|
|
12
|
+
// Meta documents `max` for Muse Wonder (dev.meta.ai/docs/reasoning); the
|
|
13
|
+
// Muse Code-only Wonder Full and contributor tiers accept it too (verified
|
|
14
|
+
// 2026-10-12).
|
|
15
|
+
models "muse-wonder-1.0" "muse-wonder-1.0-contributor" "muse-wonder-full-1.0" "muse-wonder-full-1.0-contributor" {
|
|
16
|
+
thinking-efforts "minimal" "low" "medium" "high" "xhigh" "max"
|
|
17
|
+
thinking-mode "effort"
|
|
18
|
+
}
|
|
12
19
|
models "muse-spark-1.1" "muse-spark-1.2" "muse-spark-1.2-contributor" {
|
|
13
20
|
thinking-efforts "minimal" "low" "medium" "high" "xhigh"
|
|
14
21
|
thinking-mode "effort"
|
|
@@ -7,6 +7,16 @@ class "minimax" {
|
|
|
7
7
|
}
|
|
8
8
|
// Replaces the MiniMax lineage branch in both OpenAI baselines.
|
|
9
9
|
reasoning-deltas-may-be-cumulative #true
|
|
10
|
+
// Replaces the identity default: M2/M3 thinking rides Anthropic adaptive
|
|
11
|
+
// thinking on every Messages route, custom provider ids included.
|
|
12
|
+
on-api "anthropic-messages" {
|
|
13
|
+
family "m2" {
|
|
14
|
+
thinking-mode "anthropic-adaptive"
|
|
15
|
+
}
|
|
16
|
+
family "m3" {
|
|
17
|
+
thinking-mode "anthropic-adaptive"
|
|
18
|
+
}
|
|
19
|
+
}
|
|
10
20
|
on "aimlapi" "coreweave" "fireworks" "huggingface" "kilo" "nanogpt" "novita" "nvidia" \
|
|
11
21
|
"opencode-go" "opencode-zen" "together" "venice" "wafer-serverless" "zenmux" {
|
|
12
22
|
family "m3" {
|
|
@@ -30,7 +40,7 @@ class "minimax" {
|
|
|
30
40
|
// upstream metadata, not the model ceiling (documented: 1M in / 128K out).
|
|
31
41
|
// Exact selectors are case-sensitive, so both served spellings are listed:
|
|
32
42
|
// MiniMax hosts publish `MiniMax-M3`, Charm Hyper publishes `minimax-m3`.
|
|
33
|
-
on "charm-hyper" "minimax" "minimax-cn" "minimax-code" "minimax-code-cn" {
|
|
43
|
+
on "charm-hyper" "minimax" "minimax-cn" "minimax-code" "minimax-code-cn" "sambanova" {
|
|
34
44
|
models "MiniMax-M3" "minimax-m3" {
|
|
35
45
|
limits-patch {
|
|
36
46
|
context-window 1000000
|
|
@@ -11,6 +11,14 @@ class "openai" {
|
|
|
11
11
|
revision ">=5" {
|
|
12
12
|
supports-sampling-params #false
|
|
13
13
|
}
|
|
14
|
+
// GPT-5.4 serves its 1M window, and its long-context price tier does not
|
|
15
|
+
// cap that window. GitHub Copilot keeps its own cap (github-copilot.kdl).
|
|
16
|
+
models "gpt-5.4" {
|
|
17
|
+
limits-patch {
|
|
18
|
+
context-window 1000000
|
|
19
|
+
}
|
|
20
|
+
long-context-window-uncapped #true
|
|
21
|
+
}
|
|
14
22
|
// GPT wire ladders are model generations, not host contracts: <5.2 keeps
|
|
15
23
|
// the classic four-tier scale, 5.2+ drops minimal for xhigh, and 5.6+
|
|
16
24
|
// exposes the wire-exact five-tier low..max scale.
|
|
@@ -95,9 +103,28 @@ class "openai" {
|
|
|
95
103
|
// Older lines carry no lineage rule and bill at their wire API's fallback
|
|
96
104
|
// (providers/image-tokenization.kdl).
|
|
97
105
|
class "openai" {
|
|
98
|
-
// gpt-5.6 sizing
|
|
99
|
-
|
|
100
|
-
|
|
106
|
+
// gpt-5.6 sizing. verified: billing matched this formula on gpt-5.6 through 6.1.
|
|
107
|
+
revision ">=5.6 <6.2" {
|
|
108
|
+
image-tokenization {
|
|
109
|
+
regime "openai-patch"
|
|
110
|
+
verified #true
|
|
111
|
+
multiplier 1.2
|
|
112
|
+
auto "original"
|
|
113
|
+
low {
|
|
114
|
+
max-edge 512
|
|
115
|
+
}
|
|
116
|
+
high {
|
|
117
|
+
max-edge 2048
|
|
118
|
+
patch-budget 2500
|
|
119
|
+
}
|
|
120
|
+
original {
|
|
121
|
+
max-edge 65535
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
// Later lines size like gpt-5.6, unverified until measured. `<10` keeps
|
|
126
|
+
// separator-collapsed revisions (`openai-gpt-52-codex` parses as 52) off it.
|
|
127
|
+
revision ">=6.2 <10" {
|
|
101
128
|
image-tokenization {
|
|
102
129
|
regime "openai-patch"
|
|
103
130
|
multiplier 1.2
|
|
@@ -114,9 +141,11 @@ class "openai" {
|
|
|
114
141
|
}
|
|
115
142
|
}
|
|
116
143
|
}
|
|
144
|
+
// verified: billing matched this formula on gpt-5.5.
|
|
117
145
|
revision "=5.5" {
|
|
118
146
|
image-tokenization {
|
|
119
147
|
regime "openai-patch"
|
|
148
|
+
verified #true
|
|
120
149
|
multiplier 1.2
|
|
121
150
|
auto "original"
|
|
122
151
|
low {
|
|
@@ -173,9 +202,11 @@ class "openai" {
|
|
|
173
202
|
}
|
|
174
203
|
}
|
|
175
204
|
// residue: astra's limits differ from the rest of its revision.
|
|
205
|
+
// verified: billing matched this formula on gpt-6-astra.
|
|
176
206
|
models "*gpt-6-astra*" {
|
|
177
207
|
image-tokenization {
|
|
178
208
|
regime "openai-patch"
|
|
209
|
+
verified #true
|
|
179
210
|
multiplier 1.2
|
|
180
211
|
auto "original"
|
|
181
212
|
low {
|
|
@@ -41,6 +41,32 @@ class "xai" {
|
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
|
+
// Grok bills 32px patches plus ~30–40 tokens per image, resizing past
|
|
45
|
+
// 2,401 patches at every detail level; the 1.017 multiplier carries the
|
|
46
|
+
// per-image tokens at full size (small images bill slightly more).
|
|
47
|
+
// verified: billing matched this rule on Grok 4.6, 4.7 and 4.20.
|
|
48
|
+
family "grok" {
|
|
49
|
+
revision ">=4.6 <=4.20" {
|
|
50
|
+
image-tokenization {
|
|
51
|
+
regime "openai-patch"
|
|
52
|
+
verified #true
|
|
53
|
+
multiplier 1.017
|
|
54
|
+
auto "original"
|
|
55
|
+
low {
|
|
56
|
+
max-edge 65535
|
|
57
|
+
patch-budget 2401
|
|
58
|
+
}
|
|
59
|
+
high {
|
|
60
|
+
max-edge 65535
|
|
61
|
+
patch-budget 2401
|
|
62
|
+
}
|
|
63
|
+
original {
|
|
64
|
+
max-edge 65535
|
|
65
|
+
patch-budget 2401
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
44
70
|
thinking-loop-guard "xai"
|
|
45
71
|
}
|
|
46
72
|
|
|
@@ -74,6 +74,10 @@ provider "anthropic" {
|
|
|
74
74
|
// combines this fact with a per-request effective-URL check, so it never
|
|
75
75
|
// authorizes a block on its own.
|
|
76
76
|
first-party-provider #true
|
|
77
|
+
// Shares Claude Code's `ANTHROPIC_*` env routing, so it also honors Claude
|
|
78
|
+
// Code's `CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS` kill switch for gateways
|
|
79
|
+
// that reject experimental beta fields.
|
|
80
|
+
honors-claude-code-beta-kill-switch #true
|
|
77
81
|
// Messages requests cap at 32 MB. Reserve 8 MB for text, tools, and JSON
|
|
78
82
|
// framing when retaining inline base64 images in a long conversation.
|
|
79
83
|
// Applied only on the official endpoint; a custom baseUrl has its own limit.
|
|
@@ -81,7 +85,26 @@ provider "anthropic" {
|
|
|
81
85
|
on-api "anthropic-messages" {
|
|
82
86
|
inline-image-byte-budget 24000000
|
|
83
87
|
}
|
|
88
|
+
// The official endpoint carries at most 600 images and documents per
|
|
89
|
+
// request, 100 on models with a 200k-token window: every Claude line before
|
|
90
|
+
// 4.6, including separator-collapsed revisions (`claude-opus-45` parses as
|
|
91
|
+
// 45). A custom baseUrl keeps the conservative 90.
|
|
92
|
+
// https://platform.claude.com/docs/en/build-with-claude/vision
|
|
93
|
+
image-count-budget 90
|
|
94
|
+
official-image-count-budget 600
|
|
95
|
+
// The Messages API decodes gzip request bodies and rejects zstd and br
|
|
96
|
+
// with a 400 (`request_body_encoding_invalid`). Gzip bytes that arrive
|
|
97
|
+
// without their `Content-Encoding` (a proxy dropped the header) get a 400
|
|
98
|
+
// "The request body is not valid JSON" (live, 2026-10-17).
|
|
99
|
+
request-encodings "gzip"
|
|
100
|
+
request-encoding-rejection "request_body_encoding_invalid|Unsupported Content-Encoding|request body is not valid JSON"
|
|
84
101
|
class "anthropic" {
|
|
102
|
+
revision "<4.6" {
|
|
103
|
+
official-image-count-budget 100
|
|
104
|
+
}
|
|
105
|
+
revision ">=10 <46" {
|
|
106
|
+
official-image-count-budget 100
|
|
107
|
+
}
|
|
85
108
|
revision ">=3.7 <4.6" {
|
|
86
109
|
thinking-efforts "minimal" "low" "medium" "high" "xhigh"
|
|
87
110
|
}
|
|
@@ -10,6 +10,9 @@ provider "cerebras" {
|
|
|
10
10
|
// Replaces the Cerebras provider branches in the completions baseline.
|
|
11
11
|
supports-usage-in-streaming #false
|
|
12
12
|
tool-strict-mode "all_strict"
|
|
13
|
+
// Replaces the provider check in agent-loop history normalization: replayed
|
|
14
|
+
// assistant history drops its thinking blocks.
|
|
15
|
+
strip-thinking-history #true
|
|
13
16
|
// Prompt caching carries no discount: cached input tokens bill at the
|
|
14
17
|
// standard input rate (https://inference-docs.cerebras.ai/capabilities/prompt-caching).
|
|
15
18
|
cache-read-at-input-rate #true
|
|
@@ -10,4 +10,20 @@ provider "cline-pass" {
|
|
|
10
10
|
wire-model-id-mode "cline-pass"
|
|
11
11
|
// Replaces the Cline Pass thinking-format branch.
|
|
12
12
|
thinking-format "openai"
|
|
13
|
+
// Replaces the Cline Pass completions baseline branches: the reasoning
|
|
14
|
+
// field, the disable shape, and reasoning kept on under tool choice.
|
|
15
|
+
reasoning-content-field "reasoning"
|
|
16
|
+
reasoning-disable-mode "cline-enabled-false"
|
|
17
|
+
disable-reasoning-on-forced-tool-choice #false
|
|
18
|
+
disable-reasoning-on-tool-choice #false
|
|
19
|
+
// Discovery reports each row's thinking ladder; a row without one
|
|
20
|
+
// (`supportsReasoningEffort: false`) has no reasoning control at all.
|
|
21
|
+
trust-explicit-thinking-only #true
|
|
22
|
+
class "qwen" {
|
|
23
|
+
supports-forced-tool-choice #false
|
|
24
|
+
cache-control-format "anthropic"
|
|
25
|
+
}
|
|
26
|
+
class "anthropic" {
|
|
27
|
+
cache-control-format "anthropic"
|
|
28
|
+
}
|
|
13
29
|
}
|
|
@@ -337,6 +337,16 @@ provider "commandcode" {
|
|
|
337
337
|
cache-write 0.0
|
|
338
338
|
}
|
|
339
339
|
}
|
|
340
|
+
// Restate the 64K provider output cap beside the openai class's GPT-5.4
|
|
341
|
+
// window patch, or the class rule wins the whole limits axis.
|
|
342
|
+
class "openai" {
|
|
343
|
+
models "gpt-5.4" {
|
|
344
|
+
limits-patch {
|
|
345
|
+
context-window 1000000
|
|
346
|
+
max-tokens 65536
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
}
|
|
340
350
|
models "gpt-5.3-codex" {
|
|
341
351
|
cost-patch {
|
|
342
352
|
input 2.0
|