@theokit/sdk 4.13.0 → 4.14.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 (37) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/{cron-C7catiH8.d.ts → cron-DY0uC1ng.d.ts} +7 -0
  3. package/dist/{cron-DK1WVZnI.d.cts → cron-ElTj1cSH.d.cts} +7 -0
  4. package/dist/cron.cjs +183 -20
  5. package/dist/cron.cjs.map +1 -1
  6. package/dist/cron.d.cts +1 -1
  7. package/dist/cron.d.ts +1 -1
  8. package/dist/cron.js +183 -20
  9. package/dist/cron.js.map +1 -1
  10. package/dist/eval.cjs +183 -20
  11. package/dist/eval.cjs.map +1 -1
  12. package/dist/eval.js +183 -20
  13. package/dist/eval.js.map +1 -1
  14. package/dist/index.cjs +183 -20
  15. package/dist/index.cjs.map +1 -1
  16. package/dist/index.d.cts +2 -2
  17. package/dist/index.d.ts +2 -2
  18. package/dist/index.js +183 -20
  19. package/dist/index.js.map +1 -1
  20. package/dist/internal/llm/openai.d.ts +1 -0
  21. package/dist/internal/providers/builtin/cerebras.d.ts +5 -0
  22. package/dist/internal/providers/builtin/cohere.d.ts +6 -0
  23. package/dist/internal/providers/builtin/deepinfra.d.ts +2 -0
  24. package/dist/internal/providers/builtin/google.d.ts +6 -0
  25. package/dist/internal/providers/builtin/groq.d.ts +2 -0
  26. package/dist/internal/providers/builtin/mistral.d.ts +2 -0
  27. package/dist/internal/providers/builtin/openai-compatible.d.ts +1 -0
  28. package/dist/internal/providers/builtin/perplexity.d.ts +5 -0
  29. package/dist/internal/providers/builtin/together.d.ts +2 -0
  30. package/dist/internal/providers/builtin/xai.d.ts +2 -0
  31. package/dist/models.cjs +753 -17
  32. package/dist/models.cjs.map +1 -1
  33. package/dist/models.js +754 -18
  34. package/dist/models.js.map +1 -1
  35. package/dist/provider-catalog.json +473 -146
  36. package/dist/types/provider-profile.d.ts +7 -0
  37. package/package.json +1 -1
package/dist/eval.js CHANGED
@@ -10531,8 +10531,17 @@ var catalogModelSchema = z.object({
10531
10531
  }).loose();
10532
10532
 
10533
10533
  // src/internal/providers/registry.ts
10534
- var REGISTRY = /* @__PURE__ */ new Map();
10535
- var ALIASES = /* @__PURE__ */ new Map();
10534
+ function globalSingleton(key, create) {
10535
+ const g = globalThis;
10536
+ const sym = Symbol.for(key);
10537
+ if (g[sym] === void 0) g[sym] = create();
10538
+ return g[sym];
10539
+ }
10540
+ var REGISTRY = globalSingleton(
10541
+ "theokit-sdk.providers.registry",
10542
+ () => /* @__PURE__ */ new Map()
10543
+ );
10544
+ var ALIASES = globalSingleton("theokit-sdk.providers.aliases", () => /* @__PURE__ */ new Map());
10536
10545
  function registerProvider(profile) {
10537
10546
  if (REGISTRY.has(profile.name)) {
10538
10547
  process.stderr.write(`[theokit-sdk] Provider "${profile.name}" overridden by user plugin.
@@ -10557,18 +10566,43 @@ function getProviderProfile(name) {
10557
10566
 
10558
10567
  // src/internal/providers/catalog-loader.ts
10559
10568
  var __dirname_resolved = dirname(fileURLToPath(import.meta.url));
10560
- var modelInfoIndex = /* @__PURE__ */ new Map();
10569
+ function globalSingleton2(key, create) {
10570
+ const g = globalThis;
10571
+ const sym = Symbol.for(key);
10572
+ if (g[sym] === void 0) g[sym] = create();
10573
+ return g[sym];
10574
+ }
10575
+ var modelInfoIndex = globalSingleton2(
10576
+ "theokit-sdk.providers.model-info-index",
10577
+ () => /* @__PURE__ */ new Map()
10578
+ );
10579
+ var patchedModelKeys = globalSingleton2(
10580
+ "theokit-sdk.providers.model-info-patched",
10581
+ () => /* @__PURE__ */ new Set()
10582
+ );
10583
+ var indexState = globalSingleton2("theokit-sdk.providers.model-info-loaded", () => ({
10584
+ loaded: false
10585
+ }));
10561
10586
  function getCatalogModelInfo(key) {
10562
10587
  ensureModelIndexLoaded();
10563
10588
  return modelInfoIndex.get(key);
10564
10589
  }
10565
- var _modelIndexLoaded = false;
10590
+ function isPatchedModelKey(key) {
10591
+ return patchedModelKeys.has(key);
10592
+ }
10566
10593
  function ensureModelIndexLoaded() {
10567
- if (_modelIndexLoaded) return;
10568
- _modelIndexLoaded = true;
10569
- const catalog = loadProviderCatalog();
10570
- for (const entry of Object.values(catalog)) {
10571
- indexEntryModels(entry);
10594
+ if (indexState.loaded) return;
10595
+ indexState.loaded = true;
10596
+ try {
10597
+ const catalog = loadProviderCatalog();
10598
+ for (const entry of Object.values(catalog)) {
10599
+ indexEntryModels(entry);
10600
+ }
10601
+ } catch (err) {
10602
+ process.stderr.write(
10603
+ `[theokit-sdk] WARN: provider catalog unavailable (${err.message}) \u2014 per-model data disabled
10604
+ `
10605
+ );
10572
10606
  }
10573
10607
  }
10574
10608
  function indexEntryModels(entry) {
@@ -10821,8 +10855,10 @@ function getPricingEntry(opts) {
10821
10855
  return void 0;
10822
10856
  }
10823
10857
  function catalogCostFallback(provider, cleanedModel) {
10824
- const keys = [`${provider}/${cleanedModel}`, cleanedModel];
10825
- for (const key of keys) {
10858
+ const stripped = stripDateSuffix(cleanedModel);
10859
+ const candidates = [`${provider}/${cleanedModel}`, cleanedModel];
10860
+ if (stripped !== cleanedModel) candidates.push(`${provider}/${stripped}`, stripped);
10861
+ for (const key of candidates) {
10826
10862
  const info = getCatalogModelInfo(key);
10827
10863
  const cost = info?.cost;
10828
10864
  if (cost === void 0) continue;
@@ -10834,7 +10870,8 @@ function catalogCostFallback(provider, cleanedModel) {
10834
10870
  outputCostPerMillion: cost.output,
10835
10871
  ...cost.cache_read !== void 0 ? { cacheReadCostPerMillion: cost.cache_read } : {},
10836
10872
  ...cost.cache_write !== void 0 ? { cacheWriteCostPerMillion: cost.cache_write } : {},
10837
- pricingVersion: "catalog-vendored"
10873
+ // M44 M5 fix — honest provenance: a key patched by the LIVE models-dev source is not "vendored".
10874
+ pricingVersion: isPatchedModelKey(key) ? "catalog-models-dev" : "catalog-vendored"
10838
10875
  };
10839
10876
  }
10840
10877
  return void 0;
@@ -11362,7 +11399,13 @@ var ANTHROPIC = {
11362
11399
  baseUrl: "https://api.anthropic.com",
11363
11400
  modelsUrl: "https://api.anthropic.com/v1/models",
11364
11401
  hostname: "api.anthropic.com",
11365
- fallbackModels: ["claude-opus-4-7", "claude-sonnet-4-6", "claude-haiku-4-5-20251001"]
11402
+ fallbackModels: ["claude-opus-4-7", "claude-sonnet-4-6", "claude-haiku-4-5-20251001"],
11403
+ // M45 — the Anthropic beta-features header (interleaved thinking + fine-grained tool streaming). An
11404
+ // Anthropic API constant, adapted verbatim from OpenCode's anthropic plugin (MIT © 2025 opencode). The
11405
+ // SANCTIONED behavior delta of M45 (ADR D4) — consumed by the anthropic transport's extraHeaders wiring.
11406
+ extraHeaders: {
11407
+ "anthropic-beta": "interleaved-thinking-2025-05-14,fine-grained-tool-streaming-2025-05-14"
11408
+ }
11366
11409
  };
11367
11410
 
11368
11411
  // src/internal/providers/builtin/bedrock.ts
@@ -11397,6 +11440,101 @@ function resolveBedrockBaseUrl(modelId) {
11397
11440
  return `https://bedrock-runtime.${region}.amazonaws.com`;
11398
11441
  }
11399
11442
 
11443
+ // src/internal/providers/builtin/openai-compatible.ts
11444
+ function openAiCompatibleProfile(p) {
11445
+ return {
11446
+ apiMode: "chat_completions",
11447
+ authType: "api_key",
11448
+ fallbackModels: [],
11449
+ ...p
11450
+ };
11451
+ }
11452
+
11453
+ // src/internal/providers/builtin/cerebras.ts
11454
+ var CEREBRAS = openAiCompatibleProfile({
11455
+ name: "cerebras",
11456
+ baseUrl: "https://api.cerebras.ai/v1",
11457
+ envVars: ["CEREBRAS_API_KEY"],
11458
+ fallbackModels: ["gpt-oss-120b", "zai-glm-4.7"],
11459
+ extraHeaders: { "X-Cerebras-3rd-Party-Integration": "theokit" },
11460
+ hostname: "api.cerebras.ai"
11461
+ });
11462
+
11463
+ // src/internal/providers/builtin/cohere.ts
11464
+ var COHERE = openAiCompatibleProfile({
11465
+ name: "cohere",
11466
+ baseUrl: "https://api.cohere.ai/compatibility/v1",
11467
+ envVars: ["COHERE_API_KEY", "CO_API_KEY"],
11468
+ fallbackModels: ["command-a-03-2025"],
11469
+ hostname: "api.cohere.ai"
11470
+ });
11471
+
11472
+ // src/internal/providers/builtin/deepinfra.ts
11473
+ var DEEPINFRA = openAiCompatibleProfile({
11474
+ name: "deepinfra",
11475
+ baseUrl: "https://api.deepinfra.com/v1/openai",
11476
+ envVars: ["DEEPINFRA_API_KEY"],
11477
+ fallbackModels: ["Qwen/Qwen3-32B"],
11478
+ hostname: "api.deepinfra.com"
11479
+ });
11480
+
11481
+ // src/internal/providers/builtin/google.ts
11482
+ var GOOGLE = openAiCompatibleProfile({
11483
+ name: "google",
11484
+ baseUrl: "https://generativelanguage.googleapis.com/v1beta/openai",
11485
+ envVars: ["GOOGLE_API_KEY", "GEMINI_API_KEY"],
11486
+ fallbackModels: ["gemini-2.5-pro", "gemini-2.5-flash"],
11487
+ hostname: "generativelanguage.googleapis.com"
11488
+ });
11489
+
11490
+ // src/internal/providers/builtin/groq.ts
11491
+ var GROQ = openAiCompatibleProfile({
11492
+ name: "groq",
11493
+ baseUrl: "https://api.groq.com/openai/v1",
11494
+ envVars: ["GROQ_API_KEY"],
11495
+ fallbackModels: ["llama-3.3-70b-versatile", "llama-3.1-8b-instant"],
11496
+ hostname: "api.groq.com"
11497
+ });
11498
+
11499
+ // src/internal/providers/builtin/mistral.ts
11500
+ var MISTRAL = openAiCompatibleProfile({
11501
+ name: "mistral",
11502
+ baseUrl: "https://api.mistral.ai/v1",
11503
+ envVars: ["MISTRAL_API_KEY"],
11504
+ fallbackModels: ["mistral-large-latest", "codestral-latest"],
11505
+ hostname: "api.mistral.ai"
11506
+ });
11507
+
11508
+ // src/internal/providers/builtin/perplexity.ts
11509
+ var PERPLEXITY = openAiCompatibleProfile({
11510
+ name: "perplexity",
11511
+ baseUrl: "https://api.perplexity.ai",
11512
+ chatCompletionsPath: "/chat/completions",
11513
+ envVars: ["PERPLEXITY_API_KEY"],
11514
+ fallbackModels: ["sonar-pro", "sonar"],
11515
+ hostname: "api.perplexity.ai"
11516
+ });
11517
+
11518
+ // src/internal/providers/builtin/together.ts
11519
+ var TOGETHER = openAiCompatibleProfile({
11520
+ name: "together",
11521
+ aliases: ["togetherai"],
11522
+ baseUrl: "https://api.together.xyz/v1",
11523
+ envVars: ["TOGETHER_API_KEY"],
11524
+ fallbackModels: ["Qwen/Qwen2.5-7B-Instruct-Turbo"],
11525
+ hostname: "api.together.xyz"
11526
+ });
11527
+
11528
+ // src/internal/providers/builtin/xai.ts
11529
+ var XAI = openAiCompatibleProfile({
11530
+ name: "xai",
11531
+ aliases: ["grok"],
11532
+ baseUrl: "https://api.x.ai/v1",
11533
+ envVars: ["XAI_API_KEY"],
11534
+ fallbackModels: ["grok-4.5", "grok-4.3"],
11535
+ hostname: "api.x.ai"
11536
+ });
11537
+
11400
11538
  // src/internal/providers/builtin/gemini.ts
11401
11539
  var GEMINI = {
11402
11540
  name: "gemini",
@@ -11821,7 +11959,11 @@ var OPENROUTER = {
11821
11959
  baseUrl: "https://openrouter.ai/api",
11822
11960
  modelsUrl: "https://openrouter.ai/api/v1/models",
11823
11961
  hostname: "openrouter.ai",
11824
- fallbackModels: ["openai/gpt-4o-mini", "anthropic/claude-3-haiku"]
11962
+ // M45 — models refreshed (claude-3-haiku retired upstream).
11963
+ fallbackModels: ["openai/gpt-4o-mini", "anthropic/claude-haiku-4-5"],
11964
+ // M45 — OpenRouter app-attribution headers (mechanism from OpenCode's openrouter plugin, MIT; VALUES are
11965
+ // theokit's own — copying another app's referer would misattribute traffic).
11966
+ extraHeaders: { "HTTP-Referer": "https://usetheo.dev", "X-Title": "theokit" }
11825
11967
  };
11826
11968
 
11827
11969
  // src/internal/providers/builtin/vertex.ts
@@ -11870,6 +12012,15 @@ function registerBuiltins() {
11870
12012
  registerProvider(LLAMACPP);
11871
12013
  registerProvider(BEDROCK);
11872
12014
  registerProvider(VERTEX);
12015
+ registerProvider(GOOGLE);
12016
+ registerProvider(MISTRAL);
12017
+ registerProvider(GROQ);
12018
+ registerProvider(COHERE);
12019
+ registerProvider(DEEPINFRA);
12020
+ registerProvider(TOGETHER);
12021
+ registerProvider(XAI);
12022
+ registerProvider(PERPLEXITY);
12023
+ registerProvider(CEREBRAS);
11873
12024
  registerCatalogProviders();
11874
12025
  }
11875
12026
 
@@ -12137,14 +12288,16 @@ var AnthropicClient = class {
12137
12288
  // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: HTTP+SSE handshake + accumulator is intentionally one block
12138
12289
  async *stream(request, signal) {
12139
12290
  const body = buildAnthropicBody(request);
12291
+ const headers = {
12292
+ "content-type": "application/json",
12293
+ "x-api-key": this.options.apiKey,
12294
+ "anthropic-version": this.options.version ?? "2023-06-01"
12295
+ };
12296
+ if (this.options.extraHeaders !== void 0) Object.assign(headers, this.options.extraHeaders);
12140
12297
  const response = await this.fetchImpl(`${this.baseUrl}/v1/messages`, {
12141
12298
  method: "POST",
12142
12299
  signal,
12143
- headers: {
12144
- "content-type": "application/json",
12145
- "x-api-key": this.options.apiKey,
12146
- "anthropic-version": this.options.version ?? "2023-06-01"
12147
- },
12300
+ headers,
12148
12301
  body: JSON.stringify(body)
12149
12302
  });
12150
12303
  if (!response.ok) {
@@ -13021,11 +13174,13 @@ var OpenAIClient = class {
13021
13174
  constructor(options) {
13022
13175
  this.options = options;
13023
13176
  this.baseUrl = options.baseUrl ?? "https://api.openai.com";
13177
+ this.chatPath = options.chatCompletionsPath ?? (/\/v\d+[a-z]*(\/|$)/.test(new URL(this.baseUrl).pathname) ? "/chat/completions" : "/v1/chat/completions");
13024
13178
  this.fetchImpl = options.fetch ?? fetch;
13025
13179
  }
13026
13180
  options;
13027
13181
  name = "openai";
13028
13182
  baseUrl;
13183
+ chatPath;
13029
13184
  fetchImpl;
13030
13185
  /**
13031
13186
  * Whether this client recovers leaked Hermes tool-call dialect from assistant
@@ -13048,7 +13203,7 @@ var OpenAIClient = class {
13048
13203
  const providerId = this.options.providerName ?? this.name;
13049
13204
  let response;
13050
13205
  try {
13051
- response = await this.fetchImpl(`${this.baseUrl}/v1/chat/completions`, {
13206
+ response = await this.fetchImpl(`${this.baseUrl}${this.chatPath}`, {
13052
13207
  method: "POST",
13053
13208
  signal,
13054
13209
  headers,
@@ -14145,6 +14300,9 @@ function selectTransport(profile, apiKey) {
14145
14300
  if (profile.extractToolCallsFromContent === true) {
14146
14301
  opts.extractToolCallsFromContent = true;
14147
14302
  }
14303
+ if (profile.chatCompletionsPath !== void 0) {
14304
+ opts.chatCompletionsPath = profile.chatCompletionsPath;
14305
+ }
14148
14306
  if (profile.name === "openai" && process.env.OPENAI_ORGANIZATION !== void 0) {
14149
14307
  opts.organization = process.env.OPENAI_ORGANIZATION;
14150
14308
  }
@@ -14164,6 +14322,11 @@ function selectTransport(profile, apiKey) {
14164
14322
  }
14165
14323
  const opts = { apiKey };
14166
14324
  opts.baseUrl = process.env.ANTHROPIC_API_BASE_URL ?? profile.baseUrl;
14325
+ const t = applyTransform();
14326
+ assertOAuthResolved(t);
14327
+ if (t.fetch !== void 0) opts.fetch = t.fetch;
14328
+ const merged = profile.extraHeaders !== void 0 || t.headers !== void 0 ? { ...profile.extraHeaders, ...t.headers } : void 0;
14329
+ if (merged !== void 0) opts.extraHeaders = merged;
14167
14330
  return new AnthropicClient(opts);
14168
14331
  }
14169
14332
  if (profile.apiMode === "bedrock_anthropic") {