@codeworksh/aikit 0.7.2 → 0.8.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/llm/failure.d.mts CHANGED
@@ -1,2 +1,2 @@
1
- import { _ as Unavailable, a as Authorization, c as Failure, d as InvalidResponse, f as ModelUnavailable, g as Transport, h as Timeout, i as Authentication, l as FailureSchema, m as RateLimit, n as fromMessage, o as Configuration, p as Quota, r as normalize, s as ContentPolicy, u as InvalidRequest, v as Unknown, y as isFailure } from "../failure-C0lCOdFE.mjs";
1
+ import { _ as Unavailable, a as Authorization, c as Failure, d as InvalidResponse, f as ModelUnavailable, g as Transport, h as Timeout, i as Authentication, l as FailureSchema, m as RateLimit, n as fromMessage, o as Configuration, p as Quota, r as normalize, s as ContentPolicy, u as InvalidRequest, v as Unknown, y as isFailure } from "../failure-5Wjd-qFH.mjs";
2
2
  export { Authentication, Authorization, Configuration, ContentPolicy, Failure, FailureSchema, InvalidRequest, InvalidResponse, ModelUnavailable, Quota, RateLimit, Timeout, Transport, Unavailable, Unknown, fromMessage, isFailure, normalize };
package/llm/failure.mjs CHANGED
@@ -1,2 +1,3 @@
1
- import { _ as Unknown, a as Authorization, c as FailureSchema, d as ModelUnavailable, f as Quota, g as Unavailable, h as Transport, i as Authentication, l as InvalidRequest, m as Timeout, n as fromMessage, o as Configuration, p as RateLimit, r as normalize, s as ContentPolicy, u as InvalidResponse, v as isFailure } from "../failure-xra3YPdY.mjs";
1
+ import { a as FailureSchema, c as ModelUnavailable, d as Timeout, f as Transport, h as isFailure, i as ContentPolicy, l as Quota, m as Unknown, n as Authorization, o as InvalidRequest, p as Unavailable, r as Configuration, s as InvalidResponse, t as Authentication, u as RateLimit } from "../schema-rXSoWhic.mjs";
2
+ import { n as fromMessage, r as normalize } from "../failure-SAPyG-w2.mjs";
2
3
  export { Authentication, Authorization, Configuration, ContentPolicy, FailureSchema, InvalidRequest, InvalidResponse, ModelUnavailable, Quota, RateLimit, Timeout, Transport, Unavailable, Unknown, fromMessage, isFailure, normalize };
@@ -0,0 +1,453 @@
1
+ import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.mjs";
2
+ import Type$1 from "typebox";
3
+ import { join, resolve } from "node:path";
4
+ import { dirname } from "path";
5
+ import { mkdir, readFile, writeFile } from "fs/promises";
6
+ //#region src/utils/lazy.ts
7
+ function lazy(fn) {
8
+ let value;
9
+ let loaded = false;
10
+ const result = () => {
11
+ if (loaded) return value;
12
+ value = fn();
13
+ loaded = true;
14
+ return value;
15
+ };
16
+ result.reset = () => {
17
+ loaded = false;
18
+ value = void 0;
19
+ };
20
+ return result;
21
+ }
22
+ //#endregion
23
+ //#region src/utils/error.ts
24
+ var NamedError = class NamedError extends Error {
25
+ static create(name, data) {
26
+ const schema = {
27
+ $id: name,
28
+ type: "object",
29
+ required: ["name", "data"],
30
+ properties: {
31
+ name: { const: name },
32
+ data
33
+ }
34
+ };
35
+ const result = class extends NamedError {
36
+ static Schema = schema;
37
+ name = name;
38
+ data;
39
+ constructor(data, options) {
40
+ super(name, options);
41
+ this.data = data;
42
+ this.name = name;
43
+ }
44
+ static isInstance(input) {
45
+ return typeof input === "object" && input !== null && "name" in input && input.name === name;
46
+ }
47
+ schema() {
48
+ return schema;
49
+ }
50
+ toObject() {
51
+ return {
52
+ name,
53
+ data: this.data
54
+ };
55
+ }
56
+ };
57
+ Object.defineProperty(result, "name", { value: name });
58
+ return result;
59
+ }
60
+ static Unknown = NamedError.create("UnknownError", {
61
+ type: "object",
62
+ required: ["message"],
63
+ properties: { message: { type: "string" } }
64
+ });
65
+ };
66
+ //#endregion
67
+ //#region src/utils/filesystem.ts
68
+ async function readText(path) {
69
+ return readFile(path, "utf-8");
70
+ }
71
+ async function readJson(path) {
72
+ return JSON.parse(await readFile(path, "utf-8"));
73
+ }
74
+ function isEnoent(error) {
75
+ return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
76
+ }
77
+ async function write(path, content, mode) {
78
+ try {
79
+ if (mode) await writeFile(path, content, { mode });
80
+ else await writeFile(path, content);
81
+ } catch (error) {
82
+ if (isEnoent(error)) {
83
+ await mkdir(dirname(path), { recursive: true });
84
+ if (mode) await writeFile(path, content, { mode });
85
+ else await writeFile(path, content);
86
+ return;
87
+ }
88
+ throw error;
89
+ }
90
+ }
91
+ async function writeJson(path, data, mode) {
92
+ return write(path, JSON.stringify(data, null, 2), mode);
93
+ }
94
+ //#endregion
95
+ //#region src/model/catalog.ts
96
+ const KnownProviderEnum$1 = {
97
+ anthropic: "anthropic",
98
+ google: "google",
99
+ googleVertex: "google-vertex",
100
+ googleVertexAnthropic: "google-vertex-anthropic",
101
+ openai: "openai",
102
+ openaiCompatible: "openai-compatible",
103
+ openaiCodex: "openai-codex",
104
+ openrouter: "openrouter",
105
+ xai: "xai"
106
+ };
107
+ const KnownProviderEnumSchema$1 = Type$1.Union([
108
+ Type$1.Literal(KnownProviderEnum$1.anthropic),
109
+ Type$1.Literal(KnownProviderEnum$1.google),
110
+ Type$1.Literal(KnownProviderEnum$1.googleVertex),
111
+ Type$1.Literal(KnownProviderEnum$1.googleVertexAnthropic),
112
+ Type$1.Literal(KnownProviderEnum$1.openai),
113
+ Type$1.Literal(KnownProviderEnum$1.openaiCompatible),
114
+ Type$1.Literal(KnownProviderEnum$1.openaiCodex),
115
+ Type$1.Literal(KnownProviderEnum$1.openrouter),
116
+ Type$1.Literal(KnownProviderEnum$1.xai)
117
+ ]);
118
+ const ModelCatalogLoadError$1 = NamedError.create("ModelCatalogLoadError", Type$1.Object({
119
+ path: Type$1.String(),
120
+ reason: Type$1.Union([
121
+ Type$1.Literal("missing"),
122
+ Type$1.Literal("unreadable"),
123
+ Type$1.Literal("empty"),
124
+ Type$1.Literal("invalid")
125
+ ]),
126
+ message: Type$1.String()
127
+ }));
128
+ function projectRoot() {
129
+ return process.cwd();
130
+ }
131
+ function path() {
132
+ return resolve(process.env.CODEWORK_MODELS_FILE ?? join(projectRoot(), "models.gen.json"));
133
+ }
134
+ async function load(catalogPath = path()) {
135
+ let content;
136
+ try {
137
+ content = await readText(catalogPath);
138
+ } catch (cause) {
139
+ const reason = (typeof cause === "object" && cause !== null && "code" in cause && typeof cause.code === "string" ? cause.code : void 0) === "ENOENT" ? "missing" : "unreadable";
140
+ throw new ModelCatalogLoadError$1({
141
+ path: catalogPath,
142
+ reason,
143
+ message: reason === "missing" ? `model catalog not found at ${catalogPath}` : `model catalog could not be read at ${catalogPath}`
144
+ }, { cause });
145
+ }
146
+ if (!content.trim()) throw new ModelCatalogLoadError$1({
147
+ path: catalogPath,
148
+ reason: "empty",
149
+ message: `model catalog is empty at ${catalogPath}`
150
+ });
151
+ try {
152
+ const parsed = JSON.parse(content);
153
+ if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) throw new Error("expected an object");
154
+ return parsed;
155
+ } catch (cause) {
156
+ throw new ModelCatalogLoadError$1({
157
+ path: catalogPath,
158
+ reason: "invalid",
159
+ message: `model catalog contains invalid json at ${catalogPath}`
160
+ }, { cause });
161
+ }
162
+ }
163
+ const data = lazy(() => load());
164
+ async function get() {
165
+ return data();
166
+ }
167
+ //#endregion
168
+ //#region src/model/model.ts
169
+ var model_exports = /* @__PURE__ */ __exportAll({
170
+ APIMetadataSchema: () => APIMetadataSchema,
171
+ APIMethodEnum: () => APIMethodEnum,
172
+ APIMethodEnumSchema: () => APIMethodEnumSchema,
173
+ ActiveThinkingLevel: () => ActiveThinkingLevel,
174
+ CompatibilitySchema: () => CompatibilitySchema,
175
+ ExtrasSchema: () => ExtrasSchema,
176
+ Info: () => Info,
177
+ KnownProviderEnum: () => KnownProviderEnum,
178
+ KnownProviderEnumSchema: () => KnownProviderEnumSchema,
179
+ ModelCatalogLoadError: () => ModelCatalogLoadError,
180
+ ProviderInfo: () => ProviderInfo,
181
+ Schema: () => Schema,
182
+ ThinkingBudgets: () => ThinkingBudgets,
183
+ ThinkingLevel: () => ThinkingLevel,
184
+ ThinkingLevelEnum: () => ThinkingLevelEnum,
185
+ ThinkingLevelMapSchema: () => ThinkingLevelMapSchema,
186
+ calculateCost: () => calculateCost,
187
+ clampThinkingLevel: () => clampThinkingLevel,
188
+ getBuiltInModels: () => getBuiltInModels,
189
+ getModel: () => getModel,
190
+ getModels: () => getModels,
191
+ getProviders: () => getProviders,
192
+ getSupportedThinkingLevels: () => getSupportedThinkingLevels,
193
+ modelsAreEqual: () => modelsAreEqual,
194
+ normalizeInput: () => normalizeInput,
195
+ optionsKey: () => optionsKey,
196
+ registry: () => registry,
197
+ supportsProtocol: () => supportsProtocol,
198
+ thinkingTokenBudgetField: () => thinkingTokenBudgetField
199
+ });
200
+ const KnownProviderEnum = KnownProviderEnum$1;
201
+ const KnownProviderEnumSchema = KnownProviderEnumSchema$1;
202
+ const ModelCatalogLoadError = ModelCatalogLoadError$1;
203
+ const ThinkingLevelEnum = {
204
+ off: "off",
205
+ minimal: "minimal",
206
+ low: "low",
207
+ medium: "medium",
208
+ high: "high",
209
+ xhigh: "xhigh",
210
+ max: "max"
211
+ };
212
+ const ThinkingLevel = Type$1.Union([
213
+ Type$1.Literal(ThinkingLevelEnum.off),
214
+ Type$1.Literal(ThinkingLevelEnum.minimal),
215
+ Type$1.Literal(ThinkingLevelEnum.low),
216
+ Type$1.Literal(ThinkingLevelEnum.medium),
217
+ Type$1.Literal(ThinkingLevelEnum.high),
218
+ Type$1.Literal(ThinkingLevelEnum.xhigh),
219
+ Type$1.Literal(ThinkingLevelEnum.max)
220
+ ]);
221
+ const ActiveThinkingLevel = Type$1.Union([
222
+ Type$1.Literal(ThinkingLevelEnum.minimal),
223
+ Type$1.Literal(ThinkingLevelEnum.low),
224
+ Type$1.Literal(ThinkingLevelEnum.medium),
225
+ Type$1.Literal(ThinkingLevelEnum.high),
226
+ Type$1.Literal(ThinkingLevelEnum.xhigh),
227
+ Type$1.Literal(ThinkingLevelEnum.max)
228
+ ]);
229
+ const ThinkingBudgets = Type$1.Partial(Type$1.Record(ActiveThinkingLevel, Type$1.Number()));
230
+ const ACTIVE_THINKING_LEVELS = [
231
+ ThinkingLevelEnum.minimal,
232
+ ThinkingLevelEnum.low,
233
+ ThinkingLevelEnum.medium,
234
+ ThinkingLevelEnum.high,
235
+ ThinkingLevelEnum.xhigh,
236
+ ThinkingLevelEnum.max
237
+ ];
238
+ const MODEL_THINKING_LEVELS = [ThinkingLevelEnum.off, ...ACTIVE_THINKING_LEVELS];
239
+ const ProviderInfo = Type$1.Object({
240
+ id: Type$1.String(),
241
+ name: Type$1.String(),
242
+ source: Type$1.Enum([
243
+ "env",
244
+ "config",
245
+ "custom",
246
+ "api",
247
+ "unknown"
248
+ ]),
249
+ env: Type$1.Array(Type$1.String()),
250
+ key: Type$1.Optional(Type$1.String()),
251
+ options: Type$1.Optional(Type$1.Record(Type$1.String(), Type$1.Any()))
252
+ });
253
+ const InputSchema = Type$1.Array(Type$1.Union([Type$1.Literal("text"), Type$1.Literal("image")]));
254
+ const CostRatesSchema = Type$1.Object({
255
+ input: Type$1.Number(),
256
+ output: Type$1.Number(),
257
+ cacheRead: Type$1.Number(),
258
+ cacheWrite: Type$1.Number()
259
+ });
260
+ const CostTierSchema = Type$1.Object({
261
+ ...CostRatesSchema.properties,
262
+ inputTokensAbove: Type$1.Number()
263
+ });
264
+ const CostSchema = Type$1.Object({
265
+ ...CostRatesSchema.properties,
266
+ tiers: Type$1.Optional(Type$1.Array(CostTierSchema)),
267
+ serviceTierMultipliers: Type$1.Optional(Type$1.Record(Type$1.String(), Type$1.Number()))
268
+ });
269
+ const SupportedProtocolsSchema = Type$1.Partial(Type$1.Object({
270
+ anthropic: KnownProviderEnumSchema,
271
+ google: KnownProviderEnumSchema,
272
+ googleVertex: KnownProviderEnumSchema,
273
+ googleVertexAnthropic: KnownProviderEnumSchema,
274
+ openai: KnownProviderEnumSchema,
275
+ openaiCompatible: KnownProviderEnumSchema,
276
+ openaiCodex: KnownProviderEnumSchema,
277
+ openrouter: KnownProviderEnumSchema,
278
+ xai: KnownProviderEnumSchema
279
+ }));
280
+ const APIMethodEnum = {
281
+ languageModel: "languageModel",
282
+ chat: "chat",
283
+ completion: "completion",
284
+ completionModel: "completionModel",
285
+ messages: "messages",
286
+ responses: "responses"
287
+ };
288
+ const APIMethodEnumSchema = Type$1.Union([
289
+ Type$1.Literal(APIMethodEnum.languageModel),
290
+ Type$1.Literal(APIMethodEnum.chat),
291
+ Type$1.Literal(APIMethodEnum.completion),
292
+ Type$1.Literal(APIMethodEnum.completionModel),
293
+ Type$1.Literal(APIMethodEnum.messages),
294
+ Type$1.Literal(APIMethodEnum.responses)
295
+ ]);
296
+ const APIMetadataSchema = Type$1.Object({
297
+ id: Type$1.Optional(Type$1.String()),
298
+ url: Type$1.Optional(Type$1.String()),
299
+ method: Type$1.Optional(APIMethodEnumSchema)
300
+ });
301
+ const ThinkingLevelMapSchema = Type$1.Partial(Type$1.Record(ThinkingLevel, Type$1.Union([Type$1.String(), Type$1.Null()])));
302
+ const CompatibilitySchema = Type$1.Object({
303
+ /** The Google protocol accepts thinking levels rather than a token budget. */
304
+ supportsThinkingLevel: Type$1.Optional(Type$1.Boolean()),
305
+ supportsToolSearch: Type$1.Optional(Type$1.Boolean()),
306
+ supportsAdditionalTools: Type$1.Optional(Type$1.Boolean()),
307
+ supportsStrictMode: Type$1.Optional(Type$1.Boolean()),
308
+ supportsOpenAIGrammarTools: Type$1.Optional(Type$1.Boolean()),
309
+ /** The model takes a thinking-token budget as a top-level request field. */
310
+ supportsThinkingTokenBudget: Type$1.Optional(Type$1.Boolean()),
311
+ /** Claude model that sizes its own thinking, driven by `effort` instead of a token budget. */
312
+ forceAdaptiveThinking: Type$1.Optional(Type$1.Boolean()),
313
+ /** Name of that field, when it is not the conventional `thinking_token_budget`. */
314
+ thinkingTokenBudgetField: Type$1.Optional(Type$1.String())
315
+ });
316
+ const Schema = Type$1.Object({
317
+ id: Type$1.String(),
318
+ name: Type$1.String(),
319
+ provider: ProviderInfo,
320
+ baseUrl: Type$1.String(),
321
+ reasoning: Type$1.Boolean(),
322
+ thinkingLevelMap: Type$1.Optional(ThinkingLevelMapSchema),
323
+ /** Default budgets; request-level thinkingBudgets take precedence. */
324
+ thinkingBudgets: Type$1.Optional(ThinkingBudgets),
325
+ input: InputSchema,
326
+ cost: CostSchema,
327
+ contextWindow: Type$1.Number(),
328
+ maxTokens: Type$1.Number(),
329
+ headers: Type$1.Optional(Type$1.Record(Type$1.String(), Type$1.String())),
330
+ npm: Type$1.Optional(Type$1.String()),
331
+ api: Type$1.Optional(APIMetadataSchema),
332
+ providerOptionsKey: Type$1.Optional(Type$1.String()),
333
+ options: Type$1.Optional(Type$1.Record(Type$1.String(), Type$1.Unknown())),
334
+ providerOptions: Type$1.Optional(Type$1.Record(Type$1.String(), Type$1.Unknown())),
335
+ compat: Type$1.Optional(CompatibilitySchema),
336
+ protocol: KnownProviderEnumSchema,
337
+ supportedProtocols: Type$1.Optional(SupportedProtocolsSchema)
338
+ });
339
+ const ExtrasSchema = Type$1.Object({});
340
+ const Info = Type$1.Evaluate(Type$1.Intersect([Schema, ExtrasSchema]));
341
+ function calculateCost(model, usage) {
342
+ const inputTokens = usage.input + usage.cacheRead + usage.cacheWrite;
343
+ let rates = model.cost;
344
+ let matchedThreshold = -1;
345
+ for (const tier of model.cost.tiers ?? []) if (inputTokens > tier.inputTokensAbove && tier.inputTokensAbove > matchedThreshold) {
346
+ rates = tier;
347
+ matchedThreshold = tier.inputTokensAbove;
348
+ }
349
+ const longWrite = usage.cacheWrite1h ?? 0;
350
+ const shortWrite = usage.cacheWrite - longWrite;
351
+ usage.cost.input = usage.input / 1e6 * rates.input;
352
+ usage.cost.output = usage.output / 1e6 * rates.output;
353
+ usage.cost.cacheRead = usage.cacheRead / 1e6 * rates.cacheRead;
354
+ usage.cost.cacheWrite = (rates.cacheWrite * shortWrite + rates.input * 2 * longWrite) / 1e6;
355
+ usage.cost.total = usage.cost.input + usage.cost.output + usage.cost.cacheRead + usage.cost.cacheWrite;
356
+ }
357
+ function normalizeInput(input) {
358
+ const normalized = /* @__PURE__ */ new Set();
359
+ for (const modality of input ?? ["text"]) if (modality === "text" || modality === "image") normalized.add(modality);
360
+ if (normalized.size === 0) normalized.add("text");
361
+ return [...normalized];
362
+ }
363
+ async function getBuiltInModels() {
364
+ return await get();
365
+ }
366
+ const registry = lazy(async () => {
367
+ const registry = /* @__PURE__ */ new Map();
368
+ const models = await getBuiltInModels();
369
+ for (const [provider, value] of Object.entries(models)) {
370
+ const providerModels = /* @__PURE__ */ new Map();
371
+ for (const [id, model] of Object.entries(value)) providerModels.set(id, model);
372
+ registry.set(provider, providerModels);
373
+ }
374
+ return registry;
375
+ });
376
+ /**
377
+ * The key a provider's own option bag is filed under.
378
+ *
379
+ * Providers that speak another provider's protocol still carry their own option
380
+ * namespace, so this is not always the protocol.
381
+ */
382
+ /**
383
+ * The request-body field a model takes its thinking-token budget in, if any.
384
+ *
385
+ * OpenAI-compatible endpoints have no standard place for this, so each one names
386
+ * its own field; a bare `supportsThinkingTokenBudget` means the conventional name.
387
+ */
388
+ function thinkingTokenBudgetField(model) {
389
+ if (model.compat?.thinkingTokenBudgetField) return model.compat.thinkingTokenBudgetField;
390
+ return model.compat?.supportsThinkingTokenBudget ? "thinking_token_budget" : void 0;
391
+ }
392
+ function optionsKey(model) {
393
+ return model.providerOptionsKey ?? model.protocol;
394
+ }
395
+ function supportsProtocol(model, protocol) {
396
+ if (model.protocol === protocol) return true;
397
+ return Object.values(model.supportedProtocols ?? {}).includes(protocol);
398
+ }
399
+ async function getModel(provider, model, overrides) {
400
+ const result = (await registry()).get(provider)?.get(model);
401
+ if (result && overrides) {
402
+ if (overrides.protocol && !supportsProtocol(result, overrides.protocol)) return;
403
+ return {
404
+ ...result,
405
+ ...overrides
406
+ };
407
+ }
408
+ return result;
409
+ }
410
+ async function getProviders() {
411
+ const data = await registry();
412
+ return Array.from(data.keys());
413
+ }
414
+ async function getModels(provider) {
415
+ const models = (await registry()).get(provider);
416
+ return models ? Array.from(models.values()) : [];
417
+ }
418
+ /**
419
+ * Check if two models are equal by comparing both their id and provider id.
420
+ * Returns false if either model is null or undefined.
421
+ */
422
+ function modelsAreEqual(a, b) {
423
+ if (!a || !b) return false;
424
+ return a.id === b.id && a.provider.id === b.provider.id;
425
+ }
426
+ function getSupportedThinkingLevels(model) {
427
+ if (!model.reasoning) return ["off"];
428
+ return MODEL_THINKING_LEVELS.filter((level) => {
429
+ const mapped = model.thinkingLevelMap?.[level];
430
+ if (mapped === null) return false;
431
+ if (level === "xhigh" || level === "max") return mapped !== void 0;
432
+ return true;
433
+ });
434
+ }
435
+ function clampThinkingLevel(model, level) {
436
+ const availableLevels = getSupportedThinkingLevels(model);
437
+ if (availableLevels.includes(level)) return level;
438
+ const requestedIndex = MODEL_THINKING_LEVELS.indexOf(level);
439
+ if (requestedIndex === -1) return availableLevels[0] ?? "off";
440
+ for (let i = requestedIndex; i < MODEL_THINKING_LEVELS.length; i++) {
441
+ const candidate = MODEL_THINKING_LEVELS[i];
442
+ if (availableLevels.includes(candidate)) return candidate;
443
+ }
444
+ for (let i = requestedIndex - 1; i >= 0; i--) {
445
+ const candidate = MODEL_THINKING_LEVELS[i];
446
+ if (availableLevels.includes(candidate)) return candidate;
447
+ }
448
+ return availableLevels[0] ?? "off";
449
+ }
450
+ //#endregion
451
+ export { lazy as C, NamedError as S, registry as _, KnownProviderEnumSchema as a, readJson as b, calculateCost as c, getModels as d, getProviders as f, optionsKey as g, normalizeInput as h, KnownProviderEnum as i, clampThinkingLevel as l, modelsAreEqual as m, APIMethodEnumSchema as n, ProviderInfo as o, model_exports as p, ActiveThinkingLevel as r, ThinkingBudgets as s, APIMethodEnum as t, getModel as u, thinkingTokenBudgetField as v, writeJson as x, path as y };
452
+
453
+ //# sourceMappingURL=model-CBnredXj.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-CBnredXj.mjs","names":["KnownProviderEnum","KnownProviderEnumSchema","Type","ModelCatalogLoadError","Filesystem.readText","ModelCatalog.KnownProviderEnum","ModelCatalog.KnownProviderEnumSchema","ModelCatalog.ModelCatalogLoadError","Type","ModelCatalog.get"],"sources":["../../src/utils/lazy.ts","../../src/utils/error.ts","../../src/utils/filesystem.ts","../../src/model/catalog.ts","../../src/model/model.ts"],"sourcesContent":["export function lazy<T>(fn: () => T) {\n\tlet value: T | undefined;\n\tlet loaded = false;\n\n\tconst result = (): T => {\n\t\tif (loaded) return value as T;\n\t\tvalue = fn();\n\t\tloaded = true;\n\t\treturn value as T;\n\t};\n\n\tresult.reset = () => {\n\t\tloaded = false;\n\t\tvalue = undefined;\n\t};\n\n\treturn result;\n}\n","import type { Static, TSchema } from \"typebox\";\n\ntype SchemaLike = TSchema;\ntype StaticData<Data extends SchemaLike> = Static<Data>;\n\nexport abstract class NamedError extends Error {\n\tabstract schema(): SchemaLike;\n\tabstract toObject(): { name: string; data: unknown };\n\n\tstatic create<Name extends string, Data extends SchemaLike>(name: Name, data: Data) {\n\t\tconst schema = {\n\t\t\t$id: name,\n\t\t\ttype: \"object\",\n\t\t\trequired: [\"name\", \"data\"],\n\t\t\tproperties: {\n\t\t\t\tname: {\n\t\t\t\t\tconst: name,\n\t\t\t\t},\n\t\t\t\tdata,\n\t\t\t},\n\t\t} as const;\n\n\t\tconst result = class extends NamedError {\n\t\t\tpublic static readonly Schema = schema;\n\n\t\t\tpublic override readonly name = name as Name;\n\n\t\t\tpublic readonly data: StaticData<Data>;\n\n\t\t\tconstructor(data: StaticData<Data>, options?: ErrorOptions) {\n\t\t\t\tsuper(name, options);\n\t\t\t\tthis.data = data;\n\t\t\t\tthis.name = name;\n\t\t\t}\n\n\t\t\tstatic isInstance(input: unknown): input is InstanceType<typeof result> {\n\t\t\t\treturn typeof input === \"object\" && input !== null && \"name\" in input && input.name === name;\n\t\t\t}\n\n\t\t\tschema() {\n\t\t\t\treturn schema;\n\t\t\t}\n\n\t\t\ttoObject() {\n\t\t\t\treturn {\n\t\t\t\t\tname,\n\t\t\t\t\tdata: this.data,\n\t\t\t\t};\n\t\t\t}\n\t\t};\n\n\t\tObject.defineProperty(result, \"name\", { value: name });\n\t\treturn result;\n\t}\n\n\tpublic static readonly Unknown = NamedError.create(\"UnknownError\", {\n\t\ttype: \"object\",\n\t\trequired: [\"message\"],\n\t\tproperties: {\n\t\t\tmessage: {\n\t\t\t\ttype: \"string\",\n\t\t\t},\n\t\t},\n\t});\n}\n","import { dirname } from \"path\";\nimport { mkdir, readFile, writeFile } from \"fs/promises\";\n\nexport async function readText(path: string): Promise<string> {\n\treturn readFile(path, \"utf-8\");\n}\n\nexport async function readJson<T = unknown>(path: string): Promise<T> {\n\treturn JSON.parse(await readFile(path, \"utf-8\"));\n}\n\nfunction isEnoent(error: unknown): error is { code: \"ENOENT\" } {\n\treturn (\n\t\ttypeof error === \"object\" && error !== null && \"code\" in error && (error as { code: string }).code === \"ENOENT\"\n\t);\n}\n\nexport async function write(path: string, content: string | Buffer | Uint8Array, mode?: number): Promise<void> {\n\ttry {\n\t\tif (mode) {\n\t\t\tawait writeFile(path, content, { mode });\n\t\t} else {\n\t\t\tawait writeFile(path, content);\n\t\t}\n\t} catch (error) {\n\t\tif (isEnoent(error)) {\n\t\t\tawait mkdir(dirname(path), { recursive: true });\n\t\t\tif (mode) {\n\t\t\t\tawait writeFile(path, content, { mode });\n\t\t\t} else {\n\t\t\t\tawait writeFile(path, content);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tthrow error;\n\t}\n}\n\nexport async function writeJson(path: string, data: unknown, mode?: number): Promise<void> {\n\treturn write(path, JSON.stringify(data, null, 2), mode);\n}\n","import { join, resolve } from \"node:path\";\nimport Type, { type Static } from \"typebox\";\nimport { NamedError } from \"../utils/error.ts\";\nimport * as Filesystem from \"../utils/filesystem.ts\";\nimport { lazy } from \"../utils/lazy.ts\";\n\n// known AI SDK LLM providers\n// used as the public protocol discriminator for the AI SDK transport layer\nexport const KnownProviderEnum = {\n\tanthropic: \"anthropic\",\n\tgoogle: \"google\",\n\tgoogleVertex: \"google-vertex\",\n\tgoogleVertexAnthropic: \"google-vertex-anthropic\",\n\topenai: \"openai\",\n\topenaiCompatible: \"openai-compatible\",\n\topenaiCodex: \"openai-codex\",\n\topenrouter: \"openrouter\",\n\txai: \"xai\",\n} as const;\nexport const KnownProviderEnumSchema = Type.Union([\n\tType.Literal(KnownProviderEnum.anthropic),\n\tType.Literal(KnownProviderEnum.google),\n\tType.Literal(KnownProviderEnum.googleVertex),\n\tType.Literal(KnownProviderEnum.googleVertexAnthropic),\n\tType.Literal(KnownProviderEnum.openai),\n\tType.Literal(KnownProviderEnum.openaiCompatible),\n\tType.Literal(KnownProviderEnum.openaiCodex),\n\tType.Literal(KnownProviderEnum.openrouter),\n\tType.Literal(KnownProviderEnum.xai),\n]);\nexport type KnownProviderEnum = Static<typeof KnownProviderEnumSchema>;\n\nexport type GeneratedCatalog = Partial<Record<string, Record<string, unknown>>>;\ntype LazyGeneratedCatalog = ReturnType<typeof lazy<Promise<GeneratedCatalog>>>;\n\nexport const ModelCatalogLoadError = NamedError.create(\n\t\"ModelCatalogLoadError\",\n\tType.Object({\n\t\tpath: Type.String(),\n\t\treason: Type.Union([\n\t\t\tType.Literal(\"missing\"),\n\t\t\tType.Literal(\"unreadable\"),\n\t\t\tType.Literal(\"empty\"),\n\t\t\tType.Literal(\"invalid\"),\n\t\t]),\n\t\tmessage: Type.String(),\n\t}),\n);\nexport type ModelCatalogLoadError = InstanceType<typeof ModelCatalogLoadError>;\n\nexport function projectRoot(): string {\n\treturn process.cwd();\n}\n\nexport const filename = \"models.gen.json\";\nexport function path(): string {\n\treturn resolve(process.env.CODEWORK_MODELS_FILE ?? join(projectRoot(), filename));\n}\n\nexport async function load(catalogPath = path()): Promise<GeneratedCatalog> {\n\tlet content: string;\n\ttry {\n\t\tcontent = await Filesystem.readText(catalogPath);\n\t} catch (cause) {\n\t\tconst value =\n\t\t\ttypeof cause === \"object\" && cause !== null && \"code\" in cause && typeof cause.code === \"string\"\n\t\t\t\t? cause.code\n\t\t\t\t: undefined;\n\t\tconst reason = value === \"ENOENT\" ? \"missing\" : \"unreadable\";\n\t\tthrow new ModelCatalogLoadError(\n\t\t\t{\n\t\t\t\tpath: catalogPath,\n\t\t\t\treason,\n\t\t\t\tmessage:\n\t\t\t\t\treason === \"missing\"\n\t\t\t\t\t\t? `model catalog not found at ${catalogPath}`\n\t\t\t\t\t\t: `model catalog could not be read at ${catalogPath}`,\n\t\t\t},\n\t\t\t{ cause },\n\t\t);\n\t}\n\tif (!content.trim()) {\n\t\tthrow new ModelCatalogLoadError({\n\t\t\tpath: catalogPath,\n\t\t\treason: \"empty\",\n\t\t\tmessage: `model catalog is empty at ${catalogPath}`,\n\t\t});\n\t}\n\ttry {\n\t\tconst parsed: unknown = JSON.parse(content);\n\t\tif (typeof parsed !== \"object\" || parsed === null || Array.isArray(parsed)) throw new Error(\"expected an object\");\n\t\treturn parsed as GeneratedCatalog;\n\t} catch (cause) {\n\t\tthrow new ModelCatalogLoadError(\n\t\t\t{\n\t\t\t\tpath: catalogPath,\n\t\t\t\treason: \"invalid\",\n\t\t\t\tmessage: `model catalog contains invalid json at ${catalogPath}`,\n\t\t\t},\n\t\t\t{ cause },\n\t\t);\n\t}\n}\n\nexport const data: LazyGeneratedCatalog = lazy(() => load());\n\nexport async function get(): Promise<GeneratedCatalog> {\n\treturn data();\n}\n","import Type, { type Static } from \"typebox\";\nimport { lazy } from \"../utils/lazy.ts\";\nimport * as ModelCatalog from \"./catalog.ts\";\n\n// re-export\nexport const KnownProviderEnum = ModelCatalog.KnownProviderEnum;\nexport const KnownProviderEnumSchema = ModelCatalog.KnownProviderEnumSchema;\nexport type KnownProviderEnum = ModelCatalog.KnownProviderEnum;\n\nexport const ModelCatalogLoadError = ModelCatalog.ModelCatalogLoadError;\nexport type ModelCatalogLoadError = ModelCatalog.ModelCatalogLoadError;\n\n// Common reasoning-effort levels used by adapters that expose model reasoning,\n// thinking, or deliberation controls. Protocol-specific layers can map these\n// values to native fields like OpenAI `reasoning_effort`, Anthropic `thinking`,\n// or Gemini `thinkingConfig`.\nexport const ThinkingLevelEnum = {\n\t// Disable explicit reasoning controls when the provider supports turning them off.\n\toff: \"off\",\n\t// Smallest reasoning budget/effort above off; useful for fastest low-cost responses.\n\tminimal: \"minimal\",\n\t// Light reasoning for simple tasks that still benefit from some deliberation.\n\tlow: \"low\",\n\t// Balanced default for general tasks.\n\tmedium: \"medium\",\n\t// Higher reasoning effort for complex coding, analysis, or planning.\n\thigh: \"high\",\n\t// Extra-high reasoning effort for difficult tasks when supported by the model.\n\txhigh: \"xhigh\",\n\t// Maximum provider-defined effort above xhigh when explicitly supported by the model.\n\tmax: \"max\",\n} as const;\n\nexport const ThinkingLevel = Type.Union([\n\tType.Literal(ThinkingLevelEnum.off),\n\tType.Literal(ThinkingLevelEnum.minimal),\n\tType.Literal(ThinkingLevelEnum.low),\n\tType.Literal(ThinkingLevelEnum.medium),\n\tType.Literal(ThinkingLevelEnum.high),\n\tType.Literal(ThinkingLevelEnum.xhigh),\n\tType.Literal(ThinkingLevelEnum.max),\n]);\nexport type ThinkingLevel = Static<typeof ThinkingLevel>;\n\nexport const ActiveThinkingLevel = Type.Union([\n\tType.Literal(ThinkingLevelEnum.minimal),\n\tType.Literal(ThinkingLevelEnum.low),\n\tType.Literal(ThinkingLevelEnum.medium),\n\tType.Literal(ThinkingLevelEnum.high),\n\tType.Literal(ThinkingLevelEnum.xhigh),\n\tType.Literal(ThinkingLevelEnum.max),\n]);\nexport type ActiveThinkingLevel = Static<typeof ActiveThinkingLevel>;\n\nexport const ThinkingBudgets = Type.Partial(Type.Record(ActiveThinkingLevel, Type.Number()));\nexport type ThinkingBudgets = Static<typeof ThinkingBudgets>;\n\n// Note: order of entries matters!\nconst ACTIVE_THINKING_LEVELS = [\n\tThinkingLevelEnum.minimal,\n\tThinkingLevelEnum.low,\n\tThinkingLevelEnum.medium,\n\tThinkingLevelEnum.high,\n\tThinkingLevelEnum.xhigh,\n\tThinkingLevelEnum.max,\n] as const satisfies readonly ActiveThinkingLevel[];\nconst MODEL_THINKING_LEVELS = [\n\tThinkingLevelEnum.off,\n\t...ACTIVE_THINKING_LEVELS,\n] as const satisfies readonly ThinkingLevel[];\n\nexport const ProviderInfo = Type.Object({\n\tid: Type.String(),\n\tname: Type.String(),\n\tsource: Type.Enum([\"env\", \"config\", \"custom\", \"api\", \"unknown\"]),\n\tenv: Type.Array(Type.String()),\n\tkey: Type.Optional(Type.String()), // runtime api/oauth key\n\toptions: Type.Optional(Type.Record(Type.String(), Type.Any())),\n});\nexport type ProviderInfo = Static<typeof ProviderInfo>;\n\nconst InputSchema = Type.Array(Type.Union([Type.Literal(\"text\"), Type.Literal(\"image\")]));\nconst CostRatesSchema = Type.Object({\n\tinput: Type.Number(),\n\toutput: Type.Number(),\n\tcacheRead: Type.Number(),\n\tcacheWrite: Type.Number(),\n});\nconst CostTierSchema = Type.Object({\n\t...CostRatesSchema.properties,\n\tinputTokensAbove: Type.Number(),\n});\nconst CostSchema = Type.Object({\n\t...CostRatesSchema.properties,\n\ttiers: Type.Optional(Type.Array(CostTierSchema)),\n\tserviceTierMultipliers: Type.Optional(Type.Record(Type.String(), Type.Number())),\n});\nconst SupportedProtocolsSchema = Type.Partial(\n\tType.Object({\n\t\tanthropic: KnownProviderEnumSchema,\n\t\tgoogle: KnownProviderEnumSchema,\n\t\tgoogleVertex: KnownProviderEnumSchema,\n\t\tgoogleVertexAnthropic: KnownProviderEnumSchema,\n\t\topenai: KnownProviderEnumSchema,\n\t\topenaiCompatible: KnownProviderEnumSchema,\n\t\topenaiCodex: KnownProviderEnumSchema,\n\t\topenrouter: KnownProviderEnumSchema,\n\t\txai: KnownProviderEnumSchema,\n\t}),\n);\n\nexport const APIMethodEnum = {\n\tlanguageModel: \"languageModel\",\n\tchat: \"chat\",\n\tcompletion: \"completion\",\n\tcompletionModel: \"completionModel\",\n\tmessages: \"messages\",\n\tresponses: \"responses\",\n} as const;\nexport const APIMethodEnumSchema = Type.Union([\n\tType.Literal(APIMethodEnum.languageModel),\n\tType.Literal(APIMethodEnum.chat),\n\tType.Literal(APIMethodEnum.completion),\n\tType.Literal(APIMethodEnum.completionModel),\n\tType.Literal(APIMethodEnum.messages),\n\tType.Literal(APIMethodEnum.responses),\n]);\nexport type APIMethodEnum = Static<typeof APIMethodEnumSchema>;\n\nexport const APIMetadataSchema = Type.Object({\n\tid: Type.Optional(Type.String()),\n\turl: Type.Optional(Type.String()),\n\tmethod: Type.Optional(APIMethodEnumSchema),\n});\nexport type APIMetadata = Static<typeof APIMetadataSchema>;\n\nexport const ThinkingLevelMapSchema = Type.Partial(\n\tType.Record(\n\t\tThinkingLevel, // Safe key validation\n\t\tType.Union([Type.String(), Type.Null()]), // Allowed values\n\t),\n);\nexport type ThinkingLevelMap = Static<typeof ThinkingLevelMapSchema>;\n\nexport const CompatibilitySchema = Type.Object({\n\t/** The Google protocol accepts thinking levels rather than a token budget. */\n\tsupportsThinkingLevel: Type.Optional(Type.Boolean()),\n\tsupportsToolSearch: Type.Optional(Type.Boolean()),\n\tsupportsAdditionalTools: Type.Optional(Type.Boolean()),\n\tsupportsStrictMode: Type.Optional(Type.Boolean()),\n\tsupportsOpenAIGrammarTools: Type.Optional(Type.Boolean()),\n\t/** The model takes a thinking-token budget as a top-level request field. */\n\tsupportsThinkingTokenBudget: Type.Optional(Type.Boolean()),\n\t/** Claude model that sizes its own thinking, driven by `effort` instead of a token budget. */\n\tforceAdaptiveThinking: Type.Optional(Type.Boolean()),\n\t/** Name of that field, when it is not the conventional `thinking_token_budget`. */\n\tthinkingTokenBudgetField: Type.Optional(Type.String()),\n});\nexport type Compatibility = Static<typeof CompatibilitySchema>;\n\nexport const Schema = Type.Object({\n\tid: Type.String(),\n\tname: Type.String(),\n\tprovider: ProviderInfo,\n\tbaseUrl: Type.String(),\n\treasoning: Type.Boolean(),\n\tthinkingLevelMap: Type.Optional(ThinkingLevelMapSchema),\n\t/** Default budgets; request-level thinkingBudgets take precedence. */\n\tthinkingBudgets: Type.Optional(ThinkingBudgets),\n\tinput: InputSchema,\n\tcost: CostSchema,\n\tcontextWindow: Type.Number(),\n\tmaxTokens: Type.Number(),\n\theaders: Type.Optional(Type.Record(Type.String(), Type.String())),\n\tnpm: Type.Optional(Type.String()),\n\tapi: Type.Optional(APIMetadataSchema),\n\tproviderOptionsKey: Type.Optional(Type.String()),\n\toptions: Type.Optional(Type.Record(Type.String(), Type.Unknown())),\n\tproviderOptions: Type.Optional(Type.Record(Type.String(), Type.Unknown())),\n\tcompat: Type.Optional(CompatibilitySchema),\n\tprotocol: KnownProviderEnumSchema, // provider as the underlying protocol\n\tsupportedProtocols: Type.Optional(SupportedProtocolsSchema), // provider as the underlying supported protocols\n});\n\nexport const ExtrasSchema = Type.Object({});\n\nexport const Info = Type.Evaluate(Type.Intersect([Schema, ExtrasSchema]));\nexport type Info = Static<typeof Info>;\nexport type TModel<TProtocol extends KnownProviderEnum> = Omit<Info, \"protocol\"> & { protocol: TProtocol };\n\nexport function calculateCost(\n\tmodel: Info,\n\tusage: {\n\t\tinput: number;\n\t\toutput: number;\n\t\tcacheRead: number;\n\t\tcacheWrite: number;\n\t\tcacheWrite1h?: number;\n\t\tcost: {\n\t\t\tinput: number;\n\t\t\toutput: number;\n\t\t\tcacheRead: number;\n\t\t\tcacheWrite: number;\n\t\t\ttotal: number;\n\t\t};\n\t},\n): void {\n\tconst inputTokens = usage.input + usage.cacheRead + usage.cacheWrite;\n\tlet rates = model.cost;\n\tlet matchedThreshold = -1;\n\tfor (const tier of model.cost.tiers ?? []) {\n\t\tif (inputTokens > tier.inputTokensAbove && tier.inputTokensAbove > matchedThreshold) {\n\t\t\trates = tier;\n\t\t\tmatchedThreshold = tier.inputTokensAbove;\n\t\t}\n\t}\n\n\t// Anthropic charges 2x base input for 1h cache writes; `cost.cacheWrite` is the 5m rate.\n\tconst longWrite = usage.cacheWrite1h ?? 0;\n\tconst shortWrite = usage.cacheWrite - longWrite;\n\n\tusage.cost.input = (usage.input / 1_000_000) * rates.input;\n\tusage.cost.output = (usage.output / 1_000_000) * rates.output;\n\tusage.cost.cacheRead = (usage.cacheRead / 1_000_000) * rates.cacheRead;\n\tusage.cost.cacheWrite = (rates.cacheWrite * shortWrite + rates.input * 2 * longWrite) / 1_000_000;\n\tusage.cost.total = usage.cost.input + usage.cost.output + usage.cost.cacheRead + usage.cost.cacheWrite;\n}\n\nexport type BuiltInModels = Partial<Record<string, Record<string, Info>>>;\n\nexport function normalizeInput(input?: string[]): Array<\"text\" | \"image\"> {\n\tconst normalized = new Set<\"text\" | \"image\">();\n\tfor (const modality of input ?? [\"text\"]) {\n\t\tif (modality === \"text\" || modality === \"image\") {\n\t\t\tnormalized.add(modality);\n\t\t}\n\t}\n\tif (normalized.size === 0) normalized.add(\"text\");\n\treturn [...normalized];\n}\n\nexport async function getBuiltInModels(): Promise<BuiltInModels> {\n\treturn (await ModelCatalog.get()) as BuiltInModels;\n}\n\nexport const registry = lazy(async () => {\n\tconst registry: Map<string, Map<string, Info>> = new Map();\n\tconst models = await getBuiltInModels();\n\tfor (const [provider, value] of Object.entries(models) as Array<[string, Record<string, Info>]>) {\n\t\tconst providerModels = new Map<string, Info>();\n\t\tfor (const [id, model] of Object.entries(value)) {\n\t\t\tproviderModels.set(id, model);\n\t\t}\n\t\tregistry.set(provider, providerModels);\n\t}\n\treturn registry;\n});\n\n/**\n * The key a provider's own option bag is filed under.\n *\n * Providers that speak another provider's protocol still carry their own option\n * namespace, so this is not always the protocol.\n */\n/**\n * The request-body field a model takes its thinking-token budget in, if any.\n *\n * OpenAI-compatible endpoints have no standard place for this, so each one names\n * its own field; a bare `supportsThinkingTokenBudget` means the conventional name.\n */\nexport function thinkingTokenBudgetField(model: Info): string | undefined {\n\tif (model.compat?.thinkingTokenBudgetField) return model.compat.thinkingTokenBudgetField;\n\treturn model.compat?.supportsThinkingTokenBudget ? \"thinking_token_budget\" : undefined;\n}\n\nexport function optionsKey(model: Info): string {\n\treturn model.providerOptionsKey ?? model.protocol;\n}\n\nexport function supportsProtocol(model: Info, protocol: KnownProviderEnum): boolean {\n\tif (model.protocol === protocol) return true;\n\treturn Object.values(model.supportedProtocols ?? {}).includes(protocol);\n}\n\nexport type ProviderToProtocol<TProvider extends string> = TProvider extends KnownProviderEnum\n\t? TProvider\n\t: KnownProviderEnum;\n\nexport async function getModel<\n\tTProvider extends string,\n\tTProtocol extends KnownProviderEnum = ProviderToProtocol<TProvider>,\n>(\n\tprovider: TProvider,\n\tmodel: string,\n\toverrides?: Partial<Info> & { protocol?: TProtocol },\n): Promise<TModel<TProtocol> | undefined> {\n\tconst data = await registry();\n\tconst providerModels = data.get(provider);\n\tconst result = providerModels?.get(model);\n\tif (result && overrides) {\n\t\tif (overrides.protocol && !supportsProtocol(result, overrides.protocol)) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn {\n\t\t\t...result,\n\t\t\t...overrides,\n\t\t} as TModel<TProtocol>;\n\t}\n\treturn result as TModel<TProtocol> | undefined;\n}\n\nexport async function getProviders(): Promise<string[]> {\n\tconst data = await registry();\n\treturn Array.from(data.keys());\n}\n\nexport async function getModels<TProvider extends string>(provider: TProvider): Promise<Info[]> {\n\tconst data = await registry();\n\tconst models = data.get(provider);\n\treturn models ? Array.from(models.values()) : [];\n}\n\n/**\n * Check if two models are equal by comparing both their id and provider id.\n * Returns false if either model is null or undefined.\n */\nexport function modelsAreEqual(a: Info | null | undefined, b: Info | null | undefined): boolean {\n\tif (!a || !b) return false;\n\treturn a.id === b.id && a.provider.id === b.provider.id;\n}\n\nexport function getSupportedThinkingLevels<TProtocol extends KnownProviderEnum>(\n\tmodel: TModel<TProtocol>,\n): ThinkingLevel[] {\n\tif (!model.reasoning) return [\"off\"];\n\n\treturn MODEL_THINKING_LEVELS.filter((level) => {\n\t\tconst mapped = model.thinkingLevelMap?.[level];\n\t\tif (mapped === null) return false;\n\t\tif (level === \"xhigh\" || level === \"max\") return mapped !== undefined;\n\t\treturn true;\n\t});\n}\n\nexport function clampThinkingLevel<TProtocol extends KnownProviderEnum>(\n\tmodel: TModel<TProtocol>,\n\tlevel: ThinkingLevel,\n): ThinkingLevel {\n\tconst availableLevels = getSupportedThinkingLevels(model);\n\tif (availableLevels.includes(level)) return level;\n\n\tconst requestedIndex = MODEL_THINKING_LEVELS.indexOf(level);\n\tif (requestedIndex === -1) return availableLevels[0] ?? \"off\";\n\n\t// walk up the ladder from the point and pick first supported\n\t// biased to avail more thinking, then less not round to nearest.\n\tfor (let i = requestedIndex; i < MODEL_THINKING_LEVELS.length; i++) {\n\t\tconst candidate = MODEL_THINKING_LEVELS[i]!;\n\t\tif (availableLevels.includes(candidate)) return candidate;\n\t}\n\t// otherwise walk down from the point\n\tfor (let i = requestedIndex - 1; i >= 0; i--) {\n\t\tconst candidate = MODEL_THINKING_LEVELS[i]!;\n\t\tif (availableLevels.includes(candidate)) return candidate;\n\t}\n\treturn availableLevels[0] ?? \"off\";\n}\n"],"mappings":";;;;;;AAAA,SAAgB,KAAQ,IAAa;CACpC,IAAI;CACJ,IAAI,SAAS;CAEb,MAAM,eAAkB;EACvB,IAAI,QAAQ,OAAO;EACnB,QAAQ,GAAG;EACX,SAAS;EACT,OAAO;CACR;CAEA,OAAO,cAAc;EACpB,SAAS;EACT,QAAQ,KAAA;CACT;CAEA,OAAO;AACR;;;ACZA,IAAsB,aAAtB,MAAsB,mBAAmB,MAAM;CAI9C,OAAO,OAAqD,MAAY,MAAY;EACnF,MAAM,SAAS;GACd,KAAK;GACL,MAAM;GACN,UAAU,CAAC,QAAQ,MAAM;GACzB,YAAY;IACX,MAAM,EACL,OAAO,KACR;IACA;GACD;EACD;EAEA,MAAM,SAAS,cAAc,WAAW;GACvC,OAAuB,SAAS;GAEhC,OAAgC;GAEhC;GAEA,YAAY,MAAwB,SAAwB;IAC3D,MAAM,MAAM,OAAO;IACnB,KAAK,OAAO;IACZ,KAAK,OAAO;GACb;GAEA,OAAO,WAAW,OAAsD;IACvE,OAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,UAAU,SAAS,MAAM,SAAS;GACzF;GAEA,SAAS;IACR,OAAO;GACR;GAEA,WAAW;IACV,OAAO;KACN;KACA,MAAM,KAAK;IACZ;GACD;EACD;EAEA,OAAO,eAAe,QAAQ,QAAQ,EAAE,OAAO,KAAK,CAAC;EACrD,OAAO;CACR;CAEA,OAAuB,UAAU,WAAW,OAAO,gBAAgB;EAClE,MAAM;EACN,UAAU,CAAC,SAAS;EACpB,YAAY,EACX,SAAS,EACR,MAAM,SACP,EACD;CACD,CAAC;AACF;;;AC7DA,eAAsB,SAAS,MAA+B;CAC7D,OAAO,SAAS,MAAM,OAAO;AAC9B;AAEA,eAAsB,SAAsB,MAA0B;CACrE,OAAO,KAAK,MAAM,MAAM,SAAS,MAAM,OAAO,CAAC;AAChD;AAEA,SAAS,SAAS,OAA6C;CAC9D,OACC,OAAO,UAAU,YAAY,UAAU,QAAQ,UAAU,SAAU,MAA2B,SAAS;AAEzG;AAEA,eAAsB,MAAM,MAAc,SAAuC,MAA8B;CAC9G,IAAI;EACH,IAAI,MACH,MAAM,UAAU,MAAM,SAAS,EAAE,KAAK,CAAC;OAEvC,MAAM,UAAU,MAAM,OAAO;CAE/B,SAAS,OAAO;EACf,IAAI,SAAS,KAAK,GAAG;GACpB,MAAM,MAAM,QAAQ,IAAI,GAAG,EAAE,WAAW,KAAK,CAAC;GAC9C,IAAI,MACH,MAAM,UAAU,MAAM,SAAS,EAAE,KAAK,CAAC;QAEvC,MAAM,UAAU,MAAM,OAAO;GAE9B;EACD;EACA,MAAM;CACP;AACD;AAEA,eAAsB,UAAU,MAAc,MAAe,MAA8B;CAC1F,OAAO,MAAM,MAAM,KAAK,UAAU,MAAM,MAAM,CAAC,GAAG,IAAI;AACvD;;;AChCA,MAAaA,sBAAoB;CAChC,WAAW;CACX,QAAQ;CACR,cAAc;CACd,uBAAuB;CACvB,QAAQ;CACR,kBAAkB;CAClB,aAAa;CACb,YAAY;CACZ,KAAK;AACN;AACA,MAAaC,4BAA0BC,OAAK,MAAM;CACjDA,OAAK,QAAQF,oBAAkB,SAAS;CACxCE,OAAK,QAAQF,oBAAkB,MAAM;CACrCE,OAAK,QAAQF,oBAAkB,YAAY;CAC3CE,OAAK,QAAQF,oBAAkB,qBAAqB;CACpDE,OAAK,QAAQF,oBAAkB,MAAM;CACrCE,OAAK,QAAQF,oBAAkB,gBAAgB;CAC/CE,OAAK,QAAQF,oBAAkB,WAAW;CAC1CE,OAAK,QAAQF,oBAAkB,UAAU;CACzCE,OAAK,QAAQF,oBAAkB,GAAG;AACnC,CAAC;AAMD,MAAaG,0BAAwB,WAAW,OAC/C,yBACAD,OAAK,OAAO;CACX,MAAMA,OAAK,OAAO;CAClB,QAAQA,OAAK,MAAM;EAClBA,OAAK,QAAQ,SAAS;EACtBA,OAAK,QAAQ,YAAY;EACzBA,OAAK,QAAQ,OAAO;EACpBA,OAAK,QAAQ,SAAS;CACvB,CAAC;CACD,SAASA,OAAK,OAAO;AACtB,CAAC,CACF;AAGA,SAAgB,cAAsB;CACrC,OAAO,QAAQ,IAAI;AACpB;AAGA,SAAgB,OAAe;CAC9B,OAAO,QAAQ,QAAQ,IAAI,wBAAwB,KAAK,YAAY,GAAA,iBAAW,CAAC;AACjF;AAEA,eAAsB,KAAK,cAAc,KAAK,GAA8B;CAC3E,IAAI;CACJ,IAAI;EACH,UAAU,MAAME,SAAoB,WAAW;CAChD,SAAS,OAAO;EAKf,MAAM,UAHL,OAAO,UAAU,YAAY,UAAU,QAAQ,UAAU,SAAS,OAAO,MAAM,SAAS,WACrF,MAAM,OACN,KAAA,OACqB,WAAW,YAAY;EAChD,MAAM,IAAID,wBACT;GACC,MAAM;GACN;GACA,SACC,WAAW,YACR,8BAA8B,gBAC9B,sCAAsC;EAC3C,GACA,EAAE,MAAM,CACT;CACD;CACA,IAAI,CAAC,QAAQ,KAAK,GACjB,MAAM,IAAIA,wBAAsB;EAC/B,MAAM;EACN,QAAQ;EACR,SAAS,6BAA6B;CACvC,CAAC;CAEF,IAAI;EACH,MAAM,SAAkB,KAAK,MAAM,OAAO;EAC1C,IAAI,OAAO,WAAW,YAAY,WAAW,QAAQ,MAAM,QAAQ,MAAM,GAAG,MAAM,IAAI,MAAM,oBAAoB;EAChH,OAAO;CACR,SAAS,OAAO;EACf,MAAM,IAAIA,wBACT;GACC,MAAM;GACN,QAAQ;GACR,SAAS,0CAA0C;EACpD,GACA,EAAE,MAAM,CACT;CACD;AACD;AAEA,MAAa,OAA6B,WAAW,KAAK,CAAC;AAE3D,eAAsB,MAAiC;CACtD,OAAO,KAAK;AACb;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACvGA,MAAa,oBAAoBE;AACjC,MAAa,0BAA0BC;AAGvC,MAAa,wBAAwBC;AAOrC,MAAa,oBAAoB;CAEhC,KAAK;CAEL,SAAS;CAET,KAAK;CAEL,QAAQ;CAER,MAAM;CAEN,OAAO;CAEP,KAAK;AACN;AAEA,MAAa,gBAAgBC,OAAK,MAAM;CACvCA,OAAK,QAAQ,kBAAkB,GAAG;CAClCA,OAAK,QAAQ,kBAAkB,OAAO;CACtCA,OAAK,QAAQ,kBAAkB,GAAG;CAClCA,OAAK,QAAQ,kBAAkB,MAAM;CACrCA,OAAK,QAAQ,kBAAkB,IAAI;CACnCA,OAAK,QAAQ,kBAAkB,KAAK;CACpCA,OAAK,QAAQ,kBAAkB,GAAG;AACnC,CAAC;AAGD,MAAa,sBAAsBA,OAAK,MAAM;CAC7CA,OAAK,QAAQ,kBAAkB,OAAO;CACtCA,OAAK,QAAQ,kBAAkB,GAAG;CAClCA,OAAK,QAAQ,kBAAkB,MAAM;CACrCA,OAAK,QAAQ,kBAAkB,IAAI;CACnCA,OAAK,QAAQ,kBAAkB,KAAK;CACpCA,OAAK,QAAQ,kBAAkB,GAAG;AACnC,CAAC;AAGD,MAAa,kBAAkBA,OAAK,QAAQA,OAAK,OAAO,qBAAqBA,OAAK,OAAO,CAAC,CAAC;AAI3F,MAAM,yBAAyB;CAC9B,kBAAkB;CAClB,kBAAkB;CAClB,kBAAkB;CAClB,kBAAkB;CAClB,kBAAkB;CAClB,kBAAkB;AACnB;AACA,MAAM,wBAAwB,CAC7B,kBAAkB,KAClB,GAAG,sBACJ;AAEA,MAAa,eAAeA,OAAK,OAAO;CACvC,IAAIA,OAAK,OAAO;CAChB,MAAMA,OAAK,OAAO;CAClB,QAAQA,OAAK,KAAK;EAAC;EAAO;EAAU;EAAU;EAAO;CAAS,CAAC;CAC/D,KAAKA,OAAK,MAAMA,OAAK,OAAO,CAAC;CAC7B,KAAKA,OAAK,SAASA,OAAK,OAAO,CAAC;CAChC,SAASA,OAAK,SAASA,OAAK,OAAOA,OAAK,OAAO,GAAGA,OAAK,IAAI,CAAC,CAAC;AAC9D,CAAC;AAGD,MAAM,cAAcA,OAAK,MAAMA,OAAK,MAAM,CAACA,OAAK,QAAQ,MAAM,GAAGA,OAAK,QAAQ,OAAO,CAAC,CAAC,CAAC;AACxF,MAAM,kBAAkBA,OAAK,OAAO;CACnC,OAAOA,OAAK,OAAO;CACnB,QAAQA,OAAK,OAAO;CACpB,WAAWA,OAAK,OAAO;CACvB,YAAYA,OAAK,OAAO;AACzB,CAAC;AACD,MAAM,iBAAiBA,OAAK,OAAO;CAClC,GAAG,gBAAgB;CACnB,kBAAkBA,OAAK,OAAO;AAC/B,CAAC;AACD,MAAM,aAAaA,OAAK,OAAO;CAC9B,GAAG,gBAAgB;CACnB,OAAOA,OAAK,SAASA,OAAK,MAAM,cAAc,CAAC;CAC/C,wBAAwBA,OAAK,SAASA,OAAK,OAAOA,OAAK,OAAO,GAAGA,OAAK,OAAO,CAAC,CAAC;AAChF,CAAC;AACD,MAAM,2BAA2BA,OAAK,QACrCA,OAAK,OAAO;CACX,WAAW;CACX,QAAQ;CACR,cAAc;CACd,uBAAuB;CACvB,QAAQ;CACR,kBAAkB;CAClB,aAAa;CACb,YAAY;CACZ,KAAK;AACN,CAAC,CACF;AAEA,MAAa,gBAAgB;CAC5B,eAAe;CACf,MAAM;CACN,YAAY;CACZ,iBAAiB;CACjB,UAAU;CACV,WAAW;AACZ;AACA,MAAa,sBAAsBA,OAAK,MAAM;CAC7CA,OAAK,QAAQ,cAAc,aAAa;CACxCA,OAAK,QAAQ,cAAc,IAAI;CAC/BA,OAAK,QAAQ,cAAc,UAAU;CACrCA,OAAK,QAAQ,cAAc,eAAe;CAC1CA,OAAK,QAAQ,cAAc,QAAQ;CACnCA,OAAK,QAAQ,cAAc,SAAS;AACrC,CAAC;AAGD,MAAa,oBAAoBA,OAAK,OAAO;CAC5C,IAAIA,OAAK,SAASA,OAAK,OAAO,CAAC;CAC/B,KAAKA,OAAK,SAASA,OAAK,OAAO,CAAC;CAChC,QAAQA,OAAK,SAAS,mBAAmB;AAC1C,CAAC;AAGD,MAAa,yBAAyBA,OAAK,QAC1CA,OAAK,OACJ,eACAA,OAAK,MAAM,CAACA,OAAK,OAAO,GAAGA,OAAK,KAAK,CAAC,CAAC,CACxC,CACD;AAGA,MAAa,sBAAsBA,OAAK,OAAO;;CAE9C,uBAAuBA,OAAK,SAASA,OAAK,QAAQ,CAAC;CACnD,oBAAoBA,OAAK,SAASA,OAAK,QAAQ,CAAC;CAChD,yBAAyBA,OAAK,SAASA,OAAK,QAAQ,CAAC;CACrD,oBAAoBA,OAAK,SAASA,OAAK,QAAQ,CAAC;CAChD,4BAA4BA,OAAK,SAASA,OAAK,QAAQ,CAAC;;CAExD,6BAA6BA,OAAK,SAASA,OAAK,QAAQ,CAAC;;CAEzD,uBAAuBA,OAAK,SAASA,OAAK,QAAQ,CAAC;;CAEnD,0BAA0BA,OAAK,SAASA,OAAK,OAAO,CAAC;AACtD,CAAC;AAGD,MAAa,SAASA,OAAK,OAAO;CACjC,IAAIA,OAAK,OAAO;CAChB,MAAMA,OAAK,OAAO;CAClB,UAAU;CACV,SAASA,OAAK,OAAO;CACrB,WAAWA,OAAK,QAAQ;CACxB,kBAAkBA,OAAK,SAAS,sBAAsB;;CAEtD,iBAAiBA,OAAK,SAAS,eAAe;CAC9C,OAAO;CACP,MAAM;CACN,eAAeA,OAAK,OAAO;CAC3B,WAAWA,OAAK,OAAO;CACvB,SAASA,OAAK,SAASA,OAAK,OAAOA,OAAK,OAAO,GAAGA,OAAK,OAAO,CAAC,CAAC;CAChE,KAAKA,OAAK,SAASA,OAAK,OAAO,CAAC;CAChC,KAAKA,OAAK,SAAS,iBAAiB;CACpC,oBAAoBA,OAAK,SAASA,OAAK,OAAO,CAAC;CAC/C,SAASA,OAAK,SAASA,OAAK,OAAOA,OAAK,OAAO,GAAGA,OAAK,QAAQ,CAAC,CAAC;CACjE,iBAAiBA,OAAK,SAASA,OAAK,OAAOA,OAAK,OAAO,GAAGA,OAAK,QAAQ,CAAC,CAAC;CACzE,QAAQA,OAAK,SAAS,mBAAmB;CACzC,UAAU;CACV,oBAAoBA,OAAK,SAAS,wBAAwB;AAC3D,CAAC;AAED,MAAa,eAAeA,OAAK,OAAO,CAAC,CAAC;AAE1C,MAAa,OAAOA,OAAK,SAASA,OAAK,UAAU,CAAC,QAAQ,YAAY,CAAC,CAAC;AAIxE,SAAgB,cACf,OACA,OAcO;CACP,MAAM,cAAc,MAAM,QAAQ,MAAM,YAAY,MAAM;CAC1D,IAAI,QAAQ,MAAM;CAClB,IAAI,mBAAmB;CACvB,KAAK,MAAM,QAAQ,MAAM,KAAK,SAAS,CAAC,GACvC,IAAI,cAAc,KAAK,oBAAoB,KAAK,mBAAmB,kBAAkB;EACpF,QAAQ;EACR,mBAAmB,KAAK;CACzB;CAID,MAAM,YAAY,MAAM,gBAAgB;CACxC,MAAM,aAAa,MAAM,aAAa;CAEtC,MAAM,KAAK,QAAS,MAAM,QAAQ,MAAa,MAAM;CACrD,MAAM,KAAK,SAAU,MAAM,SAAS,MAAa,MAAM;CACvD,MAAM,KAAK,YAAa,MAAM,YAAY,MAAa,MAAM;CAC7D,MAAM,KAAK,cAAc,MAAM,aAAa,aAAa,MAAM,QAAQ,IAAI,aAAa;CACxF,MAAM,KAAK,QAAQ,MAAM,KAAK,QAAQ,MAAM,KAAK,SAAS,MAAM,KAAK,YAAY,MAAM,KAAK;AAC7F;AAIA,SAAgB,eAAe,OAA2C;CACzE,MAAM,6BAAa,IAAI,IAAsB;CAC7C,KAAK,MAAM,YAAY,SAAS,CAAC,MAAM,GACtC,IAAI,aAAa,UAAU,aAAa,SACvC,WAAW,IAAI,QAAQ;CAGzB,IAAI,WAAW,SAAS,GAAG,WAAW,IAAI,MAAM;CAChD,OAAO,CAAC,GAAG,UAAU;AACtB;AAEA,eAAsB,mBAA2C;CAChE,OAAQ,MAAMC,IAAiB;AAChC;AAEA,MAAa,WAAW,KAAK,YAAY;CACxC,MAAM,2BAA2C,IAAI,IAAI;CACzD,MAAM,SAAS,MAAM,iBAAiB;CACtC,KAAK,MAAM,CAAC,UAAU,UAAU,OAAO,QAAQ,MAAM,GAA4C;EAChG,MAAM,iCAAiB,IAAI,IAAkB;EAC7C,KAAK,MAAM,CAAC,IAAI,UAAU,OAAO,QAAQ,KAAK,GAC7C,eAAe,IAAI,IAAI,KAAK;EAE7B,SAAS,IAAI,UAAU,cAAc;CACtC;CACA,OAAO;AACR,CAAC;;;;;;;;;;;;;AAcD,SAAgB,yBAAyB,OAAiC;CACzE,IAAI,MAAM,QAAQ,0BAA0B,OAAO,MAAM,OAAO;CAChE,OAAO,MAAM,QAAQ,8BAA8B,0BAA0B,KAAA;AAC9E;AAEA,SAAgB,WAAW,OAAqB;CAC/C,OAAO,MAAM,sBAAsB,MAAM;AAC1C;AAEA,SAAgB,iBAAiB,OAAa,UAAsC;CACnF,IAAI,MAAM,aAAa,UAAU,OAAO;CACxC,OAAO,OAAO,OAAO,MAAM,sBAAsB,CAAC,CAAC,CAAC,CAAC,SAAS,QAAQ;AACvE;AAMA,eAAsB,SAIrB,UACA,OACA,WACyC;CAGzC,MAAM,UADiB,MADJ,SAAS,EAAA,CACA,IAAI,QACJ,CAAC,EAAE,IAAI,KAAK;CACxC,IAAI,UAAU,WAAW;EACxB,IAAI,UAAU,YAAY,CAAC,iBAAiB,QAAQ,UAAU,QAAQ,GACrE;EAED,OAAO;GACN,GAAG;GACH,GAAG;EACJ;CACD;CACA,OAAO;AACR;AAEA,eAAsB,eAAkC;CACvD,MAAM,OAAO,MAAM,SAAS;CAC5B,OAAO,MAAM,KAAK,KAAK,KAAK,CAAC;AAC9B;AAEA,eAAsB,UAAoC,UAAsC;CAE/F,MAAM,UAAS,MADI,SAAS,EAAA,CACR,IAAI,QAAQ;CAChC,OAAO,SAAS,MAAM,KAAK,OAAO,OAAO,CAAC,IAAI,CAAC;AAChD;;;;;AAMA,SAAgB,eAAe,GAA4B,GAAqC;CAC/F,IAAI,CAAC,KAAK,CAAC,GAAG,OAAO;CACrB,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,OAAO,EAAE,SAAS;AACtD;AAEA,SAAgB,2BACf,OACkB;CAClB,IAAI,CAAC,MAAM,WAAW,OAAO,CAAC,KAAK;CAEnC,OAAO,sBAAsB,QAAQ,UAAU;EAC9C,MAAM,SAAS,MAAM,mBAAmB;EACxC,IAAI,WAAW,MAAM,OAAO;EAC5B,IAAI,UAAU,WAAW,UAAU,OAAO,OAAO,WAAW,KAAA;EAC5D,OAAO;CACR,CAAC;AACF;AAEA,SAAgB,mBACf,OACA,OACgB;CAChB,MAAM,kBAAkB,2BAA2B,KAAK;CACxD,IAAI,gBAAgB,SAAS,KAAK,GAAG,OAAO;CAE5C,MAAM,iBAAiB,sBAAsB,QAAQ,KAAK;CAC1D,IAAI,mBAAmB,IAAI,OAAO,gBAAgB,MAAM;CAIxD,KAAK,IAAI,IAAI,gBAAgB,IAAI,sBAAsB,QAAQ,KAAK;EACnE,MAAM,YAAY,sBAAsB;EACxC,IAAI,gBAAgB,SAAS,SAAS,GAAG,OAAO;CACjD;CAEA,KAAK,IAAI,IAAI,iBAAiB,GAAG,KAAK,GAAG,KAAK;EAC7C,MAAM,YAAY,sBAAsB;EACxC,IAAI,gBAAgB,SAAS,SAAS,GAAG,OAAO;CACjD;CACA,OAAO,gBAAgB,MAAM;AAC9B"}