@openclaw/ai 2026.9.4 → 2026.9.6

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 (101) hide show
  1. package/README.md +1 -1
  2. package/dist/{anthropic-C4Qu4H0Z.mjs → anthropic-DZQ_7gD1.mjs} +37 -38
  3. package/dist/{anthropic-payload-policy-BZ8umAbk.d.mts → anthropic-payload-policy-DyfwikYJ.d.mts} +4 -4
  4. package/dist/{anthropic-stream-reducer-CILWF7JD.mjs → anthropic-stream-reducer-D6ZI1wwj.mjs} +70 -50
  5. package/dist/{api-registry-ByUwIR0e.d.mts → api-registry-C2T3lTV7.d.mts} +2 -2
  6. package/dist/{assistant-output-tLt4H-iQ.mjs → assistant-output-DM1JBNs1.mjs} +1 -1
  7. package/dist/{azure-openai-responses-BAlqlKKc.mjs → azure-openai-responses-DS86GYzq.mjs} +6 -9
  8. package/dist/{base64-D-su8YVo.mjs → base64-CPmadnUf.mjs} +12 -12
  9. package/dist/credential-redaction-BKv49aiv.d.mts +24 -0
  10. package/dist/{diagnostics-QuErwCIl.mjs → diagnostics-CH8j2wIG.mjs} +139 -7
  11. package/dist/{diagnostics-CPeq9F7y.mjs → diagnostics-DzrF1h4J.mjs} +18 -1
  12. package/dist/diagnostics.d.mts +11 -24
  13. package/dist/diagnostics.mjs +4 -4
  14. package/dist/event-stream-C0nsgbj2.d.mts +1 -0
  15. package/dist/{event-stream-Bt5Y4Pav.d.mts → event-stream-CjnIZZst.d.mts} +1 -1
  16. package/dist/event-stream.d.mts +2 -2
  17. package/dist/expect-lbe3Hgrh.mjs +8 -0
  18. package/dist/{google-DPBAOaOW.mjs → google-BZJFjhuC.mjs} +6 -9
  19. package/dist/{google-messages-6JkpHrhJ.mjs → google-messages-DB7GKkDk.mjs} +3 -3
  20. package/dist/{google-shared-BvBeW9aq.mjs → google-shared-Bok4I6zB.mjs} +13 -13
  21. package/dist/{google-vertex-k-TMCAYD.mjs → google-vertex-3eVNR2qW.mjs} +5 -8
  22. package/dist/{host-4atIX-2V.d.mts → host-DH-Z-LDb.d.mts} +5 -3
  23. package/dist/{host-policy-Zcg_cNz8.mjs → host-policy-DZO3oPPk.mjs} +1 -1
  24. package/dist/{host-B8YfDGd4.mjs → host-yTvBrYM2.mjs} +63 -31
  25. package/dist/{index-DdD3qerf.d.mts → index-C25RT6bP.d.mts} +37 -14
  26. package/dist/index.d.mts +7 -8
  27. package/dist/index.mjs +5 -6
  28. package/dist/internal/anthropic.d.mts +13 -10
  29. package/dist/internal/anthropic.mjs +5 -5
  30. package/dist/internal/openai-completions-compat.d.mts +2 -0
  31. package/dist/internal/openai-completions-compat.mjs +2 -0
  32. package/dist/internal/openai-responses-payload-policy.d.mts +2 -2
  33. package/dist/internal/openai-responses-payload-policy.mjs +2 -2
  34. package/dist/internal/openai.d.mts +24 -53
  35. package/dist/internal/openai.mjs +12 -9
  36. package/dist/internal/runtime.d.mts +6 -8
  37. package/dist/internal/runtime.mjs +6 -10
  38. package/dist/internal/shared.d.mts +7 -5
  39. package/dist/internal/shared.mjs +4 -3
  40. package/dist/internal/tool-schema.d.mts +4 -4
  41. package/dist/internal/tool-schema.mjs +2 -2
  42. package/dist/{mistral-CxUZ1jUb.mjs → mistral-C_13dVBn.mjs} +9 -13
  43. package/dist/{model-transport-url-DKocrEsb.d.mts → model-transport-url-C5f59L3Y.d.mts} +1 -1
  44. package/dist/{openai-chatgpt-responses-CgO6kZfo.mjs → openai-chatgpt-responses-sTxPl4zM.mjs} +150 -83
  45. package/dist/{openai-completions-yJuk7eis.mjs → openai-completions-BO6D_hrB.mjs} +11 -12
  46. package/dist/{openai-prompt-cache-Bds-n_9Q.mjs → openai-completions-compat-CUollwl6.mjs} +5 -50
  47. package/dist/{openai-completions-compat-eHgh5UPE.d.mts → openai-completions-compat-DfJG1wSO.d.mts} +4 -4
  48. package/dist/{openai-completions-stream-Da2vvl-S.mjs → openai-completions-stream-BpuJ0ZOA.mjs} +117 -106
  49. package/dist/{openai-prompt-cache-B4eYo2-I.d.mts → openai-prompt-cache-C4RHdN4n.d.mts} +2 -2
  50. package/dist/openai-prompt-cache-CjV_2IRI.mjs +46 -0
  51. package/dist/{openai-provider-client-S2gCrM2Z.mjs → openai-provider-client-BP8J1aeg.mjs} +2 -2
  52. package/dist/openai-reasoning-effort-ash8dPrd.mjs +243 -0
  53. package/dist/{openai-responses-DaYwH05E.mjs → openai-responses-BJ_IEoMU.mjs} +8 -12
  54. package/dist/{openai-responses-compaction-window-CIhBAkkq.mjs → openai-responses-compaction-window-BiNCT0bS.mjs} +20 -62
  55. package/dist/{openai-responses-contracts-BjBAqAg_.d.mts → openai-responses-contracts-B1ENJFpI.d.mts} +9 -5
  56. package/dist/openai-responses-contracts-DWrfMODE.mjs +81 -0
  57. package/dist/{openai-responses-payload-policy-rLRPsSmB.d.mts → openai-responses-payload-policy-C7GsA1y0.d.mts} +5 -3
  58. package/dist/openai-responses-prompt-observer-internal-DPHWgbBH.mjs +198 -0
  59. package/dist/openai-responses-request-lifecycle-DFuyO1pQ.mjs +36 -0
  60. package/dist/{openai-responses-shared-B8RdBPCv.mjs → openai-responses-shared-DvSqtJ6_.mjs} +859 -581
  61. package/dist/openai-responses-terminal-usage-BNFbvY9f.d.mts +47 -0
  62. package/dist/{openai-tool-schema-CzjyYXun.mjs → openai-tool-schema-D4BMcj2D.mjs} +262 -162
  63. package/dist/{openai-transport-params-9aPuV5YY.mjs → openai-transport-params-DZKOTSfH.mjs} +157 -47
  64. package/dist/{positive-integer-41zhOdcV.mjs → positive-integer-BiUxrd71.mjs} +1 -1
  65. package/dist/{provider-error-BA-v_tKd.mjs → provider-error-CRhW7lkJ.mjs} +139 -44
  66. package/dist/{provider-error-CzNw4BWX.d.mts → provider-error-xumb1V3F.d.mts} +3 -1
  67. package/dist/{provider-options-Ceqv1OKk.d.mts → provider-options-DZYq53lj.d.mts} +12 -7
  68. package/dist/{provider-replay-context-CJ_YvcEW.mjs → provider-replay-context-DPr3w20a.mjs} +1 -1
  69. package/dist/{provider-transcript-transform-V5YzU9zh.mjs → provider-transcript-transform-BTocjCRs.mjs} +1 -1
  70. package/dist/{provider-transport-turn-state-D5EXOFL2.mjs → provider-transport-turn-state-lrXEFkYr.mjs} +1 -1
  71. package/dist/{provider-types-CVjKjsuq.d.mts → provider-types-w1rEqrGP.d.mts} +3 -3
  72. package/dist/provider-types.d.mts +6 -7
  73. package/dist/providers.d.mts +2 -2
  74. package/dist/providers.mjs +10 -10
  75. package/dist/{reasoning-tag-text-partitioner-BcR5pztD.mjs → reasoning-tag-text-partitioner-Di38crhI.mjs} +167 -40
  76. package/dist/{simple-options-BQbb4yQL.mjs → simple-options-np1XPuhm.mjs} +5 -3
  77. package/dist/{usage-cost-BNWbbXav.mjs → src-DwGYYyZp.mjs} +18 -11
  78. package/dist/{stream-first-event-timeout-2hfrquuz.mjs → stream-first-event-timeout-BeptfRL6.mjs} +1 -1
  79. package/dist/{string-normalization-CmLIasuf.mjs → string-normalization-J9ZiLfGO.mjs} +13 -1
  80. package/dist/tool-schema-json-projection-CD9c_fK8.mjs +134 -0
  81. package/dist/{transport-stream-shared-zHll9BxO.mjs → transport-stream-shared-B5RioB_Q.mjs} +16 -24
  82. package/dist/{transport-stream-shared-DNvmoWnv.d.mts → transport-stream-shared-B7Z9oCYg.d.mts} +5 -5
  83. package/dist/{transport-utils-zrYjICLZ.mjs → transport-utils-03Qi0CN2.mjs} +3 -3
  84. package/dist/transports.d.mts +27 -13
  85. package/dist/transports.mjs +168 -462
  86. package/dist/types-DTvddOfm.d.mts +1 -0
  87. package/dist/{types-Ntv5z2g2.d.mts → types-qZFbaDbK.d.mts} +49 -3
  88. package/dist/types.d.mts +6 -7
  89. package/dist/types.mjs +4 -5
  90. package/dist/{validation-B0t_G2H6.d.mts → validation-DhQhmt6t.d.mts} +1 -1
  91. package/dist/{validation-BDzVDnTs.mjs → validation-Dw7cb6BV.mjs} +1 -0
  92. package/dist/validation.d.mts +1 -1
  93. package/dist/validation.mjs +1 -1
  94. package/package.json +11 -6
  95. package/dist/diagnostics-DnPnOui6.d.mts +0 -29
  96. package/dist/event-stream-C3WGFsum.d.mts +0 -1
  97. package/dist/openai-responses-contracts-DDOHA62Y.mjs +0 -245
  98. package/dist/openai-responses-prompt-observer-internal-f8J7wpsk.mjs +0 -32
  99. package/dist/src-DDmEryvj.mjs +0 -2
  100. package/dist/tool-schema-json-projection-ClptDdAO.mjs +0 -82
  101. package/dist/types-DlfwzH3T.d.mts +0 -1
@@ -1,26 +1,27 @@
1
1
  import { r as appendAssistantThinking } from "./event-stream-D8PARQfL.mjs";
2
- import { _ as isImageWithMediaPayload, d as describeToolResultMediaPlaceholder, m as extractToolResultText, v as sanitizeSurrogates } from "./host-B8YfDGd4.mjs";
3
2
  import { o as isRecord } from "./record-coerce-DwRYMj3t.mjs";
3
+ import { n as isOpenAIGpt55Model, r as isOpenAIGpt56Model, t as isOpenAIGpt54MiniModel } from "./openai-reasoning-effort-ash8dPrd.mjs";
4
+ import { r as uniqueStrings } from "./string-normalization-J9ZiLfGO.mjs";
5
+ import { _ as isImageWithMediaPayload, d as describeToolResultMediaPlaceholder, m as extractToolResultText, v as sanitizeSurrogates } from "./host-yTvBrYM2.mjs";
4
6
  import { t as truncateUtf16Safe } from "./utf16-slice-CvGodqok.mjs";
5
- import { d as shouldOmitOllamaCompatResponseFormat, i as detectOpenAICompletionsCompat, r as resolveOpenAIPromptCacheParams, u as resolveOpenAICompletionsResponseFormat } from "./openai-prompt-cache-Bds-n_9Q.mjs";
6
- import { r as emitModelTransportDebug } from "./diagnostics-QuErwCIl.mjs";
7
- import { i as asNonNegativeFiniteNumber } from "./base64-D-su8YVo.mjs";
8
- import { c as supportsModelTools, r as estimateStringChars } from "./transport-utils-zrYjICLZ.mjs";
9
- import { n as uniqueStrings } from "./string-normalization-CmLIasuf.mjs";
10
- import { i as resolveProviderEndpoint, r as resolveOpenAIStrictToolSetting } from "./host-policy-Zcg_cNz8.mjs";
7
+ import { r as resolveOpenAIPromptCacheParams } from "./openai-prompt-cache-CjV_2IRI.mjs";
8
+ import { r as emitModelTransportDebug } from "./diagnostics-CH8j2wIG.mjs";
9
+ import { i as asNonNegativeFiniteNumber } from "./base64-CPmadnUf.mjs";
10
+ import { c as supportsModelTools, r as estimateStringChars } from "./transport-utils-03Qi0CN2.mjs";
11
+ import { c as shouldOmitOllamaCompatResponseFormat, n as isNativeOpenAIEndpoint, s as resolveOpenAICompletionsResponseFormat, t as detectOpenAICompletionsCompat } from "./openai-completions-compat-CUollwl6.mjs";
12
+ import { i as resolveProviderEndpoint, r as resolveOpenAIStrictToolSetting } from "./host-policy-DZO3oPPk.mjs";
11
13
  import { t as resolveCacheRetention } from "./cache-retention-0x979a5V.mjs";
12
- import { f as splitSystemPromptCacheBoundary, h as stripSystemPromptRelocatableBoundary, m as stripSystemPromptCacheBoundary, p as splitSystemPromptRelocatableBoundary, v as sortPromptCacheToolsByName } from "./simple-options-BQbb4yQL.mjs";
13
- import { C as readOpenAICompletionsContentDeltas, D as throwIfModelStreamAborted, E as resolvePromptCacheKey, S as parseOpenAICompletionsUsage, b as log, d as resolveOpenAIReasoningEffortMap, f as projectOpenAITools, g as createModelStreamCooperativeScheduler, h as GEMINI_THOUGHT_SIGNATURE_VALIDATOR_SKIP, p as reconcileOpenAICompletionsToolChoice, s as getCompat, u as resolveOpenAIStrictToolFlagWithDiagnostics, w as readOpenAICompletionsReasoningBatch, x as measureUtf8AppendBytes, y as isOpenAICompletionsThinkingEnabled } from "./openai-transport-params-9aPuV5YY.mjs";
14
- import { E as parseStreamingJson, c as finalizeTerminalToolCallArguments, w as createToolArgumentPreviewSchedule } from "./transport-stream-shared-zHll9BxO.mjs";
14
+ import { f as splitSystemPromptCacheBoundary, h as stripSystemPromptRelocatableBoundary, m as stripSystemPromptCacheBoundary, p as splitSystemPromptRelocatableBoundary, v as sortPromptCacheToolsByName } from "./simple-options-np1XPuhm.mjs";
15
+ import { A as resolvePromptCacheKey, C as isOpenAICompletionsThinkingEnabled, D as readOpenAICompletionsContentDeltas, E as parseOpenAICompletionsUsage, O as readOpenAICompletionsReasoningBatch, T as measureUtf8AppendBytes, d as prepareOpenAITools, f as projectOpenAITools, g as resolveOpenAISimpleReasoningEffort, h as resolveOpenAIRequestReasoning, j as throwIfModelStreamAborted, p as reconcileOpenAICompletionsToolChoice, s as getCompat, u as resolveOpenAIStrictToolFlagWithDiagnostics, v as GEMINI_THOUGHT_SIGNATURE_VALIDATOR_SKIP, w as log, y as createModelStreamCooperativeScheduler } from "./openai-transport-params-DZKOTSfH.mjs";
16
+ import { E as parseStreamingJson, c as finalizeTerminalToolCallArguments, w as createToolArgumentPreviewSchedule } from "./transport-stream-shared-B5RioB_Q.mjs";
15
17
  import { a as tagUnresolvedTextAsCommentary, i as tagPendingCommentaryText, n as rememberPendingCommentaryTags, r as tagInterruptedTextPhases, t as clearPendingCommentaryText } from "./assistant-text-phase-C20rxWwP.mjs";
16
18
  import { t as notifyLlmRequestActivity } from "./llm-request-activity-BjtkplhG.mjs";
17
- import { a as withFirstStreamEventTimeout } from "./stream-first-event-timeout-2hfrquuz.mjs";
18
- import { t as transformProviderMessages } from "./provider-transcript-transform-V5YzU9zh.mjs";
19
- import { _ as isOpenAIGpt56Model, b as resolveOpenAIReasoningEffortForModel, g as isOpenAIGpt55Model, h as isOpenAIGpt54MiniModel } from "./openai-responses-contracts-DDOHA62Y.mjs";
20
- import { r as normalizeOpenAIStrictToolParameters } from "./openai-tool-schema-CzjyYXun.mjs";
19
+ import { a as withFirstStreamEventTimeout } from "./stream-first-event-timeout-BeptfRL6.mjs";
20
+ import { t as transformProviderMessages } from "./provider-transcript-transform-BTocjCRs.mjs";
21
+ import { f as withPreparedToolSchemaNormalization, r as normalizeOpenAIStrictToolParameters } from "./openai-tool-schema-D4BMcj2D.mjs";
21
22
  import { isGoogleGemini3FlashModel, isGoogleGemini3ProModel } from "./internal/google-model-family.mjs";
22
23
  import { t as mapOpenAIStopReason } from "./openai-stop-reason-Drnn_6Qj.mjs";
23
- import { t as createReasoningTagTextPartitioner } from "./reasoning-tag-text-partitioner-BcR5pztD.mjs";
24
+ import { t as createReasoningTagTextPartitioner } from "./reasoning-tag-text-partitioner-Di38crhI.mjs";
24
25
  import { randomUUID } from "node:crypto";
25
26
  //#region packages/ai/src/transports/deepseek-dsml-grammar.ts
26
27
  const DEEPSEEK_DSML_MARKERS = [
@@ -254,10 +255,18 @@ function createOpenAIEncryptedToolCallReasoningTracker() {
254
255
  const firstBlocks = /* @__PURE__ */ new Map();
255
256
  const pendingDetails = /* @__PURE__ */ new Map();
256
257
  return {
257
- rememberToolCall(id, block) {
258
+ rememberToolCall(id, block, previousId = id) {
259
+ const previous = firstBlocks.get(previousId);
260
+ if (previousId !== id && previous?.block === block) {
261
+ firstBlocks.delete(previousId);
262
+ if (previous.signature && block.thoughtSignature === previous.signature) delete block.thoughtSignature;
263
+ }
258
264
  if (!id || firstBlocks.has(id)) return;
259
- firstBlocks.set(id, block);
260
265
  const pendingDetail = pendingDetails.get(id);
266
+ firstBlocks.set(id, {
267
+ block,
268
+ signature: pendingDetail
269
+ });
261
270
  if (pendingDetail) {
262
271
  block.thoughtSignature = pendingDetail;
263
272
  pendingDetails.delete(id);
@@ -269,8 +278,10 @@ function createOpenAIEncryptedToolCallReasoningTracker() {
269
278
  if (!isRecord(detail) || detail.type !== "reasoning.encrypted" || typeof detail.id !== "string" || detail.id.length === 0 || typeof detail.data !== "string" || detail.data.length === 0) continue;
270
279
  const serializedDetail = JSON.stringify(detail);
271
280
  const matchingBlock = firstBlocks.get(detail.id);
272
- if (matchingBlock) matchingBlock.thoughtSignature = serializedDetail;
273
- else pendingDetails.set(detail.id, serializedDetail);
281
+ if (matchingBlock) {
282
+ matchingBlock.signature = serializedDetail;
283
+ matchingBlock.block.thoughtSignature = serializedDetail;
284
+ } else pendingDetails.set(detail.id, serializedDetail);
274
285
  }
275
286
  }
276
287
  };
@@ -336,7 +347,7 @@ function createOpenAICompletionsToolCallDeltaNormalizer() {
336
347
  }];
337
348
  }
338
349
  const functionCall = delta.function_call;
339
- if (sawModernToolCall) return [{
350
+ if (sawModernToolCall || !functionCall && !pendingLegacyToolCall) return [{
340
351
  delta: ordinaryDelta,
341
352
  toolCalls: []
342
353
  }];
@@ -640,12 +651,9 @@ function relocateNonBehavioralRegion(args) {
640
651
  }
641
652
  //#endregion
642
653
  //#region packages/ai/src/transports/openai-completions-direct-policy.ts
643
- function applyDirectCompletionsReasoningAndRouting(params, model, options, compat) {
644
- const reasoningEffortMap = resolveOpenAIReasoningEffortMap(model);
645
- const thinkingLevelMap = model.thinkingLevelMap;
646
- const offReasoningEffort = reasoningEffortMap.off ?? model.thinkingLevelMap?.off;
647
- const reasoningEffort = options?.reasoningEffort === void 0 ? offReasoningEffort ?? void 0 : reasoningEffortMap[options.reasoningEffort] ?? thinkingLevelMap?.[options.reasoningEffort] ?? options.reasoningEffort;
648
- const reasoningEnabled = reasoningEffort !== void 0 && reasoningEffort !== "none";
654
+ function applyDirectCompletionsReasoningAndRouting(params, model, reasoning, compat) {
655
+ const nativeEffort = compat.thinkingFormat === "openrouter" ? void 0 : reasoning.effort;
656
+ const reasoningEnabled = reasoning.thinkingEnabled ?? false;
649
657
  if (compat.thinkingFormat === "zai" && model.reasoning) params.thinking = reasoningEnabled ? {
650
658
  type: "enabled",
651
659
  clear_thinking: false
@@ -657,17 +665,11 @@ function applyDirectCompletionsReasoningAndRouting(params, model, options, compa
657
665
  };
658
666
  else if (compat.thinkingFormat === "deepseek" && model.reasoning) {
659
667
  params.thinking = { type: reasoningEnabled ? "enabled" : "disabled" };
660
- if (reasoningEnabled && compat.supportsReasoningEffort) params.reasoning_effort = reasoningEffort;
661
- } else if (compat.thinkingFormat === "openrouter" && model.reasoning) {
662
- if (reasoningEnabled) params.reasoning = { effort: reasoningEffort };
663
- else if (offReasoningEffort !== null) params.reasoning = { effort: offReasoningEffort ?? "none" };
668
+ if (reasoningEnabled && compat.supportsReasoningEffort && nativeEffort !== void 0) params.reasoning_effort = nativeEffort;
664
669
  } else if (compat.thinkingFormat === "together" && model.reasoning) {
665
670
  params.reasoning = { enabled: reasoningEnabled };
666
- if (reasoningEnabled && compat.supportsReasoningEffort) params.reasoning_effort = reasoningEffort;
667
- } else if (reasoningEnabled && model.reasoning && compat.supportsReasoningEffort) params.reasoning_effort = reasoningEffort;
668
- else if (model.reasoning && compat.supportsReasoningEffort) {
669
- if (typeof offReasoningEffort === "string") params.reasoning_effort = offReasoningEffort;
670
- }
671
+ if (reasoningEnabled && compat.supportsReasoningEffort && nativeEffort !== void 0) params.reasoning_effort = nativeEffort;
672
+ } else if (model.reasoning && compat.supportsReasoningEffort && nativeEffort !== void 0) params.reasoning_effort = nativeEffort;
671
673
  if (compat.openRouterRouting) params.provider = compat.openRouterRouting;
672
674
  if (model.baseUrl.includes("ai-gateway.vercel.sh") && model.compat?.vercelGatewayRouting) {
673
675
  const routing = model.compat.vercelGatewayRouting;
@@ -774,7 +776,9 @@ const REASONING_CONTENT_REPLAY_MODEL_IDS = /* @__PURE__ */ new Set([
774
776
  "mimo-v2-omni",
775
777
  "mimo-v2.5",
776
778
  "mimo-v2.5-pro",
777
- "mimo-v2.6-pro"
779
+ "mimo-v2.6-flash",
780
+ "mimo-v2.6-pro",
781
+ "mimo-v2.6-pro-ultraspeed"
778
782
  ]);
779
783
  const REASONING_CONTENT_REPLAY_TIER_SUFFIXES = [
780
784
  "-free",
@@ -838,7 +842,7 @@ function applyCompletionsReplay(outgoingMessages, context, model, compat) {
838
842
  //#endregion
839
843
  //#region packages/ai/src/transports/openai-completions-params.ts
840
844
  function isKnownOpenAICompletionsEndpoint(model) {
841
- if (!model.baseUrl.trim()) return true;
845
+ if (!model.baseUrl.trim() || isNativeOpenAIEndpoint(model)) return true;
842
846
  const endpointClass = resolveProviderEndpoint(model).endpointClass;
843
847
  if (endpointClass === "openai-public" || endpointClass === "azure-openai") return true;
844
848
  try {
@@ -847,9 +851,6 @@ function isKnownOpenAICompletionsEndpoint(model) {
847
851
  return false;
848
852
  }
849
853
  }
850
- function resolveOpenAICompletionsReasoningEffort(options) {
851
- return options?.reasoningEffort ?? options?.reasoning ?? "high";
852
- }
853
854
  function resolveOpenAICompletionsMaxTokens(model, options) {
854
855
  if (options?.maxTokens) return {
855
856
  maxTokens: options.maxTokens,
@@ -870,6 +871,7 @@ function resolveOpenAICompletionsModelMaxTokens(model) {
870
871
  }
871
872
  const OPENAI_COMPLETIONS_INPUT_TOKEN_SAFETY_MARGIN = 1.25;
872
873
  const OPENAI_COMPLETIONS_IMAGE_CHAR_ESTIMATE = 8e3;
874
+ const MIN_USEFUL_OUTPUT_TOKENS = 16;
873
875
  function estimateOpenAICompletionsInputTokens(payload) {
874
876
  let adjustedChars = 0;
875
877
  adjustedChars += estimateOpenAICompletionsMessagesChars(payload.messages);
@@ -930,9 +932,6 @@ function resolveOpenAICompletionsEffectiveContextTokens(model) {
930
932
  if (typeof contextTokens === "number" && Number.isFinite(contextTokens) && contextTokens > 0) return contextTokens;
931
933
  return typeof model.contextWindow === "number" && Number.isFinite(model.contextWindow) && model.contextWindow > 0 ? model.contextWindow : void 0;
932
934
  }
933
- function isQwenOpenAICompletionsThinkingFormat(format) {
934
- return format === "qwen" || format === "qwen-chat-template";
935
- }
936
935
  function setQwenChatTemplateThinking(params, enabled) {
937
936
  const existing = params.chat_template_kwargs;
938
937
  params.chat_template_kwargs = existing && typeof existing === "object" && !Array.isArray(existing) ? {
@@ -940,41 +939,51 @@ function setQwenChatTemplateThinking(params, enabled) {
940
939
  enable_thinking: enabled
941
940
  } : { enable_thinking: enabled };
942
941
  }
943
- function applyQwenOpenAICompletionsThinkingParams(params) {
944
- if (!params.modelReasoning || !isQwenOpenAICompletionsThinkingFormat(params.compatThinkingFormat)) return false;
945
- const enabled = isOpenAICompletionsThinkingEnabled(params.requestedEffort);
946
- if (params.compatThinkingFormat === "qwen-chat-template") setQwenChatTemplateThinking(params.payload, enabled);
947
- else params.payload.enable_thinking = enabled;
948
- return true;
949
- }
950
- function applyTogetherOpenAICompletionsThinkingParams(params) {
951
- if (!params.modelReasoning || params.compatThinkingFormat !== "together") return;
952
- params.payload.reasoning = { enabled: isOpenAICompletionsThinkingEnabled(params.requestedEffort) };
942
+ /** Return whether the binary control replaces scalar reasoning effort. */
943
+ function applyBinaryCompletionsThinkingParams(params) {
944
+ if (!params.modelReasoning) return false;
945
+ const enabled = params.thinkingEnabled;
946
+ switch (params.compatThinkingFormat) {
947
+ case "qwen-chat-template":
948
+ setQwenChatTemplateThinking(params.payload, enabled);
949
+ return true;
950
+ case "qwen":
951
+ params.payload.enable_thinking = enabled;
952
+ return true;
953
+ case "together":
954
+ params.payload.reasoning = { enabled };
955
+ return !enabled;
956
+ default: return false;
957
+ }
953
958
  }
954
959
  function convertTools(tools, compat, model, mode) {
955
- const projection = projectOpenAITools(tools);
956
- const strict = mode === "direct" ? compat.supportsStrictMode ? false : void 0 : resolveOpenAIStrictToolFlagWithDiagnostics(projection, resolveOpenAIStrictToolSetting(model, {
957
- transport: "stream",
958
- supportsStrictMode: compat?.supportsStrictMode
959
- }), {
960
- transport: "completions",
961
- model
962
- });
963
- return {
964
- projection,
965
- tools: sortPromptCacheToolsByName(projection.tools).map((tool) => {
966
- const functionTool = {
967
- name: tool.name,
968
- description: tool.description,
969
- parameters: mode === "direct" ? tool.parameters : normalizeOpenAIStrictToolParameters(tool.parameters, strict === true, model.compat)
970
- };
971
- if (strict !== void 0) functionTool.strict = strict;
972
- return {
973
- type: "function",
974
- function: functionTool
975
- };
976
- })
960
+ const prepared = mode === "managed" ? prepareOpenAITools(tools) : void 0;
961
+ const projection = prepared?.projection ?? projectOpenAITools(tools);
962
+ const convert = () => {
963
+ const strict = mode === "direct" ? compat.supportsStrictMode ? false : void 0 : resolveOpenAIStrictToolFlagWithDiagnostics(projection, resolveOpenAIStrictToolSetting(model, {
964
+ transport: "stream",
965
+ supportsStrictMode: compat?.supportsStrictMode
966
+ }), {
967
+ transport: "completions",
968
+ model
969
+ });
970
+ return {
971
+ projection,
972
+ tools: sortPromptCacheToolsByName(projection.tools).map((tool) => {
973
+ const functionTool = {
974
+ name: tool.name,
975
+ description: tool.description,
976
+ parameters: mode === "direct" ? tool.parameters : normalizeOpenAIStrictToolParameters(tool.parameters, strict === true, model.compat)
977
+ };
978
+ if (strict !== void 0) functionTool.strict = strict;
979
+ return {
980
+ type: "function",
981
+ function: functionTool
982
+ };
983
+ })
984
+ };
977
985
  };
986
+ return prepared ? withPreparedToolSchemaNormalization(prepared.schemas, convert) : convert();
978
987
  }
979
988
  function buildOpenAICompletionsParams(model, context, options) {
980
989
  return buildOpenAICompletionsRequest(model, context, options, { mode: "managed" });
@@ -1071,6 +1080,7 @@ function buildOpenAICompletionsRequest(model, context, options, policy) {
1071
1080
  if (clampedMaxTokens > remainingBudget) {
1072
1081
  clampedMaxTokens = remainingBudget;
1073
1082
  emitModelTransportDebug(log, `[completions] clamp_max_tokens provider=${model.provider} api=${model.api} model=${model.id} requested=${effectiveMaxTokens} output=${clampedMaxTokens} effectiveContext=${effectiveContextTokens} estimatedInput=${estimatedInputTokens}`);
1083
+ if (remainingBudget < MIN_USEFUL_OUTPUT_TOKENS) log.warn(`[completions] insufficient_output_budget provider=${model.provider} api=${model.api} model=${model.id} output=${clampedMaxTokens} effectiveContext=${effectiveContextTokens} estimatedInput=${estimatedInputTokens}`);
1074
1084
  }
1075
1085
  }
1076
1086
  if (policy.mode === "direct" ? options?.maxTokens : clampedMaxTokens) {
@@ -1078,34 +1088,34 @@ function buildOpenAICompletionsRequest(model, context, options, policy) {
1078
1088
  else params.max_completion_tokens = clampedMaxTokens;
1079
1089
  }
1080
1090
  }
1081
- if (policy.mode === "direct") {
1082
- applyDirectCompletionsReasoningAndRouting(params, model, options, compat);
1083
- return params;
1091
+ const isOpenRouter = compat.thinkingFormat === "openrouter";
1092
+ const usesBinaryOpenRouterThinking = isOpenRouter && (model.compat?.supportsReasoningEffort === false || model.compat?.supportedReasoningEfforts?.length === 0);
1093
+ const simpleReasoning = options?.reasoning;
1094
+ const requestedEffort = policy.mode === "direct" ? options?.reasoningEffort : options?.reasoningEffort ?? (simpleReasoning === "none" ? "none" : resolveOpenAISimpleReasoningEffort({
1095
+ ...model,
1096
+ compat: model.compat ?? void 0
1097
+ }, simpleReasoning)) ?? (usesBinaryOpenRouterThinking ? void 0 : "high");
1098
+ const reasoning = resolveOpenAIRequestReasoning(model, requestedEffort);
1099
+ const { effort, thinkingEnabled } = reasoning;
1100
+ if (isOpenRouter && model.reasoning) {
1101
+ if (usesBinaryOpenRouterThinking && thinkingEnabled !== void 0) params.reasoning = { enabled: thinkingEnabled };
1102
+ else if (effort !== void 0) params.reasoning = { effort };
1103
+ }
1104
+ if (policy.mode === "direct") applyDirectCompletionsReasoningAndRouting(params, model, reasoning, compat);
1105
+ else {
1106
+ const suppressScalarEffort = applyBinaryCompletionsThinkingParams({
1107
+ compatThinkingFormat: compat.thinkingFormat,
1108
+ modelReasoning: model.reasoning,
1109
+ payload: params,
1110
+ thinkingEnabled: thinkingEnabled ?? false
1111
+ });
1112
+ if (!isOpenRouter && effort && model.reasoning && compat.supportsReasoningEffort && !suppressScalarEffort) params.reasoning_effort = effort;
1113
+ if (compat.cacheControlFormat === "anthropic") applyCompletionsAnthropicCacheControl(params, cacheControl ?? null, cacheOptOutIndexes, markTools, !managedCompat?.requiresStringContent);
1114
+ }
1115
+ if (params.tools?.length && isKnownOpenAICompletionsEndpoint(model)) {
1116
+ if (isOpenAIGpt56Model(model)) params.reasoning_effort = "none";
1117
+ else if (isOpenAIGpt54MiniModel(model) || isOpenAIGpt55Model(model)) delete params.reasoning_effort;
1084
1118
  }
1085
- const completionsReasoningEffort = resolveOpenAICompletionsReasoningEffort(options);
1086
- const resolvedCompletionsReasoningEffort = completionsReasoningEffort ? resolveOpenAIReasoningEffortForModel({
1087
- model,
1088
- effort: completionsReasoningEffort,
1089
- fallbackMap: managedCompat?.reasoningEffortMap
1090
- }) : void 0;
1091
- const omitChatCompletionsToolReasoningEffort = Array.isArray(params.tools) && params.tools.length > 0 && (isOpenAIGpt54MiniModel(model) || isOpenAIGpt55Model(model) && isKnownOpenAICompletionsEndpoint(model));
1092
- const disableChatCompletionsToolReasoning = Array.isArray(params.tools) && params.tools.length > 0 && isOpenAIGpt56Model(model) && isKnownOpenAICompletionsEndpoint(model);
1093
- const handledQwenThinkingFormat = applyQwenOpenAICompletionsThinkingParams({
1094
- compatThinkingFormat: compat.thinkingFormat,
1095
- modelReasoning: model.reasoning,
1096
- payload: params,
1097
- requestedEffort: completionsReasoningEffort
1098
- });
1099
- applyTogetherOpenAICompletionsThinkingParams({
1100
- compatThinkingFormat: compat.thinkingFormat,
1101
- modelReasoning: model.reasoning,
1102
- payload: params,
1103
- requestedEffort: completionsReasoningEffort
1104
- });
1105
- if (disableChatCompletionsToolReasoning) params.reasoning_effort = "none";
1106
- else if (compat.thinkingFormat === "openrouter" && model.reasoning && resolvedCompletionsReasoningEffort) params.reasoning = { effort: resolvedCompletionsReasoningEffort };
1107
- else if (resolvedCompletionsReasoningEffort && model.reasoning && compat.supportsReasoningEffort && !handledQwenThinkingFormat && !omitChatCompletionsToolReasoningEffort) params.reasoning_effort = resolvedCompletionsReasoningEffort;
1108
- if (compat.cacheControlFormat === "anthropic") applyCompletionsAnthropicCacheControl(params, cacheControl ?? null, cacheOptOutIndexes, markTools, !managedCompat?.requiresStringContent);
1109
1119
  return params;
1110
1120
  }
1111
1121
  //#endregion
@@ -1416,7 +1426,7 @@ async function processCompletionsStream(responseStream, output, model, stream, o
1416
1426
  let isFlushingPendingPostToolCallDeltas = false;
1417
1427
  const toolCallBlocksByIndex = /* @__PURE__ */ new Map();
1418
1428
  const toolCallBlocksById = /* @__PURE__ */ new Map();
1419
- const encryptedReasoning = directMode ? createOpenAIEncryptedToolCallReasoningTracker() : void 0;
1429
+ const encryptedReasoning = createOpenAIEncryptedToolCallReasoningTracker();
1420
1430
  const toolArgumentPreviewSchedules = /* @__PURE__ */ new WeakMap();
1421
1431
  const provisionalCommentaryTags = directMode ? options.provisionalCommentaryTags : /* @__PURE__ */ new Map();
1422
1432
  const contentBlockIndices = /* @__PURE__ */ new WeakMap();
@@ -1751,7 +1761,7 @@ async function processCompletionsStream(responseStream, output, model, stream, o
1751
1761
  partialArgs: "",
1752
1762
  ...initialSig ? { thoughtSignature: initialSig } : {}
1753
1763
  };
1754
- encryptedReasoning?.rememberToolCall(block.id, block);
1764
+ encryptedReasoning.rememberToolCall(block.id, block);
1755
1765
  toolArgumentPreviewSchedules.set(block, createToolArgumentPreviewSchedule());
1756
1766
  output.content.push(block);
1757
1767
  toolCallBlockIndices.set(block, output.content.length - 1);
@@ -1763,9 +1773,10 @@ async function processCompletionsStream(responseStream, output, model, stream, o
1763
1773
  }
1764
1774
  if (streamIndex !== void 0 && !toolCallBlocksByIndex.has(streamIndex)) toolCallBlocksByIndex.set(streamIndex, block);
1765
1775
  if (toolCall.id) {
1776
+ const previousId = block.id;
1766
1777
  if (!directMode || !block.id) block.id = toolCall.id;
1767
1778
  toolCallBlocksById.set(toolCall.id, block);
1768
- if (block.id === toolCall.id) encryptedReasoning?.rememberToolCall(toolCall.id, block);
1779
+ if (block.id === toolCall.id) encryptedReasoning.rememberToolCall(toolCall.id, block, previousId);
1769
1780
  }
1770
1781
  currentBlock = block;
1771
1782
  const conflictingId = directMode && block.id && toolCall.id && block.id !== toolCall.id;
@@ -1785,7 +1796,7 @@ async function processCompletionsStream(responseStream, output, model, stream, o
1785
1796
  });
1786
1797
  }
1787
1798
  }
1788
- encryptedReasoning?.consumeDetails(deltaFields.reasoning_details);
1799
+ encryptedReasoning.consumeDetails(deltaFields.reasoning_details);
1789
1800
  }
1790
1801
  flushPendingPostToolCallDeltas();
1791
1802
  emitReasoningUsageActivity(hasReasoningUsageActivity);
@@ -1,5 +1,5 @@
1
- import { M as OpenAICompletionsCompat, O as Model, l as CacheRetention } from "./types-Ntv5z2g2.mjs";
2
- import "./types-DlfwzH3T.mjs";
1
+ import { M as OpenAICompletionsCompat, O as Model, l as CacheRetention } from "./types-qZFbaDbK.mjs";
2
+ import "./types-DTvddOfm.mjs";
3
3
  //#region packages/ai/src/providers/openai-prompt-cache.d.ts
4
4
  /** Selects documented lifetime fields shared by Responses and Chat Completions. */
5
5
  declare function resolveOpenAIPromptCacheParams(model: Pick<Model, "id" | "provider" | "baseUrl">, cacheRetention: CacheRetention, compat: Required<Pick<OpenAICompletionsCompat, "supportsPromptCacheKey" | "supportsLongCacheRetention">>): {
@@ -0,0 +1,46 @@
1
+ import { n as isNativeOpenAIEndpoint } from "./openai-completions-compat-CUollwl6.mjs";
2
+ //#region packages/normalization-core/src/code-points.ts
3
+ /** Truncates to a nonnegative code-point budget; grapheme clusters may be split. */
4
+ function truncateCodePoints(text, maxCodePoints) {
5
+ const limit = Math.max(0, Math.trunc(maxCodePoints) || 0);
6
+ if (text.length <= limit) return text;
7
+ const prefix = [];
8
+ for (const codePoint of text) {
9
+ if (prefix.length >= limit) break;
10
+ prefix.push(codePoint);
11
+ }
12
+ return prefix.join("");
13
+ }
14
+ //#endregion
15
+ //#region packages/ai/src/providers/openai-prompt-cache.ts
16
+ const EXTENDED_RETENTION_MODELS = /* @__PURE__ */ new Set([
17
+ "gpt-5.5",
18
+ "gpt-5.5-pro",
19
+ "gpt-5.4",
20
+ "gpt-5.2",
21
+ "gpt-5.1-codex-max",
22
+ "gpt-5.1",
23
+ "gpt-5.1-codex",
24
+ "gpt-5.1-codex-mini",
25
+ "gpt-5.1-chat-latest",
26
+ "gpt-5",
27
+ "gpt-5-codex",
28
+ "gpt-4.1"
29
+ ]);
30
+ /** Selects documented lifetime fields shared by Responses and Chat Completions. */
31
+ function resolveOpenAIPromptCacheParams(model, cacheRetention, compat) {
32
+ if (cacheRetention !== "long" || !compat.supportsPromptCacheKey || !compat.supportsLongCacheRetention) return {};
33
+ const version = /^gpt-(\d+)(?:\.(\d+))?(?:-|$)/.exec(model.id);
34
+ if (version && (Number(version[1]) > 5 || Number(version[1]) === 5 && Number(version[2]) >= 6)) return { prompt_cache_options: { ttl: "30m" } };
35
+ const modelId = model.id.replace(/-\d{4}-\d{2}-\d{2}$/, "");
36
+ return !isNativeOpenAIEndpoint(model) || EXTENDED_RETENTION_MODELS.has(modelId) ? { prompt_cache_retention: "24h" } : {};
37
+ }
38
+ /** Maximum prompt cache key length accepted by OpenAI-compatible request metadata. */
39
+ const OPENAI_PROMPT_CACHE_KEY_MAX_LENGTH = 64;
40
+ /** Truncates a prompt cache key by Unicode code point count. */
41
+ function clampOpenAIPromptCacheKey(key) {
42
+ if (key === void 0) return;
43
+ return truncateCodePoints(key, 64);
44
+ }
45
+ //#endregion
46
+ export { clampOpenAIPromptCacheKey as n, resolveOpenAIPromptCacheParams as r, OPENAI_PROMPT_CACHE_KEY_MAX_LENGTH as t };
@@ -1,5 +1,5 @@
1
- import { n as getAiTransportHost } from "./host-B8YfDGd4.mjs";
2
- import { T as resolveOpenAIClientBaseUrl } from "./openai-transport-params-9aPuV5YY.mjs";
1
+ import { n as getAiTransportHost } from "./host-yTvBrYM2.mjs";
2
+ import { k as resolveOpenAIClientBaseUrl } from "./openai-transport-params-DZKOTSfH.mjs";
3
3
  import { i as resolveCloudflareBaseUrl, r as isCloudflareProvider } from "./github-copilot-headers-B37TB3rB.mjs";
4
4
  import OpenAI from "openai";
5
5
  //#region packages/ai/src/providers/openai-provider-client.ts