@oh-my-pi/pi-catalog 18.1.14 → 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.
@@ -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.14",
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.14",
39
- "@oh-my-pi/pi-utils": "18.1.14"
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.14",
43
+ "@oh-my-pi/pi-ai": "18.1.15",
44
44
  "@types/bun": "^1.3.14"
45
45
  },
46
46
  "engines": {
@@ -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;
@@ -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),
@@ -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. The
92
- // Cloud Code Assist first-call variant is a host contract in providers/.
93
- on "google" "opencode-zen" {
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
@@ -4822,11 +4822,10 @@
4822
4822
  }
4823
4823
  },
4824
4824
  {
4825
- "source": "classes/gemini.kdl:94",
4825
+ "source": "classes/gemini.kdl:96",
4826
4826
  "class": "gemini",
4827
- "providers": [
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:100",
4842
+ "source": "classes/gemini.kdl:102",
4844
4843
  "class": "gemini",
4845
4844
  "providers": [
4846
4845
  "google-antigravity",
@@ -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. */