@omnicross/core 0.1.8 → 0.1.9

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 (93) hide show
  1. package/dist/auth/GeminiCodeAssistProjectResolver.cjs +5 -3
  2. package/dist/auth/GeminiCodeAssistProjectResolver.js +4 -2
  3. package/dist/{chunk-N5T4M4GU.js → chunk-2UTGX6FM.js} +2 -2
  4. package/dist/{chunk-32O35CIF.js → chunk-45FHEOKW.js} +22 -7
  5. package/dist/{chunk-LVUCAWMK.js → chunk-55FMGZ3L.js} +13 -5
  6. package/dist/{chunk-OF3BECU2.cjs → chunk-56QD3YW6.cjs} +18 -5
  7. package/dist/{chunk-V4TXMEJS.cjs → chunk-5LNYGCIW.cjs} +15 -7
  8. package/dist/chunk-77USGNRW.cjs +37 -0
  9. package/dist/chunk-AOFWNWLT.cjs +203 -0
  10. package/dist/{chunk-LB6EBS6Y.js → chunk-CCVRRJOX.js} +17 -4
  11. package/dist/{chunk-OVQBNVSV.cjs → chunk-CMVXX7ON.cjs} +42 -27
  12. package/dist/{chunk-QYC54PMG.js → chunk-CQIJCPMF.js} +177 -77
  13. package/dist/{chunk-PEGTIPB3.js → chunk-HKB656B4.js} +37 -43
  14. package/dist/chunk-N2EIM2XJ.js +203 -0
  15. package/dist/{chunk-MYYR3HZL.js → chunk-NGYOO5TO.js} +5 -5
  16. package/dist/{chunk-OKMJLEXX.cjs → chunk-OC6DOOFX.cjs} +5 -5
  17. package/dist/{chunk-2Z4XM3H5.cjs → chunk-P7EM6BND.cjs} +10 -10
  18. package/dist/{chunk-KBM2W6UY.cjs → chunk-RICPANBY.cjs} +41 -24
  19. package/dist/{chunk-TOVPMMHM.js → chunk-S3DYFEBE.js} +37 -20
  20. package/dist/chunk-WYVGULTQ.js +37 -0
  21. package/dist/{chunk-26K6T2YS.cjs → chunk-XELFM7KL.cjs} +301 -201
  22. package/dist/{chunk-OXHNSZ53.cjs → chunk-ZQQUD66M.cjs} +54 -60
  23. package/dist/completion/CompletionService.cjs +12 -10
  24. package/dist/completion/CompletionService.js +11 -9
  25. package/dist/completion.cjs +12 -10
  26. package/dist/completion.js +11 -9
  27. package/dist/index.cjs +12 -10
  28. package/dist/index.d.cts +2 -2
  29. package/dist/index.d.ts +2 -2
  30. package/dist/index.js +11 -9
  31. package/dist/outbound-api/routeResolver.d.cts +1 -1
  32. package/dist/outbound-api/routeResolver.d.ts +1 -1
  33. package/dist/outbound-api/types.d.cts +1 -1
  34. package/dist/outbound-api/types.d.ts +1 -1
  35. package/dist/outbound-api.cjs +12 -10
  36. package/dist/outbound-api.d.cts +1 -1
  37. package/dist/outbound-api.d.ts +1 -1
  38. package/dist/outbound-api.js +11 -9
  39. package/dist/pipeline/AccountAllowanceScheduling.d.cts +1 -1
  40. package/dist/pipeline/AccountAllowanceScheduling.d.ts +1 -1
  41. package/dist/pipeline/executeProviderCall.d.cts +2 -0
  42. package/dist/pipeline/executeProviderCall.d.ts +2 -0
  43. package/dist/pipeline/resolveProviderChain.d.cts +1 -0
  44. package/dist/pipeline/resolveProviderChain.d.ts +1 -0
  45. package/dist/pipeline/resolveSubscriptionChain.d.cts +2 -0
  46. package/dist/pipeline/resolveSubscriptionChain.d.ts +2 -0
  47. package/dist/ports/provider-config-source.d.cts +1 -0
  48. package/dist/ports/provider-config-source.d.ts +1 -0
  49. package/dist/ports.d.cts +1 -1
  50. package/dist/ports.d.ts +1 -1
  51. package/dist/provider-proxy/ProviderProxy.cjs +12 -10
  52. package/dist/provider-proxy/ProviderProxy.js +11 -9
  53. package/dist/provider-proxy/ingress/providerProxyShared.cjs +12 -10
  54. package/dist/provider-proxy/ingress/providerProxyShared.js +11 -9
  55. package/dist/provider-proxy.cjs +12 -10
  56. package/dist/provider-proxy.js +11 -9
  57. package/dist/transformer/TransformerChainExecutor.d.cts +2 -0
  58. package/dist/transformer/TransformerChainExecutor.d.ts +2 -0
  59. package/dist/transformer/TransformerService.d.cts +2 -0
  60. package/dist/transformer/TransformerService.d.ts +2 -0
  61. package/dist/transformer/transformers/AnthropicTransformer.cjs +4 -2
  62. package/dist/transformer/transformers/AnthropicTransformer.d.cts +7 -2
  63. package/dist/transformer/transformers/AnthropicTransformer.d.ts +7 -2
  64. package/dist/transformer/transformers/AnthropicTransformer.js +3 -1
  65. package/dist/transformer/transformers/GeminiCodeAssistTransformer.cjs +5 -3
  66. package/dist/transformer/transformers/GeminiCodeAssistTransformer.d.cts +2 -0
  67. package/dist/transformer/transformers/GeminiCodeAssistTransformer.d.ts +2 -0
  68. package/dist/transformer/transformers/GeminiCodeAssistTransformer.js +4 -2
  69. package/dist/transformer/transformers/GeminiTransformer.cjs +5 -3
  70. package/dist/transformer/transformers/GeminiTransformer.d.cts +4 -2
  71. package/dist/transformer/transformers/GeminiTransformer.d.ts +4 -2
  72. package/dist/transformer/transformers/GeminiTransformer.js +4 -2
  73. package/dist/transformer/transformers/OpenAIResponseTransformer.cjs +3 -2
  74. package/dist/transformer/transformers/OpenAIResponseTransformer.d.cts +4 -2
  75. package/dist/transformer/transformers/OpenAIResponseTransformer.d.ts +4 -2
  76. package/dist/transformer/transformers/OpenAIResponseTransformer.js +2 -1
  77. package/dist/transformer/transformers/OpenAITransformer.cjs +3 -2
  78. package/dist/transformer/transformers/OpenAITransformer.d.cts +3 -1
  79. package/dist/transformer/transformers/OpenAITransformer.d.ts +3 -1
  80. package/dist/transformer/transformers/OpenAITransformer.js +2 -1
  81. package/dist/transformer/transformers.cjs +10 -8
  82. package/dist/transformer/transformers.d.cts +2 -0
  83. package/dist/transformer/transformers.d.ts +2 -0
  84. package/dist/transformer/transformers.js +9 -7
  85. package/dist/transformer/types.d.cts +16 -5
  86. package/dist/transformer/types.d.ts +16 -5
  87. package/dist/transformer.cjs +28 -9
  88. package/dist/transformer.d.cts +76 -1
  89. package/dist/transformer.d.ts +76 -1
  90. package/dist/transformer.js +28 -9
  91. package/package.json +1 -1
  92. /package/dist/{chunk-FZ46M34D.cjs → chunk-QVOB2DNX.cjs} +0 -0
  93. /package/dist/{chunk-46RLHI7D.js → chunk-WTQMX2Q6.js} +0 -0
@@ -4,13 +4,13 @@ import {
4
4
  import {
5
5
  AnthropicTransformer,
6
6
  resolveAnthropicMaxTokens
7
- } from "./chunk-PEGTIPB3.js";
7
+ } from "./chunk-HKB656B4.js";
8
8
  import {
9
9
  GeminiTransformer
10
- } from "./chunk-LVUCAWMK.js";
10
+ } from "./chunk-55FMGZ3L.js";
11
11
  import {
12
12
  OpenAIResponseTransformer
13
- } from "./chunk-32O35CIF.js";
13
+ } from "./chunk-45FHEOKW.js";
14
14
  import {
15
15
  TransformerChainExecutor
16
16
  } from "./chunk-WNKWAEUR.js";
@@ -109,6 +109,9 @@ import {
109
109
  convertAnthropicToOpenAI,
110
110
  convertOpenAIToAnthropic
111
111
  } from "./chunk-5NJLQ6T6.js";
112
+ import {
113
+ resolveReasoningPlan
114
+ } from "./chunk-N2EIM2XJ.js";
112
115
  import {
113
116
  fetchUpstream
114
117
  } from "./chunk-RJ5ZGNI3.js";
@@ -413,9 +416,6 @@ function addOpenRouterProviderToRequest(requestBody, provider, modelId) {
413
416
  };
414
417
  }
415
418
 
416
- // src/completion/DirectApiHandler.ts
417
- import { getOpenAIReasoningEffort } from "@omnicross/contracts/thinking-config";
418
-
419
419
  // src/provider-proxy/ProviderProxy.ts
420
420
  import http from "http";
421
421
 
@@ -1432,7 +1432,8 @@ async function buildByoPlan(res, route, deps, resolvedModel, isStream) {
1432
1432
  name: provider.name,
1433
1433
  baseUrl: provider.api_base_url,
1434
1434
  apiKey,
1435
- models: provider.models || []
1435
+ models: provider.models || [],
1436
+ modelConfigs: provider.modelConfigs
1436
1437
  };
1437
1438
  const byoUrl = buildProviderApiUrl(provider, { model: resolvedModel, stream: isStream });
1438
1439
  const sameFormat = route.targetProviderFormat === "anthropic" || resolveApiFormat(provider) === "anthropic";
@@ -1740,7 +1741,8 @@ async function buildByoPlan2(res, route, deps, resolvedModel, isStream) {
1740
1741
  name: provider.name,
1741
1742
  baseUrl: provider.api_base_url,
1742
1743
  apiKey,
1743
- models: provider.models || []
1744
+ models: provider.models || [],
1745
+ modelConfigs: provider.modelConfigs
1744
1746
  };
1745
1747
  const byoUrl = buildProviderApiUrl(provider, { model: resolvedModel, stream: isStream });
1746
1748
  return {
@@ -1957,7 +1959,8 @@ async function buildByoPlan3(res, route, deps, resolvedModel, isStream) {
1957
1959
  name: provider.name,
1958
1960
  baseUrl: provider.api_base_url,
1959
1961
  apiKey,
1960
- models: provider.models || []
1962
+ models: provider.models || [],
1963
+ modelConfigs: provider.modelConfigs
1961
1964
  };
1962
1965
  const byoUrl = buildProviderApiUrl(provider, { model: resolvedModel, stream: isStream });
1963
1966
  return {
@@ -2351,7 +2354,8 @@ async function buildByoPlan4(res, route, deps, resolvedModel, isStream) {
2351
2354
  name: provider.name,
2352
2355
  baseUrl: provider.api_base_url,
2353
2356
  apiKey,
2354
- models: provider.models || []
2357
+ models: provider.models || [],
2358
+ modelConfigs: provider.modelConfigs
2355
2359
  };
2356
2360
  const byoUrl = buildProviderApiUrl(provider, { model: resolvedModel, stream: isStream });
2357
2361
  return {
@@ -3562,6 +3566,7 @@ var KeyedMutex = class {
3562
3566
 
3563
3567
  // src/outbound-api/outboundApiRouter.ts
3564
3568
  import { Readable } from "stream";
3569
+ import { SUBSCRIPTION_MODEL_CATALOG } from "@omnicross/contracts/subscription-model-catalog";
3565
3570
 
3566
3571
  // src/outbound-api/apiServerConfig.ts
3567
3572
  import { DEFAULT_AUDIT_CONFIG } from "@omnicross/contracts/audit-types";
@@ -4987,33 +4992,51 @@ function isModelsListRequest(url) {
4987
4992
  const path = url.split("?")[0]?.replace(/\/+$/, "") ?? "";
4988
4993
  return path.endsWith("/models");
4989
4994
  }
4990
- function writeModelsList(res, config, apiKeyId, allowedEndpoints) {
4991
- const refs = [];
4992
- const endpointConfigs = [];
4995
+ async function writeModelsList(res, llmConfig, config, apiKeyId, allowedEndpoints) {
4996
+ const modelIds = [];
4993
4997
  for (const endpoint of ["chat", "responses", "messages", "gemini"]) {
4994
4998
  if (allowedEndpoints && !allowedEndpoints.includes(endpoint)) continue;
4995
- endpointConfigs.push(
4996
- ...candidateGatewayBindings(config.bindings, apiKeyId, endpoint).map(
4997
- (binding) => gatewayBindingToEndpointConfig(binding)
4998
- )
4999
- );
5000
- }
5001
- for (const endpoint of endpointConfigs) {
5002
- if (allowedEndpoints && !allowedEndpoints.includes(endpoint.endpoint)) continue;
5003
- if (endpoint.endpoint === "chat") refs.push(...endpoint.models ?? []);
5004
- else if (endpoint.endpoint === "messages" || endpoint.endpoint === "responses") {
5005
- refs.push(...Object.values(endpoint.modelMap ?? {}));
5006
- } else {
5007
- if (endpoint.defaultModel) refs.push(endpoint.defaultModel);
5008
- if (endpoint.backgroundModel) refs.push(endpoint.backgroundModel);
4999
+ for (const binding of candidateGatewayBindings(config.bindings, apiKeyId, endpoint)) {
5000
+ if (binding.modelMode === "passthrough") {
5001
+ if (binding.target.kind === "provider") {
5002
+ const provider = await llmConfig.getProvider(binding.target.providerId);
5003
+ modelIds.push(...provider?.models ?? []);
5004
+ } else if (Object.prototype.hasOwnProperty.call(
5005
+ SUBSCRIPTION_MODEL_CATALOG,
5006
+ binding.target.providerId
5007
+ )) {
5008
+ modelIds.push(
5009
+ ...SUBSCRIPTION_MODEL_CATALOG[binding.target.providerId]
5010
+ );
5011
+ }
5012
+ continue;
5013
+ }
5014
+ if (binding.modelMappings?.length) {
5015
+ modelIds.push(
5016
+ ...binding.modelMappings.map((mapping) => mapping.source.trim()).filter((source) => source !== "" && !source.includes("*"))
5017
+ );
5018
+ continue;
5019
+ }
5020
+ const endpointConfig = gatewayBindingToEndpointConfig(binding);
5021
+ const refs = [];
5022
+ if (endpointConfig.endpoint === "chat") refs.push(...endpointConfig.models ?? []);
5023
+ else if (endpointConfig.endpoint === "messages" || endpointConfig.endpoint === "responses") {
5024
+ refs.push(...Object.values(endpointConfig.modelMap ?? {}));
5025
+ } else {
5026
+ if (endpointConfig.defaultModel) refs.push(endpointConfig.defaultModel);
5027
+ if (endpointConfig.backgroundModel) refs.push(endpointConfig.backgroundModel);
5028
+ }
5029
+ modelIds.push(
5030
+ ...refs.map((ref) => parseModelRef(ref)?.modelId).filter((modelId) => modelId !== void 0)
5031
+ );
5009
5032
  }
5010
5033
  }
5011
5034
  const seen = /* @__PURE__ */ new Set();
5012
- const data = refs.map((ref) => parseModelRef(ref)).filter((p) => p !== null).filter((p) => {
5013
- if (seen.has(p.modelId)) return false;
5014
- seen.add(p.modelId);
5035
+ const data = modelIds.filter((modelId) => {
5036
+ if (seen.has(modelId)) return false;
5037
+ seen.add(modelId);
5015
5038
  return true;
5016
- }).map((p) => ({ id: p.modelId, object: "model", owned_by: "omnicross" }));
5039
+ }).map((modelId) => ({ id: modelId, object: "model", owned_by: "omnicross" }));
5017
5040
  res.writeHead(200, { "Content-Type": "application/json" });
5018
5041
  res.end(JSON.stringify({ object: "list", data }));
5019
5042
  }
@@ -5081,7 +5104,7 @@ async function handleOutboundRequest(req, res, deps, config, rateLimiter, serial
5081
5104
  writeJsonError(res, 403, "API key is not allowed to access this endpoint");
5082
5105
  return;
5083
5106
  }
5084
- writeModelsList(res, config, verified.id, verified.allowedEndpoints);
5107
+ await writeModelsList(res, deps.llmConfig, config, verified.id, verified.allowedEndpoints);
5085
5108
  return;
5086
5109
  }
5087
5110
  const endpoint = selectEndpoint(req.method, req.url);
@@ -5637,6 +5660,70 @@ function __resetOutboundApiServerForTests() {
5637
5660
  instance2 = null;
5638
5661
  }
5639
5662
 
5663
+ // src/completion/ReasoningRequestBuilder.ts
5664
+ var LEGACY_ANTHROPIC_MAX_TOKENS = 16384;
5665
+ function intentFromOptions(options) {
5666
+ return options.thinkLevel ? { effort: options.thinkLevel, enabled: options.thinkLevel !== "none" } : void 0;
5667
+ }
5668
+ function resolveCompletionReasoningPlan(provider, options, target, requestMaxTokens = options.maxTokens) {
5669
+ return resolveReasoningPlan({
5670
+ intent: intentFromOptions(options),
5671
+ model: options.model,
5672
+ provider,
5673
+ target,
5674
+ requestMaxTokens
5675
+ });
5676
+ }
5677
+ function resolveOpenAIEffort(provider, options, target) {
5678
+ const plan = resolveCompletionReasoningPlan(provider, options, target);
5679
+ return plan?.kind === "level" && plan.enabled ? plan.effort : void 0;
5680
+ }
5681
+ function buildAnthropicReasoningWire(provider, options) {
5682
+ const configuredMaxTokens = options.maxTokens ?? LEGACY_ANTHROPIC_MAX_TOKENS;
5683
+ const legacyBound = Math.min(configuredMaxTokens, LEGACY_ANTHROPIC_MAX_TOKENS);
5684
+ const plan = resolveCompletionReasoningPlan(
5685
+ provider,
5686
+ options,
5687
+ "anthropic",
5688
+ legacyBound
5689
+ );
5690
+ if (plan?.kind === "level" && plan.enabled) {
5691
+ return {
5692
+ effectiveMaxTokens: configuredMaxTokens,
5693
+ thinking: { type: "adaptive" },
5694
+ outputConfig: { effort: plan.effort },
5695
+ legacyBudgetEnabled: false
5696
+ };
5697
+ }
5698
+ if (plan?.kind === "budget" && plan.enabled) {
5699
+ return {
5700
+ effectiveMaxTokens: legacyBound,
5701
+ thinking: { type: "enabled", budget_tokens: plan.budgetTokens },
5702
+ legacyBudgetEnabled: true
5703
+ };
5704
+ }
5705
+ return {
5706
+ effectiveMaxTokens: configuredMaxTokens,
5707
+ legacyBudgetEnabled: false
5708
+ };
5709
+ }
5710
+ function buildGeminiThinkingConfig(provider, options) {
5711
+ const plan = resolveCompletionReasoningPlan(provider, options, "gemini");
5712
+ if (plan?.kind === "level") {
5713
+ return {
5714
+ includeThoughts: plan.enabled,
5715
+ thinkingLevel: plan.effort
5716
+ };
5717
+ }
5718
+ if (plan?.kind === "budget") {
5719
+ return {
5720
+ includeThoughts: plan.enabled,
5721
+ thinkingBudget: plan.budgetTokens
5722
+ };
5723
+ }
5724
+ return void 0;
5725
+ }
5726
+
5640
5727
  // src/completion/DirectApiHandler.ts
5641
5728
  async function callOpenAICompletion(provider, apiKey, options, logger) {
5642
5729
  const request = {
@@ -5648,11 +5735,9 @@ async function callOpenAICompletion(provider, apiKey, options, logger) {
5648
5735
  stream: false
5649
5736
  // For now, non-streaming only
5650
5737
  };
5651
- if (options.thinkLevel && options.thinkLevel !== "none") {
5652
- const effort = getOpenAIReasoningEffort(options.thinkLevel);
5653
- if (effort) {
5654
- request.reasoning_effort = effort;
5655
- }
5738
+ const effort = resolveOpenAIEffort(provider, options, "openai-chat");
5739
+ if (effort) {
5740
+ request.reasoning_effort = effort;
5656
5741
  }
5657
5742
  const apiUrl = buildProviderApiUrl(provider, { model: options.model, stream: false });
5658
5743
  const headers = getProviderHeaders(provider, apiKey);
@@ -5689,16 +5774,19 @@ async function callOpenAICompletion(provider, apiKey, options, logger) {
5689
5774
  }
5690
5775
  async function callAnthropicCompletion(provider, apiKey, options, logger) {
5691
5776
  const hasImages = options.messages.some((m) => m.images && m.images.length > 0);
5777
+ const reasoningWire = buildAnthropicReasoningWire(provider, options);
5692
5778
  if (hasImages) {
5693
5779
  const systemMessages = options.messages.filter((m) => m.role === "system");
5694
5780
  const nonSystemMessages = options.messages.filter((m) => m.role !== "system");
5695
5781
  const anthropicRequest2 = {
5696
5782
  model: options.model,
5697
- max_tokens: options.maxTokens ?? 16384,
5698
- temperature: options.temperature,
5783
+ max_tokens: reasoningWire.effectiveMaxTokens,
5784
+ ...reasoningWire.legacyBudgetEnabled ? {} : { temperature: options.temperature },
5699
5785
  ...systemMessages.length > 0 ? { system: systemMessages.map((m) => m.content).join("\n\n") } : {},
5700
5786
  messages: nonSystemMessages.map((m) => convertMessageToAnthropic(m)),
5701
- stream: false
5787
+ stream: false,
5788
+ ...reasoningWire.thinking ? { thinking: reasoningWire.thinking } : {},
5789
+ ...reasoningWire.outputConfig ? { output_config: reasoningWire.outputConfig } : {}
5702
5790
  };
5703
5791
  const apiUrl2 = buildProviderApiUrl(provider, { model: options.model, stream: false });
5704
5792
  const headers2 = getProviderHeaders(provider, apiKey);
@@ -5740,14 +5828,24 @@ async function callAnthropicCompletion(provider, apiKey, options, logger) {
5740
5828
  content: m.content
5741
5829
  })),
5742
5830
  // Anthropic requires max_tokens; use 16384 default if not explicitly set
5743
- max_tokens: options.maxTokens ?? 16384,
5744
- temperature: options.temperature,
5831
+ max_tokens: reasoningWire.effectiveMaxTokens,
5832
+ temperature: reasoningWire.legacyBudgetEnabled ? void 0 : options.temperature,
5745
5833
  stream: false
5746
5834
  };
5747
5835
  const config = {
5748
5836
  defaultModel: options.model
5749
5837
  };
5750
5838
  const anthropicRequest = convertOpenAIToAnthropic(openaiRequest, config);
5839
+ const anthropicRequestBody = anthropicRequest;
5840
+ if (reasoningWire.thinking) {
5841
+ anthropicRequestBody.thinking = reasoningWire.thinking;
5842
+ }
5843
+ if (reasoningWire.outputConfig) {
5844
+ anthropicRequestBody.output_config = reasoningWire.outputConfig;
5845
+ }
5846
+ if (reasoningWire.legacyBudgetEnabled) {
5847
+ delete anthropicRequestBody.temperature;
5848
+ }
5751
5849
  const apiUrl = buildProviderApiUrl(provider, { model: options.model, stream: false });
5752
5850
  const headers = getProviderHeaders(provider, apiKey);
5753
5851
  logger.info("Calling Anthropic completion API", { url: apiUrl, model: options.model });
@@ -5792,11 +5890,13 @@ async function callGeminiCompletion(provider, apiKey, options, logger) {
5792
5890
  contents.push(convertMessageToGemini(msg));
5793
5891
  }
5794
5892
  }
5893
+ const thinkingConfig = buildGeminiThinkingConfig(provider, options);
5795
5894
  const request = {
5796
5895
  contents,
5797
5896
  generationConfig: {
5798
5897
  ...options.maxTokens !== void 0 ? { maxOutputTokens: options.maxTokens } : {},
5799
- ...options.temperature !== void 0 ? { temperature: options.temperature } : {}
5898
+ ...options.temperature !== void 0 ? { temperature: options.temperature } : {},
5899
+ ...thinkingConfig ? { thinkingConfig } : {}
5800
5900
  }
5801
5901
  };
5802
5902
  if (systemInstruction) {
@@ -5867,11 +5967,9 @@ async function callOpenAIResponseCompletion(provider, apiKey, options, logger) {
5867
5967
  ...options.maxTokens !== void 0 ? { max_output_tokens: options.maxTokens } : {},
5868
5968
  ...options.temperature !== void 0 ? { temperature: options.temperature } : {}
5869
5969
  };
5870
- if (options.thinkLevel && options.thinkLevel !== "none") {
5871
- const effort = getOpenAIReasoningEffort(options.thinkLevel);
5872
- if (effort) {
5873
- request.reasoning = { effort, summary: "auto" };
5874
- }
5970
+ const responseEffort = resolveOpenAIEffort(provider, options, "openai-responses");
5971
+ if (responseEffort) {
5972
+ request.reasoning = { effort: responseEffort, summary: "auto" };
5875
5973
  }
5876
5974
  const apiUrl = buildProviderApiUrl(provider, { model: options.model, stream: false });
5877
5975
  const headers = getProviderHeaders(provider, apiKey);
@@ -5923,7 +6021,6 @@ async function callOpenAIResponseCompletion(provider, apiKey, options, logger) {
5923
6021
  }
5924
6022
 
5925
6023
  // src/completion/StreamHandler.ts
5926
- import { buildAnthropicThinking, getOpenAIReasoningEffort as getOpenAIReasoningEffort2 } from "@omnicross/contracts/thinking-config";
5927
6024
  async function streamOpenAICompletion(provider, apiKey, options, messageId, callbacks, logger) {
5928
6025
  const request = {
5929
6026
  model: options.model,
@@ -5933,11 +6030,9 @@ async function streamOpenAICompletion(provider, apiKey, options, messageId, call
5933
6030
  temperature: options.temperature,
5934
6031
  stream: true
5935
6032
  };
5936
- if (options.thinkLevel && options.thinkLevel !== "none") {
5937
- const effort = getOpenAIReasoningEffort2(options.thinkLevel);
5938
- if (effort) {
5939
- request.reasoning_effort = effort;
5940
- }
6033
+ const effort = resolveOpenAIEffort(provider, options, "openai-chat");
6034
+ if (effort) {
6035
+ request.reasoning_effort = effort;
5941
6036
  }
5942
6037
  const apiUrl = buildProviderApiUrl(provider, { model: options.model, stream: true });
5943
6038
  const headers = getProviderHeaders(provider, apiKey);
@@ -5987,16 +6082,11 @@ async function streamOpenAICompletion(provider, apiKey, options, messageId, call
5987
6082
  }
5988
6083
  async function streamAnthropicCompletion(provider, apiKey, options, messageId, callbacks, logger) {
5989
6084
  const hasImages = options.messages.some((m) => m.images && m.images.length > 0);
5990
- const MAX_TOKENS_FOR_THINKING = 16384;
5991
- let effectiveMaxTokens = options.maxTokens ?? 16384;
5992
- const thinkingMaxTokens = options.thinkLevel && options.thinkLevel !== "none" ? Math.min(effectiveMaxTokens, MAX_TOKENS_FOR_THINKING) : effectiveMaxTokens;
5993
- const thinkingConfig = options.thinkLevel && options.thinkLevel !== "none" ? buildAnthropicThinking(options.model, options.thinkLevel, thinkingMaxTokens) : void 0;
5994
- if (thinkingConfig) {
5995
- effectiveMaxTokens = thinkingMaxTokens;
5996
- }
6085
+ const reasoningWire = buildAnthropicReasoningWire(provider, options);
6086
+ const effectiveMaxTokens = reasoningWire.effectiveMaxTokens;
5997
6087
  logger.debug("Anthropic thinking configuration", {
5998
6088
  thinkLevel: options.thinkLevel,
5999
- thinkingConfig,
6089
+ thinkingConfig: reasoningWire.thinking,
6000
6090
  effectiveMaxTokens
6001
6091
  });
6002
6092
  let anthropicRequest;
@@ -6007,12 +6097,15 @@ async function streamAnthropicCompletion(provider, apiKey, options, messageId, c
6007
6097
  model: options.model,
6008
6098
  max_tokens: effectiveMaxTokens,
6009
6099
  // Omit temperature when thinking is enabled (Anthropic will use default temperature=1)
6010
- ...thinkingConfig ? {} : { temperature: options.temperature },
6100
+ ...reasoningWire.legacyBudgetEnabled ? {} : { temperature: options.temperature },
6011
6101
  ...systemMessages.length > 0 ? { system: systemMessages.map((m) => m.content).join("\n\n") } : {},
6012
6102
  messages: nonSystemMessages.map((m) => convertMessageToAnthropic(m)),
6013
6103
  stream: true,
6014
- ...thinkingConfig ? { thinking: thinkingConfig } : {}
6104
+ ...reasoningWire.thinking ? { thinking: reasoningWire.thinking } : {}
6015
6105
  };
6106
+ if (reasoningWire.outputConfig) {
6107
+ anthropicRequest.output_config = reasoningWire.outputConfig;
6108
+ }
6016
6109
  } else {
6017
6110
  const config = {
6018
6111
  defaultModel: options.model
@@ -6026,12 +6119,17 @@ async function streamAnthropicCompletion(provider, apiKey, options, messageId, c
6026
6119
  // Anthropic requires max_tokens; use adjusted value
6027
6120
  max_tokens: effectiveMaxTokens,
6028
6121
  // Omit temperature when thinking is enabled (Anthropic will use default temperature=1)
6029
- temperature: thinkingConfig ? void 0 : options.temperature,
6122
+ temperature: reasoningWire.legacyBudgetEnabled ? void 0 : options.temperature,
6030
6123
  stream: true
6031
6124
  };
6032
6125
  anthropicRequest = convertOpenAIToAnthropic(openaiRequest, config);
6033
- if (thinkingConfig) {
6034
- anthropicRequest.thinking = thinkingConfig;
6126
+ if (reasoningWire.thinking) {
6127
+ anthropicRequest.thinking = reasoningWire.thinking;
6128
+ }
6129
+ if (reasoningWire.outputConfig) {
6130
+ anthropicRequest.output_config = reasoningWire.outputConfig;
6131
+ }
6132
+ if (reasoningWire.legacyBudgetEnabled) {
6035
6133
  delete anthropicRequest.temperature;
6036
6134
  }
6037
6135
  }
@@ -6097,11 +6195,13 @@ async function streamGeminiCompletion(provider, apiKey, options, messageId, call
6097
6195
  contents.push(convertMessageToGemini(msg));
6098
6196
  }
6099
6197
  }
6198
+ const thinkingConfig = buildGeminiThinkingConfig(provider, options);
6100
6199
  const request = {
6101
6200
  contents,
6102
6201
  generationConfig: {
6103
6202
  ...options.maxTokens !== void 0 ? { maxOutputTokens: options.maxTokens } : {},
6104
- ...options.temperature !== void 0 ? { temperature: options.temperature } : {}
6203
+ ...options.temperature !== void 0 ? { temperature: options.temperature } : {},
6204
+ ...thinkingConfig ? { thinkingConfig } : {}
6105
6205
  }
6106
6206
  };
6107
6207
  if (systemInstruction) {
@@ -6167,11 +6267,9 @@ async function streamOpenAIResponseCompletion(provider, apiKey, options, message
6167
6267
  ...options.maxTokens !== void 0 ? { max_output_tokens: options.maxTokens } : {},
6168
6268
  ...options.temperature !== void 0 ? { temperature: options.temperature } : {}
6169
6269
  };
6170
- if (options.thinkLevel && options.thinkLevel !== "none") {
6171
- const effort = getOpenAIReasoningEffort2(options.thinkLevel);
6172
- if (effort) {
6173
- request.reasoning = { effort, summary: "auto" };
6174
- }
6270
+ const responseEffort = resolveOpenAIEffort(provider, options, "openai-responses");
6271
+ if (responseEffort) {
6272
+ request.reasoning = { effort: responseEffort, summary: "auto" };
6175
6273
  }
6176
6274
  const apiUrl = buildProviderApiUrl(provider, { model: options.model, stream: true });
6177
6275
  const headers = getProviderHeaders(provider, apiKey);
@@ -6215,7 +6313,7 @@ async function streamOpenAIResponseCompletion(provider, apiKey, options, message
6215
6313
 
6216
6314
  // src/completion/ThinkingResolver.ts
6217
6315
  import {
6218
- buildAnthropicThinking as buildAnthropicThinking2,
6316
+ buildAnthropicThinking,
6219
6317
  calculateThinkingBudget,
6220
6318
  DEFAULT_MAX_TOKENS,
6221
6319
  getClaudeMaxTokens,
@@ -6259,7 +6357,7 @@ async function resolveThinkingBudget(getProvider, logger, providerId, modelId, m
6259
6357
  const providerName = provider?.name?.toLowerCase() || "";
6260
6358
  const apiFormat = provider ? resolveApiFormat(provider) : "openai";
6261
6359
  if (apiFormat === "anthropic" || providerName === "anthropic" || providerName.includes("claude")) {
6262
- const thinkingConfig = buildAnthropicThinking2(modelId, thinkLevel, maxTokens);
6360
+ const thinkingConfig = buildAnthropicThinking(modelId, thinkLevel, maxTokens);
6263
6361
  const adjustedMaxTokens = getClaudeMaxTokens(maxTokens, thinkingBudget) || maxTokens;
6264
6362
  logger.debug("Claude model thinking budget", {
6265
6363
  thinkingBudget,
@@ -6914,7 +7012,8 @@ async function completeWithTransformers(options, llmConfig, getProvider, resolve
6914
7012
  name: provider.name,
6915
7013
  baseUrl: provider.api_base_url,
6916
7014
  apiKey,
6917
- models: provider.models || []
7015
+ models: provider.models || [],
7016
+ modelConfigs: provider.modelConfigs
6918
7017
  };
6919
7018
  const executor = getSharedExecutor2();
6920
7019
  const { response } = await executeProviderCall({
@@ -7044,7 +7143,8 @@ async function completeStreamWithTransformers(options, callbacks, llmConfig, get
7044
7143
  name: provider.name,
7045
7144
  baseUrl: provider.api_base_url,
7046
7145
  apiKey,
7047
- models: provider.models || []
7146
+ models: provider.models || [],
7147
+ modelConfigs: provider.modelConfigs
7048
7148
  };
7049
7149
  const executor = getSharedExecutor2();
7050
7150
  const { response } = await executeProviderCall({
@@ -1,6 +1,16 @@
1
1
  import {
2
2
  anthropicUsageToChatUsage
3
3
  } from "./chunk-FU7EAR73.js";
4
+ import {
5
+ flattenToolResultContent,
6
+ formatBase64,
7
+ getThinkLevel
8
+ } from "./chunk-WYVGULTQ.js";
9
+ import {
10
+ extractReasoningIntent,
11
+ normalizeThinkLevel,
12
+ resolveReasoningPlan
13
+ } from "./chunk-N2EIM2XJ.js";
4
14
 
5
15
  // src/transformer/transformers/AnthropicToolHandling.ts
6
16
  function isServerSideTool(tool) {
@@ -18,38 +28,6 @@ function convertAnthropicToolsToOpenAI(tools) {
18
28
  }));
19
29
  }
20
30
 
21
- // src/transformer/transformers/AnthropicTypes.ts
22
- function getThinkLevel(budgetTokens) {
23
- if (!budgetTokens || budgetTokens <= 0) return "none";
24
- if (budgetTokens < 4096) return "low";
25
- if (budgetTokens < 16384) return "medium";
26
- return "high";
27
- }
28
- function formatBase64(data, mediaType) {
29
- if (data.startsWith("data:")) return data;
30
- return `data:${mediaType || "image/png"};base64,${data}`;
31
- }
32
- function flattenToolResultContent(content) {
33
- if (typeof content === "string") return content;
34
- if (content == null) return "";
35
- if (!Array.isArray(content)) return JSON.stringify(content);
36
- const parts = [];
37
- for (const block of content) {
38
- if (typeof block === "string") {
39
- parts.push(block);
40
- continue;
41
- }
42
- if (!block || typeof block !== "object") continue;
43
- const typed = block;
44
- if (typed.type === "image" || typed.type === "image_url") {
45
- parts.push("[image omitted]");
46
- } else if (typeof typed.text === "string") {
47
- parts.push(typed.text);
48
- }
49
- }
50
- return parts.filter((text) => text !== "").join("\n");
51
- }
52
-
53
31
  // src/anthropicMaxTokens.ts
54
32
  import { lookupCanonicalCapabilities } from "@omnicross/contracts/canonical-models";
55
33
  var ANTHROPIC_FALLBACK_MAX_TOKENS = 128e3;
@@ -65,7 +43,7 @@ function resolveAnthropicMaxTokens(model, requested) {
65
43
  }
66
44
 
67
45
  // src/transformer/transformers/AnthropicRequestBuilder.ts
68
- function buildAnthropicRequestBody(request) {
46
+ function buildAnthropicRequestBody(request, provider) {
69
47
  let systemContent;
70
48
  const anthropicMessages = [];
71
49
  for (let i = 0; i < request.messages.length; i++) {
@@ -202,10 +180,18 @@ function buildAnthropicRequestBody(request) {
202
180
  body.tool_choice = { type: "tool", name: request.tool_choice.function.name };
203
181
  }
204
182
  }
205
- if (request.reasoning?.enabled) {
206
- const budgetMap = { low: 2048, medium: 8192, high: 32768 };
207
- const budget = request.reasoning.max_tokens || budgetMap[request.reasoning.effort || "medium"] || 8192;
208
- body.thinking = { type: "enabled", budget_tokens: budget };
183
+ const reasoningPlan = resolveReasoningPlan({
184
+ intent: extractReasoningIntent(request),
185
+ model: request.model,
186
+ provider,
187
+ target: "anthropic",
188
+ requestMaxTokens: request.max_tokens
189
+ });
190
+ if (reasoningPlan?.kind === "level" && reasoningPlan.enabled) {
191
+ body.thinking = { type: "adaptive" };
192
+ body.output_config = { effort: reasoningPlan.effort };
193
+ } else if (reasoningPlan?.kind === "budget" && reasoningPlan.enabled) {
194
+ body.thinking = { type: "enabled", budget_tokens: reasoningPlan.budgetTokens };
209
195
  body.temperature = 1;
210
196
  }
211
197
  return body;
@@ -461,10 +447,18 @@ function transformAnthropicRequestToUnified(request) {
461
447
  result._serverSideTools = serverSideTools;
462
448
  }
463
449
  if (anthropicRequest.thinking) {
464
- result.reasoning = {
465
- effort: getThinkLevel(anthropicRequest.thinking.budget_tokens),
466
- enabled: anthropicRequest.thinking.type === "enabled"
467
- };
450
+ if (anthropicRequest.thinking.type === "disabled") {
451
+ result.reasoning = { effort: "none", enabled: false };
452
+ } else if (anthropicRequest.thinking.type === "adaptive") {
453
+ const effort = normalizeThinkLevel(anthropicRequest.output_config?.effort);
454
+ if (effort) result.reasoning = { effort, enabled: effort !== "none" };
455
+ } else {
456
+ result.reasoning = {
457
+ effort: getThinkLevel(anthropicRequest.thinking.budget_tokens),
458
+ enabled: true,
459
+ ...typeof anthropicRequest.thinking.budget_tokens === "number" ? { max_tokens: anthropicRequest.thinking.budget_tokens } : {}
460
+ };
461
+ }
468
462
  }
469
463
  if (anthropicRequest.tool_choice) {
470
464
  if (anthropicRequest.tool_choice.type === "tool" && anthropicRequest.tool_choice.name) {
@@ -994,8 +988,8 @@ var AnthropicTransformer = class {
994
988
  * This is the reverse of transformRequestOut — converts OpenAI/unified format
995
989
  * to Anthropic's expected request body structure.
996
990
  */
997
- async transformRequestIn(request, _provider, _context) {
998
- return buildAnthropicRequestBody(request);
991
+ async transformRequestIn(request, provider, _context) {
992
+ return buildAnthropicRequestBody(request, provider);
999
993
  }
1000
994
  /**
1001
995
  * Transform Anthropic response to OpenAI/unified format