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