@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/index.cjs CHANGED
@@ -13121,8 +13121,17 @@ var catalogModelSchema = zod.z.object({
13121
13121
  }).loose();
13122
13122
 
13123
13123
  // src/internal/providers/registry.ts
13124
- var REGISTRY = /* @__PURE__ */ new Map();
13125
- var ALIASES = /* @__PURE__ */ new Map();
13124
+ function globalSingleton(key2, create) {
13125
+ const g = globalThis;
13126
+ const sym = Symbol.for(key2);
13127
+ if (g[sym] === void 0) g[sym] = create();
13128
+ return g[sym];
13129
+ }
13130
+ var REGISTRY = globalSingleton(
13131
+ "theokit-sdk.providers.registry",
13132
+ () => /* @__PURE__ */ new Map()
13133
+ );
13134
+ var ALIASES = globalSingleton("theokit-sdk.providers.aliases", () => /* @__PURE__ */ new Map());
13126
13135
  function registerProvider(profile) {
13127
13136
  if (REGISTRY.has(profile.name)) {
13128
13137
  process.stderr.write(`[theokit-sdk] Provider "${profile.name}" overridden by user plugin.
@@ -13150,18 +13159,43 @@ function listProviders() {
13150
13159
 
13151
13160
  // src/internal/providers/catalog-loader.ts
13152
13161
  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('index.cjs', document.baseURI).href))));
13153
- var modelInfoIndex = /* @__PURE__ */ new Map();
13162
+ function globalSingleton2(key2, create) {
13163
+ const g = globalThis;
13164
+ const sym = Symbol.for(key2);
13165
+ if (g[sym] === void 0) g[sym] = create();
13166
+ return g[sym];
13167
+ }
13168
+ var modelInfoIndex = globalSingleton2(
13169
+ "theokit-sdk.providers.model-info-index",
13170
+ () => /* @__PURE__ */ new Map()
13171
+ );
13172
+ var patchedModelKeys = globalSingleton2(
13173
+ "theokit-sdk.providers.model-info-patched",
13174
+ () => /* @__PURE__ */ new Set()
13175
+ );
13176
+ var indexState = globalSingleton2("theokit-sdk.providers.model-info-loaded", () => ({
13177
+ loaded: false
13178
+ }));
13154
13179
  function getCatalogModelInfo(key2) {
13155
13180
  ensureModelIndexLoaded();
13156
13181
  return modelInfoIndex.get(key2);
13157
13182
  }
13158
- var _modelIndexLoaded = false;
13183
+ function isPatchedModelKey(key2) {
13184
+ return patchedModelKeys.has(key2);
13185
+ }
13159
13186
  function ensureModelIndexLoaded() {
13160
- if (_modelIndexLoaded) return;
13161
- _modelIndexLoaded = true;
13162
- const catalog = loadProviderCatalog();
13163
- for (const entry of Object.values(catalog)) {
13164
- indexEntryModels(entry);
13187
+ if (indexState.loaded) return;
13188
+ indexState.loaded = true;
13189
+ try {
13190
+ const catalog = loadProviderCatalog();
13191
+ for (const entry of Object.values(catalog)) {
13192
+ indexEntryModels(entry);
13193
+ }
13194
+ } catch (err) {
13195
+ process.stderr.write(
13196
+ `[theokit-sdk] WARN: provider catalog unavailable (${err.message}) \u2014 per-model data disabled
13197
+ `
13198
+ );
13165
13199
  }
13166
13200
  }
13167
13201
  function indexEntryModels(entry) {
@@ -13425,8 +13459,10 @@ function getPricingEntry(opts) {
13425
13459
  return void 0;
13426
13460
  }
13427
13461
  function catalogCostFallback(provider, cleanedModel) {
13428
- const keys = [`${provider}/${cleanedModel}`, cleanedModel];
13429
- for (const key2 of keys) {
13462
+ const stripped = stripDateSuffix(cleanedModel);
13463
+ const candidates = [`${provider}/${cleanedModel}`, cleanedModel];
13464
+ if (stripped !== cleanedModel) candidates.push(`${provider}/${stripped}`, stripped);
13465
+ for (const key2 of candidates) {
13430
13466
  const info = getCatalogModelInfo(key2);
13431
13467
  const cost = info?.cost;
13432
13468
  if (cost === void 0) continue;
@@ -13438,7 +13474,8 @@ function catalogCostFallback(provider, cleanedModel) {
13438
13474
  outputCostPerMillion: cost.output,
13439
13475
  ...cost.cache_read !== void 0 ? { cacheReadCostPerMillion: cost.cache_read } : {},
13440
13476
  ...cost.cache_write !== void 0 ? { cacheWriteCostPerMillion: cost.cache_write } : {},
13441
- pricingVersion: "catalog-vendored"
13477
+ // M44 M5 fix — honest provenance: a key patched by the LIVE models-dev source is not "vendored".
13478
+ pricingVersion: isPatchedModelKey(key2) ? "catalog-models-dev" : "catalog-vendored"
13442
13479
  };
13443
13480
  }
13444
13481
  return void 0;
@@ -13966,7 +14003,13 @@ var ANTHROPIC = {
13966
14003
  baseUrl: "https://api.anthropic.com",
13967
14004
  modelsUrl: "https://api.anthropic.com/v1/models",
13968
14005
  hostname: "api.anthropic.com",
13969
- fallbackModels: ["claude-opus-4-7", "claude-sonnet-4-6", "claude-haiku-4-5-20251001"]
14006
+ fallbackModels: ["claude-opus-4-7", "claude-sonnet-4-6", "claude-haiku-4-5-20251001"],
14007
+ // M45 — the Anthropic beta-features header (interleaved thinking + fine-grained tool streaming). An
14008
+ // Anthropic API constant, adapted verbatim from OpenCode's anthropic plugin (MIT © 2025 opencode). The
14009
+ // SANCTIONED behavior delta of M45 (ADR D4) — consumed by the anthropic transport's extraHeaders wiring.
14010
+ extraHeaders: {
14011
+ "anthropic-beta": "interleaved-thinking-2025-05-14,fine-grained-tool-streaming-2025-05-14"
14012
+ }
13970
14013
  };
13971
14014
 
13972
14015
  // src/internal/providers/builtin/bedrock.ts
@@ -14001,6 +14044,101 @@ function resolveBedrockBaseUrl(modelId) {
14001
14044
  return `https://bedrock-runtime.${region}.amazonaws.com`;
14002
14045
  }
14003
14046
 
14047
+ // src/internal/providers/builtin/openai-compatible.ts
14048
+ function openAiCompatibleProfile(p) {
14049
+ return {
14050
+ apiMode: "chat_completions",
14051
+ authType: "api_key",
14052
+ fallbackModels: [],
14053
+ ...p
14054
+ };
14055
+ }
14056
+
14057
+ // src/internal/providers/builtin/cerebras.ts
14058
+ var CEREBRAS = openAiCompatibleProfile({
14059
+ name: "cerebras",
14060
+ baseUrl: "https://api.cerebras.ai/v1",
14061
+ envVars: ["CEREBRAS_API_KEY"],
14062
+ fallbackModels: ["gpt-oss-120b", "zai-glm-4.7"],
14063
+ extraHeaders: { "X-Cerebras-3rd-Party-Integration": "theokit" },
14064
+ hostname: "api.cerebras.ai"
14065
+ });
14066
+
14067
+ // src/internal/providers/builtin/cohere.ts
14068
+ var COHERE = openAiCompatibleProfile({
14069
+ name: "cohere",
14070
+ baseUrl: "https://api.cohere.ai/compatibility/v1",
14071
+ envVars: ["COHERE_API_KEY", "CO_API_KEY"],
14072
+ fallbackModels: ["command-a-03-2025"],
14073
+ hostname: "api.cohere.ai"
14074
+ });
14075
+
14076
+ // src/internal/providers/builtin/deepinfra.ts
14077
+ var DEEPINFRA = openAiCompatibleProfile({
14078
+ name: "deepinfra",
14079
+ baseUrl: "https://api.deepinfra.com/v1/openai",
14080
+ envVars: ["DEEPINFRA_API_KEY"],
14081
+ fallbackModels: ["Qwen/Qwen3-32B"],
14082
+ hostname: "api.deepinfra.com"
14083
+ });
14084
+
14085
+ // src/internal/providers/builtin/google.ts
14086
+ var GOOGLE = openAiCompatibleProfile({
14087
+ name: "google",
14088
+ baseUrl: "https://generativelanguage.googleapis.com/v1beta/openai",
14089
+ envVars: ["GOOGLE_API_KEY", "GEMINI_API_KEY"],
14090
+ fallbackModels: ["gemini-2.5-pro", "gemini-2.5-flash"],
14091
+ hostname: "generativelanguage.googleapis.com"
14092
+ });
14093
+
14094
+ // src/internal/providers/builtin/groq.ts
14095
+ var GROQ = openAiCompatibleProfile({
14096
+ name: "groq",
14097
+ baseUrl: "https://api.groq.com/openai/v1",
14098
+ envVars: ["GROQ_API_KEY"],
14099
+ fallbackModels: ["llama-3.3-70b-versatile", "llama-3.1-8b-instant"],
14100
+ hostname: "api.groq.com"
14101
+ });
14102
+
14103
+ // src/internal/providers/builtin/mistral.ts
14104
+ var MISTRAL = openAiCompatibleProfile({
14105
+ name: "mistral",
14106
+ baseUrl: "https://api.mistral.ai/v1",
14107
+ envVars: ["MISTRAL_API_KEY"],
14108
+ fallbackModels: ["mistral-large-latest", "codestral-latest"],
14109
+ hostname: "api.mistral.ai"
14110
+ });
14111
+
14112
+ // src/internal/providers/builtin/perplexity.ts
14113
+ var PERPLEXITY = openAiCompatibleProfile({
14114
+ name: "perplexity",
14115
+ baseUrl: "https://api.perplexity.ai",
14116
+ chatCompletionsPath: "/chat/completions",
14117
+ envVars: ["PERPLEXITY_API_KEY"],
14118
+ fallbackModels: ["sonar-pro", "sonar"],
14119
+ hostname: "api.perplexity.ai"
14120
+ });
14121
+
14122
+ // src/internal/providers/builtin/together.ts
14123
+ var TOGETHER = openAiCompatibleProfile({
14124
+ name: "together",
14125
+ aliases: ["togetherai"],
14126
+ baseUrl: "https://api.together.xyz/v1",
14127
+ envVars: ["TOGETHER_API_KEY"],
14128
+ fallbackModels: ["Qwen/Qwen2.5-7B-Instruct-Turbo"],
14129
+ hostname: "api.together.xyz"
14130
+ });
14131
+
14132
+ // src/internal/providers/builtin/xai.ts
14133
+ var XAI = openAiCompatibleProfile({
14134
+ name: "xai",
14135
+ aliases: ["grok"],
14136
+ baseUrl: "https://api.x.ai/v1",
14137
+ envVars: ["XAI_API_KEY"],
14138
+ fallbackModels: ["grok-4.5", "grok-4.3"],
14139
+ hostname: "api.x.ai"
14140
+ });
14141
+
14004
14142
  // src/internal/providers/builtin/gemini.ts
14005
14143
  var GEMINI = {
14006
14144
  name: "gemini",
@@ -14425,7 +14563,11 @@ var OPENROUTER = {
14425
14563
  baseUrl: "https://openrouter.ai/api",
14426
14564
  modelsUrl: "https://openrouter.ai/api/v1/models",
14427
14565
  hostname: "openrouter.ai",
14428
- fallbackModels: ["openai/gpt-4o-mini", "anthropic/claude-3-haiku"]
14566
+ // M45 — models refreshed (claude-3-haiku retired upstream).
14567
+ fallbackModels: ["openai/gpt-4o-mini", "anthropic/claude-haiku-4-5"],
14568
+ // M45 — OpenRouter app-attribution headers (mechanism from OpenCode's openrouter plugin, MIT; VALUES are
14569
+ // theokit's own — copying another app's referer would misattribute traffic).
14570
+ extraHeaders: { "HTTP-Referer": "https://usetheo.dev", "X-Title": "theokit" }
14429
14571
  };
14430
14572
 
14431
14573
  // src/internal/providers/builtin/vertex.ts
@@ -14474,6 +14616,15 @@ function registerBuiltins() {
14474
14616
  registerProvider(LLAMACPP);
14475
14617
  registerProvider(BEDROCK);
14476
14618
  registerProvider(VERTEX);
14619
+ registerProvider(GOOGLE);
14620
+ registerProvider(MISTRAL);
14621
+ registerProvider(GROQ);
14622
+ registerProvider(COHERE);
14623
+ registerProvider(DEEPINFRA);
14624
+ registerProvider(TOGETHER);
14625
+ registerProvider(XAI);
14626
+ registerProvider(PERPLEXITY);
14627
+ registerProvider(CEREBRAS);
14477
14628
  registerCatalogProviders();
14478
14629
  }
14479
14630
 
@@ -14742,14 +14893,16 @@ var AnthropicClient = class {
14742
14893
  // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: HTTP+SSE handshake + accumulator is intentionally one block
14743
14894
  async *stream(request, signal) {
14744
14895
  const body = buildAnthropicBody(request);
14896
+ const headers = {
14897
+ "content-type": "application/json",
14898
+ "x-api-key": this.options.apiKey,
14899
+ "anthropic-version": this.options.version ?? "2023-06-01"
14900
+ };
14901
+ if (this.options.extraHeaders !== void 0) Object.assign(headers, this.options.extraHeaders);
14745
14902
  const response = await this.fetchImpl(`${this.baseUrl}/v1/messages`, {
14746
14903
  method: "POST",
14747
14904
  signal,
14748
- headers: {
14749
- "content-type": "application/json",
14750
- "x-api-key": this.options.apiKey,
14751
- "anthropic-version": this.options.version ?? "2023-06-01"
14752
- },
14905
+ headers,
14753
14906
  body: JSON.stringify(body)
14754
14907
  });
14755
14908
  if (!response.ok) {
@@ -15626,11 +15779,13 @@ var OpenAIClient = class {
15626
15779
  constructor(options) {
15627
15780
  this.options = options;
15628
15781
  this.baseUrl = options.baseUrl ?? "https://api.openai.com";
15782
+ this.chatPath = options.chatCompletionsPath ?? (/\/v\d+[a-z]*(\/|$)/.test(new URL(this.baseUrl).pathname) ? "/chat/completions" : "/v1/chat/completions");
15629
15783
  this.fetchImpl = options.fetch ?? fetch;
15630
15784
  }
15631
15785
  options;
15632
15786
  name = "openai";
15633
15787
  baseUrl;
15788
+ chatPath;
15634
15789
  fetchImpl;
15635
15790
  /**
15636
15791
  * Whether this client recovers leaked Hermes tool-call dialect from assistant
@@ -15653,7 +15808,7 @@ var OpenAIClient = class {
15653
15808
  const providerId = this.options.providerName ?? this.name;
15654
15809
  let response;
15655
15810
  try {
15656
- response = await this.fetchImpl(`${this.baseUrl}/v1/chat/completions`, {
15811
+ response = await this.fetchImpl(`${this.baseUrl}${this.chatPath}`, {
15657
15812
  method: "POST",
15658
15813
  signal,
15659
15814
  headers,
@@ -16750,6 +16905,9 @@ function selectTransport(profile, apiKey) {
16750
16905
  if (profile.extractToolCallsFromContent === true) {
16751
16906
  opts.extractToolCallsFromContent = true;
16752
16907
  }
16908
+ if (profile.chatCompletionsPath !== void 0) {
16909
+ opts.chatCompletionsPath = profile.chatCompletionsPath;
16910
+ }
16753
16911
  if (profile.name === "openai" && process.env.OPENAI_ORGANIZATION !== void 0) {
16754
16912
  opts.organization = process.env.OPENAI_ORGANIZATION;
16755
16913
  }
@@ -16769,6 +16927,11 @@ function selectTransport(profile, apiKey) {
16769
16927
  }
16770
16928
  const opts = { apiKey };
16771
16929
  opts.baseUrl = process.env.ANTHROPIC_API_BASE_URL ?? profile.baseUrl;
16930
+ const t = applyTransform();
16931
+ assertOAuthResolved(t);
16932
+ if (t.fetch !== void 0) opts.fetch = t.fetch;
16933
+ const merged = profile.extraHeaders !== void 0 || t.headers !== void 0 ? { ...profile.extraHeaders, ...t.headers } : void 0;
16934
+ if (merged !== void 0) opts.extraHeaders = merged;
16772
16935
  return new AnthropicClient(opts);
16773
16936
  }
16774
16937
  if (profile.apiMode === "bedrock_anthropic") {