@oh-my-pi/pi-catalog 18.1.13 → 18.1.15
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 +16 -1
- package/dist/types/compat/context-window.d.ts +28 -3
- package/dist/types/compat/types.d.ts +4 -0
- package/package.json +4 -4
- package/src/compat/axes.ts +1 -0
- package/src/compat/cascade.ts +3 -1
- package/src/compat/context-window.ts +59 -16
- package/src/compat/delegation.ts +1 -0
- package/src/compat/resolve.ts +1 -0
- package/src/compat/rules/README.md +11 -5
- package/src/compat/rules/classes/gemini.kdl +5 -3
- package/src/compat/rules/providers/openai-codex.kdl +18 -15
- package/src/compat/rules/providers/openai.kdl +13 -0
- package/src/compat/rules.json +49 -25
- package/src/compat/types.ts +4 -0
- package/src/models.json +1 -1
- package/src/provider-models/cache-provider-id.ts +7 -1
- package/src/provider-models/openai-compat.ts +16 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,22 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [18.1.14] - 2026-09-07
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
|
|
9
|
+
- Bills Astra API requests above 272K input at the documented 2x input / 1.5x output long-context tier; the Codex subscription route stays exempt with free cache writes ([#11157](https://github.com/can1357/oh-my-pi/pull/11157) by [@H4vC](https://github.com/H4vC)).
|
|
10
|
+
- Fixed Astra's extended window over-advertising input by 128K; it now uses the documented 922K input cap inside the 1.05M total context ([#11157](https://github.com/can1357/oh-my-pi/pull/11157) by [@H4vC](https://github.com/H4vC)).
|
|
11
|
+
- Fixed explicit Codex context-window overrides widening past the server-honored maximum; they now clamp to the documented ceiling like upstream Codex ([#11157](https://github.com/can1357/oh-my-pi/pull/11157) by [@H4vC](https://github.com/H4vC)).
|
|
12
|
+
- Fixed Codex Astra using its larger window without opt-in; its default is 272K and Extended Context enables at least the documented 1.05M window ([#11126](https://github.com/can1357/oh-my-pi/pull/11126) by [@H4vC](https://github.com/H4vC)).
|
|
13
|
+
- Fixed GitHub Copilot enterprise-only model ids inheriting another provider's wire routing (e.g. `gpt-5.6-sol-fast` pinning every request to the `-none` sibling id regardless of thinking level) ([#11128](https://github.com/can1357/oh-my-pi/pull/11128) by [@H4vC](https://github.com/H4vC)).
|
|
14
|
+
|
|
15
|
+
## [18.1.13] - 2026-09-07
|
|
16
|
+
|
|
17
|
+
### Fixed
|
|
18
|
+
|
|
19
|
+
- Fixed GPT-6 Astra compacting early at a 272K-token window with its full window gated behind `/extended-context`: it now defaults to the documented 1.05M-token window.
|
|
20
|
+
|
|
5
21
|
## [18.1.12] - 2026-09-06
|
|
6
22
|
|
|
7
23
|
### Added
|
|
@@ -15,7 +31,6 @@
|
|
|
15
31
|
- Fixed OpenCode Go/Zen live model discovery (`GET /v1/models`) missing `x-opencode-session` and omp's `User-Agent`: discovery requests now attribute with the stable install id so the requests OpenCode flags as `Bun fetch` carry the required session header.
|
|
16
32
|
- Fixed GPT-6 Astra requests through GitHub Copilot failing with an unsupported endpoint error ([#10874](https://github.com/can1357/oh-my-pi/pull/10874) by [@xpcmdshell](https://github.com/xpcmdshell)).
|
|
17
33
|
- Fixed GPT-6 Astra showing as free with a 272K-token window in the OpenAI Codex catalog by applying its documented pricing; `/extended-context` enables the wire-advertised 872K-token maximum ([#10980](https://github.com/can1357/oh-my-pi/pull/10980) by [@H4vC](https://github.com/H4vC)).
|
|
18
|
-
- Fixed GPT-6 Astra compacting early at a 272K-token window with its full window gated behind `/extended-context`: it now defaults to the documented 1.05M-token window.
|
|
19
34
|
- Made extended-context catalog rebuilds faster by resolving each model's maximum window once per process ([#11039](https://github.com/can1357/oh-my-pi/pull/11039) by [@H4vC](https://github.com/H4vC)).
|
|
20
35
|
|
|
21
36
|
## [18.1.9] - 2026-09-04
|
|
@@ -1,7 +1,32 @@
|
|
|
1
1
|
import type { Model } from "../types.js";
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
3
|
+
* Extended-context capacity. Curated maxima correct stale lower discovery
|
|
4
|
+
* values; a higher live maximum still wins. The registry applies this capacity
|
|
5
|
+
* only when extended context is enabled, before explicit user overrides.
|
|
6
6
|
*/
|
|
7
7
|
export declare function resolveMaxContextWindow(model: Model): number | undefined;
|
|
8
|
+
/**
|
|
9
|
+
* Override ceiling for Codex models. Upstream clamps `model_context_window`
|
|
10
|
+
* to `min(override, max_context_window)` (`with_config_overrides` in
|
|
11
|
+
* `models-manager/src/model_info.rs`); the ceiling here is stale-aware — the
|
|
12
|
+
* curated maximum corrects a lower server value (Astra reports a stale 872K
|
|
13
|
+
* maximum; OpenAI documents at most 922K input) while a higher live maximum
|
|
14
|
+
* still wins. No curated or live maximum means no ceiling: overrides pass
|
|
15
|
+
* through, matching upstream's unclamped branch.
|
|
16
|
+
*/
|
|
17
|
+
export declare function codexOverrideCeiling(model: Model): number | undefined;
|
|
18
|
+
/**
|
|
19
|
+
* Whether explicit context-window overrides for this model clamp to the
|
|
20
|
+
* server-honored ceiling. KDL-owned (`clamp-context-override`): branching on
|
|
21
|
+
* it here keeps provider deployment contracts out of TypeScript.
|
|
22
|
+
*/
|
|
23
|
+
export declare function clampsContextOverride(model: Model): boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Clamp a requested Codex context window to the override ceiling, mirroring
|
|
26
|
+
* upstream. `model` is the pre-override model: the ceiling never shrinks the
|
|
27
|
+
* request below the window that already works, so a stale-low live maximum
|
|
28
|
+
* (e.g. 128K base with a 64K advertised maximum) cannot punish an explicit
|
|
29
|
+
* override. Returns the request unchanged when no ceiling applies or it
|
|
30
|
+
* already fits.
|
|
31
|
+
*/
|
|
32
|
+
export declare function clampCodexContextWindow(model: Model, requested: number): number;
|
|
@@ -180,6 +180,8 @@ export interface CompiledRule {
|
|
|
180
180
|
source: string;
|
|
181
181
|
class?: string;
|
|
182
182
|
providers?: string[];
|
|
183
|
+
/** Request adapter identifiers matched by an `on-api` selector. */
|
|
184
|
+
apis?: string[];
|
|
183
185
|
family?: string;
|
|
184
186
|
revision?: CompiledRevisionTerm[];
|
|
185
187
|
models?: CompiledSelector[];
|
|
@@ -549,6 +551,8 @@ export interface ModelIdentity {
|
|
|
549
551
|
export interface ResolveTarget {
|
|
550
552
|
/** Deployment provider hosting the model. */
|
|
551
553
|
provider: string;
|
|
554
|
+
/** Request adapter used to serialize the model. */
|
|
555
|
+
api: string;
|
|
552
556
|
/** Centrally classified vendor lineage. */
|
|
553
557
|
class: string;
|
|
554
558
|
/** Classified product family within the class, when known. */
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@oh-my-pi/pi-catalog",
|
|
4
|
-
"version": "18.1.
|
|
4
|
+
"version": "18.1.15",
|
|
5
5
|
"description": "Model catalog for omp: bundled model database, provider discovery descriptors, model identity, classification, and equivalence",
|
|
6
6
|
"homepage": "https://omp.sh",
|
|
7
7
|
"author": "Stencil Labs, Inc.",
|
|
@@ -35,12 +35,12 @@
|
|
|
35
35
|
"gen:proto": "bun scripts/generate-protocols.ts"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@oh-my-pi/omptype": "18.1.
|
|
39
|
-
"@oh-my-pi/pi-utils": "18.1.
|
|
38
|
+
"@oh-my-pi/omptype": "18.1.15",
|
|
39
|
+
"@oh-my-pi/pi-utils": "18.1.15"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
42
|
"@bgotink/kdl": "0.4.0",
|
|
43
|
-
"@oh-my-pi/pi-ai": "18.1.
|
|
43
|
+
"@oh-my-pi/pi-ai": "18.1.15",
|
|
44
44
|
"@types/bun": "^1.3.14"
|
|
45
45
|
},
|
|
46
46
|
"engines": {
|
package/src/compat/axes.ts
CHANGED
|
@@ -267,6 +267,7 @@ export const AXES: Readonly<Record<string, AxisDef>> = {
|
|
|
267
267
|
shape: "scalar",
|
|
268
268
|
values: ["freeform", "function"],
|
|
269
269
|
},
|
|
270
|
+
"clamp-context-override": { key: "clampContextOverride", set: "catalog", shape: "scalar" },
|
|
270
271
|
"context-promotion-target": { key: "contextPromotionTarget", set: "catalog", shape: "scalar" },
|
|
271
272
|
"context-window-floor": { key: "contextWindowFloor", set: "catalog", shape: "scalar" },
|
|
272
273
|
"cost-patch": { key: "costPatch", set: "catalog", shape: "object" },
|
package/src/compat/cascade.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* for one structured model target from the compiled rule tree.
|
|
4
4
|
*
|
|
5
5
|
* Faithful port of the o2 reference resolver (`cascade.rs`): rules are
|
|
6
|
-
* conjunctions over `(class, provider, family, revision, models)`; per axis
|
|
6
|
+
* conjunctions over `(class, provider, api, family, revision, models)`; per axis
|
|
7
7
|
* the matching rule with the greatest `(model-selector exactness,
|
|
8
8
|
* constrained-dimension count, priority)` tuple wins, and an equal-tuple
|
|
9
9
|
* same-axis contest throws {@link AmbiguousOverlapError}. Declaration and
|
|
@@ -74,6 +74,7 @@ function buildRuleIndex(cascade: CompiledCascade): IndexedRule[] {
|
|
|
74
74
|
const dimensions =
|
|
75
75
|
Number(compiled.class !== undefined) +
|
|
76
76
|
Number(compiled.providers !== undefined) +
|
|
77
|
+
Number(compiled.apis !== undefined) +
|
|
77
78
|
Number(compiled.family !== undefined) +
|
|
78
79
|
Number(compiled.revision !== undefined) +
|
|
79
80
|
Number(compiled.models !== undefined);
|
|
@@ -117,6 +118,7 @@ function rankRule(
|
|
|
117
118
|
const { compiled } = rule;
|
|
118
119
|
if (compiled.class !== undefined && compiled.class !== target.class) return undefined;
|
|
119
120
|
if (compiled.providers !== undefined && !compiled.providers.includes(target.provider)) return undefined;
|
|
121
|
+
if (compiled.apis !== undefined && !compiled.apis.includes(target.api)) return undefined;
|
|
120
122
|
if (compiled.family !== undefined && compiled.family !== target.family) return undefined;
|
|
121
123
|
if (rule.revision !== undefined && (!revision || !revisionSatisfies(revision, rule.revision))) return undefined;
|
|
122
124
|
let exactness = 0;
|
|
@@ -3,29 +3,72 @@ import type { Model } from "../types";
|
|
|
3
3
|
import { resolveModelPolicy } from "./resolve";
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
|
-
* Rule-owned
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* context is enabled, and the full policy resolve (identity classification
|
|
10
|
-
* plus cascade walk) is wasted work per call.
|
|
6
|
+
* Rule-owned maxima by provider/id/api. Resolve once per process rather than
|
|
7
|
+
* walking the static policy cascade on every catalog rebuild. Null caches the
|
|
8
|
+
* absence of a curated maximum; undefined means the key has not been resolved.
|
|
11
9
|
*/
|
|
12
|
-
const
|
|
10
|
+
const ruleMaximumCache = new Map<string, number | null>();
|
|
13
11
|
|
|
14
12
|
/**
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
13
|
+
* Extended-context capacity. Curated maxima correct stale lower discovery
|
|
14
|
+
* values; a higher live maximum still wins. The registry applies this capacity
|
|
15
|
+
* only when extended context is enabled, before explicit user overrides.
|
|
18
16
|
*/
|
|
19
17
|
export function resolveMaxContextWindow(model: Model): number | undefined {
|
|
18
|
+
const key = `${model.provider} ${model.id} ${model.api}`;
|
|
19
|
+
let curated = ruleMaximumCache.get(key);
|
|
20
|
+
if (curated === undefined) {
|
|
21
|
+
const maximum = resolveModelPolicy(toModelSpec(model)).catalog.maxContextWindow;
|
|
22
|
+
curated = typeof maximum === "number" && Number.isFinite(maximum) && maximum > 0 ? maximum : null;
|
|
23
|
+
ruleMaximumCache.set(key, curated);
|
|
24
|
+
}
|
|
25
|
+
|
|
20
26
|
const maximum = model.maxContextWindow;
|
|
21
27
|
if (typeof maximum === "number" && Number.isFinite(maximum) && maximum > 0) {
|
|
22
|
-
return maximum;
|
|
28
|
+
return Math.max(maximum, curated ?? 0);
|
|
23
29
|
}
|
|
30
|
+
return curated ?? undefined;
|
|
31
|
+
}
|
|
24
32
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
33
|
+
/**
|
|
34
|
+
* Override ceiling for Codex models. Upstream clamps `model_context_window`
|
|
35
|
+
* to `min(override, max_context_window)` (`with_config_overrides` in
|
|
36
|
+
* `models-manager/src/model_info.rs`); the ceiling here is stale-aware — the
|
|
37
|
+
* curated maximum corrects a lower server value (Astra reports a stale 872K
|
|
38
|
+
* maximum; OpenAI documents at most 922K input) while a higher live maximum
|
|
39
|
+
* still wins. No curated or live maximum means no ceiling: overrides pass
|
|
40
|
+
* through, matching upstream's unclamped branch.
|
|
41
|
+
*/
|
|
42
|
+
export function codexOverrideCeiling(model: Model): number | undefined {
|
|
43
|
+
return resolveMaxContextWindow(model);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Whether explicit context-window overrides for this model clamp to the
|
|
48
|
+
* server-honored ceiling. KDL-owned (`clamp-context-override`): branching on
|
|
49
|
+
* it here keeps provider deployment contracts out of TypeScript.
|
|
50
|
+
*/
|
|
51
|
+
export function clampsContextOverride(model: Model): boolean {
|
|
52
|
+
return resolveModelPolicy(toModelSpec(model)).catalog.clampContextOverride === true;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Clamp a requested Codex context window to the override ceiling, mirroring
|
|
57
|
+
* upstream. `model` is the pre-override model: the ceiling never shrinks the
|
|
58
|
+
* request below the window that already works, so a stale-low live maximum
|
|
59
|
+
* (e.g. 128K base with a 64K advertised maximum) cannot punish an explicit
|
|
60
|
+
* override. Returns the request unchanged when no ceiling applies or it
|
|
61
|
+
* already fits.
|
|
62
|
+
*/
|
|
63
|
+
export function clampCodexContextWindow(model: Model, requested: number): number {
|
|
64
|
+
if (!Number.isFinite(requested) || requested <= 0) {
|
|
65
|
+
return requested;
|
|
66
|
+
}
|
|
67
|
+
const ceiling = codexOverrideCeiling(model);
|
|
68
|
+
if (ceiling === undefined || requested <= ceiling) {
|
|
69
|
+
return requested;
|
|
70
|
+
}
|
|
71
|
+
const current = model.contextWindow;
|
|
72
|
+
const floor = typeof current === "number" && Number.isFinite(current) && current > 0 ? current : 0;
|
|
73
|
+
return Math.min(requested, Math.max(ceiling, floor));
|
|
31
74
|
}
|
package/src/compat/delegation.ts
CHANGED
|
@@ -27,6 +27,7 @@ export function resolveDelegationBias(model: Model): DelegationBias {
|
|
|
27
27
|
const { identity } = model;
|
|
28
28
|
const bias = resolveCascade({
|
|
29
29
|
provider: model.provider,
|
|
30
|
+
api: model.api,
|
|
30
31
|
class: identity.class,
|
|
31
32
|
model: model.id,
|
|
32
33
|
reasoning: Boolean(model.reasoning),
|
package/src/compat/resolve.ts
CHANGED
|
@@ -1173,6 +1173,7 @@ function fillExplicitThinking<TApi extends Api>(
|
|
|
1173
1173
|
function buildResolveTarget<TApi extends Api>(spec: ModelSpec<TApi>, identity: ModelIdentity): ResolveTarget {
|
|
1174
1174
|
const target: ResolveTarget = {
|
|
1175
1175
|
provider: spec.provider,
|
|
1176
|
+
api: spec.api,
|
|
1176
1177
|
class: identity.class,
|
|
1177
1178
|
model: spec.id,
|
|
1178
1179
|
reasoning: Boolean(spec.reasoning),
|
|
@@ -5,7 +5,7 @@ This tree is the checked-in source of model identity and compatibility policy. A
|
|
|
5
5
|
There are three ownership strata:
|
|
6
6
|
|
|
7
7
|
- `taxonomy/*.kdl` defines identity: class membership, product families, revision extraction, reviewed exact corrections, and suffix collapse.
|
|
8
|
-
- `classes/*.kdl` defines model-lineage truths: behavior inherent to a model line, optionally scoped to the providers where the census established it.
|
|
8
|
+
- `classes/*.kdl` defines model-lineage truths: behavior inherent to a model line, optionally scoped to the providers or request adapters where the census established it.
|
|
9
9
|
- `providers/*.kdl` defines deployment contracts: behavior imposed by a host, plus documented per-model residue that taxonomy cannot express exactly.
|
|
10
10
|
- `runtime/behavior.kdl` defines heuristics used before or outside exact model lookup: responses routing, API routes, quota tiers, plan requirements, model limits, roster exclusions, hosted defaults, pricing peers.
|
|
11
11
|
- `auth/<provider>.kdl` defines the provider's auth contract: display name, env-var fallback, credential storage/format, and the declarative login / refresh flow that `@oh-my-pi/pi-ai`'s registry engines interpret (see [Auth grammar](#auth-grammar)).
|
|
@@ -151,10 +151,15 @@ discovery {
|
|
|
151
151
|
|
|
152
152
|
## Cascade grammar
|
|
153
153
|
|
|
154
|
-
A cascade document starts with `class` or `provider`. Every selector adds a conjunct to the current rule. Axis directives may appear directly in any permitted scope, and nested selector blocks may appear alongside them.
|
|
154
|
+
A cascade document starts with `class` or `provider`. Every selector adds a conjunct to the current rule. `on` scopes by deployment provider; `on-api` scopes by request adapter, including custom provider names. Axis directives may appear directly in any permitted scope, and nested selector blocks may appear alongside them.
|
|
155
155
|
|
|
156
156
|
```kdl
|
|
157
157
|
class "gemini" {
|
|
158
|
+
on-api "google-generative-ai" {
|
|
159
|
+
revision ">=3" {
|
|
160
|
+
requires-skip-thought-signature #true
|
|
161
|
+
}
|
|
162
|
+
}
|
|
158
163
|
on "google" "google-vertex" "openrouter" {
|
|
159
164
|
family "flash" {
|
|
160
165
|
revision ">=2.5 <3.8" {
|
|
@@ -175,14 +180,15 @@ provider "openrouter" {
|
|
|
175
180
|
|
|
176
181
|
| Selector | Form | Matching semantics |
|
|
177
182
|
| --- | --- | --- |
|
|
178
|
-
| `class` | `class "id" { ... }` | Exact class ID. At document root it may contain `on`, `family`, `revision`, and `models`. Under `provider` it may contain `family`, `revision`, and `models`. |
|
|
183
|
+
| `class` | `class "id" { ... }` | Exact class ID. At document root it may contain `on`, `on-api`, `family`, `revision`, and `models`. Under `provider` it may contain `family`, `revision`, and `models`. |
|
|
179
184
|
| `provider` | `provider "id" { ... }` | Exact provider ID. It is root-only and may contain `class` and `models`. |
|
|
180
185
|
| `on` | `on "provider-a" "provider-b" { ... }` | One or more provider IDs, combined as OR. It is allowed only under a root `class`, and may contain `family`, `revision`, and `models`. |
|
|
186
|
+
| `on-api` | `on-api "adapter-a" "adapter-b" { ... }` | One or more request adapter IDs, combined as OR. It is allowed only under a root `class`, and may contain `family`, `revision`, and `models`. |
|
|
181
187
|
| `family` | `family "id" { ... }` | Exact classified family ID. It may contain `revision` and `models`. A target with no family does not match. |
|
|
182
188
|
| `revision` | `revision ">=2.5 <4" { ... }` | A non-empty, whitespace-separated conjunction of comparisons. It may contain `models`. A target with no revision does not match. |
|
|
183
189
|
| `models` | `models "id" "vendor/*" { ... }` | One or more alternatives, combined as OR. It cannot contain another selector. `token="name"` matches an ASCII-case-insensitive token bounded by non-alphanumerics. |
|
|
184
190
|
|
|
185
|
-
Class, provider/`on`, and family selector values are compared exactly and case-sensitively to the structured resolve target. Revision operators are `>=`, `>`, `<=`, `<`, and `=`; operands have one to three dot-separated unsigned 8-bit components, omitted components zero.
|
|
191
|
+
Class, provider/`on`, `on-api`, and family selector values are compared exactly and case-sensitively to the structured resolve target. Revision operators are `>=`, `>`, `<=`, `<`, and `=`; operands have one to three dot-separated unsigned 8-bit components, omitted components zero.
|
|
186
192
|
|
|
187
193
|
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.
|
|
188
194
|
|
|
@@ -212,7 +218,7 @@ Rules resolve independently per axis. A matching rule is ranked by:
|
|
|
212
218
|
The tuple is compared lexicographically, greatest first:
|
|
213
219
|
|
|
214
220
|
- model exactness is `2` when any matching `models` selector is exact, `1` when the best matching selector is a glob or token, and `0` when the rule has no `models` selector;
|
|
215
|
-
- dimension count is the number of present dimensions among class, provider/`on`, family, revision, and models;
|
|
221
|
+
- dimension count is the number of present dimensions among class, provider/`on`, API/`on-api`, family, revision, and models;
|
|
216
222
|
- priority is the local block's `priority`, defaulting to `0`.
|
|
217
223
|
|
|
218
224
|
The highest-ranked matching assignment wins for that axis. Two distinct rules that tie on all three components and assign the same axis are an ambiguity error even if their values are equal. File and declaration order never resolve the tie; add an explicit priority only after confirming the overlap is intentional.
|
|
@@ -88,9 +88,11 @@ class "gemini" {
|
|
|
88
88
|
// Replaces the Gemini 3+ mandatory-reasoning fallback.
|
|
89
89
|
thinking-requires-effort #true
|
|
90
90
|
}
|
|
91
|
-
// Public Gemini requires the bypass sentinel on every unsigned call
|
|
92
|
-
//
|
|
93
|
-
|
|
91
|
+
// Public Gemini requires the bypass sentinel on every unsigned call and
|
|
92
|
+
// supports function-part ids. Scope by adapter so custom providers using
|
|
93
|
+
// the same wire protocol inherit both contracts. The Cloud Code Assist
|
|
94
|
+
// first-call variant is a host contract in providers/.
|
|
95
|
+
on-api "google-generative-ai" {
|
|
94
96
|
revision ">=3" {
|
|
95
97
|
requires-skip-thought-signature #true
|
|
96
98
|
supports-function-part-id #true
|
|
@@ -9,6 +9,11 @@ provider "openai-codex" {
|
|
|
9
9
|
// Harmony-protocol leak detection/mitigation applies to every Codex model,
|
|
10
10
|
// current and future; replaces the provider check in harmony-leak.ts.
|
|
11
11
|
harmony-leak-mitigation #true
|
|
12
|
+
// Every Codex SKU clamps explicit context-window overrides to the
|
|
13
|
+
// server-honored ceiling (`min(override, max)`, mirroring upstream
|
|
14
|
+
// `with_config_overrides`); models without a curated or live maximum
|
|
15
|
+
// pass through. Replaces the provider check in model-registry.ts.
|
|
16
|
+
clamp-context-override #true
|
|
12
17
|
// Subscription (Codex) discovery reports no pricing; the curated Daybreak
|
|
13
18
|
// aliases carry the standard GPT-5.6 Sol/Cyber API list price so cost
|
|
14
19
|
// display reads as API-equivalent spend. The `-wm` worker sibling bills
|
|
@@ -29,16 +34,15 @@ provider "openai-codex" {
|
|
|
29
34
|
cache-write 15.625
|
|
30
35
|
}
|
|
31
36
|
}
|
|
32
|
-
// Codex
|
|
33
|
-
//
|
|
34
|
-
//
|
|
35
|
-
//
|
|
36
|
-
//
|
|
37
|
-
//
|
|
38
|
-
//
|
|
39
|
-
//
|
|
40
|
-
//
|
|
41
|
-
// writes and no >272K multiplier.
|
|
37
|
+
// Codex reports a 272K default and a stale 872K maximum for Astra. Keep
|
|
38
|
+
// the default explicit so cached 1.05M rows from #11089 cannot bypass the
|
|
39
|
+
// opt-in; the curated maximum is applied only with extended context on.
|
|
40
|
+
// OpenAI documents 1.05M total context with at most 922K input and 128K
|
|
41
|
+
// output, so the input ceiling is 922K — not the total. A higher live
|
|
42
|
+
// maximum still wins as the ceiling.
|
|
43
|
+
// Subscription credit-equivalent pricing: no per-token billing, free cache
|
|
44
|
+
// writes, exempt from the API long-context multiplier. The first-party API
|
|
45
|
+
// route bills the documented >272K tier instead — see providers/openai.kdl.
|
|
42
46
|
models "gpt-6-astra" "gpt-6-astra-wm" {
|
|
43
47
|
cost-patch {
|
|
44
48
|
input 10.0
|
|
@@ -50,7 +54,10 @@ provider "openai-codex" {
|
|
|
50
54
|
flex 0.5
|
|
51
55
|
priority 2.5
|
|
52
56
|
}
|
|
53
|
-
|
|
57
|
+
limits-patch {
|
|
58
|
+
context-window 272000
|
|
59
|
+
}
|
|
60
|
+
max-context-window 922000
|
|
54
61
|
}
|
|
55
62
|
class "openai" {
|
|
56
63
|
revision ">=5.3 <5.7" {
|
|
@@ -141,8 +148,4 @@ provider "openai-codex" {
|
|
|
141
148
|
models "gpt-5.6-luna" "gpt-5.6-sol" "gpt-5.6-terra" {
|
|
142
149
|
context-window-floor 1000000
|
|
143
150
|
}
|
|
144
|
-
// (No `max-context-window` fallback: the 1.05M floor already exceeds the
|
|
145
|
-
// stale 872K wire maximum, so offline and cached rows compose to the
|
|
146
|
-
// documented window and the live maximum is ignored by the
|
|
147
|
-
// `maximum > contextWindow` guard — same as Luna/Sol/Terra above.)
|
|
148
151
|
}
|
|
@@ -72,6 +72,19 @@ provider "openai" {
|
|
|
72
72
|
cache-write 5.0
|
|
73
73
|
}
|
|
74
74
|
}
|
|
75
|
+
// Astra API route bills the documented long-context tier above 272K input:
|
|
76
|
+
// 2x input and cache rates, 1.5x output for the full request; cache writes
|
|
77
|
+
// stay 1.25x the long input rate (25.0). The Codex subscription route stays
|
|
78
|
+
// exempt (credit-equivalent, free cache writes) — see openai-codex.kdl.
|
|
79
|
+
models "gpt-6-astra*" {
|
|
80
|
+
long-context-cost {
|
|
81
|
+
input-threshold 272000
|
|
82
|
+
input 20.0
|
|
83
|
+
output 75.0
|
|
84
|
+
cache-read 2.0
|
|
85
|
+
cache-write 25.0
|
|
86
|
+
}
|
|
87
|
+
}
|
|
75
88
|
// residue: the bare Daybreak rolling aliases pin the documented 5.6-gen
|
|
76
89
|
// wire restrictions without carrying the gpt- prefix identity.
|
|
77
90
|
models "daybreak-blue-latest" "daybreak-red-latest" {
|
package/src/compat/rules.json
CHANGED
|
@@ -4822,11 +4822,10 @@
|
|
|
4822
4822
|
}
|
|
4823
4823
|
},
|
|
4824
4824
|
{
|
|
4825
|
-
"source": "classes/gemini.kdl:
|
|
4825
|
+
"source": "classes/gemini.kdl:96",
|
|
4826
4826
|
"class": "gemini",
|
|
4827
|
-
"
|
|
4828
|
-
"google"
|
|
4829
|
-
"opencode-zen"
|
|
4827
|
+
"apis": [
|
|
4828
|
+
"google-generative-ai"
|
|
4830
4829
|
],
|
|
4831
4830
|
"revision": [
|
|
4832
4831
|
{
|
|
@@ -4840,7 +4839,7 @@
|
|
|
4840
4839
|
}
|
|
4841
4840
|
},
|
|
4842
4841
|
{
|
|
4843
|
-
"source": "classes/gemini.kdl:
|
|
4842
|
+
"source": "classes/gemini.kdl:102",
|
|
4844
4843
|
"class": "gemini",
|
|
4845
4844
|
"providers": [
|
|
4846
4845
|
"google-antigravity",
|
|
@@ -10544,7 +10543,7 @@
|
|
|
10544
10543
|
}
|
|
10545
10544
|
},
|
|
10546
10545
|
{
|
|
10547
|
-
"source": "providers/openai-codex.kdl:
|
|
10546
|
+
"source": "providers/openai-codex.kdl:21",
|
|
10548
10547
|
"providers": [
|
|
10549
10548
|
"openai-codex"
|
|
10550
10549
|
],
|
|
@@ -10568,7 +10567,7 @@
|
|
|
10568
10567
|
}
|
|
10569
10568
|
},
|
|
10570
10569
|
{
|
|
10571
|
-
"source": "providers/openai-codex.kdl:
|
|
10570
|
+
"source": "providers/openai-codex.kdl:29",
|
|
10572
10571
|
"providers": [
|
|
10573
10572
|
"openai-codex"
|
|
10574
10573
|
],
|
|
@@ -10592,7 +10591,7 @@
|
|
|
10592
10591
|
}
|
|
10593
10592
|
},
|
|
10594
10593
|
{
|
|
10595
|
-
"source": "providers/openai-codex.kdl:
|
|
10594
|
+
"source": "providers/openai-codex.kdl:46",
|
|
10596
10595
|
"providers": [
|
|
10597
10596
|
"openai-codex"
|
|
10598
10597
|
],
|
|
@@ -10617,11 +10616,14 @@
|
|
|
10617
10616
|
"flex": 0.5,
|
|
10618
10617
|
"priority": 2.5
|
|
10619
10618
|
},
|
|
10620
|
-
"
|
|
10619
|
+
"limitsPatch": {
|
|
10620
|
+
"contextWindow": 272000
|
|
10621
|
+
},
|
|
10622
|
+
"maxContextWindow": 922000
|
|
10621
10623
|
}
|
|
10622
10624
|
},
|
|
10623
10625
|
{
|
|
10624
|
-
"source": "providers/openai-codex.kdl:
|
|
10626
|
+
"source": "providers/openai-codex.kdl:63",
|
|
10625
10627
|
"class": "openai",
|
|
10626
10628
|
"providers": [
|
|
10627
10629
|
"openai-codex"
|
|
@@ -10641,7 +10643,7 @@
|
|
|
10641
10643
|
}
|
|
10642
10644
|
},
|
|
10643
10645
|
{
|
|
10644
|
-
"source": "providers/openai-codex.kdl:
|
|
10646
|
+
"source": "providers/openai-codex.kdl:68",
|
|
10645
10647
|
"class": "openai",
|
|
10646
10648
|
"providers": [
|
|
10647
10649
|
"openai-codex"
|
|
@@ -10657,7 +10659,7 @@
|
|
|
10657
10659
|
}
|
|
10658
10660
|
},
|
|
10659
10661
|
{
|
|
10660
|
-
"source": "providers/openai-codex.kdl:
|
|
10662
|
+
"source": "providers/openai-codex.kdl:71",
|
|
10661
10663
|
"class": "openai",
|
|
10662
10664
|
"providers": [
|
|
10663
10665
|
"openai-codex"
|
|
@@ -10673,7 +10675,7 @@
|
|
|
10673
10675
|
}
|
|
10674
10676
|
},
|
|
10675
10677
|
{
|
|
10676
|
-
"source": "providers/openai-codex.kdl:
|
|
10678
|
+
"source": "providers/openai-codex.kdl:76",
|
|
10677
10679
|
"class": "openai",
|
|
10678
10680
|
"providers": [
|
|
10679
10681
|
"openai-codex"
|
|
@@ -10692,7 +10694,7 @@
|
|
|
10692
10694
|
}
|
|
10693
10695
|
},
|
|
10694
10696
|
{
|
|
10695
|
-
"source": "providers/openai-codex.kdl:
|
|
10697
|
+
"source": "providers/openai-codex.kdl:88",
|
|
10696
10698
|
"class": "openai",
|
|
10697
10699
|
"providers": [
|
|
10698
10700
|
"openai-codex"
|
|
@@ -10718,7 +10720,7 @@
|
|
|
10718
10720
|
}
|
|
10719
10721
|
},
|
|
10720
10722
|
{
|
|
10721
|
-
"source": "providers/openai-codex.kdl:
|
|
10723
|
+
"source": "providers/openai-codex.kdl:94",
|
|
10722
10724
|
"class": "openai",
|
|
10723
10725
|
"providers": [
|
|
10724
10726
|
"openai-codex"
|
|
@@ -10744,7 +10746,7 @@
|
|
|
10744
10746
|
}
|
|
10745
10747
|
},
|
|
10746
10748
|
{
|
|
10747
|
-
"source": "providers/openai-codex.kdl:
|
|
10749
|
+
"source": "providers/openai-codex.kdl:86",
|
|
10748
10750
|
"class": "openai",
|
|
10749
10751
|
"providers": [
|
|
10750
10752
|
"openai-codex"
|
|
@@ -10761,7 +10763,7 @@
|
|
|
10761
10763
|
}
|
|
10762
10764
|
},
|
|
10763
10765
|
{
|
|
10764
|
-
"source": "providers/openai-codex.kdl:
|
|
10766
|
+
"source": "providers/openai-codex.kdl:104",
|
|
10765
10767
|
"class": "openai",
|
|
10766
10768
|
"providers": [
|
|
10767
10769
|
"openai-codex"
|
|
@@ -10781,7 +10783,7 @@
|
|
|
10781
10783
|
}
|
|
10782
10784
|
},
|
|
10783
10785
|
{
|
|
10784
|
-
"source": "providers/openai-codex.kdl:
|
|
10786
|
+
"source": "providers/openai-codex.kdl:110",
|
|
10785
10787
|
"class": "unknown",
|
|
10786
10788
|
"providers": [
|
|
10787
10789
|
"openai-codex"
|
|
@@ -10797,7 +10799,7 @@
|
|
|
10797
10799
|
}
|
|
10798
10800
|
},
|
|
10799
10801
|
{
|
|
10800
|
-
"source": "providers/openai-codex.kdl:
|
|
10802
|
+
"source": "providers/openai-codex.kdl:113",
|
|
10801
10803
|
"class": "unknown",
|
|
10802
10804
|
"providers": [
|
|
10803
10805
|
"openai-codex"
|
|
@@ -10813,7 +10815,7 @@
|
|
|
10813
10815
|
}
|
|
10814
10816
|
},
|
|
10815
10817
|
{
|
|
10816
|
-
"source": "providers/openai-codex.kdl:
|
|
10818
|
+
"source": "providers/openai-codex.kdl:119",
|
|
10817
10819
|
"providers": [
|
|
10818
10820
|
"openai-codex"
|
|
10819
10821
|
],
|
|
@@ -10834,7 +10836,7 @@
|
|
|
10834
10836
|
}
|
|
10835
10837
|
},
|
|
10836
10838
|
{
|
|
10837
|
-
"source": "providers/openai-codex.kdl:
|
|
10839
|
+
"source": "providers/openai-codex.kdl:128",
|
|
10838
10840
|
"providers": [
|
|
10839
10841
|
"openai-codex"
|
|
10840
10842
|
],
|
|
@@ -10859,7 +10861,7 @@
|
|
|
10859
10861
|
}
|
|
10860
10862
|
},
|
|
10861
10863
|
{
|
|
10862
|
-
"source": "providers/openai-codex.kdl:
|
|
10864
|
+
"source": "providers/openai-codex.kdl:137",
|
|
10863
10865
|
"providers": [
|
|
10864
10866
|
"openai-codex"
|
|
10865
10867
|
],
|
|
@@ -10880,7 +10882,7 @@
|
|
|
10880
10882
|
}
|
|
10881
10883
|
},
|
|
10882
10884
|
{
|
|
10883
|
-
"source": "providers/openai-codex.kdl:
|
|
10885
|
+
"source": "providers/openai-codex.kdl:148",
|
|
10884
10886
|
"providers": [
|
|
10885
10887
|
"openai-codex"
|
|
10886
10888
|
],
|
|
@@ -10914,7 +10916,8 @@
|
|
|
10914
10916
|
"serviceTierCost": {
|
|
10915
10917
|
"flex": 0.5,
|
|
10916
10918
|
"priority": 2
|
|
10917
|
-
}
|
|
10919
|
+
},
|
|
10920
|
+
"clampContextOverride": true
|
|
10918
10921
|
}
|
|
10919
10922
|
},
|
|
10920
10923
|
{
|
|
@@ -11157,7 +11160,28 @@
|
|
|
11157
11160
|
}
|
|
11158
11161
|
},
|
|
11159
11162
|
{
|
|
11160
|
-
"source": "providers/openai.kdl:
|
|
11163
|
+
"source": "providers/openai.kdl:79",
|
|
11164
|
+
"providers": [
|
|
11165
|
+
"openai"
|
|
11166
|
+
],
|
|
11167
|
+
"models": [
|
|
11168
|
+
{
|
|
11169
|
+
"kind": "glob",
|
|
11170
|
+
"value": "gpt-6-astra*"
|
|
11171
|
+
}
|
|
11172
|
+
],
|
|
11173
|
+
"catalog": {
|
|
11174
|
+
"longContext": {
|
|
11175
|
+
"inputThreshold": 272000,
|
|
11176
|
+
"input": 20,
|
|
11177
|
+
"output": 75,
|
|
11178
|
+
"cacheRead": 2,
|
|
11179
|
+
"cacheWrite": 25
|
|
11180
|
+
}
|
|
11181
|
+
}
|
|
11182
|
+
},
|
|
11183
|
+
{
|
|
11184
|
+
"source": "providers/openai.kdl:90",
|
|
11161
11185
|
"providers": [
|
|
11162
11186
|
"openai"
|
|
11163
11187
|
],
|
package/src/compat/types.ts
CHANGED
|
@@ -198,6 +198,8 @@ export interface CompiledRule {
|
|
|
198
198
|
source: string;
|
|
199
199
|
class?: string;
|
|
200
200
|
providers?: string[];
|
|
201
|
+
/** Request adapter identifiers matched by an `on-api` selector. */
|
|
202
|
+
apis?: string[];
|
|
201
203
|
family?: string;
|
|
202
204
|
revision?: CompiledRevisionTerm[];
|
|
203
205
|
models?: CompiledSelector[];
|
|
@@ -568,6 +570,8 @@ export interface ModelIdentity {
|
|
|
568
570
|
export interface ResolveTarget {
|
|
569
571
|
/** Deployment provider hosting the model. */
|
|
570
572
|
provider: string;
|
|
573
|
+
/** Request adapter used to serialize the model. */
|
|
574
|
+
api: string;
|
|
571
575
|
/** Centrally classified vendor lineage. */
|
|
572
576
|
class: string;
|
|
573
577
|
/** Classified product family within the class, when known. */
|
package/src/models.json
CHANGED
|
@@ -261375,7 +261375,7 @@
|
|
|
261375
261375
|
"api": "openai-codex-responses",
|
|
261376
261376
|
"v2StreamingEnabled": true
|
|
261377
261377
|
},
|
|
261378
|
-
"contextWindow":
|
|
261378
|
+
"contextWindow": 272000,
|
|
261379
261379
|
"maxTokens": 128000,
|
|
261380
261380
|
"preferWebsockets": true,
|
|
261381
261381
|
"useResponsesLite": true,
|
|
@@ -92,9 +92,15 @@ export function resolveModelCacheProviderId(providerId: string, options: ModelCa
|
|
|
92
92
|
// switching `COPILOT_GITHUB_TOKEN` to a different account misses the
|
|
93
93
|
// prior endpoint's cache and re-runs discovery instead of hitting the
|
|
94
94
|
// stale host and 403ing (PR #8510 review).
|
|
95
|
+
// v2: rows cached before the cross-provider routing strip inherit
|
|
96
|
+
// Cursor collapsed-family wire ids (e.g. enterprise-only
|
|
97
|
+
// `gpt-5.6-sol-fast` pinned to `-none-fast`); use a fresh namespace
|
|
98
|
+
// so they refetch instead of serving the poisoned rows. Listing ids
|
|
99
|
+
// cannot cover this class — any enterprise-only sibling can carry
|
|
100
|
+
// another provider's routing — so version the namespace instead.
|
|
95
101
|
const baseUrl = options.baseUrl ?? PERSONAL_GITHUB_COPILOT_BASE_URL;
|
|
96
102
|
const scope = `${options.apiKey ?? ""}\u0000${baseUrl}`;
|
|
97
|
-
return `github-copilot:models-
|
|
103
|
+
return `github-copilot:models-v2:${Bun.hash(scope).toString(36)}`;
|
|
98
104
|
}
|
|
99
105
|
case "openrouter":
|
|
100
106
|
return "openrouter:pseudo-api";
|
|
@@ -6380,6 +6380,22 @@ export function githubCopilotModelManagerOptions(config?: GithubCopilotModelMana
|
|
|
6380
6380
|
}
|
|
6381
6381
|
: {}),
|
|
6382
6382
|
};
|
|
6383
|
+
// Cross-provider fallback references (e.g. a Cursor
|
|
6384
|
+
// collapsed family for an enterprise-only sibling id)
|
|
6385
|
+
// carry provider-specific wire routing that must not
|
|
6386
|
+
// transfer: the off-tier `requestModelId` pin would send
|
|
6387
|
+
// every Copilot request under the `-none` sibling id
|
|
6388
|
+
// regardless of thinking level.
|
|
6389
|
+
if (reference && reference.provider !== "github-copilot") {
|
|
6390
|
+
delete base.requestModelId;
|
|
6391
|
+
if (base.thinking) {
|
|
6392
|
+
// `base` is a shallow copy of the shared global
|
|
6393
|
+
// reference: clone before deleting or the bundled
|
|
6394
|
+
// entry loses its routing process-wide.
|
|
6395
|
+
base.thinking = { ...base.thinking };
|
|
6396
|
+
delete base.thinking.effortRouting;
|
|
6397
|
+
}
|
|
6398
|
+
}
|
|
6383
6399
|
const defaultCost = copilotTierCost(tokenPrices.defaultTier);
|
|
6384
6400
|
if (defaultCost) {
|
|
6385
6401
|
// Cache writes are not reported per tier; retain the bundled provider rate.
|