@openclaw/ai 2026.9.1-beta.1 → 2026.9.2

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 (88) hide show
  1. package/dist/{anthropic-DI4PZKKB.mjs → anthropic-BDdqdVLK.mjs} +222 -216
  2. package/dist/{anthropic-compaction-replay-nhKaCXu6.mjs → anthropic-compaction-replay-DB2FGLQc.mjs} +160 -68
  3. package/dist/{anthropic-payload-policy-B_0n0enE.d.mts → anthropic-payload-policy-d46X2pR0.d.mts} +28 -4
  4. package/dist/{api-registry-CTd8NzcD.d.mts → api-registry-DWtPjzyn.d.mts} +2 -2
  5. package/dist/{azure-openai-responses-D8dI0ekg.mjs → azure-openai-responses-C5bZRfAP.mjs} +12 -9
  6. package/dist/{number-coercion-H9qHik3g.mjs → base64-CEFBpSkN.mjs} +73 -1
  7. package/dist/{diagnostics-COpOtRwq.mjs → diagnostics-CPeq9F7y.mjs} +5 -1
  8. package/dist/diagnostics-DfFyKeX_.mjs +136 -0
  9. package/dist/{diagnostics-BaTA9eVl.d.mts → diagnostics-DnPnOui6.d.mts} +5 -1
  10. package/dist/diagnostics.d.mts +8 -3
  11. package/dist/diagnostics.mjs +4 -3
  12. package/dist/{env-api-keys-DrgeBuva.mjs → env-api-keys-bktO00EJ.mjs} +2 -15
  13. package/dist/{event-stream-uSMZJ3FA.mjs → event-stream-BgDvQeum.mjs} +3 -9
  14. package/dist/{event-stream-LiXePESD.d.mts → event-stream-BhT5T1Ay.d.mts} +1 -1
  15. package/dist/event-stream-zctLx0yr.d.mts +1 -0
  16. package/dist/event-stream.d.mts +2 -2
  17. package/dist/event-stream.mjs +1 -1
  18. package/dist/{google-Od-LLdVK.mjs → google-4qeuE8iX.mjs} +9 -7
  19. package/dist/{google-shared-Bgr9lFPw.mjs → google-shared-CWeG8RIl.mjs} +27 -23
  20. package/dist/{google-vertex-aerRSXc4.mjs → google-vertex-O9BcnB6X.mjs} +8 -6
  21. package/dist/{host-D51fmkH6.mjs → host-CEvLw30U.mjs} +54 -9
  22. package/dist/{host-DsbPMFU6.d.mts → host-DjzGmdZ2.d.mts} +3 -3
  23. package/dist/index-FnHM2FcI.d.mts +117 -0
  24. package/dist/index.d.mts +10 -11
  25. package/dist/index.mjs +6 -6
  26. package/dist/internal/anthropic.d.mts +59 -55
  27. package/dist/internal/anthropic.mjs +5 -5
  28. package/dist/internal/openai-responses-payload-policy.d.mts +3 -3
  29. package/dist/internal/openai-responses-payload-policy.mjs +2 -3
  30. package/dist/internal/openai.d.mts +66 -64
  31. package/dist/internal/openai.mjs +10 -10
  32. package/dist/internal/retry-after.d.mts +2 -3
  33. package/dist/internal/runtime.d.mts +43 -43
  34. package/dist/internal/runtime.mjs +10 -8
  35. package/dist/internal/shared.d.mts +25 -25
  36. package/dist/internal/shared.mjs +95 -4
  37. package/dist/{mistral-EiHdymeb.mjs → mistral-Tb6oalqH.mjs} +30 -23
  38. package/dist/{openai-chatgpt-responses-DHpF9o1e.mjs → openai-chatgpt-responses-yUXjPNfu.mjs} +76 -137
  39. package/dist/{openai-completions-EFPiUGfS.mjs → openai-completions-BIUV3RDT.mjs} +26 -22
  40. package/dist/{openai-completions-compat-BefmHT26.d.mts → openai-completions-compat-CpjYUArk.d.mts} +5 -5
  41. package/dist/{openai-completions-stream-DUlGwRMz.mjs → openai-completions-stream-BsrBe3Gg.mjs} +103 -96
  42. package/dist/openai-prompt-cache-CGnVB74a.mjs +21 -0
  43. package/dist/openai-prompt-cache-CNoIfHYC.d.mts +16 -0
  44. package/dist/{openai-responses-BogP8OjX.mjs → openai-responses-CCL41ALM.mjs} +15 -14
  45. package/dist/openai-responses-compaction-window-BMVHFOtq.mjs +697 -0
  46. package/dist/{openai-responses-contracts-Dvj_UtPy.d.mts → openai-responses-contracts-rF5DDRNS.d.mts} +23 -6
  47. package/dist/{openai-responses-payload-policy-CNGFT9zr.d.mts → openai-responses-payload-policy-rLRPsSmB.d.mts} +1 -0
  48. package/dist/{openai-responses-prompt-observer-internal-Cd4hJG-S.mjs → openai-responses-prompt-observer-internal-D0bhBfgL.mjs} +4 -18
  49. package/dist/{openai-responses-shared-DJThc6jW.mjs → openai-responses-shared-Bmma_3Qc.mjs} +438 -309
  50. package/dist/{openai-tool-schema-ho-hIkQf.mjs → openai-tool-schema-_pTAJqKF.mjs} +30 -40
  51. package/dist/{provider-error-DDOs_Bz0.mjs → provider-error-9TraxGvt.mjs} +20 -92
  52. package/dist/{provider-options-MdMBLzlU.d.mts → provider-options-Bcc_p-TU.d.mts} +26 -6
  53. package/dist/provider-replay-context-BuSUaAk5.mjs +21 -0
  54. package/dist/{provider-transcript-transform-C01bQ5a3.mjs → provider-transcript-transform-BaMbI1hr.mjs} +1 -1
  55. package/dist/provider-types.d.mts +19 -20
  56. package/dist/providers.d.mts +6 -6
  57. package/dist/providers.mjs +11 -11
  58. package/dist/{reasoning-tag-text-partitioner-5ygO2rZc.mjs → reasoning-tag-text-partitioner-DLCNXki6.mjs} +158 -94
  59. package/dist/rolldown-runtime-BhDjJH2R.mjs +15 -0
  60. package/dist/{sanitize-unicode-DCkltN94.mjs → sanitize-unicode-D6xUvZaS.mjs} +2 -8
  61. package/dist/{simple-options-CFj7x3J4.mjs → simple-options-BjHCCh4v.mjs} +42 -6
  62. package/dist/{src-Bu3FiFAG.mjs → src-2qBGKg8O.mjs} +83 -2
  63. package/dist/{stream-first-event-timeout-MK28puvq.mjs → stream-first-event-timeout-DcNjoFQE.mjs} +1 -1
  64. package/dist/{tool-schema-json-projection-qvTEs5Am.mjs → tool-schema-json-projection-mJhXDcyz.mjs} +21 -31
  65. package/dist/{transport-stream-shared-ljShVIZB.mjs → transport-stream-shared-CZqMhfIw.mjs} +19 -6
  66. package/dist/{transport-stream-shared-rvaCyFYt.d.mts → transport-stream-shared-xnaqxmbP.d.mts} +5 -5
  67. package/dist/{transport-utils-LJ1_rbi-.mjs → transport-utils-7il795_9.mjs} +5 -8
  68. package/dist/transports.d.mts +121 -85
  69. package/dist/transports.mjs +747 -464
  70. package/dist/types-3Lnm-QSJ.d.mts +1 -0
  71. package/dist/{types-DhLoJbFm.d.mts → types-CJ1-Ht7A.d.mts} +55 -19
  72. package/dist/types.d.mts +7 -7
  73. package/dist/types.mjs +5 -5
  74. package/dist/{validation-Dk7q7NMN.d.mts → validation-AKZBDGQd.d.mts} +1 -1
  75. package/dist/{validation-B61OhAio.mjs → validation-CJZtym2g.mjs} +7 -5
  76. package/dist/validation.d.mts +1 -1
  77. package/dist/validation.mjs +1 -1
  78. package/package.json +5 -5
  79. package/dist/anthropic-BECQCNdF.d.mts +0 -98
  80. package/dist/event-stream-BKp4fOt_.d.mts +0 -1
  81. package/dist/index-Qbej8io0.d.mts +0 -3
  82. package/dist/openai-prompt-cache-2uo_1OR1.d.mts +0 -7
  83. package/dist/openai-prompt-cache-mZTCdRPo.mjs +0 -12
  84. package/dist/openai-responses-contracts-QUY12X0B.mjs +0 -233
  85. package/dist/openai-responses-payload-policy-D8EdimYe.mjs +0 -204
  86. package/dist/provider-options-AvldWZt8.mjs +0 -21
  87. package/dist/tls-certificate-errors-DXSpluKI.mjs +0 -93
  88. package/dist/types-GiAjXatj.d.mts +0 -1
@@ -1,18 +1,18 @@
1
1
  import { c as normalizeLowercaseStringOrEmpty, i as asOptionalObjectRecord, o as isRecord, t as truncateUtf16Safe } from "./utf16-slice-qz3nsy87.mjs";
2
- import { t as sanitizeSurrogates } from "./sanitize-unicode-DCkltN94.mjs";
3
- import { a as describeToolResultMediaPlaceholder, c as extractToolResultText, d as isImageWithMediaPayload, n as getAiTransportHost } from "./host-D51fmkH6.mjs";
4
- import { n as clampOpenAIPromptCacheKey } from "./openai-prompt-cache-mZTCdRPo.mjs";
5
- import { l as stripSystemPromptCacheBoundary } from "./simple-options-CFj7x3J4.mjs";
6
- import { o as resolveProviderRequestCapabilities, r as resolveModelRequestTimeoutMs, s as resolveProviderRequestPolicyConfig } from "./tool-schema-json-projection-qvTEs5Am.mjs";
7
- import { i as isCodeModeModelVisibleToolName, m as sha256Hex } from "./transport-utils-LJ1_rbi-.mjs";
8
- import { s as finalizeTerminalToolCallArguments } from "./transport-stream-shared-ljShVIZB.mjs";
2
+ import { t as sanitizeSurrogates } from "./sanitize-unicode-D6xUvZaS.mjs";
3
+ import { a as describeToolResultMediaPlaceholder, c as extractToolResultText, d as isImageWithMediaPayload, n as getAiTransportHost } from "./host-CEvLw30U.mjs";
4
+ import { t as createReasoningTagTextPartitioner } from "./reasoning-tag-text-partitioner-DLCNXki6.mjs";
5
+ import { n as clampOpenAIPromptCacheKey } from "./openai-prompt-cache-CGnVB74a.mjs";
6
+ import { d as stripSystemPromptCacheBoundary } from "./simple-options-BjHCCh4v.mjs";
7
+ import { o as resolveProviderRequestCapabilities, r as resolveModelRequestTimeoutMs, s as resolveProviderRequestPolicyConfig } from "./tool-schema-json-projection-mJhXDcyz.mjs";
8
+ import { i as isCodeModeModelVisibleToolName, p as sha256Hex } from "./transport-utils-7il795_9.mjs";
9
+ import { s as finalizeTerminalToolCallArguments } from "./transport-stream-shared-CZqMhfIw.mjs";
9
10
  import { r as parseStreamingJson, t as createToolArgumentPreviewSchedule } from "./json-parse-BuAJEbdW.mjs";
10
11
  import { t as notifyLlmRequestActivity } from "./llm-request-activity-BjtkplhG.mjs";
11
- import { A as readOpenAICompletionsReasoningBatch, D as measureUtf8AppendBytes, N as throwIfModelStreamAborted, O as parseOpenAICompletionsUsage, S as createModelStreamCooperativeScheduler, T as isOpenAICompletionsThinkingEnabled, a as resolveOpenAIProjectedToolsStrictToolFlag, k as readOpenAICompletionsContentDeltas, t as findOpenAIStrictToolProjectionDiagnostics } from "./openai-tool-schema-ho-hIkQf.mjs";
12
- import { a as withFirstStreamEventTimeout } from "./stream-first-event-timeout-MK28puvq.mjs";
13
- import { t as transformProviderMessages } from "./provider-transcript-transform-C01bQ5a3.mjs";
12
+ import { A as readOpenAICompletionsReasoningBatch, D as measureUtf8AppendBytes, N as throwIfModelStreamAborted, O as parseOpenAICompletionsUsage, S as createModelStreamCooperativeScheduler, T as isOpenAICompletionsThinkingEnabled, a as resolveOpenAIProjectedToolsStrictToolFlag, k as readOpenAICompletionsContentDeltas, t as findOpenAIStrictToolProjectionDiagnostics } from "./openai-tool-schema-_pTAJqKF.mjs";
13
+ import { a as withFirstStreamEventTimeout } from "./stream-first-event-timeout-DcNjoFQE.mjs";
14
+ import { t as transformProviderMessages } from "./provider-transcript-transform-BaMbI1hr.mjs";
14
15
  import { t as mapOpenAIStopReason } from "./openai-stop-reason-Drnn_6Qj.mjs";
15
- import { t as createReasoningTagTextPartitioner } from "./reasoning-tag-text-partitioner-5ygO2rZc.mjs";
16
16
  import { randomUUID } from "node:crypto";
17
17
  //#region packages/ai/src/utils/assistant-text-phase.ts
18
18
  const EMPTY_ASSISTANT_TEXT_BLOCK_SET = /* @__PURE__ */ new Set();
@@ -34,7 +34,7 @@ function tagUnphasedText(content, phase, idPrefix) {
34
34
  const tagged = /* @__PURE__ */ new Map();
35
35
  for (const block of textBlocks) {
36
36
  if (block.text.trim().length === 0 || block.textSignature !== void 0) continue;
37
- const signature = encodeAssistantTextSignatureV1(`${idPrefix}-${phaseIndex}`, phase);
37
+ const signature = encodeAssistantTextSignatureV1(`${idPrefix}-${phaseIndex}-${randomUUID().replaceAll("-", "").slice(0, 24)}`, phase);
38
38
  block.textSignature = signature;
39
39
  tagged.set(block, signature);
40
40
  phaseIndex += 1;
@@ -67,6 +67,14 @@ function rememberPendingCommentaryTags(target, tagged) {
67
67
  for (const [block, signature] of tagged) target.set(block, signature);
68
68
  }
69
69
  //#endregion
70
+ //#region packages/ai/src/transports/deepseek-dsml-grammar.ts
71
+ const DEEPSEEK_DSML_MARKERS = [
72
+ "|",
73
+ "|",
74
+ "||"
75
+ ].map((bar) => `${bar}DSML${bar}`);
76
+ const DEEPSEEK_DSML_MARKER_PATTERN = `(${DEEPSEEK_DSML_MARKERS.map((marker) => marker.replaceAll("|", "\\|")).join("|")})`;
77
+ //#endregion
70
78
  //#region packages/ai/src/transports/deepseek-text-filter.ts
71
79
  /**
72
80
  * DeepSeek DSML streaming text filter.
@@ -79,38 +87,35 @@ const DSML_KINDS = [
79
87
  "tool_call",
80
88
  "function_calls"
81
89
  ];
82
- const DSML_BARS = ["|", "|"];
83
- const DSML_OPEN_TOKENS = DSML_BARS.flatMap((bar) => DSML_KINDS.map((kind) => `<${bar}DSML${bar}${kind}>`));
84
- const DSML_CLOSE_TOKENS = DSML_BARS.flatMap((bar) => DSML_KINDS.map((kind) => `</${bar}DSML${bar}${kind}>`));
90
+ const DSML_OPEN_TOKENS = DEEPSEEK_DSML_MARKERS.flatMap((marker) => DSML_KINDS.map((kind) => `<${marker}${kind}>`));
85
91
  const MAX_OPEN_TOKEN_LEN = Math.max(...DSML_OPEN_TOKENS.map((token) => token.length));
86
- const MAX_CLOSE_TOKEN_LEN = Math.max(...DSML_CLOSE_TOKENS.map((token) => token.length));
87
92
  /** Create an incremental text filter that strips DeepSeek DSML tool blocks. */
88
93
  function createDeepSeekTextFilter() {
89
94
  let buffer = "";
90
- let insideDsml = false;
95
+ let closeToken;
91
96
  const consume = (final) => {
92
97
  const output = [];
93
98
  const emit = (text) => {
94
99
  if (text) output.push(text);
95
100
  };
96
101
  while (buffer) {
97
- if (insideDsml) {
98
- const close = findEarliestToken(buffer, DSML_CLOSE_TOKENS);
99
- if (close) {
100
- buffer = buffer.slice(close.index + close.token.length);
101
- insideDsml = false;
102
+ if (closeToken) {
103
+ const closeIndex = buffer.indexOf(closeToken);
104
+ if (closeIndex !== -1) {
105
+ buffer = buffer.slice(closeIndex + closeToken.length);
106
+ closeToken = void 0;
102
107
  continue;
103
108
  }
104
- const keep = final ? 0 : Math.min(buffer.length, MAX_CLOSE_TOKEN_LEN - 1);
109
+ const keep = final ? 0 : Math.min(buffer.length, closeToken.length - 1);
105
110
  buffer = buffer.slice(buffer.length - keep);
106
- if (final) insideDsml = false;
111
+ if (final) closeToken = void 0;
107
112
  return output;
108
113
  }
109
114
  const open = findEarliestToken(buffer, DSML_OPEN_TOKENS);
110
115
  if (open) {
111
116
  emit(buffer.slice(0, open.index));
112
117
  buffer = buffer.slice(open.index + open.token.length);
113
- insideDsml = true;
118
+ closeToken = open.token.replace("<", "</");
114
119
  continue;
115
120
  }
116
121
  if (final) {
@@ -215,7 +220,7 @@ function resolveOpenAICompletionsCompatDefaults(input) {
215
220
  const isTogether = knownProviderFamily === "together" || input.baseUrl?.includes("api.together.ai") === true || input.baseUrl?.includes("api.together.xyz") === true || isDefaultRoute && isDefaultRouteProvider(input.provider, "together");
216
221
  const isCloudflareAiGateway = provider === "cloudflare-ai-gateway" || input.baseUrl?.includes("gateway.ai.cloudflare.com") === true;
217
222
  const isXiaomi = endpointClass === "xiaomi-native" || isDefaultRoute && isDefaultRouteProvider(input.provider, "xiaomi");
218
- const isNonStandard = endpointClass === "cerebras-native" || endpointClass === "chutes-native" || endpointClass === "deepseek-native" || endpointClass === "mistral-public" || endpointClass === "opencode-native" || endpointClass === "xai-native" || isXiaomi || isZai || isDefaultRoute && isDefaultRouteProvider(input.provider, "cerebras", "chutes", "deepseek", "opencode", "xai");
223
+ const isNonStandard = endpointClass === "cerebras-native" || endpointClass === "chutes-native" || endpointClass === "deepseek-native" || endpointClass === "mistral-public" || endpointClass === "opencode-native" || endpointClass === "opencode-go-native" || endpointClass === "xai-native" || isXiaomi || isZai || isDefaultRoute && isDefaultRouteProvider(input.provider, "cerebras", "chutes", "deepseek", "opencode", "xai");
219
224
  const isOpenRouterLike = input.provider === "openrouter" || endpointClass === "openrouter";
220
225
  const isLocalEndpoint = endpointClass === "local";
221
226
  const usesMaxTokens = endpointClass === "chutes-native" || endpointClass === "mistral-public" || knownProviderFamily === "mistral" || isMoonshot || isCloudflareAiGateway || isZai || isTogether || isDefaultRoute && isDefaultRouteProvider(provider, "chutes");
@@ -231,9 +236,9 @@ function resolveOpenAICompletionsCompatDefaults(input) {
231
236
  supportsJsonSchemaResponseFormat: (endpointClass === "openai-public" || isDefaultRoute && isDefaultRouteProvider(provider, "openai")) && isKnownOpenAIJsonSchemaModelId(modelId),
232
237
  requiresReasoningContentOnAssistantMessages: isDeepSeek || isXiaomi,
233
238
  requiresNonEmptyUserOrAssistantMessage: isModelStudioLike,
234
- cacheControlFormat: provider === "openrouter" && modelId?.startsWith("anthropic/") === true ? "anthropic" : void 0,
239
+ cacheControlFormat: isModelStudioLike && endpointClass !== "custom" || provider === "openrouter" && modelId?.startsWith("anthropic/") === true ? "anthropic" : void 0,
235
240
  sessionAffinityFormat: isOpenRouterLike ? "openrouter" : "openai",
236
- supportsLongCacheRetention: provider !== "cloudflare-workers-ai" && provider !== "cloudflare-ai-gateway" && knownProviderFamily !== "together" && !input.baseUrl?.includes("api.cloudflare.com") && !input.baseUrl?.includes("gateway.ai.cloudflare.com") && !input.baseUrl?.includes("api.together.ai") && !input.baseUrl?.includes("api.together.xyz")
241
+ supportsLongCacheRetention: !isModelStudioLike && provider !== "cloudflare-workers-ai" && provider !== "cloudflare-ai-gateway" && knownProviderFamily !== "together" && !input.baseUrl?.includes("api.cloudflare.com") && !input.baseUrl?.includes("gateway.ai.cloudflare.com") && !input.baseUrl?.includes("api.together.ai") && !input.baseUrl?.includes("api.together.xyz")
237
242
  };
238
243
  }
239
244
  function resolveOpenAICompletionsCompatDefaultsFromCapabilities(input) {
@@ -391,11 +396,13 @@ function createOpenAICompletionsToolCallDeltaNormalizer() {
391
396
  }];
392
397
  const hadPendingLegacyCall = pendingLegacyToolCall !== void 0;
393
398
  const leadingDeltas = [];
394
- if (hasOrdinaryContent(ordinaryDelta)) if (hadPendingLegacyCall) bufferFollowingDelta(ordinaryDelta);
395
- else leadingDeltas.push({
396
- delta: ordinaryDelta,
397
- toolCalls: []
398
- });
399
+ if (hasOrdinaryContent(ordinaryDelta)) {
400
+ if (hadPendingLegacyCall) bufferFollowingDelta(ordinaryDelta);
401
+ else leadingDeltas.push({
402
+ delta: ordinaryDelta,
403
+ toolCalls: []
404
+ });
405
+ }
399
406
  if (functionCall && (functionCall.name || functionCall.arguments)) {
400
407
  const nextFunctionName = pendingLegacyToolCall?.function?.name ? void 0 : functionCall.name;
401
408
  const nextArgumentBytes = Buffer.byteLength(functionCall.arguments ?? "", "utf8") + Buffer.byteLength(nextFunctionName ?? "", "utf8");
@@ -555,23 +562,24 @@ function convertMessages(model, context, compat, options = {}) {
555
562
  role: "assistant",
556
563
  content: compat.requiresAssistantAfterToolResult ? "" : null
557
564
  };
558
- const assistantTextParts = msg.content.filter(isTextContentBlock).filter((block) => block.text.trim().length > 0).map((block) => ({
559
- type: "text",
560
- text: sanitizeSurrogates(block.text)
561
- }));
562
- const assistantText = assistantTextParts.map((part) => part.text).join("\n");
565
+ const assistantTexts = msg.content.filter(isTextContentBlock).filter((block) => block.text.trim().length > 0).map((block) => sanitizeSurrogates(block.text));
566
+ const assistantText = assistantTexts.join("\n");
563
567
  const nonEmptyThinkingBlocks = msg.content.filter(isThinkingContentBlock).filter((block) => block.thinking.trim().length > 0);
564
- if (nonEmptyThinkingBlocks.length > 0) if (compat.requiresThinkingAsText) assistantMsg.content = [{
565
- type: "text",
566
- text: nonEmptyThinkingBlocks.map((block) => sanitizeSurrogates(block.thinking)).join("\n\n")
567
- }, ...assistantTextParts];
568
- else {
569
- if (assistantText.length > 0) assistantMsg.content = assistantText;
570
- let signature = nonEmptyThinkingBlocks.at(0)?.thinkingSignature;
571
- if (model.provider === "opencode-go" && signature === "reasoning") signature = "reasoning_content";
572
- if (signature && signature.length > 0) assistantMsg[signature] = nonEmptyThinkingBlocks.map((block) => block.thinking).join("\n");
573
- }
574
- else if (assistantText.length > 0) assistantMsg.content = assistantText;
568
+ if (nonEmptyThinkingBlocks.length > 0) {
569
+ if (compat.requiresThinkingAsText) assistantMsg.content = [{
570
+ type: "text",
571
+ text: nonEmptyThinkingBlocks.map((block) => sanitizeSurrogates(block.thinking)).join("\n\n")
572
+ }, ...assistantTexts.map((text) => ({
573
+ type: "text",
574
+ text
575
+ }))];
576
+ else {
577
+ if (assistantText.length > 0) assistantMsg.content = assistantText;
578
+ let signature = nonEmptyThinkingBlocks.at(0)?.thinkingSignature;
579
+ if (model.provider === "opencode-go" && signature === "reasoning") signature = "reasoning_content";
580
+ if (signature && signature.length > 0) assistantMsg[signature] = nonEmptyThinkingBlocks.map((block) => block.thinking).join("\n");
581
+ }
582
+ } else if (assistantText.length > 0) assistantMsg.content = assistantText;
575
583
  const toolCalls = msg.content.filter(isToolCallBlock);
576
584
  if (toolCalls.length > 0) {
577
585
  assistantMsg.tool_calls = toolCalls.map((toolCall) => ({
@@ -868,17 +876,20 @@ function resolveOpenAISdkTimeoutMs(model, timeoutMs) {
868
876
  }
869
877
  function buildOpenAISdkClientOptions(model) {
870
878
  const timeout = resolveOpenAISdkTimeoutMs(model);
871
- return timeout === void 0 ? {} : { timeout };
879
+ return {
880
+ ...timeout === void 0 ? {} : { timeout },
881
+ maxRetries: 0
882
+ };
872
883
  }
873
884
  function buildOpenAISdkRequestOptions(model, signal, options) {
874
885
  const timeout = resolveOpenAISdkTimeoutMs(model, options?.timeoutMs);
875
886
  const headers = options?.stream === true && usesNativeOpenAICodexResponsesBackend(model) ? { Accept: "text/event-stream" } : void 0;
876
- if (timeout === void 0 && options?.maxRetries === void 0 && !signal && !headers) return;
887
+ if (timeout === void 0 && !signal && !headers) return;
877
888
  return {
878
889
  ...headers ? { headers } : {},
879
890
  ...signal ? { signal } : {},
880
891
  ...timeout !== void 0 ? { timeout } : {},
881
- ...options?.maxRetries !== void 0 ? { maxRetries: options.maxRetries } : {}
892
+ maxRetries: 0
882
893
  };
883
894
  }
884
895
  function getCompat(model) {
@@ -896,39 +907,29 @@ function getCompat(model) {
896
907
  }
897
908
  //#endregion
898
909
  //#region packages/ai/src/transports/openai-completions-dsml.ts
899
- const DEEPSEEK_DSML_BARS = ["|", "|"];
900
910
  const DEEPSEEK_DSML_TOOL_KINDS = [
901
911
  "tool_calls",
902
912
  "tool_call",
903
913
  "function_calls"
904
914
  ];
905
- const DEEPSEEK_DSML_TOOL_OPEN_TOKENS = DEEPSEEK_DSML_BARS.flatMap((bar) => DEEPSEEK_DSML_TOOL_KINDS.map((kind) => `<${bar}DSML${bar}${kind}>`));
906
- const DEEPSEEK_DSML_TOOL_CLOSE_TOKENS = DEEPSEEK_DSML_BARS.flatMap((bar) => DEEPSEEK_DSML_TOOL_KINDS.map((kind) => `</${bar}DSML${bar}${kind}>`));
907
- const DEEPSEEK_DSML_INVOKE_OPEN_PREFIXES = DEEPSEEK_DSML_BARS.map((bar) => `<${bar}DSML${bar}invoke`);
908
- const DEEPSEEK_DSML_INVOKE_CLOSE_TOKENS = DEEPSEEK_DSML_BARS.map((bar) => `</${bar}DSML${bar}invoke>`);
915
+ const DEEPSEEK_DSML_TOOL_OPEN_TOKENS = DEEPSEEK_DSML_MARKERS.flatMap((marker) => DEEPSEEK_DSML_TOOL_KINDS.map((kind) => `<${marker}${kind}>`));
916
+ const DEEPSEEK_DSML_INVOKE_OPEN_PREFIXES = DEEPSEEK_DSML_MARKERS.map((marker) => `<${marker}invoke`);
917
+ const DEEPSEEK_DSML_INVOKE_OPEN_TAG = new RegExp(`^<${DEEPSEEK_DSML_MARKER_PATTERN}invoke\\b[^<>]*>$`);
909
918
  const DEEPSEEK_DSML_TOOL_MAX_OPEN_TOKEN_LEN = Math.max(...DEEPSEEK_DSML_TOOL_OPEN_TOKENS.map((token) => token.length));
910
- const DEEPSEEK_DSML_RECOVERY_MAX_BOUNDARY_LEN = Math.max(...DEEPSEEK_DSML_TOOL_OPEN_TOKENS.map((token) => token.length), ...DEEPSEEK_DSML_TOOL_CLOSE_TOKENS.map((token) => token.length), ...DEEPSEEK_DSML_INVOKE_OPEN_PREFIXES.map((token) => token.length), ...DEEPSEEK_DSML_INVOKE_CLOSE_TOKENS.map((token) => token.length));
919
+ const DEEPSEEK_DSML_RECOVERY_MAX_BOUNDARY_LEN = Math.max(...DEEPSEEK_DSML_TOOL_OPEN_TOKENS.map((token) => token.length + 1), ...DEEPSEEK_DSML_INVOKE_OPEN_PREFIXES.map((token) => token.length + 2));
911
920
  const MAX_DSML_RECOVERY_BUFFER_BYTES = 256e3;
912
- const DEEPSEEK_DSML_SCAN_BATCH_CHARS = 64 * 1024;
921
+ const DEEPSEEK_DSML_SCAN_BATCH_CHARS = 65536;
913
922
  function createDsmlRecoverer() {
914
923
  let buffer = "";
915
924
  let bufferBytes = 0;
916
925
  let bufferEndsWithHighSurrogate = false;
917
926
  let pendingScanChars = 0;
918
927
  let activeOpenToken = null;
919
- let blockScanState = {
920
- offset: 0,
921
- mode: "outer",
922
- invokeOpenStart: -1
923
- };
928
+ let blockScanState = { offset: 0 };
924
929
  const resetBlockScan = () => {
925
930
  activeOpenToken = null;
926
931
  pendingScanChars = 0;
927
- blockScanState = {
928
- offset: 0,
929
- mode: "outer",
930
- invokeOpenStart: -1
931
- };
932
+ blockScanState = { offset: 0 };
932
933
  };
933
934
  const consume = (final) => {
934
935
  const output = [];
@@ -1026,15 +1027,16 @@ function createDsmlRecoverer() {
1026
1027
  }
1027
1028
  function parseDeepSeekDsmlToolCallBlock(body) {
1028
1029
  const toolCalls = [];
1029
- const invokeOpenRegex = /<[||]DSML[||]invoke\b([^<>]*)>/g;
1030
+ const invokeOpenRegex = new RegExp(`<${DEEPSEEK_DSML_MARKER_PATTERN}invoke\\b([^<>]*)>`, "g");
1030
1031
  let openMatch;
1031
1032
  while ((openMatch = invokeOpenRegex.exec(body)) !== null) {
1032
1033
  const invokeBodyStart = openMatch.index + openMatch[0].length;
1033
- const invokeClose = findEarliestStringToken(body.slice(invokeBodyStart), ["</|DSML|invoke>", "</|DSML|invoke>"]);
1034
- if (!invokeClose) break;
1035
- const invokeBody = body.slice(invokeBodyStart, invokeBodyStart + invokeClose.index);
1036
- invokeOpenRegex.lastIndex = invokeBodyStart + invokeClose.index + invokeClose.token.length;
1037
- const invokeName = parseXmlAttribute(openMatch[1] ?? "", "name");
1034
+ const invokeCloseToken = `</${openMatch[1]}invoke>`;
1035
+ const invokeCloseIndex = body.indexOf(invokeCloseToken, invokeBodyStart);
1036
+ if (invokeCloseIndex === -1) break;
1037
+ const invokeBody = body.slice(invokeBodyStart, invokeCloseIndex);
1038
+ invokeOpenRegex.lastIndex = invokeCloseIndex + invokeCloseToken.length;
1039
+ const invokeName = parseXmlAttribute(openMatch[2] ?? "", "name");
1038
1040
  if (!invokeName) continue;
1039
1041
  const parsedArguments = parseDeepSeekDsmlInvokeArguments(invokeBody);
1040
1042
  if (!parsedArguments) continue;
@@ -1049,12 +1051,12 @@ function parseDeepSeekDsmlToolCallBlock(body) {
1049
1051
  }
1050
1052
  function parseDeepSeekDsmlInvokeArguments(body) {
1051
1053
  const args = {};
1052
- const parameterRegex = /<[||]DSML[||]parameter\b([^>]*)>([\s\S]*?)<\/[||]DSML[||]parameter>/g;
1054
+ const parameterRegex = new RegExp(`<${DEEPSEEK_DSML_MARKER_PATTERN}parameter\\b([^>]*)>([\\s\\S]*?)</\\1parameter>`, "g");
1053
1055
  let parameterMatch;
1054
1056
  while ((parameterMatch = parameterRegex.exec(body)) !== null) {
1055
- const name = parseXmlAttribute(parameterMatch[1] ?? "", "name");
1057
+ const name = parseXmlAttribute(parameterMatch[2] ?? "", "name");
1056
1058
  if (!name) continue;
1057
- const rawValue = parameterMatch[2] ?? "";
1059
+ const rawValue = parameterMatch[3] ?? "";
1058
1060
  if (rawValue.length === 0) continue;
1059
1061
  args[name] = decodeDeepSeekDsmlText(rawValue);
1060
1062
  }
@@ -1099,7 +1101,7 @@ function findEarliestStringToken(text, tokens, fromIndex = 0) {
1099
1101
  }
1100
1102
  function scanDeepSeekDsmlToolBlock(text, closeToken, contentStartIndex, state) {
1101
1103
  while (state.offset < text.length) {
1102
- if (state.mode === "invoke-open") {
1104
+ if (state.invoke?.kind === "open") {
1103
1105
  const nextOpen = text.indexOf("<", state.offset);
1104
1106
  const nextClose = text.indexOf(">", state.offset);
1105
1107
  if (nextClose === -1 && nextOpen === -1) {
@@ -1107,31 +1109,32 @@ function scanDeepSeekDsmlToolBlock(text, closeToken, contentStartIndex, state) {
1107
1109
  return { kind: "incomplete" };
1108
1110
  }
1109
1111
  if (nextOpen !== -1 && (nextClose === -1 || nextOpen < nextClose)) {
1110
- state.mode = "outer";
1112
+ state.invoke = void 0;
1111
1113
  state.offset = nextOpen;
1112
- state.invokeOpenStart = -1;
1113
1114
  continue;
1114
1115
  }
1115
- const invokeOpenTag = text.slice(state.invokeOpenStart, nextClose + 1);
1116
- if (!/^<[||]DSML[||]invoke\b[^<>]*>$/.test(invokeOpenTag)) {
1117
- state.mode = "outer";
1118
- state.offset = state.invokeOpenStart + 1;
1119
- state.invokeOpenStart = -1;
1116
+ const invokeOpenTag = text.slice(state.invoke.start, nextClose + 1);
1117
+ const open = DEEPSEEK_DSML_INVOKE_OPEN_TAG.exec(invokeOpenTag);
1118
+ if (!open) {
1119
+ state.offset = state.invoke.start + 1;
1120
+ state.invoke = void 0;
1120
1121
  continue;
1121
1122
  }
1122
- state.mode = "invoke-body";
1123
+ state.invoke = {
1124
+ kind: "body",
1125
+ closeToken: `</${open[1]}invoke>`
1126
+ };
1123
1127
  state.offset = nextClose + 1;
1124
- state.invokeOpenStart = -1;
1125
1128
  continue;
1126
1129
  }
1127
- if (state.mode === "invoke-body") {
1128
- const invokeClose = findEarliestStringToken(text, DEEPSEEK_DSML_INVOKE_CLOSE_TOKENS, state.offset);
1129
- if (!invokeClose) {
1130
+ if (state.invoke?.kind === "body") {
1131
+ const invokeCloseIndex = text.indexOf(state.invoke.closeToken, state.offset);
1132
+ if (invokeCloseIndex === -1) {
1130
1133
  state.offset = Math.max(0, text.length - DEEPSEEK_DSML_RECOVERY_MAX_BOUNDARY_LEN + 1);
1131
1134
  return { kind: "incomplete" };
1132
1135
  }
1133
- state.mode = "outer";
1134
- state.offset = invokeClose.index + invokeClose.token.length;
1136
+ state.offset = invokeCloseIndex + state.invoke.closeToken.length;
1137
+ state.invoke = void 0;
1135
1138
  continue;
1136
1139
  }
1137
1140
  const toolOpen = findEarliestStringToken(text, DEEPSEEK_DSML_TOOL_OPEN_TOKENS, state.offset);
@@ -1157,8 +1160,10 @@ function scanDeepSeekDsmlToolBlock(text, closeToken, contentStartIndex, state) {
1157
1160
  return { kind: "incomplete" };
1158
1161
  }
1159
1162
  if (next.kind === "invoke-open") {
1160
- state.mode = "invoke-open";
1161
- state.invokeOpenStart = next.index;
1163
+ state.invoke = {
1164
+ kind: "open",
1165
+ start: next.index
1166
+ };
1162
1167
  state.offset = next.index + next.token.length;
1163
1168
  continue;
1164
1169
  }
@@ -1196,6 +1201,7 @@ async function processCompletionsStream(responseStream, output, model, stream, o
1196
1201
  const deepSeekTextFilter = shouldFilterDeepSeekDsmlText ? createDeepSeekTextFilter() : null;
1197
1202
  const deepSeekToolCallRecoverer = shouldFilterDeepSeekDsmlText ? createDsmlRecoverer() : null;
1198
1203
  const reasoningTagTextPartitioner = createReasoningTagTextPartitioner();
1204
+ if (options?.strictReasoningTags) reasoningTagTextPartitioner.markStrict();
1199
1205
  let currentBlock = null;
1200
1206
  let directTextBlock = null;
1201
1207
  let directThinkingBlock = null;
@@ -1559,7 +1565,8 @@ async function processCompletionsStream(responseStream, output, model, stream, o
1559
1565
  if (block.id === toolCall.id) encryptedReasoning?.rememberToolCall(toolCall.id, block);
1560
1566
  }
1561
1567
  currentBlock = block;
1562
- if (toolCall.function?.name && (!directMode || !block.name)) block.name = toolCall.function.name;
1568
+ const conflictingId = directMode && block.id && toolCall.id && block.id !== toolCall.id;
1569
+ if (toolCall.function?.name && !conflictingId) block.name = toolCall.function.name;
1563
1570
  const deltaSig = directMode ? void 0 : extractToolCallThoughtSignature(toolCall);
1564
1571
  if (deltaSig) block.thoughtSignature = deltaSig;
1565
1572
  const toolArgumentsDelta = toolCall.function?.arguments;
@@ -0,0 +1,21 @@
1
+ //#region packages/ai/src/providers/openai-prompt-cache.ts
2
+ /** Selects the documented cache lifetime fields for a Responses request. */
3
+ function resolveOpenAIResponsesCacheParams(model, cacheRetention, supportsLongCacheRetention) {
4
+ if (cacheRetention === "none") return {};
5
+ if (model.id === "gpt-6-astra" && model.api === "openai-responses") {
6
+ const endpoint = URL.parse(model.baseUrl ?? "https://api.openai.com/v1");
7
+ if (endpoint?.protocol === "https:" && (endpoint.hostname === "api.openai.com" || endpoint.hostname.endsWith(".api.openai.com"))) return { prompt_cache_options: { ttl: "30m" } };
8
+ }
9
+ return cacheRetention === "long" && supportsLongCacheRetention ? { prompt_cache_retention: "24h" } : {};
10
+ }
11
+ /** Maximum prompt cache key length accepted by OpenAI-compatible request metadata. */
12
+ const OPENAI_PROMPT_CACHE_KEY_MAX_LENGTH = 64;
13
+ /** Truncates a prompt cache key by Unicode code point count. */
14
+ function clampOpenAIPromptCacheKey(key) {
15
+ if (key === void 0) return;
16
+ const chars = Array.from(key);
17
+ if (chars.length <= 64) return key;
18
+ return chars.slice(0, 64).join("");
19
+ }
20
+ //#endregion
21
+ export { clampOpenAIPromptCacheKey as n, resolveOpenAIResponsesCacheParams as r, OPENAI_PROMPT_CACHE_KEY_MAX_LENGTH as t };
@@ -0,0 +1,16 @@
1
+ import { D as Model, l as CacheRetention } from "./types-CJ1-Ht7A.mjs";
2
+ import "./types-3Lnm-QSJ.mjs";
3
+ //#region packages/ai/src/providers/openai-prompt-cache.d.ts
4
+ /** Selects the documented cache lifetime fields for a Responses request. */
5
+ declare function resolveOpenAIResponsesCacheParams(model: Pick<Model, "id" | "api" | "baseUrl">, cacheRetention: CacheRetention, supportsLongCacheRetention: boolean): {
6
+ prompt_cache_retention?: "24h";
7
+ prompt_cache_options?: {
8
+ ttl: "30m";
9
+ };
10
+ };
11
+ /** Maximum prompt cache key length accepted by OpenAI-compatible request metadata. */
12
+ declare const OPENAI_PROMPT_CACHE_KEY_MAX_LENGTH = 64;
13
+ /** Truncates a prompt cache key by Unicode code point count. */
14
+ declare function clampOpenAIPromptCacheKey(key: string | undefined): string | undefined;
15
+ //#endregion
16
+ export { clampOpenAIPromptCacheKey as n, resolveOpenAIResponsesCacheParams as r, OPENAI_PROMPT_CACHE_KEY_MAX_LENGTH as t };
@@ -1,12 +1,13 @@
1
- import { n as getEnvApiKey, r as __exportAll } from "./env-api-keys-DrgeBuva.mjs";
2
- import { t as AssistantMessageEventStream } from "./event-stream-uSMZJ3FA.mjs";
3
- import { n as getAiTransportHost } from "./host-D51fmkH6.mjs";
4
- import { n as clampOpenAIPromptCacheKey } from "./openai-prompt-cache-mZTCdRPo.mjs";
1
+ import { t as __exportAll } from "./rolldown-runtime-BhDjJH2R.mjs";
2
+ import { t as AssistantMessageEventStream } from "./event-stream-BgDvQeum.mjs";
3
+ import { n as getAiTransportHost } from "./host-CEvLw30U.mjs";
4
+ import { n as clampOpenAIPromptCacheKey, r as resolveOpenAIResponsesCacheParams } from "./openai-prompt-cache-CGnVB74a.mjs";
5
5
  import { t as resolveCacheRetention } from "./cache-retention-0x979a5V.mjs";
6
- import { n as buildBaseOptions } from "./simple-options-CFj7x3J4.mjs";
7
- import { a as resolveResponsesReasoningEffort, i as createResponsesAssistantOutput, n as applyResponsesServiceTierPricing, o as runResponsesStreamLifecycle, r as convertResponsesMessages, t as applyCommonResponsesParams } from "./openai-responses-shared-DJThc6jW.mjs";
8
- import { j as resolveOpenAIClientBaseUrl } from "./openai-tool-schema-ho-hIkQf.mjs";
9
- import { S as supportsOpenAITemperature } from "./openai-responses-contracts-QUY12X0B.mjs";
6
+ import { n as buildBaseOptions } from "./simple-options-BjHCCh4v.mjs";
7
+ import { n as getEnvApiKey } from "./env-api-keys-bktO00EJ.mjs";
8
+ import { a as resolveResponsesReasoningEffort, i as createResponsesAssistantOutput, n as applyResponsesServiceTierPricing, r as convertResponsesMessages, s as runResponsesStreamLifecycle, t as applyCommonResponsesParams } from "./openai-responses-shared-Bmma_3Qc.mjs";
9
+ import { j as resolveOpenAIClientBaseUrl } from "./openai-tool-schema-_pTAJqKF.mjs";
10
+ import { j as supportsOpenAITemperature } from "./openai-responses-compaction-window-BMVHFOtq.mjs";
10
11
  import { i as resolveCloudflareBaseUrl, n as hasCopilotVisionInput, r as isCloudflareProvider, t as buildCopilotDynamicHeaders } from "./github-copilot-headers-NCJtz9i0.mjs";
11
12
  import OpenAI from "openai";
12
13
  //#region packages/ai/src/providers/openai-responses.ts
@@ -21,18 +22,16 @@ function getCompat(model) {
21
22
  supportsLongCacheRetention: model.compat?.supportsLongCacheRetention ?? true
22
23
  };
23
24
  }
24
- function getPromptCacheRetention(compat, cacheRetention) {
25
- return cacheRetention === "long" && compat.supportsLongCacheRetention ? "24h" : void 0;
26
- }
27
25
  /**
28
26
  * Generate function for OpenAI Responses API
29
27
  */
30
28
  const streamOpenAIResponses = (model, context, options) => {
31
29
  const stream = new AssistantMessageEventStream();
30
+ const output = createResponsesAssistantOutput(model);
32
31
  runResponsesStreamLifecycle({
33
32
  stream,
34
33
  model,
35
- output: createResponsesAssistantOutput(model),
34
+ output,
36
35
  options,
37
36
  createClient: () => {
38
37
  const apiKey = options?.apiKey || getEnvApiKey(model.provider) || "";
@@ -81,11 +80,13 @@ function createClient(model, context, apiKey, optionsHeaders, sessionId) {
81
80
  Authorization: headers.Authorization ?? null,
82
81
  "cf-aig-authorization": `Bearer ${apiKey}`
83
82
  } : headers;
83
+ const baseUrl = isCloudflareProvider(model.provider) ? resolveCloudflareBaseUrl(model) : model.baseUrl;
84
84
  return new OpenAI({
85
85
  apiKey,
86
- baseURL: resolveOpenAIClientBaseUrl(model, isCloudflareProvider(model.provider) ? resolveCloudflareBaseUrl(model) : model.baseUrl),
86
+ baseURL: resolveOpenAIClientBaseUrl(model, baseUrl),
87
87
  dangerouslyAllowBrowser: true,
88
88
  defaultHeaders,
89
+ maxRetries: 0,
89
90
  fetch: getAiTransportHost().buildModelFetch(model)
90
91
  });
91
92
  }
@@ -103,7 +104,7 @@ function buildParams(model, context, options, replayMode = "checkpoint") {
103
104
  input: messages,
104
105
  stream: true,
105
106
  prompt_cache_key: cacheRetention === "none" ? void 0 : clampOpenAIPromptCacheKey(options?.promptCacheKey ?? options?.sessionId),
106
- prompt_cache_retention: getPromptCacheRetention(compat, cacheRetention),
107
+ ...resolveOpenAIResponsesCacheParams(model, cacheRetention, compat.supportsLongCacheRetention),
107
108
  store: false
108
109
  };
109
110
  if (options?.maxTokens) params.max_output_tokens = options?.maxTokens;