@theokit/sdk 4.12.2 → 4.13.1

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/eval.cjs CHANGED
@@ -569,10 +569,10 @@ function buildToolPrompt(prompt) {
569
569
  Respond by calling the \`output\` tool with the structured answer that matches the schema.`;
570
570
  }
571
571
  function setupStructuredOutput(schema, maxRetries) {
572
- const z10 = requireZod();
572
+ const z11 = requireZod();
573
573
  const jsonSchema = toJsonSchema(schema, { unrepresentable: "any" });
574
574
  return {
575
- z: z10,
575
+ z: z11,
576
576
  jsonSchema,
577
577
  maxRetries: maxRetries ?? 1,
578
578
  initialUsage: { inputTokens: 0, outputTokens: 0 }
@@ -10499,6 +10499,178 @@ function applyToolResultGuard(parts, opts) {
10499
10499
  )
10500
10500
  );
10501
10501
  }
10502
+ var MODALITIES = ["text", "audio", "image", "video", "pdf"];
10503
+ var costSchema = zod.z.object({
10504
+ /** USD per 1M tokens (models.dev convention). */
10505
+ input: zod.z.number().nonnegative(),
10506
+ output: zod.z.number().nonnegative(),
10507
+ cache_read: zod.z.number().nonnegative().optional(),
10508
+ cache_write: zod.z.number().nonnegative().optional()
10509
+ }).loose();
10510
+ var limitSchema = zod.z.object({
10511
+ context: zod.z.number().positive(),
10512
+ input: zod.z.number().positive().optional(),
10513
+ output: zod.z.number().positive().optional()
10514
+ }).loose();
10515
+ var modalitiesSchema = zod.z.object({
10516
+ input: zod.z.array(zod.z.enum(MODALITIES)).optional(),
10517
+ output: zod.z.array(zod.z.enum(MODALITIES)).optional()
10518
+ }).loose();
10519
+ var catalogModelSchema = zod.z.object({
10520
+ name: zod.z.string().optional(),
10521
+ release_date: zod.z.string().optional(),
10522
+ attachment: zod.z.boolean().optional(),
10523
+ reasoning: zod.z.boolean().optional(),
10524
+ temperature: zod.z.boolean().optional(),
10525
+ tool_call: zod.z.boolean().optional(),
10526
+ /** theokit extension — maps to ModelCapabilities.supportsStructuredOutput. */
10527
+ structured_output: zod.z.boolean().optional(),
10528
+ /** theokit extension — maps to ModelCapabilities.supportsCacheControl. */
10529
+ cache_control: zod.z.boolean().optional(),
10530
+ cost: costSchema.optional(),
10531
+ limit: limitSchema.optional(),
10532
+ modalities: modalitiesSchema.optional(),
10533
+ status: zod.z.enum(["alpha", "beta", "deprecated"]).optional()
10534
+ }).loose();
10535
+
10536
+ // src/internal/providers/registry.ts
10537
+ function globalSingleton(key, create) {
10538
+ const g = globalThis;
10539
+ const sym = Symbol.for(key);
10540
+ if (g[sym] === void 0) g[sym] = create();
10541
+ return g[sym];
10542
+ }
10543
+ var REGISTRY = globalSingleton(
10544
+ "theokit-sdk.providers.registry",
10545
+ () => /* @__PURE__ */ new Map()
10546
+ );
10547
+ var ALIASES = globalSingleton("theokit-sdk.providers.aliases", () => /* @__PURE__ */ new Map());
10548
+ function registerProvider(profile) {
10549
+ if (REGISTRY.has(profile.name)) {
10550
+ process.stderr.write(`[theokit-sdk] Provider "${profile.name}" overridden by user plugin.
10551
+ `);
10552
+ }
10553
+ REGISTRY.set(profile.name, profile);
10554
+ for (const alias of profile.aliases ?? []) {
10555
+ const previous = ALIASES.get(alias);
10556
+ if (previous !== void 0 && previous !== profile.name) {
10557
+ process.stderr.write(
10558
+ `[theokit-sdk] Alias "${alias}" collision: was "${previous}", now "${profile.name}".
10559
+ `
10560
+ );
10561
+ }
10562
+ ALIASES.set(alias, profile.name);
10563
+ }
10564
+ }
10565
+ function getProviderProfile(name) {
10566
+ const canonical = ALIASES.get(name) ?? name;
10567
+ return REGISTRY.get(canonical);
10568
+ }
10569
+
10570
+ // src/internal/providers/catalog-loader.ts
10571
+ var __dirname_resolved = path.dirname(url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('eval.cjs', document.baseURI).href))));
10572
+ function globalSingleton2(key, create) {
10573
+ const g = globalThis;
10574
+ const sym = Symbol.for(key);
10575
+ if (g[sym] === void 0) g[sym] = create();
10576
+ return g[sym];
10577
+ }
10578
+ var modelInfoIndex = globalSingleton2(
10579
+ "theokit-sdk.providers.model-info-index",
10580
+ () => /* @__PURE__ */ new Map()
10581
+ );
10582
+ var patchedModelKeys = globalSingleton2(
10583
+ "theokit-sdk.providers.model-info-patched",
10584
+ () => /* @__PURE__ */ new Set()
10585
+ );
10586
+ var indexState = globalSingleton2("theokit-sdk.providers.model-info-loaded", () => ({
10587
+ loaded: false
10588
+ }));
10589
+ function getCatalogModelInfo(key) {
10590
+ ensureModelIndexLoaded();
10591
+ return modelInfoIndex.get(key);
10592
+ }
10593
+ function isPatchedModelKey(key) {
10594
+ return patchedModelKeys.has(key);
10595
+ }
10596
+ function ensureModelIndexLoaded() {
10597
+ if (indexState.loaded) return;
10598
+ indexState.loaded = true;
10599
+ try {
10600
+ const catalog = loadProviderCatalog();
10601
+ for (const entry of Object.values(catalog)) {
10602
+ indexEntryModels(entry);
10603
+ }
10604
+ } catch (err) {
10605
+ process.stderr.write(
10606
+ `[theokit-sdk] WARN: provider catalog unavailable (${err.message}) \u2014 per-model data disabled
10607
+ `
10608
+ );
10609
+ }
10610
+ }
10611
+ function indexEntryModels(entry) {
10612
+ if (entry.models === void 0 || typeof entry.models !== "object") return;
10613
+ for (const [modelId, raw] of Object.entries(entry.models)) {
10614
+ const parsed = catalogModelSchema.safeParse(raw);
10615
+ if (!parsed.success) {
10616
+ process.stderr.write(
10617
+ `[theokit-sdk] WARN: Skipping malformed catalog model "${entry.id}/${modelId}": ${parsed.error.issues[0]?.message ?? "invalid"}
10618
+ `
10619
+ );
10620
+ continue;
10621
+ }
10622
+ modelInfoIndex.set(`${entry.id}/${modelId}`, parsed.data);
10623
+ for (const alias of entry.aliases ?? []) {
10624
+ const key = `${alias}/${modelId}`;
10625
+ if (!modelInfoIndex.has(key)) modelInfoIndex.set(key, parsed.data);
10626
+ }
10627
+ }
10628
+ }
10629
+ function validateEntry(raw) {
10630
+ if (typeof raw.id !== "string" || typeof raw.displayName !== "string" || typeof raw.apiMode !== "string" || typeof raw.authType !== "string" || typeof raw.baseUrl !== "string" || !Array.isArray(raw.envVars) || !Array.isArray(raw.fallbackModels) || raw.capabilities == null || typeof raw.capabilities !== "object") {
10631
+ return null;
10632
+ }
10633
+ return raw;
10634
+ }
10635
+ function loadProviderCatalog(opts) {
10636
+ const catalogPath = path.join(__dirname_resolved, "provider-catalog.json");
10637
+ const rawText = fs.readFileSync(catalogPath, "utf-8");
10638
+ let entries = JSON.parse(rawText);
10639
+ const result = {};
10640
+ for (const raw of entries) {
10641
+ const validated = validateEntry(raw);
10642
+ if (validated === null) {
10643
+ process.stderr.write(
10644
+ `[theokit-sdk] WARN: Skipping malformed catalog entry: ${JSON.stringify(raw).slice(0, 100)}
10645
+ `
10646
+ );
10647
+ continue;
10648
+ }
10649
+ result[validated.id] = validated;
10650
+ }
10651
+ return result;
10652
+ }
10653
+ function registerCatalogProviders(opts) {
10654
+ const catalog = loadProviderCatalog();
10655
+ for (const entry of Object.values(catalog)) {
10656
+ if (getProviderProfile(entry.id) !== void 0) continue;
10657
+ if (entry.aliases?.some((a) => getProviderProfile(a) !== void 0)) continue;
10658
+ const profile = {
10659
+ name: entry.id,
10660
+ apiMode: entry.apiMode,
10661
+ authType: entry.authType,
10662
+ baseUrl: entry.baseUrl,
10663
+ envVars: entry.envVars,
10664
+ fallbackModels: entry.fallbackModels,
10665
+ displayName: entry.displayName,
10666
+ aliases: entry.aliases,
10667
+ modelsUrl: entry.modelsUrl,
10668
+ hostname: entry.hostname,
10669
+ extraHeaders: entry.extraHeaders
10670
+ };
10671
+ registerProvider(profile);
10672
+ }
10673
+ }
10502
10674
 
10503
10675
  // src/internal/budget/pricing-data.json
10504
10676
  var pricing_data_default = {
@@ -10591,9 +10763,9 @@ var pricing_data_default = {
10591
10763
  cacheRead: 0.025
10592
10764
  },
10593
10765
  "openai/o3": {
10594
- input: 10,
10595
- output: 40,
10596
- cacheRead: 2.5
10766
+ input: 2,
10767
+ output: 8,
10768
+ cacheRead: 0.5
10597
10769
  },
10598
10770
  "openai/o3-mini": {
10599
10771
  input: 1.1,
@@ -10681,6 +10853,30 @@ function getPricingEntry(opts) {
10681
10853
  if (found2 !== void 0) return buildEntry(stripped, found2);
10682
10854
  }
10683
10855
  }
10856
+ const catalogEntry = catalogCostFallback(opts.provider, cleaned);
10857
+ if (catalogEntry !== void 0) return catalogEntry;
10858
+ return void 0;
10859
+ }
10860
+ function catalogCostFallback(provider, cleanedModel) {
10861
+ const stripped = stripDateSuffix(cleanedModel);
10862
+ const candidates = [`${provider}/${cleanedModel}`, cleanedModel];
10863
+ if (stripped !== cleanedModel) candidates.push(`${provider}/${stripped}`, stripped);
10864
+ for (const key of candidates) {
10865
+ const info = getCatalogModelInfo(key);
10866
+ const cost = info?.cost;
10867
+ if (cost === void 0) continue;
10868
+ const [prov, ...modelParts] = key.split("/");
10869
+ return {
10870
+ provider: prov ?? provider,
10871
+ model: modelParts.join("/") || cleanedModel,
10872
+ inputCostPerMillion: cost.input,
10873
+ outputCostPerMillion: cost.output,
10874
+ ...cost.cache_read !== void 0 ? { cacheReadCostPerMillion: cost.cache_read } : {},
10875
+ ...cost.cache_write !== void 0 ? { cacheWriteCostPerMillion: cost.cache_write } : {},
10876
+ // M44 M5 fix — honest provenance: a key patched by the LIVE models-dev source is not "vendored".
10877
+ pricingVersion: isPatchedModelKey(key) ? "catalog-models-dev" : "catalog-vendored"
10878
+ };
10879
+ }
10684
10880
  return void 0;
10685
10881
  }
10686
10882
 
@@ -11197,79 +11393,6 @@ function abortError(signal) {
11197
11393
  // src/internal/llm/router.ts
11198
11394
  init_errors();
11199
11395
 
11200
- // src/internal/providers/registry.ts
11201
- var REGISTRY = /* @__PURE__ */ new Map();
11202
- var ALIASES = /* @__PURE__ */ new Map();
11203
- function registerProvider(profile) {
11204
- if (REGISTRY.has(profile.name)) {
11205
- process.stderr.write(`[theokit-sdk] Provider "${profile.name}" overridden by user plugin.
11206
- `);
11207
- }
11208
- REGISTRY.set(profile.name, profile);
11209
- for (const alias of profile.aliases ?? []) {
11210
- const previous = ALIASES.get(alias);
11211
- if (previous !== void 0 && previous !== profile.name) {
11212
- process.stderr.write(
11213
- `[theokit-sdk] Alias "${alias}" collision: was "${previous}", now "${profile.name}".
11214
- `
11215
- );
11216
- }
11217
- ALIASES.set(alias, profile.name);
11218
- }
11219
- }
11220
- function getProviderProfile(name) {
11221
- const canonical = ALIASES.get(name) ?? name;
11222
- return REGISTRY.get(canonical);
11223
- }
11224
-
11225
- // src/internal/providers/catalog-loader.ts
11226
- var __dirname_resolved = path.dirname(url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('eval.cjs', document.baseURI).href))));
11227
- function validateEntry(raw) {
11228
- if (typeof raw.id !== "string" || typeof raw.displayName !== "string" || typeof raw.apiMode !== "string" || typeof raw.authType !== "string" || typeof raw.baseUrl !== "string" || !Array.isArray(raw.envVars) || !Array.isArray(raw.fallbackModels) || raw.capabilities == null || typeof raw.capabilities !== "object") {
11229
- return null;
11230
- }
11231
- return raw;
11232
- }
11233
- function loadProviderCatalog(opts) {
11234
- const catalogPath = path.join(__dirname_resolved, "provider-catalog.json");
11235
- const rawText = fs.readFileSync(catalogPath, "utf-8");
11236
- let entries = JSON.parse(rawText);
11237
- const result = {};
11238
- for (const raw of entries) {
11239
- const validated = validateEntry(raw);
11240
- if (validated === null) {
11241
- process.stderr.write(
11242
- `[theokit-sdk] WARN: Skipping malformed catalog entry: ${JSON.stringify(raw).slice(0, 100)}
11243
- `
11244
- );
11245
- continue;
11246
- }
11247
- result[validated.id] = validated;
11248
- }
11249
- return result;
11250
- }
11251
- function registerCatalogProviders(opts) {
11252
- const catalog = loadProviderCatalog();
11253
- for (const entry of Object.values(catalog)) {
11254
- if (getProviderProfile(entry.id) !== void 0) continue;
11255
- if (entry.aliases?.some((a) => getProviderProfile(a) !== void 0)) continue;
11256
- const profile = {
11257
- name: entry.id,
11258
- apiMode: entry.apiMode,
11259
- authType: entry.authType,
11260
- baseUrl: entry.baseUrl,
11261
- envVars: entry.envVars,
11262
- fallbackModels: entry.fallbackModels,
11263
- displayName: entry.displayName,
11264
- aliases: entry.aliases,
11265
- modelsUrl: entry.modelsUrl,
11266
- hostname: entry.hostname,
11267
- extraHeaders: entry.extraHeaders
11268
- };
11269
- registerProvider(profile);
11270
- }
11271
- }
11272
-
11273
11396
  // src/internal/providers/builtin/anthropic.ts
11274
11397
  var ANTHROPIC = {
11275
11398
  name: "anthropic",