@ggui-ai/protocol 0.15.0 → 0.16.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/dist/errors/domain-error.d.ts +70 -0
- package/dist/errors/domain-error.d.ts.map +1 -0
- package/dist/errors/domain-error.js +118 -0
- package/dist/gadgets/stdlib-gadgets.d.ts +1 -1
- package/dist/gadgets/stdlib-gadgets.js +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -2
- package/dist/integrations/mcp-apps.d.ts +33 -7
- package/dist/integrations/mcp-apps.d.ts.map +1 -1
- package/dist/integrations/mcp-apps.js +13 -13
- package/dist/integrations/overlay-hash.d.ts +19 -0
- package/dist/integrations/overlay-hash.d.ts.map +1 -0
- package/dist/integrations/overlay-hash.js +29 -0
- package/dist/integrations/theme-binding.d.ts +14 -12
- package/dist/integrations/theme-binding.d.ts.map +1 -1
- package/dist/integrations/theme-binding.js +10 -6
- package/dist/registry/blueprint-key.d.ts.map +1 -1
- package/dist/registry/blueprint-key.js +4 -3
- package/dist/schemas/app-theme.d.ts +46 -10
- package/dist/schemas/app-theme.d.ts.map +1 -1
- package/dist/schemas/app-theme.js +108 -40
- package/dist/schemas/blueprint.d.ts +2 -1
- package/dist/schemas/blueprint.d.ts.map +1 -1
- package/dist/schemas/blueprint.js +15 -3
- package/dist/schemas/data-contract.d.ts +1 -1
- package/dist/schemas/data-contract.js +1 -1
- package/dist/schemas/handshake-suggestion.d.ts.map +1 -1
- package/dist/schemas/handshake-suggestion.js +8 -1
- package/dist/schemas/mcp.d.ts +48 -22
- package/dist/schemas/mcp.d.ts.map +1 -1
- package/dist/schemas/mcp.js +44 -15
- package/dist/schemas/ops-blueprint.d.ts +4 -4
- package/dist/schemas/ops-blueprint.d.ts.map +1 -1
- package/dist/schemas/ops-blueprint.js +13 -8
- package/dist/schemas/render-input-envelope.js +1 -1
- package/dist/types/blueprint-source.d.ts +27 -7
- package/dist/types/blueprint-source.d.ts.map +1 -1
- package/dist/types/blueprint-source.js +19 -3
- package/dist/types/blueprint.d.ts +2 -2
- package/dist/types/blueprint.d.ts.map +1 -1
- package/dist/types/data-contract.d.ts +3 -3
- package/dist/types/domain-error-codes.d.ts +167 -0
- package/dist/types/domain-error-codes.d.ts.map +1 -0
- package/dist/types/domain-error-codes.js +170 -0
- package/dist/types/handshake-suggestion.d.ts +2 -2
- package/dist/types/live-channel.d.ts +1 -1
- package/dist/types/llm-route.d.ts +59 -2
- package/dist/types/llm-route.d.ts.map +1 -1
- package/dist/types/llm-route.js +62 -16
- package/dist/types/llm.d.ts +22 -2
- package/dist/types/llm.d.ts.map +1 -1
- package/dist/types/llm.js +29 -2
- package/dist/types/mcp.d.ts +31 -39
- package/dist/types/mcp.d.ts.map +1 -1
- package/dist/types/mcp.js +22 -10
- package/dist/types/refusal-codes.d.ts +31 -93
- package/dist/types/refusal-codes.d.ts.map +1 -1
- package/dist/types/refusal-codes.js +41 -96
- package/dist/types/render.d.ts +3 -3
- package/dist/types/render.d.ts.map +1 -1
- package/dist/validation/contract-validator.d.ts +8 -2
- package/dist/validation/contract-validator.d.ts.map +1 -1
- package/dist/validation/contract-validator.js +12 -4
- package/dist/validation/lint-contract.d.ts +2 -2
- package/dist/validation/lint-contract.d.ts.map +1 -1
- package/dist/validation/lint-contract.js +6 -4
- package/dist/validation/schema-subset.d.ts +3 -3
- package/dist/version.d.ts +357 -6
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js +356 -5
- package/package.json +1 -1
- package/dist/envelope-adapters.d.ts +0 -12
- package/dist/envelope-adapters.d.ts.map +0 -1
- package/dist/envelope-adapters.js +0 -30
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Plane-2 registry — the ONLY list of domain-error slugs (ggui#880).
|
|
3
|
+
*
|
|
4
|
+
* SPEC §7.9 Plane 2: a recoverable, contract-level failure the caller can
|
|
5
|
+
* fix — a missing session or handshake, props that do not satisfy the
|
|
6
|
+
* contract, an undeclared channel. The MCP SDK ships a thrown handler error
|
|
7
|
+
* to the agent as `{content: [{type: 'text', text: error.message}],
|
|
8
|
+
* isError: true}` and nothing else, so the slug travels as the LEADING
|
|
9
|
+
* token of that text — `<code>: <detail>` — composed by the `DomainError`
|
|
10
|
+
* base in `../errors/domain-error` from a code in this registry. A reader
|
|
11
|
+
* branches on `text.startsWith(code + ': ')` for a registered code and on
|
|
12
|
+
* nothing else.
|
|
13
|
+
*
|
|
14
|
+
* Same posture as the refusal registry in `./refusal-codes`: `code === key`
|
|
15
|
+
* is forced at the definer, the code type is derived from the keys, and
|
|
16
|
+
* the two registries are disjoint (pinned) — one code names one plane.
|
|
17
|
+
*/
|
|
18
|
+
/**
|
|
19
|
+
* How a caller recovers from a Plane-2 failure.
|
|
20
|
+
*
|
|
21
|
+
* - `retry-same-id` — fix the input and retry on the SAME handshakeId /
|
|
22
|
+
* sessionId; nothing was consumed.
|
|
23
|
+
* - `re-mint` — the id itself is gone (unknown, consumed, expired,
|
|
24
|
+
* another app's); mint a fresh one (`ggui_handshake`, then `ggui_render`).
|
|
25
|
+
* - `later` — a dependency the server fetches was unavailable; time
|
|
26
|
+
* restores it, the input was fine.
|
|
27
|
+
*/
|
|
28
|
+
export const DOMAIN_ERROR_RECOVERIES = ['retry-same-id', 're-mint', 'later'];
|
|
29
|
+
/**
|
|
30
|
+
* The registry is the ONLY list of domain-error codes: {@link DomainErrorCode}
|
|
31
|
+
* is derived from the keys below, and this definer forces every row's
|
|
32
|
+
* `code` to equal its key at the type level.
|
|
33
|
+
*/
|
|
34
|
+
function defineDomainErrorRegistry(rows) {
|
|
35
|
+
return rows;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* The registry with its per-key literal types kept (ggui#889):
|
|
39
|
+
* `DOMAIN_ERROR_ROWS.session_not_found.code` is `'session_not_found'`,
|
|
40
|
+
* its `recovery` is `'re-mint'`. {@link DOMAIN_ERROR_REGISTRY} is the
|
|
41
|
+
* same object read through the normalized row type.
|
|
42
|
+
*/
|
|
43
|
+
export const DOMAIN_ERROR_ROWS = /* @__PURE__ */ defineDomainErrorRegistry({
|
|
44
|
+
// ── identity ──────────────────────────────────────────────────────
|
|
45
|
+
session_not_found: {
|
|
46
|
+
code: 'session_not_found',
|
|
47
|
+
tools: [
|
|
48
|
+
'ggui_consume',
|
|
49
|
+
'ggui_get_session',
|
|
50
|
+
'ggui_get_render_source',
|
|
51
|
+
'ggui_update',
|
|
52
|
+
'ggui_amend',
|
|
53
|
+
'ggui_emit',
|
|
54
|
+
'ggui_runtime_pull',
|
|
55
|
+
],
|
|
56
|
+
recovery: 're-mint',
|
|
57
|
+
emitter: 'the session lookup on every session-scoped tool',
|
|
58
|
+
description: 'The sessionId names no session this caller can reach — never minted, expired, closed, or owned by another app (cross-app access surfaces uniformly). Re-handshake and re-render to mint a fresh one.',
|
|
59
|
+
},
|
|
60
|
+
handshake_not_found: {
|
|
61
|
+
code: 'handshake_not_found',
|
|
62
|
+
tools: ['ggui_render'],
|
|
63
|
+
recovery: 're-mint',
|
|
64
|
+
emitter: 'the handshake-record lookup at ggui_render',
|
|
65
|
+
description: 'The handshakeId is unknown, already consumed by a render, or expired. Call ggui_handshake again for a fresh id, then render with the new pair.',
|
|
66
|
+
},
|
|
67
|
+
// ── the contract gate ─────────────────────────────────────────────
|
|
68
|
+
contract_violation: {
|
|
69
|
+
code: 'contract_violation',
|
|
70
|
+
tools: ['ggui_render', 'ggui_update', 'ggui_amend', 'ggui_emit'],
|
|
71
|
+
recovery: 'retry-same-id',
|
|
72
|
+
emitter: 'the props / payload validator against the contract',
|
|
73
|
+
description: "Props or a payload do not satisfy the contract's spec — a missing required prop included. Fix the values and retry with the same id; nothing was consumed.",
|
|
74
|
+
},
|
|
75
|
+
schema_mismatch_error: {
|
|
76
|
+
code: 'schema_mismatch_error',
|
|
77
|
+
tools: ['ggui_render'],
|
|
78
|
+
recovery: 'retry-same-id',
|
|
79
|
+
emitter: 'the schema-compatibility check between the contract and the registered tool shapes',
|
|
80
|
+
description: "An actionSpec or streamSpec schema is not a subset of the named tool's registered shape. Adjust the contract or the tool, then retry with the same handshakeId.",
|
|
81
|
+
},
|
|
82
|
+
contract_validation_failed: {
|
|
83
|
+
code: 'contract_validation_failed',
|
|
84
|
+
tools: ['ggui_render'],
|
|
85
|
+
recovery: 'retry-same-id',
|
|
86
|
+
emitter: 'the contract lint gate (shape, retired fields, schema metadata, cross-references, schema compatibility)',
|
|
87
|
+
description: 'The contract failed the lint gate; the detail names the category and the finding. Fix the contract and retry with the same handshakeId.',
|
|
88
|
+
},
|
|
89
|
+
override_contract_invalid: {
|
|
90
|
+
code: 'override_contract_invalid',
|
|
91
|
+
tools: ['ggui_render'],
|
|
92
|
+
recovery: 'retry-same-id',
|
|
93
|
+
emitter: 'the override gate at ggui_render',
|
|
94
|
+
description: 'override.contract failed validation — an override commits the caller to a conforming contract. Drop the override and render the suggestion, or fix the draft.',
|
|
95
|
+
},
|
|
96
|
+
// ── the live channel ──────────────────────────────────────────────
|
|
97
|
+
channel_not_declared: {
|
|
98
|
+
code: 'channel_not_declared',
|
|
99
|
+
tools: ['ggui_emit'],
|
|
100
|
+
recovery: 'retry-same-id',
|
|
101
|
+
emitter: "ggui_emit's channel check against the contract's streamSpec",
|
|
102
|
+
description: "The channel is not declared by the session's contract. Emit on a declared channel; the detail lists them.",
|
|
103
|
+
},
|
|
104
|
+
invalid_complete: {
|
|
105
|
+
code: 'invalid_complete',
|
|
106
|
+
tools: ['ggui_emit'],
|
|
107
|
+
recovery: 'retry-same-id',
|
|
108
|
+
emitter: "ggui_emit's completion check",
|
|
109
|
+
description: 'A completion was signalled for a channel that cannot complete in its current state. Emit on the channel first, or omit the completion.',
|
|
110
|
+
},
|
|
111
|
+
// ── the gadget gate ───────────────────────────────────────────────
|
|
112
|
+
gadget_not_registered: {
|
|
113
|
+
code: 'gadget_not_registered',
|
|
114
|
+
tools: ['ggui_render'],
|
|
115
|
+
recovery: 'retry-same-id',
|
|
116
|
+
emitter: 'the gadget gate at ggui_render',
|
|
117
|
+
description: "A clientCapabilities.gadgets reference names an export the app's gadget registry does not carry. Drop the reference or fix the name; the detail suggests the nearest match.",
|
|
118
|
+
},
|
|
119
|
+
gadget_package_mismatch: {
|
|
120
|
+
code: 'gadget_package_mismatch',
|
|
121
|
+
tools: ['ggui_render'],
|
|
122
|
+
recovery: 'retry-same-id',
|
|
123
|
+
emitter: 'the gadget gate at ggui_render',
|
|
124
|
+
description: 'A gadget export is registered, but only under a different package than the contract requested. Request the registered package; the detail names it.',
|
|
125
|
+
},
|
|
126
|
+
gadget_public_env_missing: {
|
|
127
|
+
code: 'gadget_public_env_missing',
|
|
128
|
+
tools: ['ggui_render'],
|
|
129
|
+
recovery: 'retry-same-id',
|
|
130
|
+
emitter: 'the gadget gate at ggui_render',
|
|
131
|
+
description: "A registered wrapper requires a public-env key the app has not set. Set the key on the app's public env, then retry.",
|
|
132
|
+
},
|
|
133
|
+
duplicate_gadget_hook: {
|
|
134
|
+
code: 'duplicate_gadget_hook',
|
|
135
|
+
tools: ['ggui_render'],
|
|
136
|
+
recovery: 'retry-same-id',
|
|
137
|
+
emitter: 'the gadget gate at ggui_render',
|
|
138
|
+
description: 'Two gadget packages export the same name; the generated import would collide. Reference one of them.',
|
|
139
|
+
},
|
|
140
|
+
gadget_types_fetch_failed: {
|
|
141
|
+
code: 'gadget_types_fetch_failed',
|
|
142
|
+
tools: ['ggui_render'],
|
|
143
|
+
recovery: 'later',
|
|
144
|
+
emitter: 'the gadget type fetch before cold generation',
|
|
145
|
+
description: "Fetching a gadget package's types failed; the input was fine. Retry after a short delay.",
|
|
146
|
+
},
|
|
147
|
+
gadget_catalog_integrity: {
|
|
148
|
+
code: 'gadget_catalog_integrity',
|
|
149
|
+
tools: ['ggui_render'],
|
|
150
|
+
recovery: 'retry-same-id',
|
|
151
|
+
emitter: "the app's gadget catalog resolver at ggui_render",
|
|
152
|
+
description: "The app's gadget catalog is inconsistent with its registrations. Repair the catalog, then retry with the same handshakeId.",
|
|
153
|
+
},
|
|
154
|
+
// ── the blueprint registry ────────────────────────────────────────
|
|
155
|
+
blueprint_rejected: {
|
|
156
|
+
code: 'blueprint_rejected',
|
|
157
|
+
tools: ['ggui_render'],
|
|
158
|
+
recovery: 'retry-same-id',
|
|
159
|
+
emitter: 'the blueprint registry on registration',
|
|
160
|
+
description: "The blueprint was rejected by the registry's error-level findings; the detail lists them. Fix the contract and retry with the same handshakeId.",
|
|
161
|
+
},
|
|
162
|
+
});
|
|
163
|
+
/** The registry consumers read. */
|
|
164
|
+
export const DOMAIN_ERROR_REGISTRY = DOMAIN_ERROR_ROWS;
|
|
165
|
+
/** Whether `value` is a registered domain-error code. */
|
|
166
|
+
export function isDomainErrorCode(value) {
|
|
167
|
+
return Object.hasOwn(DOMAIN_ERROR_ROWS, value);
|
|
168
|
+
}
|
|
169
|
+
/** Every registered code, in registry order. */
|
|
170
|
+
export const DOMAIN_ERROR_CODES = Object.keys(DOMAIN_ERROR_ROWS).filter(isDomainErrorCode);
|
|
@@ -89,12 +89,12 @@ export interface BlueprintDraft {
|
|
|
89
89
|
readonly seedPrompt?: string;
|
|
90
90
|
};
|
|
91
91
|
/**
|
|
92
|
-
* Generator
|
|
92
|
+
* Generator identity hint (e.g. `'ui-gen-advanced'` — de-modeled, ggui#924). The
|
|
93
93
|
* server resolves the effective generator as:
|
|
94
94
|
*
|
|
95
95
|
* 1. Operator app-pin (`App.pinnedGenerator`) — wins if set.
|
|
96
96
|
* 2. This hint — if registered in the GeneratorRegistry.
|
|
97
|
-
* 3. Registry default (`ui-gen-default
|
|
97
|
+
* 3. Registry default (`ui-gen-default`).
|
|
98
98
|
*
|
|
99
99
|
* Hint-only; unknown slugs fall through to the registry default.
|
|
100
100
|
*/
|
|
@@ -23,7 +23,7 @@ import type { JsonObject, JsonValue, StreamChannelMode } from './data-contract.j
|
|
|
23
23
|
export interface SubscribePayload {
|
|
24
24
|
sessionId: string;
|
|
25
25
|
/**
|
|
26
|
-
* App
|
|
26
|
+
* App identity — the `appId` the session belongs to. OPTIONAL — absent ⇒ the server resolves the
|
|
27
27
|
* caller's identity-default app, the same resolution rule the MCP
|
|
28
28
|
* route uses: a token binding (`wsToken` binds `(sessionId, appId)`)
|
|
29
29
|
* wins, then the deployment's identity → appId mapping, then the
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
*/
|
|
53
53
|
export declare const MODELS: {
|
|
54
54
|
readonly anthropic: readonly ["claude-fable-5-1", "claude-fable-5", "claude-opus-5", "claude-sonnet-5", "claude-haiku-4-5-20251001", "claude-opus-4-8", "claude-sonnet-4-6", "claude-opus-4-7", "claude-opus-4-6"];
|
|
55
|
-
readonly openai: readonly ["gpt-5.6", "gpt-5.6-sol", "gpt-5.6-terra", "gpt-5.6-luna", "gpt-5.5", "gpt-5.5-2026-04-23", "gpt-5.5-pro", "gpt-5.5-pro-2026-04-23", "gpt-5.4", "gpt-5.4-2026-03-05", "gpt-5.4-mini", "gpt-5.4-mini-2026-03-17", "gpt-5.4-nano", "gpt-5.4-nano-2026-03-17", "gpt-5.3-codex"];
|
|
55
|
+
readonly openai: readonly ["gpt-6-astra", "gpt-5.6", "gpt-5.6-sol", "gpt-5.6-terra", "gpt-5.6-luna", "gpt-5.5", "gpt-5.5-2026-04-23", "gpt-5.5-pro", "gpt-5.5-pro-2026-04-23", "gpt-5.4", "gpt-5.4-2026-03-05", "gpt-5.4-mini", "gpt-5.4-mini-2026-03-17", "gpt-5.4-nano", "gpt-5.4-nano-2026-03-17", "gpt-5.3-codex"];
|
|
56
56
|
readonly google: readonly ["gemini-3.7-flash", "gemini-3.6-flash", "gemini-3.5-flash", "gemini-3.5-flash-lite", "gemini-flash-latest", "gemini-3.1-flash-lite", "gemini-3.1-pro-preview", "gemini-3.1-flash-lite-preview", "gemini-3-flash-preview"];
|
|
57
57
|
readonly bedrock: readonly ["anthropic.claude-fable-5-1", "anthropic.claude-fable-5", "anthropic.claude-opus-5", "anthropic.claude-sonnet-5", "anthropic.claude-opus-4-8", "us.anthropic.claude-haiku-4-5-20251001-v1:0", "eu.anthropic.claude-haiku-4-5-20251001-v1:0", "apac.anthropic.claude-haiku-4-5-20251001-v1:0", "global.anthropic.claude-haiku-4-5-20251001-v1:0", "us.anthropic.claude-sonnet-4-6", "eu.anthropic.claude-sonnet-4-6", "apac.anthropic.claude-sonnet-4-6", "us.anthropic.claude-opus-4-7", "eu.anthropic.claude-opus-4-7", "apac.anthropic.claude-opus-4-7", "global.anthropic.claude-opus-4-7", "us.anthropic.claude-opus-4-6-v1"];
|
|
58
58
|
readonly openrouter: readonly ["anthropic/claude-fable-5", "anthropic/claude-opus-5", "anthropic/claude-sonnet-5", "anthropic/claude-haiku-4.5", "anthropic/claude-sonnet-4.6", "anthropic/claude-opus-4.7", "openai/gpt-5.6-sol", "openai/gpt-5.6-terra", "openai/gpt-5.6-luna", "openai/gpt-5.5", "openai/gpt-5.5-pro", "openai/gpt-5.4-mini", "openai/gpt-5.4-nano", "google/gemini-3.6-flash", "google/gemini-3.5-flash", "google/gemini-3.5-flash-lite", "google/gemini-3.1-pro-preview", "google/gemini-3.1-flash-lite", "x-ai/grok-4.3", "meta-llama/llama-4-maverick", "meta-llama/llama-3.3-70b-instruct", "deepseek/deepseek-v4-pro", "deepseek/deepseek-r1-0528", "qwen/qwen3.7-max", "qwen/qwen3-coder", "mistralai/mistral-large-2512", "openai/gpt-oss-120b"];
|
|
@@ -189,6 +189,25 @@ export declare function serializeLlmRoute(route: LlmRoute): string;
|
|
|
189
189
|
* Round-trip with {@link serializeLlmRoute}.
|
|
190
190
|
*/
|
|
191
191
|
export declare function parseLlmRoute(serialized: string): LlmRoute | null;
|
|
192
|
+
/**
|
|
193
|
+
* Map from LiteLLM transport prefix → our `LlmProvider` enum. Used by
|
|
194
|
+
* {@link parseLiteLlmString} to accept legacy ggui.json files and
|
|
195
|
+
* ecosystem inputs without forcing a migration on every operator.
|
|
196
|
+
*
|
|
197
|
+
* Note: LiteLLM separates `gemini/` (AI Studio) from `vertex_ai/`
|
|
198
|
+
* (enterprise Vertex). We don't have a Vertex variant in this slice;
|
|
199
|
+
* `vertex_ai/` parsing falls through to `null` until Vertex lands.
|
|
200
|
+
*/
|
|
201
|
+
/**
|
|
202
|
+
* The prefixes a {@link ModelRef} may start with — the LiteLLM spellings,
|
|
203
|
+
* and the model registry's. The single source: the prefix→provider map
|
|
204
|
+
* below is keyed by it (exhaustive by type), and the JSON-Schema-facing
|
|
205
|
+
* `pattern` in `llmBlueprintSourceSchema` is built from it.
|
|
206
|
+
*/
|
|
207
|
+
export declare const MODEL_REF_PREFIXES: readonly ["anthropic", "gemini", "openai", "bedrock", "openrouter"];
|
|
208
|
+
export type ModelRefPrefix = (typeof MODEL_REF_PREFIXES)[number];
|
|
209
|
+
/** Whether `s` is one of {@link MODEL_REF_PREFIXES}. */
|
|
210
|
+
export declare function isModelRefPrefix(s: string): s is ModelRefPrefix;
|
|
192
211
|
/**
|
|
193
212
|
* Parse a LiteLLM-format string (`<prefix>/<model>` or
|
|
194
213
|
* `<prefix>/<sub>/<model>` for OpenRouter) into an `LlmRoute`.
|
|
@@ -218,7 +237,7 @@ export declare function parseLiteLlmString(s: string): LlmRoute | null;
|
|
|
218
237
|
* For models without an explicit LITELLM_TO_WIRE mapping (Gemini,
|
|
219
238
|
* OpenAI, OpenRouter), serialization uses the wire model as-is.
|
|
220
239
|
*/
|
|
221
|
-
export declare function toLiteLlmString(route: LlmRoute):
|
|
240
|
+
export declare function toLiteLlmString(route: LlmRoute): ModelRef;
|
|
222
241
|
/**
|
|
223
242
|
* Single-entry parser that accepts both canonical (`provider:model`)
|
|
224
243
|
* and LiteLLM (`prefix/model`) formats. Used at wire boundaries that
|
|
@@ -230,4 +249,42 @@ export declare function toLiteLlmString(route: LlmRoute): string;
|
|
|
230
249
|
* format produces a valid route.
|
|
231
250
|
*/
|
|
232
251
|
export declare function parseAnyLlmRoute(s: string): LlmRoute | null;
|
|
252
|
+
/**
|
|
253
|
+
* A route rendered as ONE string in the model registry's spelling —
|
|
254
|
+
* the LiteLLM form `<prefix>/<model>` (#818: one model-id vocabulary,
|
|
255
|
+
* two separators). Every registry id (`ModelId`, e.g.
|
|
256
|
+
* `anthropic/claude-haiku-4-5`, `gemini/gemini-3.5-flash`) is the ref
|
|
257
|
+
* of the route it names, so `ModelId ⊂ ModelRef`; a bedrock inference
|
|
258
|
+
* profile or an unlisted OpenRouter model is a `ModelRef` the registry
|
|
259
|
+
* does not list. Where a wire model has a LiteLLM alias
|
|
260
|
+
* (`claude-haiku-4-5-20251001` ↔ `claude-haiku-4-5`) the ref is the
|
|
261
|
+
* ALIAS — the dated wire id is not a ref spelling.
|
|
262
|
+
*
|
|
263
|
+
* Split at the FIRST `/`: prefixes contain no slash, so
|
|
264
|
+
* `openrouter/anthropic/claude-3.5-sonnet` is unambiguous.
|
|
265
|
+
*
|
|
266
|
+
* Used where a record must say which model a run used and readers must
|
|
267
|
+
* recover the route: `LlmBlueprintSource.model`.
|
|
268
|
+
*/
|
|
269
|
+
export type ModelRef = `${ModelRefPrefix}/${string}`;
|
|
270
|
+
/**
|
|
271
|
+
* The one composer of a {@link ModelRef}: render the route the run used,
|
|
272
|
+
* inverting the LiteLLM alias map so a resolved `{anthropic,
|
|
273
|
+
* claude-haiku-4-5-20251001}` renders as `anthropic/claude-haiku-4-5` —
|
|
274
|
+
* the registry id. Total: every `LlmRoute` has a ref. Feed it the ROUTE
|
|
275
|
+
* the call used; the ref is the same whether the route was configured
|
|
276
|
+
* as the alias or already resolved.
|
|
277
|
+
*/
|
|
278
|
+
export declare function modelRefOfRoute(route: LlmRoute): ModelRef;
|
|
279
|
+
/**
|
|
280
|
+
* Recover the route from a {@link ModelRef}. `null` unless `s` is a
|
|
281
|
+
* LiteLLM-form string that parses ({@link parseLiteLlmString}) AND is
|
|
282
|
+
* the spelling {@link modelRefOfRoute} produces for that route — a ref
|
|
283
|
+
* has one spelling, so the dated wire id of an aliased model and a
|
|
284
|
+
* wrong prefix are refused here even though the lenient wire parsers
|
|
285
|
+
* accept them.
|
|
286
|
+
*/
|
|
287
|
+
export declare function parseModelRef(s: string): LlmRoute | null;
|
|
288
|
+
/** Whether `s` is a {@link ModelRef} — see {@link parseModelRef}. */
|
|
289
|
+
export declare function isModelRef(s: string): s is ModelRef;
|
|
233
290
|
//# sourceMappingURL=llm-route.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"llm-route.d.ts","sourceRoot":"","sources":["../../src/types/llm-route.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAMH;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,eAAO,MAAM,MAAM;;;;;;
|
|
1
|
+
{"version":3,"file":"llm-route.d.ts","sourceRoot":"","sources":["../../src/types/llm-route.ts"],"names":[],"mappings":"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"}
|
package/dist/types/llm-route.js
CHANGED
|
@@ -78,6 +78,7 @@ export const MODELS = {
|
|
|
78
78
|
// reasoning), `terra` (balanced), `luna` (fast/cost). The bare
|
|
79
79
|
// `gpt-5.6` alias routes to Sol on OpenAI's side. No dated
|
|
80
80
|
// siblings registered at adoption time.
|
|
81
|
+
'gpt-6-astra', // ggui#977 (2026-09-09): listed by `GET /v1/models/gpt-6-astra` → 200
|
|
81
82
|
'gpt-5.6',
|
|
82
83
|
'gpt-5.6-sol',
|
|
83
84
|
'gpt-5.6-terra',
|
|
@@ -345,6 +346,13 @@ export function parseLlmRoute(serialized) {
|
|
|
345
346
|
* (enterprise Vertex). We don't have a Vertex variant in this slice;
|
|
346
347
|
* `vertex_ai/` parsing falls through to `null` until Vertex lands.
|
|
347
348
|
*/
|
|
349
|
+
/**
|
|
350
|
+
* The prefixes a {@link ModelRef} may start with — the LiteLLM spellings,
|
|
351
|
+
* and the model registry's. The single source: the prefix→provider map
|
|
352
|
+
* below is keyed by it (exhaustive by type), and the JSON-Schema-facing
|
|
353
|
+
* `pattern` in `llmBlueprintSourceSchema` is built from it.
|
|
354
|
+
*/
|
|
355
|
+
export const MODEL_REF_PREFIXES = ['anthropic', 'gemini', 'openai', 'bedrock', 'openrouter'];
|
|
348
356
|
const LITELLM_PROVIDER_PREFIX_MAP = {
|
|
349
357
|
anthropic: 'anthropic',
|
|
350
358
|
gemini: 'google',
|
|
@@ -352,6 +360,26 @@ const LITELLM_PROVIDER_PREFIX_MAP = {
|
|
|
352
360
|
bedrock: 'bedrock',
|
|
353
361
|
openrouter: 'openrouter',
|
|
354
362
|
};
|
|
363
|
+
/**
|
|
364
|
+
* Provider → its ONE LiteLLM prefix. Exhaustive by type: adding a
|
|
365
|
+
* provider to `MODELS` without a prefix here is a compile error, which
|
|
366
|
+
* is what makes {@link modelRefOfRoute} total.
|
|
367
|
+
*/
|
|
368
|
+
const PROVIDER_TO_LITELLM_PREFIX = {
|
|
369
|
+
anthropic: 'anthropic',
|
|
370
|
+
google: 'gemini',
|
|
371
|
+
openai: 'openai',
|
|
372
|
+
bedrock: 'bedrock',
|
|
373
|
+
openrouter: 'openrouter',
|
|
374
|
+
};
|
|
375
|
+
const MODEL_REF_PREFIX_LIST = MODEL_REF_PREFIXES;
|
|
376
|
+
/** Whether `s` is one of {@link MODEL_REF_PREFIXES}. */
|
|
377
|
+
export function isModelRefPrefix(s) {
|
|
378
|
+
return MODEL_REF_PREFIX_LIST.includes(s);
|
|
379
|
+
}
|
|
380
|
+
function liteLlmPrefixProvider(prefix) {
|
|
381
|
+
return isModelRefPrefix(prefix) ? LITELLM_PROVIDER_PREFIX_MAP[prefix] : undefined;
|
|
382
|
+
}
|
|
355
383
|
/**
|
|
356
384
|
* LiteLLM canonical → wire-canonical model mappings for providers
|
|
357
385
|
* whose LiteLLM-form differs from the wire-canonical form.
|
|
@@ -396,7 +424,7 @@ export function parseLiteLlmString(s) {
|
|
|
396
424
|
if (firstSlash <= 0)
|
|
397
425
|
return null;
|
|
398
426
|
const prefix = s.substring(0, firstSlash);
|
|
399
|
-
const provider =
|
|
427
|
+
const provider = liteLlmPrefixProvider(prefix);
|
|
400
428
|
if (!provider)
|
|
401
429
|
return null;
|
|
402
430
|
// For OpenRouter the model is everything after the first slash
|
|
@@ -446,23 +474,10 @@ function getWireToLitellm() {
|
|
|
446
474
|
* OpenAI, OpenRouter), serialization uses the wire model as-is.
|
|
447
475
|
*/
|
|
448
476
|
export function toLiteLlmString(route) {
|
|
449
|
-
|
|
450
|
-
const inverseMap = getWireToLitellm()[route.provider];
|
|
451
|
-
const modelForLitellm = inverseMap?.[route.model] ?? route.model;
|
|
452
|
-
return `${prefix}/${modelForLitellm}`;
|
|
477
|
+
return modelRefOfRoute(route);
|
|
453
478
|
}
|
|
454
479
|
function providerLiteLlmPrefix(provider) {
|
|
455
|
-
|
|
456
|
-
// most one prefix per provider in LITELLM_PROVIDER_PREFIX_MAP today.
|
|
457
|
-
for (const [prefix, p] of Object.entries(LITELLM_PROVIDER_PREFIX_MAP)) {
|
|
458
|
-
if (p === provider)
|
|
459
|
-
return prefix;
|
|
460
|
-
}
|
|
461
|
-
// Defensive: every provider in MODELS should have a LiteLLM prefix.
|
|
462
|
-
// If not, fall through to the provider's own name (degrades gracefully
|
|
463
|
-
// for observability — the trace just won't match LiteLLM's exact
|
|
464
|
-
// wording, but it still names the provider).
|
|
465
|
-
return provider;
|
|
480
|
+
return PROVIDER_TO_LITELLM_PREFIX[provider];
|
|
466
481
|
}
|
|
467
482
|
// ============================================================================
|
|
468
483
|
// Combined parser (accepts either format)
|
|
@@ -480,3 +495,34 @@ function providerLiteLlmPrefix(provider) {
|
|
|
480
495
|
export function parseAnyLlmRoute(s) {
|
|
481
496
|
return parseLlmRoute(s) ?? parseLiteLlmString(s);
|
|
482
497
|
}
|
|
498
|
+
/**
|
|
499
|
+
* The one composer of a {@link ModelRef}: render the route the run used,
|
|
500
|
+
* inverting the LiteLLM alias map so a resolved `{anthropic,
|
|
501
|
+
* claude-haiku-4-5-20251001}` renders as `anthropic/claude-haiku-4-5` —
|
|
502
|
+
* the registry id. Total: every `LlmRoute` has a ref. Feed it the ROUTE
|
|
503
|
+
* the call used; the ref is the same whether the route was configured
|
|
504
|
+
* as the alias or already resolved.
|
|
505
|
+
*/
|
|
506
|
+
export function modelRefOfRoute(route) {
|
|
507
|
+
const inverseMap = getWireToLitellm()[route.provider];
|
|
508
|
+
const model = inverseMap?.[route.model] ?? route.model;
|
|
509
|
+
return `${providerLiteLlmPrefix(route.provider)}/${model}`;
|
|
510
|
+
}
|
|
511
|
+
/**
|
|
512
|
+
* Recover the route from a {@link ModelRef}. `null` unless `s` is a
|
|
513
|
+
* LiteLLM-form string that parses ({@link parseLiteLlmString}) AND is
|
|
514
|
+
* the spelling {@link modelRefOfRoute} produces for that route — a ref
|
|
515
|
+
* has one spelling, so the dated wire id of an aliased model and a
|
|
516
|
+
* wrong prefix are refused here even though the lenient wire parsers
|
|
517
|
+
* accept them.
|
|
518
|
+
*/
|
|
519
|
+
export function parseModelRef(s) {
|
|
520
|
+
const route = parseLiteLlmString(s);
|
|
521
|
+
if (route === null)
|
|
522
|
+
return null;
|
|
523
|
+
return modelRefOfRoute(route) === s ? route : null;
|
|
524
|
+
}
|
|
525
|
+
/** Whether `s` is a {@link ModelRef} — see {@link parseModelRef}. */
|
|
526
|
+
export function isModelRef(s) {
|
|
527
|
+
return parseModelRef(s) !== null;
|
|
528
|
+
}
|
package/dist/types/llm.d.ts
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* - `MODEL_REGISTRY` here = LiteLLM-keyed pricing + capability
|
|
7
7
|
* metadata. Keys are LiteLLM strings (`"gemini/gemini-3.5-flash"`,
|
|
8
8
|
* `"openai/gpt-5.4-mini"`, …). Read by:
|
|
9
|
-
* -
|
|
9
|
+
* - a hosted deployment's pricing-drift test (vendored
|
|
10
10
|
* LiteLLM JSON pricing table)
|
|
11
11
|
* - `oss/misc/benchmark` runner (bench harness; picks model
|
|
12
12
|
* configs by LiteLLM key)
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
* EXISTS, and `scripts/check-litellm-pricing-drift.ts` compares the
|
|
41
41
|
* snapshot against upstream, never the registry. That gap let this
|
|
42
42
|
* table sit four months stale while production routed to models it did
|
|
43
|
-
* not even list.
|
|
43
|
+
* not even list. A hosted deployment's `pricing-tables.test.ts` now asserts every
|
|
44
44
|
* entry's `costs` match the vendored rate (with an explicit, dated
|
|
45
45
|
* PENDING_UPSTREAM allowlist for prices we learn before LiteLLM does).
|
|
46
46
|
* Add a model here and you MUST re-vendor the snapshot in the same
|
|
@@ -336,6 +336,22 @@ declare const MODEL_ROWS: {
|
|
|
336
336
|
readonly maxTokens: 1000000;
|
|
337
337
|
readonly supportsTools: true;
|
|
338
338
|
};
|
|
339
|
+
readonly "openai/gpt-6-astra": {
|
|
340
|
+
readonly id: "openai/gpt-6-astra";
|
|
341
|
+
readonly provider: "openai";
|
|
342
|
+
readonly displayName: "GPT-6 Astra";
|
|
343
|
+
readonly tier: "premium";
|
|
344
|
+
readonly state: "active";
|
|
345
|
+
readonly lineup: false;
|
|
346
|
+
readonly costs: {
|
|
347
|
+
readonly inputPer1M: 10;
|
|
348
|
+
readonly outputPer1M: 50;
|
|
349
|
+
readonly cacheWritePer1M: 12.5;
|
|
350
|
+
readonly cacheReadPer1M: 1;
|
|
351
|
+
};
|
|
352
|
+
readonly maxTokens: 922000;
|
|
353
|
+
readonly supportsTools: true;
|
|
354
|
+
};
|
|
339
355
|
readonly "openai/gpt-5.6-sol": {
|
|
340
356
|
readonly id: "openai/gpt-5.6-sol";
|
|
341
357
|
readonly provider: "openai";
|
|
@@ -453,6 +469,10 @@ export interface ModelConfig extends ModelConfigBase {
|
|
|
453
469
|
* {@link ModelId} and enforce `id === key`.
|
|
454
470
|
*/
|
|
455
471
|
export declare const MODEL_REGISTRY: Readonly<Record<ModelId, ModelConfig>>;
|
|
472
|
+
/** Whether `value` is a registry model id — provider-qualified, e.g. `anthropic/claude-haiku-4-5`. */
|
|
473
|
+
export declare function isModelId(value: string): value is ModelId;
|
|
474
|
+
/** Every registry model id, in registry order (ggui#924: the blueprint record's `model` is one of these). */
|
|
475
|
+
export declare const MODEL_IDS: readonly ModelId[];
|
|
456
476
|
/**
|
|
457
477
|
* The curated "current lineup" — derived once from the rows' `lineup`
|
|
458
478
|
* fact, in registry order. Pickers render this up front and put the
|
package/dist/types/llm.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"llm.d.ts","sourceRoot":"","sources":["../../src/types/llm.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAMlD,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,UAAU,GAAG,SAAS,CAAC;AAExD;;;;;;GAMG;AACH,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAE7C,iEAAiE;AACjE,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,WAAW,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,SAAS,CAAC;IAChB,8BAA8B;IAC9B,KAAK,EAAE,UAAU,CAAC;IAClB;;;;;OAKG;IACH,MAAM,EAAE,OAAO,CAAC;IAChB;;;;OAIG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,KAAK,EAAE;QACL,UAAU,EAAE,MAAM,CAAC;QACnB,WAAW,EAAE,MAAM,CAAC;QACpB;;;;WAIG;QACH,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB;;;;WAIG;QACH,cAAc,CAAC,EAAE,MAAM,CAAC;KACzB,CAAC;IACF,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,OAAO,CAAC;IACvB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAkBD,QAAA,MAAM,UAAU
|
|
1
|
+
{"version":3,"file":"llm.d.ts","sourceRoot":"","sources":["../../src/types/llm.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAMlD,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,UAAU,GAAG,SAAS,CAAC;AAExD;;;;;;GAMG;AACH,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAE7C,iEAAiE;AACjE,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,WAAW,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,SAAS,CAAC;IAChB,8BAA8B;IAC9B,KAAK,EAAE,UAAU,CAAC;IAClB;;;;;OAKG;IACH,MAAM,EAAE,OAAO,CAAC;IAChB;;;;OAIG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,KAAK,EAAE;QACL,UAAU,EAAE,MAAM,CAAC;QACnB,WAAW,EAAE,MAAM,CAAC;QACpB;;;;WAIG;QACH,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB;;;;WAIG;QACH,cAAc,CAAC,EAAE,MAAM,CAAC;KACzB,CAAC;IACF,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,OAAO,CAAC;IACvB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAkBD,QAAA,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmWd,CAAC;AAEH,iEAAiE;AACjE,MAAM,MAAM,OAAO,GAAG,MAAM,OAAO,UAAU,CAAC;AAE9C,4CAA4C;AAC5C,MAAM,WAAW,WAAY,SAAQ,eAAe;IAClD,EAAE,EAAE,OAAO,CAAC;CACb;AAED;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,EAAE,QAAQ,CAAC,MAAM,CAAC,OAAO,EAAE,WAAW,CAAC,CAAc,CAAC;AAEjF,sGAAsG;AACtG,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,OAAO,CAEzD;AAED,6GAA6G;AAC7G,eAAO,MAAM,SAAS,EAAE,SAAS,OAAO,EAA8C,CAAC;AAEvF;;;;;GAKG;AACH,eAAO,MAAM,YAAY,EAAE,SAAS,OAAO,EAEA,CAAC;AAE5C,+CAA+C;AAC/C,wBAAgB,aAAa,CAAC,EAAE,EAAE,OAAO,GAAG,OAAO,CAElD;AAED;;;GAGG;AACH,eAAO,MAAM,aAAa,EAAE,OAAsC,CAAC"}
|
package/dist/types/llm.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* - `MODEL_REGISTRY` here = LiteLLM-keyed pricing + capability
|
|
7
7
|
* metadata. Keys are LiteLLM strings (`"gemini/gemini-3.5-flash"`,
|
|
8
8
|
* `"openai/gpt-5.4-mini"`, …). Read by:
|
|
9
|
-
* -
|
|
9
|
+
* - a hosted deployment's pricing-drift test (vendored
|
|
10
10
|
* LiteLLM JSON pricing table)
|
|
11
11
|
* - `oss/misc/benchmark` runner (bench harness; picks model
|
|
12
12
|
* configs by LiteLLM key)
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
* EXISTS, and `scripts/check-litellm-pricing-drift.ts` compares the
|
|
41
41
|
* snapshot against upstream, never the registry. That gap let this
|
|
42
42
|
* table sit four months stale while production routed to models it did
|
|
43
|
-
* not even list.
|
|
43
|
+
* not even list. A hosted deployment's `pricing-tables.test.ts` now asserts every
|
|
44
44
|
* entry's `costs` match the vendored rate (with an explicit, dated
|
|
45
45
|
* PENDING_UPSTREAM allowlist for prices we learn before LiteLLM does).
|
|
46
46
|
* Add a model here and you MUST re-vendor the snapshot in the same
|
|
@@ -307,6 +307,27 @@ const MODEL_ROWS = defineModelRegistry({
|
|
|
307
307
|
// confirmed upstream LiteLLM has ingested both cuts, so these costs
|
|
308
308
|
// now agree with the vendored snapshot (no PENDING_UPSTREAM
|
|
309
309
|
// exemption needed).
|
|
310
|
+
// ggui#977 (2026-09-09) — Exp 008's founder-ruled second arm. Receipts on
|
|
311
|
+
// the issue: existence `GET /v1/models/gpt-6-astra` → 200; pricing from
|
|
312
|
+
// platform.openai.com/docs/pricing, standard short-context tier; context
|
|
313
|
+
// window and tool support from the model page. No retirement date is
|
|
314
|
+
// published → `retireNotBefore` unset. Not in the lineup (experiment arm).
|
|
315
|
+
"openai/gpt-6-astra": {
|
|
316
|
+
id: "openai/gpt-6-astra",
|
|
317
|
+
provider: "openai",
|
|
318
|
+
displayName: "GPT-6 Astra",
|
|
319
|
+
tier: "premium",
|
|
320
|
+
state: "active",
|
|
321
|
+
lineup: false,
|
|
322
|
+
costs: {
|
|
323
|
+
inputPer1M: 10.0,
|
|
324
|
+
outputPer1M: 50.0,
|
|
325
|
+
cacheWritePer1M: 12.5,
|
|
326
|
+
cacheReadPer1M: 1.0,
|
|
327
|
+
},
|
|
328
|
+
maxTokens: 922000,
|
|
329
|
+
supportsTools: true,
|
|
330
|
+
},
|
|
310
331
|
"openai/gpt-5.6-sol": {
|
|
311
332
|
id: "openai/gpt-5.6-sol",
|
|
312
333
|
provider: "openai",
|
|
@@ -399,6 +420,12 @@ const MODEL_ROWS = defineModelRegistry({
|
|
|
399
420
|
* {@link ModelId} and enforce `id === key`.
|
|
400
421
|
*/
|
|
401
422
|
export const MODEL_REGISTRY = MODEL_ROWS;
|
|
423
|
+
/** Whether `value` is a registry model id — provider-qualified, e.g. `anthropic/claude-haiku-4-5`. */
|
|
424
|
+
export function isModelId(value) {
|
|
425
|
+
return Object.hasOwn(MODEL_ROWS, value);
|
|
426
|
+
}
|
|
427
|
+
/** Every registry model id, in registry order (ggui#924: the blueprint record's `model` is one of these). */
|
|
428
|
+
export const MODEL_IDS = Object.keys(MODEL_ROWS).filter(isModelId);
|
|
402
429
|
/**
|
|
403
430
|
* The curated "current lineup" — derived once from the rows' `lineup`
|
|
404
431
|
* fact, in registry order. Pickers render this up front and put the
|