@dcdr/contracts 2.2.0 → 2.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.
Files changed (72) hide show
  1. package/dist/asset.contract.d.ts +195 -0
  2. package/dist/asset.contract.d.ts.map +1 -0
  3. package/dist/asset.contract.js +60 -0
  4. package/dist/catalog/anthropic.contract.d.ts +11 -0
  5. package/dist/catalog/anthropic.contract.d.ts.map +1 -0
  6. package/dist/catalog/anthropic.contract.js +342 -0
  7. package/dist/catalog/clip.contract.d.ts +10 -0
  8. package/dist/catalog/clip.contract.d.ts.map +1 -0
  9. package/dist/catalog/clip.contract.js +16 -0
  10. package/dist/catalog/cohere.contract.d.ts +10 -0
  11. package/dist/catalog/cohere.contract.d.ts.map +1 -0
  12. package/dist/catalog/cohere.contract.js +16 -0
  13. package/dist/catalog/dcdr.contract.d.ts +10 -0
  14. package/dist/catalog/dcdr.contract.d.ts.map +1 -0
  15. package/dist/catalog/dcdr.contract.js +16 -0
  16. package/dist/catalog/gemini.contract.d.ts +10 -0
  17. package/dist/catalog/gemini.contract.d.ts.map +1 -0
  18. package/dist/catalog/gemini.contract.js +1067 -0
  19. package/dist/catalog/grok.contract.d.ts +10 -0
  20. package/dist/catalog/grok.contract.d.ts.map +1 -0
  21. package/dist/catalog/grok.contract.js +194 -0
  22. package/dist/catalog/http-tool.contract.d.ts +10 -0
  23. package/dist/catalog/http-tool.contract.d.ts.map +1 -0
  24. package/dist/catalog/http-tool.contract.js +16 -0
  25. package/dist/catalog/mistral.contract.d.ts +10 -0
  26. package/dist/catalog/mistral.contract.d.ts.map +1 -0
  27. package/dist/catalog/mistral.contract.js +234 -0
  28. package/dist/catalog/ocr.contract.d.ts +10 -0
  29. package/dist/catalog/ocr.contract.d.ts.map +1 -0
  30. package/dist/catalog/ocr.contract.js +16 -0
  31. package/dist/catalog/office.contract.d.ts +10 -0
  32. package/dist/catalog/office.contract.d.ts.map +1 -0
  33. package/dist/catalog/office.contract.js +53 -0
  34. package/dist/catalog/ollama.contract.d.ts +10 -0
  35. package/dist/catalog/ollama.contract.d.ts.map +1 -0
  36. package/dist/catalog/ollama.contract.js +16 -0
  37. package/dist/catalog/openai-compatible.contract.d.ts +10 -0
  38. package/dist/catalog/openai-compatible.contract.d.ts.map +1 -0
  39. package/dist/catalog/openai-compatible.contract.js +16 -0
  40. package/dist/catalog/openai.contract.d.ts +11 -0
  41. package/dist/catalog/openai.contract.d.ts.map +1 -0
  42. package/dist/catalog/openai.contract.js +2654 -0
  43. package/dist/catalog/rules.contract.d.ts +10 -0
  44. package/dist/catalog/rules.contract.d.ts.map +1 -0
  45. package/dist/catalog/rules.contract.js +16 -0
  46. package/dist/entitlements.contract.d.ts +3 -0
  47. package/dist/entitlements.contract.d.ts.map +1 -1
  48. package/dist/execution.contract.d.ts +122 -0
  49. package/dist/execution.contract.d.ts.map +1 -1
  50. package/dist/execution.contract.js +17 -1
  51. package/dist/policies.contract.d.ts +19 -0
  52. package/dist/policies.contract.d.ts.map +1 -1
  53. package/dist/policies.contract.js +24 -1
  54. package/dist/prompt-variable-schema.contract.d.ts +8 -1
  55. package/dist/prompt-variable-schema.contract.d.ts.map +1 -1
  56. package/dist/prompt-variable-schema.contract.js +109 -4
  57. package/dist/prompts.contract.d.ts +14 -8
  58. package/dist/prompts.contract.d.ts.map +1 -1
  59. package/dist/prompts.contract.js +12 -1
  60. package/dist/provider.catalog.contract.d.ts +459 -0
  61. package/dist/provider.catalog.contract.d.ts.map +1 -0
  62. package/dist/provider.catalog.contract.js +765 -0
  63. package/dist/provider.contract.d.ts +4 -352
  64. package/dist/provider.contract.d.ts.map +1 -1
  65. package/dist/provider.contract.js +16 -3634
  66. package/dist/runtime.client.d.ts +54 -1
  67. package/dist/runtime.client.d.ts.map +1 -1
  68. package/dist/runtime.client.js +185 -0
  69. package/dist/utils.contract.d.ts +33 -0
  70. package/dist/utils.contract.d.ts.map +1 -1
  71. package/dist/utils.contract.js +35 -0
  72. package/package.json +2 -1
@@ -0,0 +1,765 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ProviderModelRegistry = exports.PROVIDER_MODEL_E2E_OVERRIDES = exports.ProviderModelE2EStatus = exports.PROVIDER_MODEL_IDS_BY_PROVIDER_AND_TYPE = exports.PROVIDER_MODEL_CATALOG = exports.PROVIDER_MODEL_DEFINITIONS_BY_PROVIDER = exports.DcdrPublicModelCategory = exports.ProviderModelParameterSupportStatus = exports.PromptParameterKey = exports.ProviderModelPreferredApi = exports.ProviderModelRuntimeSupportStatus = void 0;
4
+ exports.formatDcdrVirtualModelId = formatDcdrVirtualModelId;
5
+ exports.parseDcdrVirtualModelId = parseDcdrVirtualModelId;
6
+ const intent_contract_1 = require("./intent.contract");
7
+ const provider_contract_1 = require("./provider.contract");
8
+ const anthropic_contract_1 = require("./catalog/anthropic.contract");
9
+ const clip_contract_1 = require("./catalog/clip.contract");
10
+ const cohere_contract_1 = require("./catalog/cohere.contract");
11
+ const dcdr_contract_1 = require("./catalog/dcdr.contract");
12
+ const gemini_contract_1 = require("./catalog/gemini.contract");
13
+ const grok_contract_1 = require("./catalog/grok.contract");
14
+ const http_tool_contract_1 = require("./catalog/http-tool.contract");
15
+ const mistral_contract_1 = require("./catalog/mistral.contract");
16
+ const ocr_contract_1 = require("./catalog/ocr.contract");
17
+ const office_contract_1 = require("./catalog/office.contract");
18
+ const ollama_contract_1 = require("./catalog/ollama.contract");
19
+ const openai_compatible_contract_1 = require("./catalog/openai-compatible.contract");
20
+ const openai_contract_1 = require("./catalog/openai.contract");
21
+ const rules_contract_1 = require("./catalog/rules.contract");
22
+ /** Runtime-level support status for a (provider, modelId) pair. */
23
+ var ProviderModelRuntimeSupportStatus;
24
+ (function (ProviderModelRuntimeSupportStatus) {
25
+ /** Supported by this runtime (intended to work). */
26
+ ProviderModelRuntimeSupportStatus["SUPPORTED"] = "SUPPORTED";
27
+ /** Explicitly not supported by this runtime (do not attempt provider calls). */
28
+ ProviderModelRuntimeSupportStatus["NOT_SUPPORTED"] = "NOT_SUPPORTED";
29
+ /** Known failing in current runtime; keep visible but treat as unstable. */
30
+ ProviderModelRuntimeSupportStatus["FAILING"] = "FAILING";
31
+ /** Under active implementation/curation; not yet reliable. */
32
+ ProviderModelRuntimeSupportStatus["IN_PROGRESS"] = "IN_PROGRESS";
33
+ })(ProviderModelRuntimeSupportStatus || (exports.ProviderModelRuntimeSupportStatus = ProviderModelRuntimeSupportStatus = {}));
34
+ /** Canonical provider API surface preferred by the runtime for a model family. */
35
+ var ProviderModelPreferredApi;
36
+ (function (ProviderModelPreferredApi) {
37
+ ProviderModelPreferredApi["CHAT_COMPLETIONS"] = "CHAT_COMPLETIONS";
38
+ ProviderModelPreferredApi["RESPONSES"] = "RESPONSES";
39
+ })(ProviderModelPreferredApi || (exports.ProviderModelPreferredApi = ProviderModelPreferredApi = {}));
40
+ /** Generic prompt/runtime parameter keys that can be exposed to users (UI) and adapters. */
41
+ var PromptParameterKey;
42
+ (function (PromptParameterKey) {
43
+ PromptParameterKey["TEMPERATURE"] = "temperature";
44
+ PromptParameterKey["TOP_P"] = "top_p";
45
+ PromptParameterKey["TOP_K"] = "top_k";
46
+ PromptParameterKey["MAX_TOKENS"] = "max_tokens";
47
+ PromptParameterKey["ENABLE_THINKING"] = "enable_thinking";
48
+ PromptParameterKey["RESPONSE_FORMAT"] = "response_format";
49
+ PromptParameterKey["PRESENCE_PENALTY"] = "presence_penalty";
50
+ PromptParameterKey["FREQUENCY_PENALTY"] = "frequency_penalty";
51
+ })(PromptParameterKey || (exports.PromptParameterKey = PromptParameterKey = {}));
52
+ /** Runtime-level parameter support status for a specific model. */
53
+ var ProviderModelParameterSupportStatus;
54
+ (function (ProviderModelParameterSupportStatus) {
55
+ ProviderModelParameterSupportStatus["SUPPORTED"] = "SUPPORTED";
56
+ /** Parameter is not supported and should not be sent. */
57
+ ProviderModelParameterSupportStatus["NOT_SUPPORTED"] = "NOT_SUPPORTED";
58
+ /** Only provider default is supported; runtime should avoid sending custom values. */
59
+ ProviderModelParameterSupportStatus["DEFAULT_ONLY"] = "DEFAULT_ONLY";
60
+ })(ProviderModelParameterSupportStatus || (exports.ProviderModelParameterSupportStatus = ProviderModelParameterSupportStatus = {}));
61
+ /**
62
+ * Product-level managed categories for public customer models.
63
+ *
64
+ * Purpose
65
+ * - Provide a stable grouping/filtering abstraction for customer-facing UIs.
66
+ * - Avoid exposing a flat provider/model list by default.
67
+ */
68
+ var DcdrPublicModelCategory;
69
+ (function (DcdrPublicModelCategory) {
70
+ /** Maximum quality / strongest reasoning; typically expensive. */
71
+ DcdrPublicModelCategory["BEST"] = "BEST";
72
+ /** Best balance between quality and cost; recommended default for production chat. */
73
+ DcdrPublicModelCategory["SMART"] = "SMART";
74
+ /** Low latency; good for interactive chat/support. */
75
+ DcdrPublicModelCategory["FAST"] = "FAST";
76
+ /** Lowest cost; good for high-volume simple tasks. */
77
+ DcdrPublicModelCategory["ECONOMY"] = "ECONOMY";
78
+ /** Internal/local/company-managed models (self-hosted, Office, etc.). */
79
+ DcdrPublicModelCategory["PRIVATE"] = "PRIVATE";
80
+ })(DcdrPublicModelCategory || (exports.DcdrPublicModelCategory = DcdrPublicModelCategory = {}));
81
+ const DEFAULT_TOKEN_PRICING_UPDATED_AT = Date.UTC(2026, 2, 27);
82
+ const DEFAULT_AUDIO_PRICING_UPDATED_AT = Date.UTC(2026, 4, 22);
83
+ const PRICING_FALLBACK_RULES_BY_PROVIDER = {
84
+ [provider_contract_1.IntentProvider.DCDR]: [],
85
+ [provider_contract_1.IntentProvider.OPEN_AI]: openai_contract_1.OPENAI_PROVIDER_PRICING_FALLBACK_RULES,
86
+ [provider_contract_1.IntentProvider.ANTHROPIC]: anthropic_contract_1.ANTHROPIC_PROVIDER_PRICING_FALLBACK_RULES,
87
+ [provider_contract_1.IntentProvider.GEMINI]: [],
88
+ [provider_contract_1.IntentProvider.GROK]: [],
89
+ [provider_contract_1.IntentProvider.MISTRAL]: [],
90
+ [provider_contract_1.IntentProvider.COHERE]: [],
91
+ [provider_contract_1.IntentProvider.OFFICE]: [],
92
+ [provider_contract_1.IntentProvider.OLLAMA]: [],
93
+ [provider_contract_1.IntentProvider.OPEN_AI_COMPATIBLE]: [],
94
+ [provider_contract_1.IntentProvider.OCR]: [],
95
+ [provider_contract_1.IntentProvider.CLIP]: [],
96
+ [provider_contract_1.IntentProvider.HTTP_TOOL]: [],
97
+ [provider_contract_1.IntentProvider.RULES]: [],
98
+ };
99
+ const PROVIDER_CATALOG_MODULE_BUILD_ARGS = {
100
+ pricingPerMillionTokens,
101
+ pricingAudioMinutesPerMinute,
102
+ catalogEnums: {
103
+ runtimeSupportStatus: ProviderModelRuntimeSupportStatus,
104
+ preferredApi: ProviderModelPreferredApi,
105
+ promptParameterKey: PromptParameterKey,
106
+ parameterSupportStatus: ProviderModelParameterSupportStatus,
107
+ publicModelCategory: DcdrPublicModelCategory,
108
+ get e2eStatus() {
109
+ return ProviderModelE2EStatus;
110
+ },
111
+ },
112
+ };
113
+ const DCDR_VIRTUAL_PROVIDER_PREFIX_BY_PROVIDER = {
114
+ [provider_contract_1.IntentProvider.OPEN_AI]: "openai",
115
+ [provider_contract_1.IntentProvider.ANTHROPIC]: "anthropic",
116
+ [provider_contract_1.IntentProvider.GEMINI]: "gemini",
117
+ [provider_contract_1.IntentProvider.GROK]: "grok",
118
+ [provider_contract_1.IntentProvider.MISTRAL]: "mistral",
119
+ [provider_contract_1.IntentProvider.OFFICE]: "office",
120
+ };
121
+ const DCDR_VIRTUAL_PROVIDER_BY_PREFIX = {
122
+ openai: provider_contract_1.IntentProvider.OPEN_AI,
123
+ anthropic: provider_contract_1.IntentProvider.ANTHROPIC,
124
+ gemini: provider_contract_1.IntentProvider.GEMINI,
125
+ grok: provider_contract_1.IntentProvider.GROK,
126
+ xai: provider_contract_1.IntentProvider.GROK,
127
+ mistral: provider_contract_1.IntentProvider.MISTRAL,
128
+ office: provider_contract_1.IntentProvider.OFFICE,
129
+ };
130
+ /**
131
+ * Formats a DCDR virtual provider model id as `provider/model`.
132
+ *
133
+ * Returns an empty string for unsupported provider prefixes.
134
+ */
135
+ function formatDcdrVirtualModelId(provider, modelId) {
136
+ const prefix = DCDR_VIRTUAL_PROVIDER_PREFIX_BY_PROVIDER[provider];
137
+ if (!prefix)
138
+ return "";
139
+ const id = String(modelId ?? "").trim();
140
+ if (!id)
141
+ return "";
142
+ return `${prefix}/${id}`;
143
+ }
144
+ /**
145
+ * Parses a DCDR virtual provider model id of the form `provider/model`.
146
+ *
147
+ * Returns null when the id is not a valid DCDR virtual model id.
148
+ */
149
+ function parseDcdrVirtualModelId(prefixedModelId) {
150
+ const raw = String(prefixedModelId ?? "").trim();
151
+ if (!raw)
152
+ return null;
153
+ const idx = raw.indexOf("/");
154
+ if (idx <= 0 || idx >= raw.length - 1)
155
+ return null;
156
+ const prefix = raw.slice(0, idx).trim().toLowerCase();
157
+ const modelId = raw.slice(idx + 1).trim();
158
+ if (!prefix || !modelId)
159
+ return null;
160
+ const provider = DCDR_VIRTUAL_PROVIDER_BY_PREFIX[prefix];
161
+ if (!provider)
162
+ return null;
163
+ return { provider, modelId, prefixedModelId: raw };
164
+ }
165
+ /**
166
+ * Builds a virtual provider model list for `IntentProvider.DCDR`.
167
+ *
168
+ * Goal
169
+ * - Allow DCDR to reference any model that DCDR runtime explicitly supports.
170
+ *
171
+ * Rules
172
+ * - For hosted providers (OpenAI/Anthropic/Gemini/Grok/Mistral): include only models marked `runtimeSupport.status=SUPPORTED`.
173
+ * - For `OFFICE`: include all declared models (local/runtime-managed; support is deployment-dependent).
174
+ * - Stable deterministic ordering: provider order then model declaration order.
175
+ */
176
+ function buildDcdrVirtualProviderModelDefinitions(modelsByProvider) {
177
+ const providers = [
178
+ provider_contract_1.IntentProvider.OPEN_AI,
179
+ provider_contract_1.IntentProvider.ANTHROPIC,
180
+ provider_contract_1.IntentProvider.GEMINI,
181
+ provider_contract_1.IntentProvider.GROK,
182
+ provider_contract_1.IntentProvider.MISTRAL,
183
+ provider_contract_1.IntentProvider.OFFICE,
184
+ ];
185
+ const out = [];
186
+ for (const provider of providers) {
187
+ const defs = modelsByProvider[provider] ?? [];
188
+ for (const def of defs) {
189
+ const isOffice = provider === provider_contract_1.IntentProvider.OFFICE;
190
+ const isSupported = def.runtimeSupport?.status ===
191
+ ProviderModelRuntimeSupportStatus.SUPPORTED;
192
+ if (!isOffice && !isSupported)
193
+ continue;
194
+ const prefixedId = formatDcdrVirtualModelId(provider, def.id);
195
+ if (!prefixedId)
196
+ continue;
197
+ out.push({
198
+ ...def,
199
+ id: prefixedId,
200
+ publicForCustomers: false,
201
+ });
202
+ }
203
+ }
204
+ return out;
205
+ }
206
+ /**
207
+ * Canonical provider model catalog (single source of truth).
208
+ */
209
+ const PROVIDER_MODEL_DEFINITIONS_BY_PROVIDER_RAW = {
210
+ [provider_contract_1.IntentProvider.DCDR]: (0, dcdr_contract_1.buildDcdrProviderModelDefinitions)(PROVIDER_CATALOG_MODULE_BUILD_ARGS),
211
+ [provider_contract_1.IntentProvider.OPEN_AI]: (0, openai_contract_1.buildOpenAIProviderModelDefinitions)(PROVIDER_CATALOG_MODULE_BUILD_ARGS),
212
+ [provider_contract_1.IntentProvider.GEMINI]: (0, gemini_contract_1.buildGeminiProviderModelDefinitions)(PROVIDER_CATALOG_MODULE_BUILD_ARGS),
213
+ [provider_contract_1.IntentProvider.GROK]: (0, grok_contract_1.buildGrokProviderModelDefinitions)(PROVIDER_CATALOG_MODULE_BUILD_ARGS),
214
+ [provider_contract_1.IntentProvider.ANTHROPIC]: (0, anthropic_contract_1.buildAnthropicProviderModelDefinitions)(PROVIDER_CATALOG_MODULE_BUILD_ARGS),
215
+ [provider_contract_1.IntentProvider.MISTRAL]: (0, mistral_contract_1.buildMistralProviderModelDefinitions)(PROVIDER_CATALOG_MODULE_BUILD_ARGS),
216
+ [provider_contract_1.IntentProvider.COHERE]: (0, cohere_contract_1.buildCohereProviderModelDefinitions)(PROVIDER_CATALOG_MODULE_BUILD_ARGS),
217
+ [provider_contract_1.IntentProvider.OFFICE]: (0, office_contract_1.buildOfficeProviderModelDefinitions)(PROVIDER_CATALOG_MODULE_BUILD_ARGS),
218
+ [provider_contract_1.IntentProvider.OLLAMA]: (0, ollama_contract_1.buildOllamaProviderModelDefinitions)(PROVIDER_CATALOG_MODULE_BUILD_ARGS),
219
+ [provider_contract_1.IntentProvider.OPEN_AI_COMPATIBLE]: (0, openai_compatible_contract_1.buildOpenAICompatibleProviderModelDefinitions)(PROVIDER_CATALOG_MODULE_BUILD_ARGS),
220
+ [provider_contract_1.IntentProvider.OCR]: (0, ocr_contract_1.buildOcrProviderModelDefinitions)(PROVIDER_CATALOG_MODULE_BUILD_ARGS),
221
+ [provider_contract_1.IntentProvider.CLIP]: (0, clip_contract_1.buildClipProviderModelDefinitions)(PROVIDER_CATALOG_MODULE_BUILD_ARGS),
222
+ [provider_contract_1.IntentProvider.HTTP_TOOL]: (0, http_tool_contract_1.buildHttpToolProviderModelDefinitions)(PROVIDER_CATALOG_MODULE_BUILD_ARGS),
223
+ [provider_contract_1.IntentProvider.RULES]: (0, rules_contract_1.buildRulesProviderModelDefinitions)(PROVIDER_CATALOG_MODULE_BUILD_ARGS),
224
+ };
225
+ /**
226
+ * Token usage coverage overrides derived from provider E2E curation runs.
227
+ *
228
+ * Notes
229
+ * - This is intended to be filled iteratively (in batches) as we validate token usage reporting
230
+ * for all `runtimeSupport.status=SUPPORTED` chat models.
231
+ * - These overrides only apply when a model definition omits `tokenUsageCovered`.
232
+ * (Public customer models still require `tokenUsageCovered=true` on the definition itself.)
233
+ */
234
+ const TOKEN_USAGE_COVERAGE_BY_PROVIDER_AND_ID = {
235
+ [provider_contract_1.IntentProvider.OPEN_AI]: {
236
+ "gpt-5.5-2026-04-23": true,
237
+ "gpt-5.5-pro": true,
238
+ "gpt-5.5-pro-2026-04-23": true,
239
+ "gpt-5.4-2026-03-05": true,
240
+ "gpt-5.4-mini-2026-03-17": true,
241
+ "gpt-5.4-nano-2026-03-17": true,
242
+ "gpt-5.4-pro": true,
243
+ "gpt-5.4-pro-2026-03-05": true,
244
+ "gpt-5.3-chat-latest": true,
245
+ "gpt-5.3-codex": true,
246
+ "gpt-5.2": true,
247
+ "gpt-5.2-2025-12-11": true,
248
+ "gpt-5.2-chat-latest": true,
249
+ "gpt-5.2-codex": true,
250
+ "gpt-5.2-pro": true,
251
+ "gpt-5.2-pro-2025-12-11": true,
252
+ "gpt-5.1": true,
253
+ "gpt-5.1-2025-11-13": true,
254
+ "gpt-5.1-chat-latest": true,
255
+ "gpt-5.1-codex": true,
256
+ "gpt-5.1-codex-max": true,
257
+ "gpt-5.1-codex-mini": true,
258
+ "gpt-5": true,
259
+ "gpt-5-2025-08-07": true,
260
+ "gpt-5-chat-latest": true,
261
+ "gpt-5-codex": true,
262
+ "gpt-5-mini": true,
263
+ "gpt-5-mini-2025-08-07": true,
264
+ "gpt-5-nano": true,
265
+ "gpt-5-nano-2025-08-07": true,
266
+ "gpt-5-pro": true,
267
+ "gpt-5-pro-2025-10-06": true,
268
+ "gpt-4.1": true,
269
+ "gpt-4.1-2025-04-14": true,
270
+ "gpt-4.1-mini": true,
271
+ "gpt-4.1-mini-2025-04-14": true,
272
+ "gpt-4.1-nano": true,
273
+ "gpt-4.1-nano-2025-04-14": true,
274
+ "gpt-4o": true,
275
+ "gpt-4o-2024-08-06": true,
276
+ "gpt-4o-2024-11-20": true,
277
+ "gpt-4o-mini": true,
278
+ "gpt-4o-mini-2024-07-18": true,
279
+ "gpt-4o-2024-05-13": true,
280
+ "gpt-4-turbo": true,
281
+ "gpt-4-turbo-2024-04-09": true,
282
+ "gpt-4": true,
283
+ "gpt-4-0613": true,
284
+ "gpt-3.5-turbo": true,
285
+ "gpt-3.5-turbo-0125": true,
286
+ "gpt-3.5-turbo-1106": true,
287
+ "gpt-3.5-turbo-16k": true,
288
+ "o4-mini": true,
289
+ "o4-mini-2025-04-16": true,
290
+ "o3-pro": true,
291
+ "o3-pro-2025-06-10": true,
292
+ o3: true,
293
+ "o3-2025-04-16": true,
294
+ "o3-mini": true,
295
+ "o3-mini-2025-01-31": true,
296
+ "o1-pro": true,
297
+ "o1-pro-2025-03-19": true,
298
+ o1: true,
299
+ "o1-2024-12-17": true,
300
+ },
301
+ [provider_contract_1.IntentProvider.GEMINI]: {
302
+ "gemini-3.1-pro-preview-customtools": true,
303
+ "gemini-3.1-flash-lite-preview": true,
304
+ "gemini-3.1-flash-lite": true,
305
+ "gemini-3.1-flash-image-preview": true,
306
+ "gemini-3-pro-preview": false,
307
+ "gemini-2.5-flash-image": true,
308
+ "gemini-flash-latest": true,
309
+ "gemini-flash-lite-latest": true,
310
+ "gemini-pro-latest": true,
311
+ },
312
+ [provider_contract_1.IntentProvider.ANTHROPIC]: {
313
+ "claude-opus-4-6": true,
314
+ "claude-opus-4-5-20251101": true,
315
+ "claude-opus-4-1-20250805": true,
316
+ "claude-sonnet-4-5-20250929": true,
317
+ "claude-haiku-4-5-20251001": true,
318
+ },
319
+ [provider_contract_1.IntentProvider.OFFICE]: {},
320
+ };
321
+ function getTokenUsageCoveredOverride(provider, modelId) {
322
+ return TOKEN_USAGE_COVERAGE_BY_PROVIDER_AND_ID[provider]?.[modelId];
323
+ }
324
+ /** Normalizes catalog entries so optional flags become required (fail-closed). */
325
+ function normalizeProviderModelDefinitions(modelsByProvider) {
326
+ const out = {};
327
+ let globalDefaultCount = 0;
328
+ const categoryDefaultCounts = new Map();
329
+ const categoriesWithPublicModels = new Set();
330
+ const assertTier = (provider, modelId, field, value) => {
331
+ if (!Number.isFinite(value)) {
332
+ throw new Error(`Provider model catalog: ${provider}/${modelId} ${field} must be a finite number (1..5).`);
333
+ }
334
+ const n = Math.trunc(value);
335
+ if (n !== value || n < 1 || n > 5) {
336
+ throw new Error(`Provider model catalog: ${provider}/${modelId} ${field} must be an integer in range 1..5.`);
337
+ }
338
+ };
339
+ const assertNoLegacyManagedFields = (provider, modelId, def) => {
340
+ const d = def;
341
+ const legacyFields = [
342
+ "publicDisplayName",
343
+ "isRecommendedDefault",
344
+ "default",
345
+ ];
346
+ for (const f of legacyFields) {
347
+ if (Object.prototype.hasOwnProperty.call(d, f)) {
348
+ throw new Error(`Provider model catalog: ${provider}/${modelId} must not include legacy field '${f}'.`);
349
+ }
350
+ }
351
+ };
352
+ const assertNonEmptyStringArray = (provider, modelId, field, value) => {
353
+ if (!Array.isArray(value) || value.length === 0) {
354
+ throw new Error(`Provider model catalog: ${provider}/${modelId} ${field} must be a non-empty string array.`);
355
+ }
356
+ for (const v of value) {
357
+ if (typeof v !== "string" || !v.trim()) {
358
+ throw new Error(`Provider model catalog: ${provider}/${modelId} ${field} must contain only non-empty strings.`);
359
+ }
360
+ }
361
+ };
362
+ for (const provider of Object.values(provider_contract_1.IntentProvider)) {
363
+ const defs = modelsByProvider[provider] ?? [];
364
+ const ids = new Set();
365
+ out[provider] = defs.map((def) => {
366
+ assertNoLegacyManagedFields(provider, def.id, def);
367
+ if (ids.has(def.id)) {
368
+ throw new Error(`Provider model catalog: duplicate modelId '${def.id}' for provider ${provider}.`);
369
+ }
370
+ ids.add(def.id);
371
+ const tokenUsageCoveredOverride = getTokenUsageCoveredOverride(provider, def.id);
372
+ const normalized = {
373
+ ...def,
374
+ publicForCustomers: def.publicForCustomers === true,
375
+ tokenUsageCovered: def.tokenUsageCovered ?? tokenUsageCoveredOverride,
376
+ };
377
+ if (normalized.publicForCustomers) {
378
+ if (normalized.tokenUsageCovered !== true) {
379
+ throw new Error(`Provider model catalog: ${provider}/${normalized.id} tokenUsageCovered=true is required for publicForCustomers models.`);
380
+ }
381
+ if (!normalized.publicName?.trim()) {
382
+ throw new Error(`Provider model catalog: ${provider}/${normalized.id} publicName is required for publicForCustomers models.`);
383
+ }
384
+ if (!normalized.primaryCategory) {
385
+ throw new Error(`Provider model catalog: ${provider}/${normalized.id} primaryCategory is required for publicForCustomers models.`);
386
+ }
387
+ if (!Array.isArray(normalized.categories) ||
388
+ normalized.categories.length === 0) {
389
+ throw new Error(`Provider model catalog: ${provider}/${normalized.id} categories is required for publicForCustomers models.`);
390
+ }
391
+ if (!normalized.categories.includes(normalized.primaryCategory)) {
392
+ throw new Error(`Provider model catalog: ${provider}/${normalized.id} categories must include primaryCategory (${normalized.primaryCategory}).`);
393
+ }
394
+ categoriesWithPublicModels.add(normalized.primaryCategory);
395
+ if (typeof normalized.isRecommended !== "boolean") {
396
+ throw new Error(`Provider model catalog: ${provider}/${normalized.id} isRecommended is required for publicForCustomers models.`);
397
+ }
398
+ if (typeof normalized.isGlobalDefault !== "boolean") {
399
+ throw new Error(`Provider model catalog: ${provider}/${normalized.id} isGlobalDefault is required for publicForCustomers models.`);
400
+ }
401
+ if (typeof normalized.isCategoryDefault !== "boolean") {
402
+ throw new Error(`Provider model catalog: ${provider}/${normalized.id} isCategoryDefault is required for publicForCustomers models.`);
403
+ }
404
+ if (normalized.isGlobalDefault)
405
+ globalDefaultCount += 1;
406
+ if (normalized.isCategoryDefault) {
407
+ const c = normalized.primaryCategory;
408
+ const prev = categoryDefaultCounts.get(c) ?? 0;
409
+ categoryDefaultCounts.set(c, prev + 1);
410
+ }
411
+ assertTier(provider, normalized.id, "qualityTier", normalized.qualityTier ?? Number.NaN);
412
+ assertTier(provider, normalized.id, "speedTier", normalized.speedTier ?? Number.NaN);
413
+ assertTier(provider, normalized.id, "costTier", normalized.costTier ?? Number.NaN);
414
+ assertNonEmptyStringArray(provider, normalized.id, "recommendedUseCases", normalized.recommendedUseCases ?? []);
415
+ }
416
+ return normalized;
417
+ });
418
+ }
419
+ if (globalDefaultCount !== 1) {
420
+ throw new Error(`Provider model catalog: expected exactly one public model with isGlobalDefault=true, found ${globalDefaultCount}.`);
421
+ }
422
+ for (const c of categoriesWithPublicModels) {
423
+ const count = categoryDefaultCounts.get(c) ?? 0;
424
+ if (count <= 0) {
425
+ throw new Error(`Provider model catalog: expected at least one public model with isCategoryDefault=true for primaryCategory ${c}.`);
426
+ }
427
+ }
428
+ return out;
429
+ }
430
+ /**
431
+ * Canonical provider model catalog (after enrichment passes).
432
+ */
433
+ exports.PROVIDER_MODEL_DEFINITIONS_BY_PROVIDER = (() => {
434
+ const base = fillMissingPricingFromBaseModels(PROVIDER_MODEL_DEFINITIONS_BY_PROVIDER_RAW);
435
+ const normalized = normalizeProviderModelDefinitions(base);
436
+ return {
437
+ ...normalized,
438
+ [provider_contract_1.IntentProvider.DCDR]: buildDcdrVirtualProviderModelDefinitions(normalized),
439
+ };
440
+ })();
441
+ const _PROVIDER_MODEL_INDEXES = buildProviderModelCatalogAndTypeIndex(exports.PROVIDER_MODEL_DEFINITIONS_BY_PROVIDER);
442
+ /**
443
+ * Canonical lookup: provider -> modelId -> model definition.
444
+ */
445
+ exports.PROVIDER_MODEL_CATALOG = _PROVIDER_MODEL_INDEXES.catalog;
446
+ /**
447
+ * Primary listing structure (no duplicated metadata): provider -> intent type -> model IDs.
448
+ */
449
+ exports.PROVIDER_MODEL_IDS_BY_PROVIDER_AND_TYPE = _PROVIDER_MODEL_INDEXES.idsByType;
450
+ /**
451
+ * E2E model status used by provider test suites.
452
+ *
453
+ * Notes
454
+ * - This is an opt-in testing mechanism; it does not affect runtime behavior.
455
+ * - Use `LEGACY` to explicitly skip obsolete/retired model IDs while still keeping them
456
+ * discoverable in the catalog for historical compatibility.
457
+ */
458
+ var ProviderModelE2EStatus;
459
+ (function (ProviderModelE2EStatus) {
460
+ /** Model should be exercised by E2E suites (when provider is implemented and credentials exist). */
461
+ ProviderModelE2EStatus["ACTIVE"] = "ACTIVE";
462
+ /** Model is considered legacy/obsolete and may be skipped by E2E suites. */
463
+ ProviderModelE2EStatus["LEGACY"] = "LEGACY";
464
+ })(ProviderModelE2EStatus || (exports.ProviderModelE2EStatus = ProviderModelE2EStatus = {}));
465
+ /**
466
+ * Optional provider-model overrides consumed by the provider E2E matrix tests.
467
+ */
468
+ exports.PROVIDER_MODEL_E2E_OVERRIDES = {
469
+ [provider_contract_1.IntentProvider.DCDR]: (0, dcdr_contract_1.buildDcdrProviderModelE2EOverrides)(PROVIDER_CATALOG_MODULE_BUILD_ARGS),
470
+ [provider_contract_1.IntentProvider.OPEN_AI]: (0, openai_contract_1.buildOpenAIProviderModelE2EOverrides)(PROVIDER_CATALOG_MODULE_BUILD_ARGS),
471
+ [provider_contract_1.IntentProvider.GEMINI]: (0, gemini_contract_1.buildGeminiProviderModelE2EOverrides)(PROVIDER_CATALOG_MODULE_BUILD_ARGS),
472
+ [provider_contract_1.IntentProvider.GROK]: (0, grok_contract_1.buildGrokProviderModelE2EOverrides)(PROVIDER_CATALOG_MODULE_BUILD_ARGS),
473
+ [provider_contract_1.IntentProvider.ANTHROPIC]: (0, anthropic_contract_1.buildAnthropicProviderModelE2EOverrides)(PROVIDER_CATALOG_MODULE_BUILD_ARGS),
474
+ [provider_contract_1.IntentProvider.MISTRAL]: (0, mistral_contract_1.buildMistralProviderModelE2EOverrides)(PROVIDER_CATALOG_MODULE_BUILD_ARGS),
475
+ [provider_contract_1.IntentProvider.COHERE]: (0, cohere_contract_1.buildCohereProviderModelE2EOverrides)(PROVIDER_CATALOG_MODULE_BUILD_ARGS),
476
+ [provider_contract_1.IntentProvider.OFFICE]: (0, office_contract_1.buildOfficeProviderModelE2EOverrides)(PROVIDER_CATALOG_MODULE_BUILD_ARGS),
477
+ [provider_contract_1.IntentProvider.OLLAMA]: (0, ollama_contract_1.buildOllamaProviderModelE2EOverrides)(PROVIDER_CATALOG_MODULE_BUILD_ARGS),
478
+ [provider_contract_1.IntentProvider.OPEN_AI_COMPATIBLE]: (0, openai_compatible_contract_1.buildOpenAICompatibleProviderModelE2EOverrides)(PROVIDER_CATALOG_MODULE_BUILD_ARGS),
479
+ [provider_contract_1.IntentProvider.OCR]: (0, ocr_contract_1.buildOcrProviderModelE2EOverrides)(PROVIDER_CATALOG_MODULE_BUILD_ARGS),
480
+ [provider_contract_1.IntentProvider.CLIP]: (0, clip_contract_1.buildClipProviderModelE2EOverrides)(PROVIDER_CATALOG_MODULE_BUILD_ARGS),
481
+ [provider_contract_1.IntentProvider.HTTP_TOOL]: (0, http_tool_contract_1.buildHttpToolProviderModelE2EOverrides)(PROVIDER_CATALOG_MODULE_BUILD_ARGS),
482
+ [provider_contract_1.IntentProvider.RULES]: (0, rules_contract_1.buildRulesProviderModelE2EOverrides)(PROVIDER_CATALOG_MODULE_BUILD_ARGS),
483
+ };
484
+ function pricingPerMillionTokens(args) {
485
+ return {
486
+ currency: "USD",
487
+ sourceUrl: args.sourceUrl,
488
+ updatedAt: args.updatedAt ?? DEFAULT_TOKEN_PRICING_UPDATED_AT,
489
+ confidence: args.confidence ?? "official",
490
+ notes: args.notes,
491
+ components: [
492
+ {
493
+ kind: "tokens",
494
+ unit: "per_million_tokens",
495
+ input: args.input,
496
+ outputUsd: args.output,
497
+ cachedInput: args.cachedInput,
498
+ cachedOutput: args.cachedOutput,
499
+ tiers: args.tiers,
500
+ },
501
+ ],
502
+ };
503
+ }
504
+ /**
505
+ * Gemini token pricing helper.
506
+ *
507
+ * Notes
508
+ * - Uses the Gemini Developer API pricing page as the canonical source.
509
+ * - Pricing tables sometimes vary by modality (text vs audio) and/or prompt size (<=200k vs >200k tokens).
510
+ * We represent those as `tiers` with a human-readable condition.
511
+ */
512
+ function pricingAudioMinutesPerMinute(args) {
513
+ return {
514
+ currency: "USD",
515
+ sourceUrl: args.sourceUrl,
516
+ updatedAt: args.updatedAt ?? DEFAULT_AUDIO_PRICING_UPDATED_AT,
517
+ confidence: args.confidence ?? "official",
518
+ notes: args.notes,
519
+ components: [
520
+ {
521
+ kind: "audio_minutes",
522
+ unit: "per_minute",
523
+ input: args.input,
524
+ notes: args.notes,
525
+ },
526
+ ],
527
+ };
528
+ }
529
+ function clonePricingAsApproxFromBase(args) {
530
+ const base = args.basePricing;
531
+ const relation = args.relation ?? "base";
532
+ const extraNote = relation === "fallback"
533
+ ? `Inherited pricing from fallback model: ${args.baseId}`
534
+ : `Inherited pricing from base model: ${args.baseId}`;
535
+ const notes = base.notes ? `${base.notes} | ${extraNote}` : extraNote;
536
+ return {
537
+ currency: base.currency,
538
+ sourceUrl: base.sourceUrl,
539
+ updatedAt: base.updatedAt,
540
+ confidence: "approx",
541
+ notes,
542
+ components: base.components.map((c) => ({ ...c })),
543
+ };
544
+ }
545
+ function tryGetBaseModelIdFromVersionedId(modelId) {
546
+ const id = String(modelId || "").trim();
547
+ if (!id)
548
+ return null;
549
+ // Common vendor patterns:
550
+ // - OpenAI: gpt-4o-2024-11-20
551
+ // - OpenAI: gpt-5.4-mini-2026-03-17
552
+ // - Anthropic: claude-haiku-4-5-20251001
553
+ const m1 = id.match(/^(.*)-\d{4}-\d{2}-\d{2}$/);
554
+ if (m1?.[1])
555
+ return m1[1];
556
+ const m2 = id.match(/^(.*)-\d{8}$/);
557
+ if (m2?.[1])
558
+ return m2[1];
559
+ return null;
560
+ }
561
+ /**
562
+ * Fills pricing gaps by inheriting pricing from the base model when a vendor exposes
563
+ * versioned/dated aliases that share the same pricing.
564
+ *
565
+ * Notes
566
+ * - Inherited pricing is marked as `confidence: "approx"`.
567
+ * - Only applies when a base model is present in the same provider list.
568
+ */
569
+ function fillMissingPricingFromBaseModels(modelsByProvider) {
570
+ const out = {};
571
+ for (const provider of Object.values(provider_contract_1.IntentProvider)) {
572
+ const defs = modelsByProvider[provider] ?? [];
573
+ const pricingById = {};
574
+ for (const def of defs) {
575
+ if (def.pricing)
576
+ pricingById[def.id] = def.pricing;
577
+ }
578
+ const fallbacks = PRICING_FALLBACK_RULES_BY_PROVIDER[provider] ?? [];
579
+ out[provider] = defs.map((def) => {
580
+ if (def.pricing)
581
+ return def;
582
+ const baseId = tryGetBaseModelIdFromVersionedId(def.id);
583
+ if (baseId) {
584
+ const basePricing = pricingById[baseId];
585
+ if (basePricing) {
586
+ return {
587
+ ...def,
588
+ pricing: clonePricingAsApproxFromBase({
589
+ modelId: def.id,
590
+ baseId,
591
+ basePricing,
592
+ relation: "base",
593
+ }),
594
+ };
595
+ }
596
+ }
597
+ for (const rule of fallbacks) {
598
+ if (!rule.match.test(def.id))
599
+ continue;
600
+ const fallbackPricing = pricingById[rule.baseModelId];
601
+ if (!fallbackPricing)
602
+ continue;
603
+ return {
604
+ ...def,
605
+ pricing: clonePricingAsApproxFromBase({
606
+ modelId: def.id,
607
+ baseId: rule.baseModelId,
608
+ basePricing: fallbackPricing,
609
+ relation: "fallback",
610
+ }),
611
+ };
612
+ }
613
+ return def;
614
+ });
615
+ }
616
+ return out;
617
+ }
618
+ function buildProviderModelCatalogAndTypeIndex(modelsByProvider) {
619
+ const intentTypes = Object.values(intent_contract_1.IntentType);
620
+ const catalog = {};
621
+ const idsByType = {};
622
+ for (const provider of Object.values(provider_contract_1.IntentProvider)) {
623
+ catalog[provider] = {};
624
+ const perType = {};
625
+ for (const t of intentTypes)
626
+ perType[t] = [];
627
+ idsByType[provider] = perType;
628
+ const defs = modelsByProvider[provider] ?? [];
629
+ for (const def of defs) {
630
+ catalog[provider][def.id] = def;
631
+ for (const t of def.types) {
632
+ idsByType[provider][t].push(def.id);
633
+ }
634
+ }
635
+ }
636
+ return { catalog, idsByType };
637
+ }
638
+ /**
639
+ * Static utility class for querying the provider model catalog.
640
+ *
641
+ * Designed for client consumption: `ProviderModelRegistry.listProvidersSupportingType(...)`.
642
+ */
643
+ class ProviderModelRegistry {
644
+ /** Canonical catalog view: provider -> modelId -> definition. */
645
+ static catalog = exports.PROVIDER_MODEL_CATALOG;
646
+ /** Primary listing view: provider -> intent type -> model IDs. */
647
+ static idsByProviderAndType = exports.PROVIDER_MODEL_IDS_BY_PROVIDER_AND_TYPE;
648
+ /** Source-of-truth definitions in declared order (useful for UI display). */
649
+ static definitionsByProvider = exports.PROVIDER_MODEL_DEFINITIONS_BY_PROVIDER;
650
+ /** Returns the model definition if present; otherwise null. */
651
+ static getModelDefinition(provider, modelId) {
652
+ return ProviderModelRegistry.catalog[provider]?.[modelId] ?? null;
653
+ }
654
+ /** Lists all model IDs for a provider (stable order as declared in the catalog). */
655
+ static listProviderModelIds(provider) {
656
+ return (ProviderModelRegistry.definitionsByProvider[provider] ?? []).map((m) => m.id);
657
+ }
658
+ /** Lists all model definitions for a provider (stable order as declared in the catalog). */
659
+ static listProviderModels(provider, options) {
660
+ const defs = ProviderModelRegistry.definitionsByProvider[provider] ?? [];
661
+ if (!options?.onlyPublicForCustomers)
662
+ return defs;
663
+ return defs.filter((m) => m.publicForCustomers === true);
664
+ }
665
+ /**
666
+ * Lists all public customer models across all providers.
667
+ *
668
+ * Notes
669
+ * - Uses the catalog declared order (provider order, then per-provider declaration order).
670
+ * - This is a UI/helper surface only; execution still uses provider+modelId.
671
+ */
672
+ static listPublicCustomerModels(options) {
673
+ const out = [];
674
+ for (const provider of Object.values(provider_contract_1.IntentProvider)) {
675
+ const defs = ProviderModelRegistry.listProviderModels(provider, {
676
+ onlyPublicForCustomers: true,
677
+ });
678
+ for (const def of defs) {
679
+ const model = def;
680
+ if (options?.primaryCategory &&
681
+ model.primaryCategory !== options.primaryCategory) {
682
+ continue;
683
+ }
684
+ if (options?.includeCategories?.length) {
685
+ const include = options.includeCategories;
686
+ const hasAny = include.some((c) => model.categories.includes(c));
687
+ if (!hasAny)
688
+ continue;
689
+ }
690
+ out.push({ provider, modelId: model.id, model });
691
+ }
692
+ }
693
+ return out;
694
+ }
695
+ /**
696
+ * Groups all public customer models by their primaryCategory.
697
+ *
698
+ * Intended for the "simple UI" mode where the UI shows high-level DCDR groups.
699
+ */
700
+ static listPublicCustomerModelsByPrimaryCategory() {
701
+ const out = {};
702
+ for (const c of Object.values(DcdrPublicModelCategory)) {
703
+ out[c] = [];
704
+ }
705
+ for (const item of ProviderModelRegistry.listPublicCustomerModels()) {
706
+ out[item.model.primaryCategory].push(item);
707
+ }
708
+ return out;
709
+ }
710
+ /** Lists model IDs for a provider that support a given IntentType. */
711
+ static listProviderModelIdsForType(provider, type) {
712
+ return ProviderModelRegistry.idsByProviderAndType[provider]?.[type] ?? [];
713
+ }
714
+ /** Lists model definitions for a provider that support a given IntentType. */
715
+ static listProviderModelsForType(provider, type) {
716
+ const ids = ProviderModelRegistry.listProviderModelIdsForType(provider, type);
717
+ return ids
718
+ .map((id) => ProviderModelRegistry.getModelDefinition(provider, id))
719
+ .filter((m) => m !== null);
720
+ }
721
+ /** Returns true if the provider has at least one model for the given IntentType. */
722
+ static providerSupportsType(provider, type) {
723
+ return (ProviderModelRegistry.listProviderModelIdsForType(provider, type).length >
724
+ 0);
725
+ }
726
+ /** Returns true if the model supports the given IntentType (based on the catalog). */
727
+ static modelSupportsType(provider, modelId, type) {
728
+ const def = ProviderModelRegistry.getModelDefinition(provider, modelId);
729
+ if (!def)
730
+ return false;
731
+ return def.types.includes(type);
732
+ }
733
+ /** Lists all providers that have at least one model supporting the given IntentType. */
734
+ static listProvidersSupportingType(type) {
735
+ return Object.values(provider_contract_1.IntentProvider).filter((p) => ProviderModelRegistry.providerSupportsType(p, type));
736
+ }
737
+ /** Returns all model IDs across all providers for a given type. */
738
+ static listAllModelIdsForType(type) {
739
+ const out = [];
740
+ for (const provider of Object.values(provider_contract_1.IntentProvider)) {
741
+ for (const modelId of ProviderModelRegistry.listProviderModelIdsForType(provider, type)) {
742
+ out.push({ provider, modelId });
743
+ }
744
+ }
745
+ return out;
746
+ }
747
+ /** Convenience: get unified pricing if present (or null if not set/unknown). */
748
+ static getModelPricing(provider, modelId) {
749
+ return (ProviderModelRegistry.getModelDefinition(provider, modelId)?.pricing ??
750
+ null);
751
+ }
752
+ /** Get a specific pricing component from a model by kind (or null if absent). */
753
+ static getPricingComponent(provider, modelId, kind) {
754
+ const pricing = ProviderModelRegistry.getModelPricing(provider, modelId);
755
+ if (!pricing)
756
+ return null;
757
+ const found = pricing.components.find((c) => c.kind === kind);
758
+ return found ?? null;
759
+ }
760
+ /** Convenience: token pricing (per MTok) if present. */
761
+ static getTokenPricing(provider, modelId) {
762
+ return ProviderModelRegistry.getPricingComponent(provider, modelId, "tokens");
763
+ }
764
+ }
765
+ exports.ProviderModelRegistry = ProviderModelRegistry;