@openclaw/ai 2026.8.1-beta.1 → 2026.8.1-beta.3

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-CE-7SkF6.mjs → anthropic-B8KwTtlb.mjs} +62 -37
  2. package/dist/{anthropic-SrGtwsJu.d.mts → anthropic-BECQCNdF.d.mts} +0 -2
  3. package/dist/{src-QkygScBs.mjs → anthropic-BQXQudmA.mjs} +0 -2
  4. package/dist/{anthropic-usage-Ma4iX6uG.mjs → anthropic-compaction-replay-4Zx7-aCr.mjs} +225 -103
  5. package/dist/anthropic-payload-policy-CSx7MoKH.d.mts +50 -0
  6. package/dist/{api-registry-EpJoVwM1.d.mts → api-registry-DFxSnFqG.d.mts} +1 -1
  7. package/dist/{azure-openai-responses-Cc_kasye.mjs → azure-openai-responses-Aa4mVcYG.mjs} +23 -29
  8. package/dist/diagnostics.d.mts +24 -1
  9. package/dist/diagnostics.mjs +2 -1
  10. package/dist/event-stream-BVVgDSdq.d.mts +1 -0
  11. package/dist/{event-stream-DRmDMRHH.d.mts → event-stream-D91-ohD_.d.mts} +3 -1
  12. package/dist/{event-stream-CEV9t6da.mjs → event-stream-uSMZJ3FA.mjs} +16 -3
  13. package/dist/event-stream.d.mts +1 -1
  14. package/dist/event-stream.mjs +1 -1
  15. package/dist/{google-shared-Cq2UKx1l.mjs → google-shared-M1dl64nz.mjs} +17 -19
  16. package/dist/google-thinking-level-C-V3tecN.mjs +9 -0
  17. package/dist/{google-vertex-CusxWzvE.mjs → google-vertex-DCJHM_a5.mjs} +5 -4
  18. package/dist/{google-CGQu21aw.mjs → google-yDRnipeq.mjs} +4 -4
  19. package/dist/host-DF_yxOsA.mjs +477 -0
  20. package/dist/{host-Dn4_SZI2.d.mts → host-DJq_FGcz.d.mts} +13 -8
  21. package/dist/index.d.mts +7 -7
  22. package/dist/index.mjs +7 -5
  23. package/dist/internal/anthropic.d.mts +21 -7
  24. package/dist/internal/anthropic.mjs +5 -5
  25. package/dist/internal/openai-responses-payload-policy.d.mts +3 -0
  26. package/dist/internal/openai-responses-payload-policy.mjs +3 -0
  27. package/dist/internal/openai.d.mts +6 -6
  28. package/dist/internal/openai.mjs +9 -7
  29. package/dist/internal/runtime.d.mts +19 -5
  30. package/dist/internal/runtime.mjs +85 -72
  31. package/dist/internal/shared.d.mts +17 -8
  32. package/dist/internal/shared.mjs +4 -5
  33. package/dist/{json-parse-BvXNt1-7.mjs → json-parse-CDnesDM_.mjs} +4 -6
  34. package/dist/{mistral-Dx6VzNjf.mjs → mistral-D6hRXI7A.mjs} +67 -72
  35. package/dist/{number-coercion-1Miyb5MO.mjs → number-coercion-H9qHik3g.mjs} +7 -2
  36. package/dist/openai-chatgpt-jwt-KWcgd0d_.mjs +19 -0
  37. package/dist/{openai-chatgpt-responses-SC9m0FSf.mjs → openai-chatgpt-responses-C339VIfT.mjs} +235 -146
  38. package/dist/{openai-completions-BaIpl93j.mjs → openai-completions-D88orSJ9.mjs} +88 -67
  39. package/dist/openai-completions-compat-B0KTleXp.d.mts +43 -0
  40. package/dist/{openai-responses-Bdx3V_Yu.mjs → openai-responses-BXEcr-Tp.mjs} +17 -24
  41. package/dist/openai-responses-contracts-CD75pQ0m.d.mts +68 -0
  42. package/dist/openai-responses-contracts-DvILoqBk.mjs +247 -0
  43. package/dist/openai-responses-payload-policy-BDo8CQsx.mjs +208 -0
  44. package/dist/openai-responses-payload-policy-CNGFT9zr.d.mts +41 -0
  45. package/dist/{openai-responses-prompt-observer-internal-DDZPxRfr.mjs → openai-responses-prompt-observer-internal-BG-1AsBI.mjs} +2 -3
  46. package/dist/{openai-responses-stream-internal-Bl8YyVtF.mjs → openai-responses-shared-Cvt5MgEm.mjs} +1287 -1039
  47. package/dist/{openai-reasoning-compat-DKebnIBL.mjs → openai-stop-reason-9OONKyAm.mjs} +222 -180
  48. package/dist/{openai-transport-shared-Cipt7egQ.mjs → openai-tool-projection-CHGLt03m.mjs} +239 -128
  49. package/dist/provider-error-C8mBRJDl.mjs +424 -0
  50. package/dist/provider-error-CzNw4BWX.d.mts +12 -0
  51. package/dist/provider-options-AvldWZt8.mjs +21 -0
  52. package/dist/{provider-options-C5kYML7i.d.mts → provider-options-Cc5ZQ6Aa.d.mts} +19 -3
  53. package/dist/provider-transcript-transform--gtf0ZbR.mjs +32 -0
  54. package/dist/provider-types.d.mts +31 -0
  55. package/dist/provider-types.mjs +8 -0
  56. package/dist/providers.d.mts +1 -1
  57. package/dist/providers.mjs +17 -19
  58. package/dist/{reasoning-tag-text-partitioner-CGDyLWUR.mjs → reasoning-tag-text-partitioner-5ygO2rZc.mjs} +17 -8
  59. package/dist/record-coerce-DdXsgUd_.mjs +23 -0
  60. package/dist/{model-utils-Dau5dlgm.mjs → sanitize-unicode-BP7HLLZn.mjs} +28 -2
  61. package/dist/session-resources-CkR4WWy1.mjs +21 -0
  62. package/dist/simple-options-oqsXB6U3.mjs +450 -0
  63. package/dist/src-D2H6yKkH.mjs +2 -0
  64. package/dist/{stream-first-event-timeout-BIBomOGq.mjs → stream-first-event-timeout-MK28puvq.mjs} +2 -2
  65. package/dist/string-coerce-fsri9iCu.mjs +34 -0
  66. package/dist/{tool-schema-json-projection-B1b-XCn5.mjs → tool-schema-json-projection-FEr-jOoZ.mjs} +20 -13
  67. package/dist/transport-utils-Bv0FHkd0.mjs +138 -0
  68. package/dist/transports.d.mts +199 -209
  69. package/dist/transports.mjs +1842 -1364
  70. package/dist/types-BDdaOVi2.mjs +6 -0
  71. package/dist/{types-CH7ReIcU.d.mts → types-DTAP49HF.d.mts} +35 -2
  72. package/dist/types.d.mts +5 -5
  73. package/dist/types.mjs +6 -4
  74. package/dist/utf16-slice-CvGodqok.mjs +29 -0
  75. package/dist/{validation-DAa_yFOM.mjs → validation-B61OhAio.mjs} +6 -6
  76. package/dist/{validation-CcPcuEbR.d.mts → validation-DYNNrU9u.d.mts} +1 -1
  77. package/dist/validation.d.mts +1 -1
  78. package/dist/validation.mjs +1 -1
  79. package/package.json +15 -1
  80. package/dist/host-Bl7Kgddo.mjs +0 -407
  81. package/dist/openai-chatgpt-jwt-DhAAzLkj.mjs +0 -39
  82. package/dist/openai-responses-contracts-BBKBfAqR.d.mts +0 -116
  83. package/dist/openai-responses-shared-CCyMvg7M.mjs +0 -403
  84. package/dist/provider-error-DI0Ts28U.mjs +0 -47
  85. package/dist/sanitize-unicode-DT5o51ur.mjs +0 -26
  86. package/dist/tool-result-text-Dvkp2Dus.mjs +0 -274
  87. package/dist/transform-messages-DfjpNXNQ.mjs +0 -2
  88. package/dist/transport-stream-shared-CPNv7A3r.mjs +0 -297
@@ -1,19 +1,17 @@
1
1
  import { n as getEnvApiKey, r as __exportAll } from "./env-api-keys-DrgeBuva.mjs";
2
- import { t as AssistantMessageEventStream } from "./event-stream-CEV9t6da.mjs";
3
- import { n as getAiTransportHost } from "./host-Bl7Kgddo.mjs";
4
- import { r as clampThinkingLevel } from "./model-utils-Dau5dlgm.mjs";
2
+ import { t as AssistantMessageEventStream } from "./event-stream-uSMZJ3FA.mjs";
3
+ import { i as clampThinkingLevel } from "./sanitize-unicode-BP7HLLZn.mjs";
4
+ import { n as getAiTransportHost } from "./host-DF_yxOsA.mjs";
5
+ import { n as projectProviderError } from "./provider-error-C8mBRJDl.mjs";
5
6
  import { n as clampOpenAIPromptCacheKey } from "./openai-prompt-cache-mZTCdRPo.mjs";
6
7
  import { t as resolveCacheRetention } from "./cache-retention-0x979a5V.mjs";
7
- import { c as buildBaseOptions, m as splitSystemPromptCacheBoundary } from "./tool-result-text-Dvkp2Dus.mjs";
8
- import { a as convertMessages, c as resolveOpenAICompletionsResponseFormat, d as rememberPendingCommentaryTags, f as tagPendingCommentaryText, i as finalizeOpenAICompletionsToolCalls, l as shouldOmitOllamaCompatResponseFormat, n as mapOpenAIStopReason, r as createOpenAICompletionsToolCallDeltaNormalizer, s as resolveOpenAICompletionsCompat, t as resolveOpenAIReasoningEffortMap, u as clearPendingCommentaryText } from "./openai-reasoning-compat-DKebnIBL.mjs";
9
- import { n as parseStreamingJson } from "./json-parse-BvXNt1-7.mjs";
8
+ import { A as splitSystemPromptCacheBoundary, C as withProviderResponseHook, P as sortPromptCacheToolsByName, n as buildBaseOptions, x as transportAbortError } from "./simple-options-oqsXB6U3.mjs";
9
+ import { a as createOpenAICompletionsToolCallDeltaNormalizer, c as resolveOpenAICompletionsCompat, d as clearPendingCommentaryText, f as rememberPendingCommentaryTags, h as tagUnresolvedTextAsCommentary, i as hasToolCallHistory, l as resolveOpenAICompletionsResponseFormat, m as tagPendingCommentaryText, n as resolveOpenAIReasoningEffortMap, o as finalizeOpenAICompletionsToolCalls, p as tagInterruptedTextPhases, r as convertMessages, t as mapOpenAIStopReason, u as shouldOmitOllamaCompatResponseFormat } from "./openai-stop-reason-9OONKyAm.mjs";
10
+ import { n as parseStreamingJson } from "./json-parse-CDnesDM_.mjs";
10
11
  import { t as notifyLlmRequestActivity } from "./llm-request-activity-BjtkplhG.mjs";
11
- import { d as transportAbortError } from "./transport-stream-shared-CPNv7A3r.mjs";
12
- import { a as parseOpenAICompletionsUsage, l as projectOpenAITools, o as readOpenAICompletionsContentDeltas, r as isOpenAICompletionsThinkingEnabled, u as reconcileOpenAICompletionsToolChoice } from "./openai-transport-shared-Cipt7egQ.mjs";
13
- import { t as createReasoningTagTextPartitioner } from "./reasoning-tag-text-partitioner-CGDyLWUR.mjs";
14
- import { a as withFirstStreamEventTimeout, i as getFirstStreamEventTimeoutMs, r as getFirstStreamEventTimeoutHandler, t as createFirstStreamEventAbortController } from "./stream-first-event-timeout-BIBomOGq.mjs";
15
- import { t as headersToRecord } from "./headers-B_e4-1J0.mjs";
16
- import { t as formatProviderError } from "./provider-error-DI0Ts28U.mjs";
12
+ import { c as isOpenAICompletionsThinkingEnabled, d as parseOpenAICompletionsUsage, f as readOpenAICompletionsContentDeltas, n as reconcileOpenAICompletionsToolChoice, o as createOpenAIProviderAcceptanceHook, p as readOpenAICompletionsReasoningBatch, t as projectOpenAITools } from "./openai-tool-projection-CHGLt03m.mjs";
13
+ import { a as withFirstStreamEventTimeout, i as getFirstStreamEventTimeoutMs, r as getFirstStreamEventTimeoutHandler, t as createFirstStreamEventAbortController } from "./stream-first-event-timeout-MK28puvq.mjs";
14
+ import { t as createReasoningTagTextPartitioner } from "./reasoning-tag-text-partitioner-5ygO2rZc.mjs";
17
15
  import { i as resolveCloudflareBaseUrl, n as hasCopilotVisionInput, r as isCloudflareProvider, t as buildCopilotDynamicHeaders } from "./github-copilot-headers-NCJtz9i0.mjs";
18
16
  import OpenAI from "openai";
19
17
  //#region packages/ai/src/providers/openai-completions.ts
@@ -22,20 +20,6 @@ var openai_completions_exports = /* @__PURE__ */ __exportAll({
22
20
  streamOpenAICompletions: () => streamOpenAICompletions,
23
21
  streamSimpleOpenAICompletions: () => streamSimpleOpenAICompletions
24
22
  });
25
- /**
26
- * Check if conversation messages contain tool calls or tool results.
27
- * This is needed because Anthropic (via proxy) requires the tools param
28
- * to be present when messages include tool_calls or tool role messages.
29
- */
30
- function hasToolHistory(messages) {
31
- for (const msg of messages) {
32
- if (msg.role === "toolResult") return true;
33
- if (msg.role === "assistant") {
34
- if (Array.isArray(msg.content) && msg.content.some((block) => block.type === "toolCall")) return true;
35
- }
36
- }
37
- return false;
38
- }
39
23
  function isEncryptedReasoningDetail(detail) {
40
24
  if (typeof detail !== "object" || detail === null) return false;
41
25
  const candidate = detail;
@@ -72,6 +56,8 @@ const streamOpenAICompletions = (model, context, options) => {
72
56
  try {
73
57
  const apiKey = options?.apiKey || getEnvApiKey(model.provider) || "";
74
58
  const compat = resolveOpenAICompletionsCompat(model);
59
+ const visibleReasoningDetailTypes = new Set(compat.visibleReasoningDetailTypes);
60
+ const shouldEmitReasoning = Boolean(model.reasoning && options?.reasoningEffort && isOpenAICompletionsThinkingEnabled(options.reasoningEffort));
75
61
  const cacheRetention = resolveCacheRetention(options?.cacheRetention);
76
62
  const cacheSessionId = cacheRetention === "none" ? void 0 : options?.sessionId;
77
63
  const client = createClient(model, context, apiKey, options?.headers, cacheSessionId, compat);
@@ -85,16 +71,21 @@ const streamOpenAICompletions = (model, context, options) => {
85
71
  maxRetries: options?.maxRetries ?? 0
86
72
  };
87
73
  const { data: openaiStream, response } = await client.chat.completions.create(params, requestOptions).withResponse();
88
- await options?.onResponse?.({
89
- status: response.status,
90
- headers: headersToRecord(response.headers)
91
- }, model);
92
- stream.push({
93
- type: "start",
94
- partial: output
74
+ const hookedOpenAIStream = withProviderResponseHook({
75
+ stream: openaiStream,
76
+ signal: firstEventAbort.signal,
77
+ abort: firstEventAbort.abort,
78
+ hook: createOpenAIProviderAcceptanceHook(options, response, model),
79
+ onReady: () => stream.push({
80
+ type: "start",
81
+ partial: output
82
+ })
95
83
  });
96
84
  let textBlock = null;
85
+ let textBlockSource;
97
86
  let thinkingBlock = null;
87
+ let pendingInterruptedTextBlock = null;
88
+ let confirmedInterruptedTextBlock = null;
98
89
  let hasFinishReason = false;
99
90
  const toolCallBlocksByIndex = /* @__PURE__ */ new Map();
100
91
  const toolCallBlocksById = /* @__PURE__ */ new Map();
@@ -104,6 +95,7 @@ const streamOpenAICompletions = (model, context, options) => {
104
95
  const blocks = output.content;
105
96
  const finishedBlocks = /* @__PURE__ */ new Set();
106
97
  const contentIndices = /* @__PURE__ */ new WeakMap();
98
+ let explicitVisibleTextBlocks;
107
99
  const appendBlock = (block) => {
108
100
  contentIndices.set(block, blocks.length);
109
101
  blocks.push(block);
@@ -141,12 +133,21 @@ const streamOpenAICompletions = (model, context, options) => {
141
133
  partial: output
142
134
  });
143
135
  };
144
- const ensureTextBlock = () => {
136
+ const finishTextBlock = () => {
137
+ if (!textBlock) return;
138
+ finishBlock(textBlock);
139
+ textBlock = null;
140
+ textBlockSource = void 0;
141
+ };
142
+ const ensureTextBlock = (source) => {
143
+ if (textBlock && textBlockSource !== source) finishTextBlock();
145
144
  if (!textBlock) {
146
145
  textBlock = {
147
146
  type: "text",
148
147
  text: ""
149
148
  };
149
+ textBlockSource = source;
150
+ if (source === "reasoning_detail") (explicitVisibleTextBlocks ??= /* @__PURE__ */ new Set()).add(textBlock);
150
151
  appendBlock(textBlock);
151
152
  stream.push({
152
153
  type: "text_start",
@@ -178,10 +179,14 @@ const streamOpenAICompletions = (model, context, options) => {
178
179
  thinkingBlock = null;
179
180
  }
180
181
  };
181
- const appendTextDelta = (delta) => {
182
+ const appendTextDelta = (delta, source) => {
182
183
  sealNativeReasoningBeforeText();
183
- const block = ensureTextBlock();
184
+ const block = ensureTextBlock(source);
184
185
  block.text += delta;
186
+ if (pendingInterruptedTextBlock && delta.trim()) {
187
+ confirmedInterruptedTextBlock = pendingInterruptedTextBlock;
188
+ pendingInterruptedTextBlock = null;
189
+ }
185
190
  stream.push({
186
191
  type: "text_delta",
187
192
  contentIndex: getContentIndex(block),
@@ -199,6 +204,15 @@ const streamOpenAICompletions = (model, context, options) => {
199
204
  partial: output
200
205
  });
201
206
  };
207
+ const appendReasoningDeltas = (reasoningDeltas) => {
208
+ for (const reasoningDelta of reasoningDeltas) if (reasoningDelta.kind === "thinking") {
209
+ if (!shouldEmitReasoning) continue;
210
+ finishTextBlock();
211
+ const signature = reasoningDelta.signature;
212
+ const thinkingSignature = model.provider === "opencode-go" && signature === "reasoning" ? "reasoning_content" : signature;
213
+ appendThinkingDelta(thinkingSignature, reasoningDelta.text);
214
+ } else appendTextDelta(reasoningDelta.text, reasoningDelta.source);
215
+ };
202
216
  const ensureToolCallBlock = (toolCall) => {
203
217
  const streamIndex = typeof toolCall.index === "number" ? toolCall.index : void 0;
204
218
  let block = streamIndex !== void 0 ? toolCallBlocksByIndex.get(streamIndex) : void 0;
@@ -239,7 +253,22 @@ const streamOpenAICompletions = (model, context, options) => {
239
253
  const flushPartitionedContent = () => {
240
254
  for (const delta of reasoningTagTextPartitioner.flush()) if (delta.kind === "text") appendTextDelta(delta.text);
241
255
  };
242
- const guardedOpenaiStream = withFirstStreamEventTimeout(openaiStream, {
256
+ const sealTextBeforeReasoning = () => {
257
+ if (!textBlock && !reasoningTagTextPartitioner.hasPending()) return;
258
+ flushPartitionedContent();
259
+ if (!textBlock) return;
260
+ if (textBlockSource !== "reasoning_detail" && textBlock.text.trim()) pendingInterruptedTextBlock = textBlock;
261
+ finishTextBlock();
262
+ };
263
+ const beginReasoning = (hasFollowingVisibleText, forceStrict = false) => {
264
+ if (!output.openclawDelivery?.textPhaseRequiresTerminal) output.openclawDelivery = {
265
+ ...output.openclawDelivery,
266
+ textPhaseRequiresTerminal: true
267
+ };
268
+ if (forceStrict || reasoningTagTextPartitioner.hasPending()) reasoningTagTextPartitioner.markStrict();
269
+ if (!hasFollowingVisibleText || !reasoningTagTextPartitioner.hasPendingSyntax()) sealTextBeforeReasoning();
270
+ };
271
+ const guardedOpenaiStream = withFirstStreamEventTimeout(hookedOpenAIStream, {
243
272
  provider: model.provider,
244
273
  api: model.api,
245
274
  model: model.id,
@@ -268,30 +297,21 @@ const streamOpenAICompletions = (model, context, options) => {
268
297
  const rawChoiceDelta = choice.delta ?? choice.message;
269
298
  if (rawChoiceDelta) for (const normalizedDelta of normalizeToolCallDeltas(rawChoiceDelta, choice.finish_reason)) {
270
299
  const choiceDelta = normalizedDelta.delta;
271
- const reasoningFields = [
272
- "reasoning_content",
273
- "reasoning",
274
- "reasoning_text"
275
- ];
276
- const deltaFields = choiceDelta;
277
- const shouldEmitReasoning = Boolean(model.reasoning && options?.reasoningEffort && isOpenAICompletionsThinkingEnabled(options.reasoningEffort));
278
- let foundReasoningField = null;
279
- for (const field of reasoningFields) {
280
- const value = deltaFields[field];
281
- if (typeof value === "string" && value.length > 0) {
282
- foundReasoningField = field;
283
- break;
284
- }
300
+ const reasoningBatch = readOpenAICompletionsReasoningBatch(choiceDelta, visibleReasoningDetailTypes);
301
+ const reasoningDeltas = reasoningBatch.deltas;
302
+ const hasReasoningThinking = reasoningBatch.hasThinking;
303
+ const contentDeltas = readOpenAICompletionsContentDeltas(choiceDelta.content, choiceDelta.refusal, reasoningBatch.mirroredThinking);
304
+ const lastVisibleTextIndex = contentDeltas.findLastIndex((delta) => delta.kind === "text");
305
+ const hasSameChunkVisibleText = reasoningBatch.hasVisibleText || lastVisibleTextIndex !== -1;
306
+ if (hasReasoningThinking) {
307
+ beginReasoning(hasSameChunkVisibleText, true);
308
+ appendReasoningDeltas(reasoningDeltas);
285
309
  }
286
- if (foundReasoningField) reasoningTagTextPartitioner.markStrict();
287
- if (shouldEmitReasoning && foundReasoningField) {
288
- const delta = deltaFields[foundReasoningField];
289
- if (typeof delta === "string" && delta.length > 0) appendThinkingDelta(model.provider === "opencode-go" && foundReasoningField === "reasoning" ? "reasoning_content" : foundReasoningField, delta);
290
- }
291
- for (const contentDelta of readOpenAICompletionsContentDeltas(choiceDelta.content, choiceDelta.refusal, foundReasoningField ? [deltaFields[foundReasoningField]] : [])) if (contentDelta.kind === "thinking") {
292
- if (reasoningTagTextPartitioner.hasPending()) reasoningTagTextPartitioner.markStrict();
310
+ for (const [contentDeltaIndex, contentDelta] of contentDeltas.entries()) if (contentDelta.kind === "thinking") {
311
+ beginReasoning(contentDeltaIndex < lastVisibleTextIndex);
293
312
  if (shouldEmitReasoning) appendThinkingDelta(contentDelta.signature, contentDelta.text);
294
- } else appendPartitionedContent(contentDelta.text, Boolean(foundReasoningField));
313
+ } else appendPartitionedContent(contentDelta.text, hasReasoningThinking);
314
+ if (!hasReasoningThinking) appendReasoningDeltas(reasoningDeltas);
295
315
  const toolCallDeltas = normalizedDelta.toolCalls;
296
316
  if (toolCallDeltas.length > 0) {
297
317
  flushPartitionedContent();
@@ -345,6 +365,7 @@ const streamOpenAICompletions = (model, context, options) => {
345
365
  for (const block of blocks) if (block.type !== "toolCall") finishBlock(block);
346
366
  throw new Error(output.errorMessage || (output.stopReason === "aborted" ? "Request was aborted" : "Provider returned an invalid tool call"));
347
367
  }
368
+ if (output.stopReason !== "toolUse" && confirmedInterruptedTextBlock) tagInterruptedTextPhases(output.content, confirmedInterruptedTextBlock, explicitVisibleTextBlocks);
348
369
  for (const block of blocks) if (block.type !== "toolCall" || output.stopReason === "toolUse") finishBlock(block);
349
370
  if (output.stopReason !== "toolUse") clearPendingCommentaryText(provisionalCommentaryTags);
350
371
  if (output.stopReason === "toolUse") tagPendingCommentaryText(output.content);
@@ -355,19 +376,19 @@ const streamOpenAICompletions = (model, context, options) => {
355
376
  });
356
377
  stream.end();
357
378
  } catch (error) {
358
- output.stopReason = options?.signal?.aborted ? "aborted" : "error";
379
+ const terminal = projectProviderError(error, options?.signal);
380
+ Object.assign(output, terminal);
359
381
  finalizeOpenAICompletionsToolCalls(output, { allowSilentToolCallPromotion: false });
382
+ clearPendingCommentaryText(provisionalCommentaryTags);
383
+ tagUnresolvedTextAsCommentary(output);
360
384
  for (const block of output.content) {
361
385
  delete block.index;
362
386
  delete block.partialArgs;
363
387
  delete block.streamIndex;
364
388
  }
365
- output.errorMessage = formatProviderError(error);
366
- const rawMetadata = error?.error?.metadata?.raw;
367
- if (rawMetadata && !output.errorMessage.includes(rawMetadata)) output.errorMessage += `\n${rawMetadata}`;
368
389
  stream.push({
369
390
  type: "error",
370
- reason: output.stopReason,
391
+ reason: terminal.stopReason,
371
392
  error: output
372
393
  });
373
394
  stream.end();
@@ -458,9 +479,9 @@ function buildParams(model, context, options, compat = resolveOpenAICompletionsC
458
479
  const converted = convertTools(context.tools, compat);
459
480
  toolProjection = converted.projection;
460
481
  if (converted.tools.length > 0) params.tools = converted.tools;
461
- else if (hasToolHistory(context.messages)) params.tools = [];
482
+ else if (hasToolCallHistory(context.messages)) params.tools = [];
462
483
  if (compat.zaiToolStream && converted.tools.length > 0) params.tool_stream = true;
463
- } else if (hasToolHistory(context.messages)) params.tools = [];
484
+ } else if (hasToolCallHistory(context.messages)) params.tools = [];
464
485
  if (cacheControl) applyAnthropicCacheControl(messages, params.tools, cacheControl, cacheOptOutIndexes);
465
486
  if (options?.toolChoice) {
466
487
  const toolChoice = reconcileOpenAICompletionsToolChoice(options.toolChoice, toolProjection ?? projectOpenAITools([]));
@@ -596,7 +617,7 @@ function convertTools(tools, compat) {
596
617
  const projection = projectOpenAITools(tools);
597
618
  return {
598
619
  projection,
599
- tools: projection.tools.map((tool) => ({
620
+ tools: sortPromptCacheToolsByName(projection.tools).map((tool) => ({
600
621
  type: "function",
601
622
  function: {
602
623
  name: tool.name,
@@ -0,0 +1,43 @@
1
+ import { D as Model, k as OpenAICompletionsCompat } from "./types-DTAP49HF.mjs";
2
+ import { a as AiProviderRequestPolicyInput, i as AiProviderRequestCapabilities } from "./host-DJq_FGcz.mjs";
3
+
4
+ //#region packages/ai/src/transports/openai-completions-compat.d.ts
5
+ type ProviderRequestCapabilities = AiProviderRequestCapabilities;
6
+ type OpenAICompletionsSessionAffinity = "none" | "openai" | "openrouter";
7
+ type OpenAICompletionsCompatDefaults = {
8
+ supportsStore: boolean;
9
+ supportsDeveloperRole: boolean;
10
+ supportsReasoningEffort: boolean;
11
+ supportsUsageInStreaming: boolean;
12
+ maxTokensField: "max_completion_tokens" | "max_tokens";
13
+ thinkingFormat: "openai" | "openrouter" | "deepseek" | "together" | "zai";
14
+ visibleReasoningDetailTypes: string[];
15
+ supportsStrictMode: boolean;
16
+ supportsJsonSchemaResponseFormat: boolean;
17
+ requiresReasoningContentOnAssistantMessages: boolean;
18
+ requiresNonEmptyUserOrAssistantMessage: boolean;
19
+ cacheControlFormat?: OpenAICompletionsCompat["cacheControlFormat"];
20
+ sessionAffinityFormat: Exclude<OpenAICompletionsSessionAffinity, "none">;
21
+ supportsLongCacheRetention: boolean;
22
+ };
23
+ type DetectedOpenAICompletionsCompat = {
24
+ capabilities: ProviderRequestCapabilities;
25
+ defaults: OpenAICompletionsCompatDefaults;
26
+ };
27
+ type ResolvedOpenAICompletionsCompat = Omit<Required<OpenAICompletionsCompat>, "cacheControlFormat" | "openRouterRouting" | "sendSessionAffinityHeaders"> & {
28
+ cacheControlFormat?: OpenAICompletionsCompat["cacheControlFormat"];
29
+ openRouterRouting?: OpenAICompletionsCompat["openRouterRouting"];
30
+ sessionAffinity: OpenAICompletionsSessionAffinity;
31
+ visibleReasoningDetailTypes: string[];
32
+ requiresNonEmptyUserOrAssistantMessage: boolean;
33
+ };
34
+ /** Detects endpoint capabilities and defaults for an OpenAI-completions model. */
35
+ declare function detectOpenAICompletionsCompat(model: Pick<Model<"openai-completions">, "provider" | "baseUrl" | "id"> & {
36
+ compat?: {
37
+ supportsStore?: boolean;
38
+ } | null;
39
+ }, resolveCapabilities?: (input: AiProviderRequestPolicyInput) => ProviderRequestCapabilities): DetectedOpenAICompletionsCompat;
40
+ /** Applies explicit model overrides once on top of the canonical transport defaults. */
41
+ declare function resolveOpenAICompletionsCompat(model: Model<"openai-completions">, resolveCapabilities?: (input: AiProviderRequestPolicyInput) => ProviderRequestCapabilities): ResolvedOpenAICompletionsCompat;
42
+ //#endregion
43
+ export { detectOpenAICompletionsCompat as n, resolveOpenAICompletionsCompat as r, ResolvedOpenAICompletionsCompat as t };
@@ -1,12 +1,12 @@
1
1
  import { n as getEnvApiKey, r as __exportAll } from "./env-api-keys-DrgeBuva.mjs";
2
- import { t as AssistantMessageEventStream } from "./event-stream-CEV9t6da.mjs";
3
- import { n as getAiTransportHost } from "./host-Bl7Kgddo.mjs";
2
+ import { t as AssistantMessageEventStream } from "./event-stream-uSMZJ3FA.mjs";
3
+ import { n as getAiTransportHost } from "./host-DF_yxOsA.mjs";
4
+ import { S as supportsOpenAITemperature } from "./openai-responses-contracts-DvILoqBk.mjs";
4
5
  import { n as clampOpenAIPromptCacheKey } from "./openai-prompt-cache-mZTCdRPo.mjs";
5
6
  import { t as resolveCacheRetention } from "./cache-retention-0x979a5V.mjs";
6
- import { c as buildBaseOptions } from "./tool-result-text-Dvkp2Dus.mjs";
7
- import { pt as supportsOpenAITemperature } from "./openai-responses-stream-internal-Bl8YyVtF.mjs";
7
+ import { n as buildBaseOptions } from "./simple-options-oqsXB6U3.mjs";
8
+ import { a as resolveResponsesReasoningEffort, i as createResponsesAssistantOutput, n as applyResponsesServiceTierPricing, o as runResponsesStreamLifecycle, r as convertResponsesMessages, t as applyCommonResponsesParams } from "./openai-responses-shared-Cvt5MgEm.mjs";
8
9
  import { i as resolveCloudflareBaseUrl, n as hasCopilotVisionInput, r as isCloudflareProvider, t as buildCopilotDynamicHeaders } from "./github-copilot-headers-NCJtz9i0.mjs";
9
- import { a as resolveResponsesReasoningEffort, i as createResponsesAssistantOutput, n as applyResponsesServiceTierPricing, o as runResponsesStreamLifecycle, r as convertResponsesMessages, t as applyCommonResponsesParams } from "./openai-responses-shared-CCyMvg7M.mjs";
10
10
  import OpenAI from "openai";
11
11
  //#region packages/ai/src/providers/openai-responses.ts
12
12
  var openai_responses_exports = /* @__PURE__ */ __exportAll({
@@ -23,19 +23,6 @@ function getCompat(model) {
23
23
  function getPromptCacheRetention(compat, cacheRetention) {
24
24
  return cacheRetention === "long" && compat.supportsLongCacheRetention ? "24h" : void 0;
25
25
  }
26
- function formatOpenAIResponsesError(error) {
27
- if (error instanceof Error) {
28
- const status = error.status;
29
- const statusCode = typeof status === "number" ? status : void 0;
30
- if (statusCode !== void 0) return `OpenAI API error (${statusCode}): ${error.message}`;
31
- return error.message;
32
- }
33
- try {
34
- return JSON.stringify(error);
35
- } catch {
36
- return String(error);
37
- }
38
- }
39
26
  /**
40
27
  * Generate function for OpenAI Responses API
41
28
  */
@@ -51,12 +38,11 @@ const streamOpenAIResponses = (model, context, options) => {
51
38
  const cacheSessionId = resolveCacheRetention(options?.cacheRetention) === "none" ? void 0 : options?.sessionId;
52
39
  return createClient(model, context, apiKey, options?.headers, cacheSessionId);
53
40
  },
54
- buildParams: () => buildParams(model, context, options),
41
+ buildParams: (_requestModel, replayMode) => buildParams(model, context, options, replayMode),
55
42
  processStreamOptions: {
56
43
  serviceTier: options?.serviceTier,
57
44
  applyServiceTierPricing: (usage, serviceTier) => applyResponsesServiceTierPricing(usage, serviceTier, model)
58
- },
59
- formatError: formatOpenAIResponsesError
45
+ }
60
46
  });
61
47
  return stream;
62
48
  };
@@ -64,10 +50,12 @@ const streamSimpleOpenAIResponses = (model, context, options) => {
64
50
  const apiKey = options?.apiKey || getEnvApiKey(model.provider);
65
51
  if (!apiKey) throw new Error(`No API key for provider: ${model.provider}`);
66
52
  const base = buildBaseOptions(model, options, apiKey);
53
+ const replayOptions = options;
67
54
  return streamOpenAIResponses(model, context, {
68
55
  ...base,
56
+ authProfileId: replayOptions?.authProfileId,
69
57
  reasoningEffort: resolveResponsesReasoningEffort(model, options?.reasoning),
70
- replayResponsesItemIds: options?.replayResponsesItemIds
58
+ replayResponsesItemIds: replayOptions?.replayResponsesItemIds
71
59
  });
72
60
  };
73
61
  function createClient(model, context, apiKey, optionsHeaders, sessionId) {
@@ -100,8 +88,13 @@ function createClient(model, context, apiKey, optionsHeaders, sessionId) {
100
88
  fetch: getAiTransportHost().buildModelFetch(model)
101
89
  });
102
90
  }
103
- function buildParams(model, context, options) {
104
- const messages = convertResponsesMessages(model, context, OPENAI_TOOL_CALL_PROVIDERS, { replayResponsesItemIds: options?.replayResponsesItemIds ?? false });
91
+ function buildParams(model, context, options, replayMode = "checkpoint") {
92
+ const messages = convertResponsesMessages(model, context, OPENAI_TOOL_CALL_PROVIDERS, {
93
+ replayResponsesItemIds: options?.replayResponsesItemIds ?? false,
94
+ sessionId: options?.sessionId,
95
+ authProfileId: options?.authProfileId,
96
+ replayMode
97
+ });
105
98
  const cacheRetention = resolveCacheRetention(options?.cacheRetention);
106
99
  const compat = getCompat(model);
107
100
  const params = {
@@ -0,0 +1,68 @@
1
+ import { n as Api } from "./types-DTAP49HF.mjs";
2
+ import { h as OpenAIReasoningEffort, i as BaseOpenAIStreamOptions, m as OpenAIApiReasoningEffort } from "./provider-options-Cc5ZQ6Aa.mjs";
3
+ import { FunctionTool, ResponseCompactionItem, ResponseCreateParamsStreaming, ResponseInput } from "openai/resources/responses/responses.js";
4
+
5
+ //#region packages/ai/src/transports/openai-responses-contracts.d.ts
6
+ declare const OPENAI_RESPONSES_APIS: ReadonlySet<Api>;
7
+ type ReplayableResponseCompactionItem = Omit<ResponseCompactionItem, "id"> & {
8
+ id?: string;
9
+ };
10
+ type OpenAIResponsesReasoningReplayMetadata = {
11
+ v: 1;
12
+ source: "openai-responses";
13
+ provider: string;
14
+ api: Api;
15
+ model: string;
16
+ baseUrlHash?: string;
17
+ sessionHash?: string;
18
+ authProfileHash?: string;
19
+ };
20
+ type OpenAIResponsesOptions = BaseOpenAIStreamOptions & {
21
+ reasoning?: OpenAIReasoningEffort;
22
+ reasoningEffort?: OpenAIReasoningEffort;
23
+ reasoningSummary?: "auto" | "detailed" | "concise" | null;
24
+ replayResponsesItemIds?: boolean;
25
+ serviceTier?: ResponseCreateParamsStreaming["service_tier"];
26
+ toolChoice?: ResponseCreateParamsStreaming["tool_choice"];
27
+ };
28
+ type ResponsesPromptObservation = {
29
+ egress: "responses-sdk" | "responses-websocket" | "native-codex-websocket" | "native-codex-sse";
30
+ payloadVariant: "initial" | "reasoning-stripped" | "compaction-stripped" | "continuation-rejected";
31
+ promptSource: "instructions" | "input.developer" | "input.system" | "missing";
32
+ expectedChars: number;
33
+ observedChars: number;
34
+ matchesAssembledPrompt: boolean;
35
+ };
36
+ type ResponsesPromptObserver = (observation: ResponsesPromptObservation) => void;
37
+ declare const responsesPromptObserver: {
38
+ set(options: object, observer: ResponsesPromptObserver): void;
39
+ get(options: object): ResponsesPromptObserver | undefined;
40
+ copy(source: object | undefined, target: object): void;
41
+ };
42
+ type OpenAIResponsesRequestParams = {
43
+ model: string;
44
+ input: ResponseInput;
45
+ stream: true;
46
+ instructions?: string;
47
+ prompt_cache_key?: string;
48
+ prompt_cache_retention?: "24h";
49
+ metadata?: Record<string, string>;
50
+ previous_response_id?: string;
51
+ store?: boolean;
52
+ max_output_tokens?: number;
53
+ temperature?: number;
54
+ top_p?: number;
55
+ text?: ResponseCreateParamsStreaming["text"];
56
+ service_tier?: ResponseCreateParamsStreaming["service_tier"];
57
+ tools?: FunctionTool[];
58
+ tool_choice?: ResponseCreateParamsStreaming["tool_choice"];
59
+ reasoning?: {
60
+ effort: OpenAIApiReasoningEffort;
61
+ } | {
62
+ effort: OpenAIApiReasoningEffort;
63
+ summary: NonNullable<OpenAIResponsesOptions["reasoningSummary"]>;
64
+ };
65
+ include?: string[];
66
+ };
67
+ //#endregion
68
+ export { ReplayableResponseCompactionItem as a, OpenAIResponsesRequestParams as i, OpenAIResponsesOptions as n, ResponsesPromptObservation as o, OpenAIResponsesReasoningReplayMetadata as r, responsesPromptObserver as s, OPENAI_RESPONSES_APIS as t };