@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/cron.d.cts CHANGED
@@ -1,3 +1,3 @@
1
- export { N as Cron } from './cron-DK1WVZnI.cjs';
1
+ export { N as Cron } from './cron-ElTj1cSH.cjs';
2
2
  import './run-DFM1H2jW.cjs';
3
3
  import 'zod';
package/dist/cron.d.ts CHANGED
@@ -1,3 +1,3 @@
1
- export { N as Cron } from './cron-C7catiH8.js';
1
+ export { N as Cron } from './cron-DY0uC1ng.js';
2
2
  import './run-DFM1H2jW.js';
3
3
  import 'zod';
package/dist/cron.js CHANGED
@@ -10536,8 +10536,17 @@ var catalogModelSchema = z.object({
10536
10536
  }).loose();
10537
10537
 
10538
10538
  // src/internal/providers/registry.ts
10539
- var REGISTRY = /* @__PURE__ */ new Map();
10540
- var ALIASES = /* @__PURE__ */ new Map();
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());
10541
10550
  function registerProvider(profile) {
10542
10551
  if (REGISTRY.has(profile.name)) {
10543
10552
  process.stderr.write(`[theokit-sdk] Provider "${profile.name}" overridden by user plugin.
@@ -10562,18 +10571,43 @@ function getProviderProfile(name) {
10562
10571
 
10563
10572
  // src/internal/providers/catalog-loader.ts
10564
10573
  var __dirname_resolved = dirname(fileURLToPath(import.meta.url));
10565
- var modelInfoIndex = /* @__PURE__ */ new Map();
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
+ }));
10566
10591
  function getCatalogModelInfo(key) {
10567
10592
  ensureModelIndexLoaded();
10568
10593
  return modelInfoIndex.get(key);
10569
10594
  }
10570
- var _modelIndexLoaded = false;
10595
+ function isPatchedModelKey(key) {
10596
+ return patchedModelKeys.has(key);
10597
+ }
10571
10598
  function ensureModelIndexLoaded() {
10572
- if (_modelIndexLoaded) return;
10573
- _modelIndexLoaded = true;
10574
- const catalog = loadProviderCatalog();
10575
- for (const entry of Object.values(catalog)) {
10576
- indexEntryModels(entry);
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
+ );
10577
10611
  }
10578
10612
  }
10579
10613
  function indexEntryModels(entry) {
@@ -10826,8 +10860,10 @@ function getPricingEntry(opts) {
10826
10860
  return void 0;
10827
10861
  }
10828
10862
  function catalogCostFallback(provider, cleanedModel) {
10829
- const keys = [`${provider}/${cleanedModel}`, cleanedModel];
10830
- for (const key of keys) {
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) {
10831
10867
  const info = getCatalogModelInfo(key);
10832
10868
  const cost = info?.cost;
10833
10869
  if (cost === void 0) continue;
@@ -10839,7 +10875,8 @@ function catalogCostFallback(provider, cleanedModel) {
10839
10875
  outputCostPerMillion: cost.output,
10840
10876
  ...cost.cache_read !== void 0 ? { cacheReadCostPerMillion: cost.cache_read } : {},
10841
10877
  ...cost.cache_write !== void 0 ? { cacheWriteCostPerMillion: cost.cache_write } : {},
10842
- pricingVersion: "catalog-vendored"
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"
10843
10880
  };
10844
10881
  }
10845
10882
  return void 0;
@@ -11367,7 +11404,13 @@ var ANTHROPIC = {
11367
11404
  baseUrl: "https://api.anthropic.com",
11368
11405
  modelsUrl: "https://api.anthropic.com/v1/models",
11369
11406
  hostname: "api.anthropic.com",
11370
- fallbackModels: ["claude-opus-4-7", "claude-sonnet-4-6", "claude-haiku-4-5-20251001"]
11407
+ fallbackModels: ["claude-opus-4-7", "claude-sonnet-4-6", "claude-haiku-4-5-20251001"],
11408
+ // M45 — the Anthropic beta-features header (interleaved thinking + fine-grained tool streaming). An
11409
+ // Anthropic API constant, adapted verbatim from OpenCode's anthropic plugin (MIT © 2025 opencode). The
11410
+ // SANCTIONED behavior delta of M45 (ADR D4) — consumed by the anthropic transport's extraHeaders wiring.
11411
+ extraHeaders: {
11412
+ "anthropic-beta": "interleaved-thinking-2025-05-14,fine-grained-tool-streaming-2025-05-14"
11413
+ }
11371
11414
  };
11372
11415
 
11373
11416
  // src/internal/providers/builtin/bedrock.ts
@@ -11402,6 +11445,101 @@ function resolveBedrockBaseUrl(modelId) {
11402
11445
  return `https://bedrock-runtime.${region}.amazonaws.com`;
11403
11446
  }
11404
11447
 
11448
+ // src/internal/providers/builtin/openai-compatible.ts
11449
+ function openAiCompatibleProfile(p) {
11450
+ return {
11451
+ apiMode: "chat_completions",
11452
+ authType: "api_key",
11453
+ fallbackModels: [],
11454
+ ...p
11455
+ };
11456
+ }
11457
+
11458
+ // src/internal/providers/builtin/cerebras.ts
11459
+ var CEREBRAS = openAiCompatibleProfile({
11460
+ name: "cerebras",
11461
+ baseUrl: "https://api.cerebras.ai/v1",
11462
+ envVars: ["CEREBRAS_API_KEY"],
11463
+ fallbackModels: ["gpt-oss-120b", "zai-glm-4.7"],
11464
+ extraHeaders: { "X-Cerebras-3rd-Party-Integration": "theokit" },
11465
+ hostname: "api.cerebras.ai"
11466
+ });
11467
+
11468
+ // src/internal/providers/builtin/cohere.ts
11469
+ var COHERE = openAiCompatibleProfile({
11470
+ name: "cohere",
11471
+ baseUrl: "https://api.cohere.ai/compatibility/v1",
11472
+ envVars: ["COHERE_API_KEY", "CO_API_KEY"],
11473
+ fallbackModels: ["command-a-03-2025"],
11474
+ hostname: "api.cohere.ai"
11475
+ });
11476
+
11477
+ // src/internal/providers/builtin/deepinfra.ts
11478
+ var DEEPINFRA = openAiCompatibleProfile({
11479
+ name: "deepinfra",
11480
+ baseUrl: "https://api.deepinfra.com/v1/openai",
11481
+ envVars: ["DEEPINFRA_API_KEY"],
11482
+ fallbackModels: ["Qwen/Qwen3-32B"],
11483
+ hostname: "api.deepinfra.com"
11484
+ });
11485
+
11486
+ // src/internal/providers/builtin/google.ts
11487
+ var GOOGLE = openAiCompatibleProfile({
11488
+ name: "google",
11489
+ baseUrl: "https://generativelanguage.googleapis.com/v1beta/openai",
11490
+ envVars: ["GOOGLE_API_KEY", "GEMINI_API_KEY"],
11491
+ fallbackModels: ["gemini-2.5-pro", "gemini-2.5-flash"],
11492
+ hostname: "generativelanguage.googleapis.com"
11493
+ });
11494
+
11495
+ // src/internal/providers/builtin/groq.ts
11496
+ var GROQ = openAiCompatibleProfile({
11497
+ name: "groq",
11498
+ baseUrl: "https://api.groq.com/openai/v1",
11499
+ envVars: ["GROQ_API_KEY"],
11500
+ fallbackModels: ["llama-3.3-70b-versatile", "llama-3.1-8b-instant"],
11501
+ hostname: "api.groq.com"
11502
+ });
11503
+
11504
+ // src/internal/providers/builtin/mistral.ts
11505
+ var MISTRAL = openAiCompatibleProfile({
11506
+ name: "mistral",
11507
+ baseUrl: "https://api.mistral.ai/v1",
11508
+ envVars: ["MISTRAL_API_KEY"],
11509
+ fallbackModels: ["mistral-large-latest", "codestral-latest"],
11510
+ hostname: "api.mistral.ai"
11511
+ });
11512
+
11513
+ // src/internal/providers/builtin/perplexity.ts
11514
+ var PERPLEXITY = openAiCompatibleProfile({
11515
+ name: "perplexity",
11516
+ baseUrl: "https://api.perplexity.ai",
11517
+ chatCompletionsPath: "/chat/completions",
11518
+ envVars: ["PERPLEXITY_API_KEY"],
11519
+ fallbackModels: ["sonar-pro", "sonar"],
11520
+ hostname: "api.perplexity.ai"
11521
+ });
11522
+
11523
+ // src/internal/providers/builtin/together.ts
11524
+ var TOGETHER = openAiCompatibleProfile({
11525
+ name: "together",
11526
+ aliases: ["togetherai"],
11527
+ baseUrl: "https://api.together.xyz/v1",
11528
+ envVars: ["TOGETHER_API_KEY"],
11529
+ fallbackModels: ["Qwen/Qwen2.5-7B-Instruct-Turbo"],
11530
+ hostname: "api.together.xyz"
11531
+ });
11532
+
11533
+ // src/internal/providers/builtin/xai.ts
11534
+ var XAI = openAiCompatibleProfile({
11535
+ name: "xai",
11536
+ aliases: ["grok"],
11537
+ baseUrl: "https://api.x.ai/v1",
11538
+ envVars: ["XAI_API_KEY"],
11539
+ fallbackModels: ["grok-4.5", "grok-4.3"],
11540
+ hostname: "api.x.ai"
11541
+ });
11542
+
11405
11543
  // src/internal/providers/builtin/gemini.ts
11406
11544
  var GEMINI = {
11407
11545
  name: "gemini",
@@ -11826,7 +11964,11 @@ var OPENROUTER = {
11826
11964
  baseUrl: "https://openrouter.ai/api",
11827
11965
  modelsUrl: "https://openrouter.ai/api/v1/models",
11828
11966
  hostname: "openrouter.ai",
11829
- fallbackModels: ["openai/gpt-4o-mini", "anthropic/claude-3-haiku"]
11967
+ // M45 — models refreshed (claude-3-haiku retired upstream).
11968
+ fallbackModels: ["openai/gpt-4o-mini", "anthropic/claude-haiku-4-5"],
11969
+ // M45 — OpenRouter app-attribution headers (mechanism from OpenCode's openrouter plugin, MIT; VALUES are
11970
+ // theokit's own — copying another app's referer would misattribute traffic).
11971
+ extraHeaders: { "HTTP-Referer": "https://usetheo.dev", "X-Title": "theokit" }
11830
11972
  };
11831
11973
 
11832
11974
  // src/internal/providers/builtin/vertex.ts
@@ -11875,6 +12017,15 @@ function registerBuiltins() {
11875
12017
  registerProvider(LLAMACPP);
11876
12018
  registerProvider(BEDROCK);
11877
12019
  registerProvider(VERTEX);
12020
+ registerProvider(GOOGLE);
12021
+ registerProvider(MISTRAL);
12022
+ registerProvider(GROQ);
12023
+ registerProvider(COHERE);
12024
+ registerProvider(DEEPINFRA);
12025
+ registerProvider(TOGETHER);
12026
+ registerProvider(XAI);
12027
+ registerProvider(PERPLEXITY);
12028
+ registerProvider(CEREBRAS);
11878
12029
  registerCatalogProviders();
11879
12030
  }
11880
12031
 
@@ -12142,14 +12293,16 @@ var AnthropicClient = class {
12142
12293
  // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: HTTP+SSE handshake + accumulator is intentionally one block
12143
12294
  async *stream(request, signal) {
12144
12295
  const body = buildAnthropicBody(request);
12296
+ const headers = {
12297
+ "content-type": "application/json",
12298
+ "x-api-key": this.options.apiKey,
12299
+ "anthropic-version": this.options.version ?? "2023-06-01"
12300
+ };
12301
+ if (this.options.extraHeaders !== void 0) Object.assign(headers, this.options.extraHeaders);
12145
12302
  const response = await this.fetchImpl(`${this.baseUrl}/v1/messages`, {
12146
12303
  method: "POST",
12147
12304
  signal,
12148
- headers: {
12149
- "content-type": "application/json",
12150
- "x-api-key": this.options.apiKey,
12151
- "anthropic-version": this.options.version ?? "2023-06-01"
12152
- },
12305
+ headers,
12153
12306
  body: JSON.stringify(body)
12154
12307
  });
12155
12308
  if (!response.ok) {
@@ -13026,11 +13179,13 @@ var OpenAIClient = class {
13026
13179
  constructor(options) {
13027
13180
  this.options = options;
13028
13181
  this.baseUrl = options.baseUrl ?? "https://api.openai.com";
13182
+ this.chatPath = options.chatCompletionsPath ?? (/\/v\d+[a-z]*(\/|$)/.test(new URL(this.baseUrl).pathname) ? "/chat/completions" : "/v1/chat/completions");
13029
13183
  this.fetchImpl = options.fetch ?? fetch;
13030
13184
  }
13031
13185
  options;
13032
13186
  name = "openai";
13033
13187
  baseUrl;
13188
+ chatPath;
13034
13189
  fetchImpl;
13035
13190
  /**
13036
13191
  * Whether this client recovers leaked Hermes tool-call dialect from assistant
@@ -13053,7 +13208,7 @@ var OpenAIClient = class {
13053
13208
  const providerId = this.options.providerName ?? this.name;
13054
13209
  let response;
13055
13210
  try {
13056
- response = await this.fetchImpl(`${this.baseUrl}/v1/chat/completions`, {
13211
+ response = await this.fetchImpl(`${this.baseUrl}${this.chatPath}`, {
13057
13212
  method: "POST",
13058
13213
  signal,
13059
13214
  headers,
@@ -14150,6 +14305,9 @@ function selectTransport(profile, apiKey) {
14150
14305
  if (profile.extractToolCallsFromContent === true) {
14151
14306
  opts.extractToolCallsFromContent = true;
14152
14307
  }
14308
+ if (profile.chatCompletionsPath !== void 0) {
14309
+ opts.chatCompletionsPath = profile.chatCompletionsPath;
14310
+ }
14153
14311
  if (profile.name === "openai" && process.env.OPENAI_ORGANIZATION !== void 0) {
14154
14312
  opts.organization = process.env.OPENAI_ORGANIZATION;
14155
14313
  }
@@ -14169,6 +14327,11 @@ function selectTransport(profile, apiKey) {
14169
14327
  }
14170
14328
  const opts = { apiKey };
14171
14329
  opts.baseUrl = process.env.ANTHROPIC_API_BASE_URL ?? profile.baseUrl;
14330
+ const t = applyTransform();
14331
+ assertOAuthResolved(t);
14332
+ if (t.fetch !== void 0) opts.fetch = t.fetch;
14333
+ const merged = profile.extraHeaders !== void 0 || t.headers !== void 0 ? { ...profile.extraHeaders, ...t.headers } : void 0;
14334
+ if (merged !== void 0) opts.extraHeaders = merged;
14172
14335
  return new AnthropicClient(opts);
14173
14336
  }
14174
14337
  if (profile.apiMode === "bedrock_anthropic") {