@openclaw/ai 2026.8.1-beta.2 → 2026.9.1-beta.1

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 (82) hide show
  1. package/dist/{anthropic-SrGtwsJu.d.mts → anthropic-BECQCNdF.d.mts} +0 -2
  2. package/dist/{anthropic-B6dLpq5L.mjs → anthropic-DI4PZKKB.mjs} +46 -34
  3. package/dist/{anthropic-compaction-replay-8lJNKXOE.mjs → anthropic-compaction-replay-nhKaCXu6.mjs} +17 -22
  4. package/dist/{anthropic-payload-policy-CiEuQS72.d.mts → anthropic-payload-policy-B_0n0enE.d.mts} +3 -1
  5. package/dist/{api-registry-k3zTz0cV.d.mts → api-registry-CTd8NzcD.d.mts} +2 -1
  6. package/dist/{azure-openai-responses-mxIOtUnn.mjs → azure-openai-responses-D8dI0ekg.mjs} +3 -3
  7. package/dist/diagnostics.d.mts +0 -1
  8. package/dist/diagnostics.mjs +1 -1
  9. package/dist/event-stream-BKp4fOt_.d.mts +1 -0
  10. package/dist/{event-stream-BP6AWT8j.d.mts → event-stream-LiXePESD.d.mts} +1 -2
  11. package/dist/event-stream.d.mts +2 -1
  12. package/dist/{google-C7h2QzDX.mjs → google-Od-LLdVK.mjs} +3 -3
  13. package/dist/{google-shared-B0Qr9OR7.mjs → google-shared-Bgr9lFPw.mjs} +22 -8
  14. package/dist/{google-vertex-Bhc3TjDl.mjs → google-vertex-aerRSXc4.mjs} +4 -4
  15. package/dist/{host-DTqNc7ad.mjs → host-D51fmkH6.mjs} +40 -33
  16. package/dist/{host-vWgMMhiJ.d.mts → host-DsbPMFU6.d.mts} +7 -7
  17. package/dist/index-Qbej8io0.d.mts +3 -0
  18. package/dist/index.d.mts +8 -8
  19. package/dist/index.mjs +2 -3
  20. package/dist/internal/anthropic.d.mts +13 -6
  21. package/dist/internal/anthropic.mjs +4 -4
  22. package/dist/internal/openai-responses-payload-policy.d.mts +2 -2
  23. package/dist/internal/openai-responses-payload-policy.mjs +2 -2
  24. package/dist/internal/openai.d.mts +6 -6
  25. package/dist/internal/openai.mjs +10 -8
  26. package/dist/internal/runtime.d.mts +18 -5
  27. package/dist/internal/runtime.mjs +8 -7
  28. package/dist/internal/shared.d.mts +18 -4
  29. package/dist/internal/shared.mjs +4 -4
  30. package/dist/{json-parse-CDnesDM_.mjs → json-parse-BuAJEbdW.mjs} +18 -2
  31. package/dist/{headers-DdOQtGuU.mjs → llm-request-activity-BjtkplhG.mjs} +1 -9
  32. package/dist/{mistral-CEWoQI_g.mjs → mistral-EiHdymeb.mjs} +59 -49
  33. package/dist/{openai-chatgpt-responses-CrPmqERt.mjs → openai-chatgpt-responses-DHpF9o1e.mjs} +42 -17
  34. package/dist/{openai-completions-BPnt4Sml.mjs → openai-completions-EFPiUGfS.mjs} +60 -257
  35. package/dist/{openai-completions-compat-Dt3dcawL.d.mts → openai-completions-compat-BefmHT26.d.mts} +3 -3
  36. package/dist/openai-completions-stream-DUlGwRMz.mjs +1621 -0
  37. package/dist/{openai-responses-DhIKtOup.mjs → openai-responses-BogP8OjX.mjs} +6 -5
  38. package/dist/{openai-responses-contracts-XpZJxrRG.d.mts → openai-responses-contracts-Dvj_UtPy.d.mts} +3 -3
  39. package/dist/{openai-responses-contracts-CyfIkQi5.mjs → openai-responses-contracts-QUY12X0B.mjs} +6 -26
  40. package/dist/{openai-responses-payload-policy-BSs371VM.d.mts → openai-responses-payload-policy-CNGFT9zr.d.mts} +1 -0
  41. package/dist/{openai-responses-payload-policy-BDxV-W0c.mjs → openai-responses-payload-policy-D8EdimYe.mjs} +6 -8
  42. package/dist/{openai-responses-prompt-observer-internal-DgNTYnRY.mjs → openai-responses-prompt-observer-internal-Cd4hJG-S.mjs} +3 -3
  43. package/dist/{openai-responses-shared-DXIt3iY5.mjs → openai-responses-shared-DJThc6jW.mjs} +205 -1472
  44. package/dist/openai-stop-reason-Drnn_6Qj.mjs +28 -0
  45. package/dist/openai-tool-schema-ho-hIkQf.mjs +1695 -0
  46. package/dist/{provider-error-BUwEnjXq.mjs → provider-error-DDOs_Bz0.mjs} +20 -27
  47. package/dist/provider-options-AvldWZt8.mjs +21 -0
  48. package/dist/{provider-options-B96RdNpH.d.mts → provider-options-MdMBLzlU.d.mts} +15 -4
  49. package/dist/provider-transcript-transform-C01bQ5a3.mjs +32 -0
  50. package/dist/provider-types.d.mts +7 -5
  51. package/dist/providers.d.mts +1 -2
  52. package/dist/providers.mjs +9 -9
  53. package/dist/{reasoning-tag-text-partitioner-rnPwX2pg.mjs → reasoning-tag-text-partitioner-5ygO2rZc.mjs} +3 -0
  54. package/dist/{sanitize-unicode-BYqrYtC_.mjs → sanitize-unicode-DCkltN94.mjs} +1 -2
  55. package/dist/{simple-options-D58D5Kvw.mjs → simple-options-CFj7x3J4.mjs} +5 -4
  56. package/dist/{anthropic-JsNA5KCu.mjs → src-Bu3FiFAG.mjs} +1 -1
  57. package/dist/{streaming-byte-guard-BrbkbwUu.mjs → streaming-byte-guard-CC-HMn_u.mjs} +5 -6
  58. package/dist/string-normalization--fwJ4S2q.mjs +16 -0
  59. package/dist/{tool-schema-json-projection-q5d7QX5c.mjs → tool-schema-json-projection-qvTEs5Am.mjs} +17 -8
  60. package/dist/transport-stream-shared-ljShVIZB.mjs +342 -0
  61. package/dist/transport-stream-shared-rvaCyFYt.d.mts +138 -0
  62. package/dist/{transport-utils-DJqkxbhC.mjs → transport-utils-LJ1_rbi-.mjs} +8 -5
  63. package/dist/transports.d.mts +45 -106
  64. package/dist/transports.mjs +134 -1089
  65. package/dist/{types-BHNrPS1l.d.mts → types-DhLoJbFm.d.mts} +49 -17
  66. package/dist/types-GiAjXatj.d.mts +1 -0
  67. package/dist/types.d.mts +6 -5
  68. package/dist/types.mjs +1 -2
  69. package/dist/utf16-slice-qz3nsy87.mjs +84 -0
  70. package/dist/{validation-DT9SrFn3.d.mts → validation-Dk7q7NMN.d.mts} +1 -2
  71. package/dist/validation.d.mts +1 -1
  72. package/package.json +5 -5
  73. package/dist/index-BVVgDSdq.d.mts +0 -1
  74. package/dist/openai-stop-reason-BkFkqqK0.mjs +0 -563
  75. package/dist/openai-tool-projection-CY04OcvQ.mjs +0 -338
  76. package/dist/provider-transcript-transform-ePx-Bbfr.mjs +0 -155
  77. package/dist/record-coerce-DdXsgUd_.mjs +0 -23
  78. package/dist/src-D2H6yKkH.mjs +0 -2
  79. package/dist/stream-first-event-timeout-DvDeSucC.d.mts +0 -29
  80. package/dist/string-coerce-fsri9iCu.mjs +0 -34
  81. package/dist/types-BVVgDSdq.d.mts +0 -1
  82. package/dist/utf16-slice-CvGodqok.mjs +0 -29
@@ -1,14 +1,15 @@
1
1
  import { n as getEnvApiKey } from "./env-api-keys-DrgeBuva.mjs";
2
2
  import { t as AssistantMessageEventStream } from "./event-stream-uSMZJ3FA.mjs";
3
- import { i as clampThinkingLevel, r as calculateCost, t as sanitizeSurrogates } from "./sanitize-unicode-BYqrYtC_.mjs";
4
- import { a as describeToolResultMediaPlaceholder, l as isImageWithMediaPayload, n as getAiTransportHost, s as extractToolResultText } from "./host-DTqNc7ad.mjs";
5
- import { a as isRecord } from "./record-coerce-DdXsgUd_.mjs";
6
- import { n as projectProviderError } from "./provider-error-BUwEnjXq.mjs";
7
- import { f as sortPromptCacheToolsByName, l as stripSystemPromptCacheBoundary, n as buildBaseOptions, r as clampMaxTokensToModel } from "./simple-options-D58D5Kvw.mjs";
8
- import { n as parseStreamingJson } from "./json-parse-CDnesDM_.mjs";
3
+ import { i as clampThinkingLevel, r as calculateCost, t as sanitizeSurrogates } from "./sanitize-unicode-DCkltN94.mjs";
4
+ import { a as describeToolResultMediaPlaceholder, c as extractToolResultText, d as isImageWithMediaPayload, l as formatToolResultText, n as getAiTransportHost } from "./host-D51fmkH6.mjs";
5
+ import { n as projectProviderError } from "./provider-error-DDOs_Bz0.mjs";
6
+ import { f as sortPromptCacheToolsByName, l as stripSystemPromptCacheBoundary, n as buildBaseOptions, r as clampMaxTokensToModel } from "./simple-options-CFj7x3J4.mjs";
7
+ import { _ as transportAbortError, f as notifyProviderHttpResponse, s as finalizeTerminalToolCallArguments } from "./transport-stream-shared-ljShVIZB.mjs";
8
+ import { r as parseStreamingJson, t as createToolArgumentPreviewSchedule } from "./json-parse-BuAJEbdW.mjs";
9
9
  import { t as shortHash } from "./hash-CHgqbJmD.mjs";
10
- import { f as transportAbortError, t as transformProviderMessages } from "./provider-transcript-transform-ePx-Bbfr.mjs";
11
- import { t as createSseByteGuard } from "./streaming-byte-guard-BrbkbwUu.mjs";
10
+ import { t as transformProviderMessages } from "./provider-transcript-transform-C01bQ5a3.mjs";
11
+ import { t as mapOpenAIStopReason } from "./openai-stop-reason-Drnn_6Qj.mjs";
12
+ import { t as createSseByteGuard } from "./streaming-byte-guard-CC-HMn_u.mjs";
12
13
  import { randomUUID } from "node:crypto";
13
14
  import { HTTPClient, Mistral } from "@mistralai/mistralai";
14
15
  //#region packages/ai/src/providers/mistral.ts
@@ -63,10 +64,25 @@ const streamMistral = (model, context, options) => {
63
64
  try {
64
65
  const apiKey = options?.apiKey || getEnvApiKey(model.provider);
65
66
  if (!apiKey) throw new Error(`No API key for provider: ${model.provider}`);
67
+ const boundedFetcher = createBoundedMistralFetcher(MISTRAL_STREAM_BODY_MAX_BYTES, getAiTransportHost().buildModelFetch(model) ?? fetch);
68
+ let mistralResponse;
69
+ let reportedResponse;
70
+ const httpClient = new HTTPClient({ fetcher: boundedFetcher });
71
+ httpClient.addHook("response", async (response) => {
72
+ mistralResponse = response;
73
+ if (!response.ok) {
74
+ await notifyProviderHttpResponse({
75
+ options,
76
+ response,
77
+ model
78
+ });
79
+ reportedResponse = response;
80
+ }
81
+ });
66
82
  const mistral = new Mistral({
67
83
  apiKey,
68
84
  serverURL: model.baseUrl,
69
- httpClient: new HTTPClient({ fetcher: createBoundedMistralFetcher(MISTRAL_STREAM_BODY_MAX_BYTES, getAiTransportHost().buildModelFetch(model) ?? fetch) })
85
+ httpClient
70
86
  });
71
87
  const normalizeMistralToolCallId = createMistralToolCallIdNormalizer();
72
88
  let payload = buildChatPayload(model, context, transformProviderMessages(context.messages, model, (id) => normalizeMistralToolCallId(id)), options);
@@ -81,13 +97,19 @@ const streamMistral = (model, context, options) => {
81
97
  headers,
82
98
  signal: options?.signal
83
99
  });
100
+ if (mistralResponse && mistralResponse !== reportedResponse) await notifyProviderHttpResponse({
101
+ options,
102
+ response: mistralResponse,
103
+ model,
104
+ cancelStream: (reason) => mistralStream.cancel(reason)
105
+ });
84
106
  stream.push({
85
107
  type: "start",
86
108
  partial: output
87
109
  });
88
110
  await consumeChatStream(model, output, stream, mistralStream);
89
111
  if (options?.signal?.aborted) throw transportAbortError(options.signal);
90
- if (output.stopReason === "aborted" || output.stopReason === "error") throw new Error("An unknown error occurred");
112
+ if (output.stopReason === "aborted" || output.stopReason === "error") throw new Error(output.errorMessage ?? "An unknown error occurred");
91
113
  stream.push({
92
114
  type: "done",
93
115
  reason: output.stopReason,
@@ -221,6 +243,7 @@ async function consumeChatStream(model, output, stream, mistralStream) {
221
243
  const blocks = output.content;
222
244
  const blockIndex = () => blocks.length - 1;
223
245
  const toolBlockIdentities = /* @__PURE__ */ new Map();
246
+ const toolArgumentPreviewSchedules = /* @__PURE__ */ new WeakMap();
224
247
  const normalizeMissingToolCallId = createMistralToolCallIdNormalizer();
225
248
  const missingToolCallIdScope = randomUUID();
226
249
  const createMissingToolCallId = (contentIndex) => normalizeMissingToolCallId(`${missingToolCallIdScope}:toolcall:${contentIndex}`);
@@ -300,6 +323,7 @@ async function consumeChatStream(model, output, stream, mistralStream) {
300
323
  for await (const event of mistralStream) {
301
324
  const chunk = event.data;
302
325
  output.responseId ||= chunk.id;
326
+ if (typeof chunk.model === "string" && chunk.model.length > 0 && chunk.model !== model.id) output.responseModel ||= chunk.model;
303
327
  if (chunk.usage) {
304
328
  const promptTokens = chunk.usage.promptTokens || 0;
305
329
  const cachedPromptTokens = readMistralCachedPromptTokens(chunk.usage, promptTokens);
@@ -314,7 +338,9 @@ async function consumeChatStream(model, output, stream, mistralStream) {
314
338
  if (!choice) continue;
315
339
  if (choice.finishReason) {
316
340
  terminalFinishReason = choice.finishReason;
317
- output.stopReason = mapChatStopReason(choice.finishReason);
341
+ const { stopReason, errorMessage } = mapOpenAIStopReason(choice.finishReason === "model_length" ? "length" : choice.finishReason);
342
+ output.stopReason = stopReason;
343
+ if (errorMessage) output.errorMessage = errorMessage;
318
344
  }
319
345
  const delta = choice.delta;
320
346
  if (delta.content !== null && delta.content !== void 0) {
@@ -425,6 +451,7 @@ async function consumeChatStream(model, output, stream, mistralStream) {
425
451
  partialArgs: ""
426
452
  };
427
453
  output.content.push(block);
454
+ toolArgumentPreviewSchedules.set(block, createToolArgumentPreviewSchedule());
428
455
  toolBlockIdentities.set(contentIndex, {
429
456
  explicitIds: new Set(providedCallId ? [providedCallId] : []),
430
457
  functionNames: new Set(functionName ? [functionName] : []),
@@ -452,7 +479,7 @@ async function consumeChatStream(model, output, stream, mistralStream) {
452
479
  if (toolCallIndex !== void 0) identity.indexes.add(toolCallIndex);
453
480
  const argsDelta = typeof toolCall.function.arguments === "string" ? toolCall.function.arguments : JSON.stringify(toolCall.function.arguments || {});
454
481
  block.partialArgs = (block.partialArgs || "") + argsDelta;
455
- block.arguments = parseStreamingJson(block.partialArgs);
482
+ if (toolArgumentPreviewSchedules.get(block)?.(block.partialArgs.length)) block.arguments = parseStreamingJson(block.partialArgs);
456
483
  stream.push({
457
484
  type: "toolcall_delta",
458
485
  contentIndex,
@@ -467,23 +494,20 @@ async function consumeChatStream(model, output, stream, mistralStream) {
467
494
  if (!terminalFinishReason) throw new Error("Mistral stream ended without a terminal finish reason");
468
495
  return;
469
496
  }
470
- try {
471
- for (const index of toolBlockIdentities.keys()) {
472
- const rawArguments = blocks[index].partialArgs ?? "";
473
- if (!isRecord(JSON.parse(rawArguments))) throw new Error("Mistral tool-call arguments must be a JSON object");
474
- }
475
- } catch {
476
- throw new Error("Mistral completed tool call has invalid JSON arguments");
477
- }
478
- for (const index of toolBlockIdentities.keys()) {
479
- const block = output.content.at(index);
480
- if (block?.type !== "toolCall") continue;
481
- const toolBlock = block;
482
- delete toolBlock.partialArgs;
497
+ const completedToolCalls = [...toolBlockIdentities.keys()].flatMap((contentIndex) => {
498
+ const block = blocks[contentIndex];
499
+ return block?.type === "toolCall" ? [{
500
+ block,
501
+ contentIndex
502
+ }] : [];
503
+ });
504
+ finalizeTerminalToolCallArguments(completedToolCalls.map(({ block }) => block), (block) => block.partialArgs ?? "", "Mistral completed tool call has invalid JSON arguments");
505
+ for (const { block, contentIndex } of completedToolCalls) {
506
+ delete block.partialArgs;
483
507
  stream.push({
484
508
  type: "toolcall_end",
485
- contentIndex: index,
486
- toolCall: toolBlock,
509
+ contentIndex,
510
+ toolCall: block,
487
511
  partial: output
488
512
  });
489
513
  }
@@ -592,7 +616,14 @@ function toChatMessages(messages, supportsImages) {
592
616
  continue;
593
617
  }
594
618
  const toolContent = [];
595
- const toolText = buildToolResultText(extractToolResultText(msg.content), describeToolResultMediaPlaceholder(msg.content), msg.content.some(isImageWithMediaPayload), supportsImages, msg.isError);
619
+ const textResult = extractToolResultText(msg.content);
620
+ const mediaPlaceholder = describeToolResultMediaPlaceholder(msg.content);
621
+ const toolText = formatToolResultText({
622
+ text: textResult,
623
+ mediaPlaceholder,
624
+ omittedMediaPlaceholder: msg.content.some(isImageWithMediaPayload) && !supportsImages ? textResult.trim() ? "[tool image omitted: model does not support images]" : mediaPlaceholder === "(see attached media)" ? "(media omitted: model does not support images)" : "(image omitted: model does not support images)" : void 0,
625
+ isError: msg.isError
626
+ });
596
627
  toolContent.push({
597
628
  type: "text",
598
629
  text: toolText
@@ -614,16 +645,6 @@ function toChatMessages(messages, supportsImages) {
614
645
  }
615
646
  return result;
616
647
  }
617
- function buildToolResultText(text, mediaPlaceholder, hasImages, supportsImages, isError) {
618
- const trimmed = text.trim();
619
- const errorPrefix = isError ? "[tool error] " : "";
620
- if (trimmed.length > 0) return `${errorPrefix}${trimmed}${hasImages && !supportsImages ? "\n[tool image omitted: model does not support images]" : ""}`;
621
- if (mediaPlaceholder) {
622
- if (!hasImages || supportsImages) return `${errorPrefix}${mediaPlaceholder}`;
623
- return `${errorPrefix}${mediaPlaceholder === "(see attached media)" ? "(media omitted: model does not support images)" : "(image omitted: model does not support images)"}`;
624
- }
625
- return isError ? "[tool error] (no tool output)" : "(no tool output)";
626
- }
627
648
  function usesReasoningEffort(model) {
628
649
  return model.id === "mistral-small-2603" || model.id === "mistral-small-latest" || model.id === "mistral-medium-3-5";
629
650
  }
@@ -647,16 +668,5 @@ function mapToolChoice(choice, convertedToolNames) {
647
668
  function: { name: toolName }
648
669
  };
649
670
  }
650
- function mapChatStopReason(reason) {
651
- if (reason === null) return "stop";
652
- switch (reason) {
653
- case "stop": return "stop";
654
- case "length":
655
- case "model_length": return "length";
656
- case "tool_calls": return "toolUse";
657
- case "error": return "error";
658
- default: return "stop";
659
- }
660
- }
661
671
  //#endregion
662
672
  export { createBoundedMistralFetcher, streamMistral, streamSimpleMistral };
@@ -1,24 +1,23 @@
1
1
  import { n as getEnvApiKey } from "./env-api-keys-DrgeBuva.mjs";
2
2
  import { i as formatThrownValue, n as createAssistantMessageDiagnostic, t as appendAssistantMessageDiagnostic } from "./diagnostics-COpOtRwq.mjs";
3
3
  import { t as AssistantMessageEventStream } from "./event-stream-uSMZJ3FA.mjs";
4
- import { n as getAiTransportHost, r as resolveAiTransportHeaderSentinels } from "./host-DTqNc7ad.mjs";
5
- import { n as projectProviderError } from "./provider-error-BUwEnjXq.mjs";
6
- import { n as toErrorObject, t as createResponsesPromptEgressObserver } from "./openai-responses-prompt-observer-internal-DgNTYnRY.mjs";
4
+ import { n as getAiTransportHost, r as resolveAiTransportHeaderSentinels } from "./host-D51fmkH6.mjs";
5
+ import { n as projectProviderError } from "./provider-error-DDOs_Bz0.mjs";
6
+ import { n as toErrorObject, t as createResponsesPromptEgressObserver } from "./openai-responses-prompt-observer-internal-Cd4hJG-S.mjs";
7
7
  import { c as resolveTimerTimeoutMs, i as clampTimerTimeoutMs } from "./number-coercion-H9qHik3g.mjs";
8
- import { S as supportsOpenAITemperature, m as responsesPromptObserver } from "./openai-responses-contracts-CyfIkQi5.mjs";
9
8
  import { n as clampOpenAIPromptCacheKey } from "./openai-prompt-cache-mZTCdRPo.mjs";
10
- import { l as stripSystemPromptCacheBoundary, n as buildBaseOptions } from "./simple-options-D58D5Kvw.mjs";
11
- import { t as headersToRecord } from "./headers-DdOQtGuU.mjs";
12
- import { F as commitResponsesEncryptedContentAttempt, G as suppressOpenAIResponsesCompaction, L as isInvalidEncryptedContentError, U as buildOpenAIResponsesReasoningReplayMetadata, a as resolveResponsesReasoningEffort, c as processResponsesStream, i as createResponsesAssistantOutput, n as applyResponsesServiceTierPricing, p as ResponsesStreamFailure, r as convertResponsesMessages, s as convertResponsesToolPayload, z as resolveNextResponsesEncryptedContentAttempt } from "./openai-responses-shared-DXIt3iY5.mjs";
13
- import { f as transportAbortError, p as withProviderResponseHook } from "./provider-transcript-transform-ePx-Bbfr.mjs";
9
+ import { l as stripSystemPromptCacheBoundary, n as buildBaseOptions } from "./simple-options-CFj7x3J4.mjs";
14
10
  import { parseRetryAfterHttpDateMs } from "./internal/retry-after.mjs";
15
- import { t as MALFORMED_STREAMING_FRAGMENT_ERROR_MESSAGE } from "./transport-utils-DJqkxbhC.mjs";
16
- import { o as createOpenAIResponseHook } from "./openai-tool-projection-CY04OcvQ.mjs";
11
+ import { t as MALFORMED_STREAMING_FRAGMENT_ERROR_MESSAGE } from "./transport-utils-LJ1_rbi-.mjs";
12
+ import { C as headersToRecord, _ as transportAbortError, p as notifyProviderStreamOpened, y as withProviderResponseHook } from "./transport-stream-shared-ljShVIZB.mjs";
13
+ import { F as commitResponsesEncryptedContentAttempt, G as suppressOpenAIResponsesCompaction, L as isInvalidEncryptedContentError, U as buildOpenAIResponsesReasoningReplayMetadata, a as resolveResponsesReasoningEffort, c as processResponsesStream, i as createResponsesAssistantOutput, n as applyResponsesServiceTierPricing, p as ResponsesStreamFailure, r as convertResponsesMessages, s as convertResponsesToolPayload, z as resolveNextResponsesEncryptedContentAttempt } from "./openai-responses-shared-DJThc6jW.mjs";
14
+ import { C as createOpenAIProviderAcceptanceHook, w as createOpenAIResponseHook } from "./openai-tool-schema-ho-hIkQf.mjs";
17
15
  import { a as withFirstStreamEventTimeout, i as getFirstStreamEventTimeoutMs, r as getFirstStreamEventTimeoutHandler, t as createFirstStreamEventAbortController } from "./stream-first-event-timeout-MK28puvq.mjs";
16
+ import { S as supportsOpenAITemperature, m as responsesPromptObserver } from "./openai-responses-contracts-QUY12X0B.mjs";
18
17
  import { n as registerSessionResourceCleanup } from "./session-resources-CkR4WWy1.mjs";
19
18
  import "./diagnostics.mjs";
20
19
  import { n as resolveOpenAICodexAccountId } from "./openai-chatgpt-jwt-KWcgd0d_.mjs";
21
- import { t as createSseByteGuard } from "./streaming-byte-guard-BrbkbwUu.mjs";
20
+ import { t as createSseByteGuard } from "./streaming-byte-guard-CC-HMn_u.mjs";
22
21
  import { t as inspectTlsCertificateError } from "./tls-certificate-errors-DXSpluKI.mjs";
23
22
  //#region packages/ai/src/internal/retry-sleep.ts
24
23
  function sleepWithAbort(ms, signal) {
@@ -155,6 +154,12 @@ function isRequestTimeoutError(error, callerSignal, requestSignal, timeoutMs) {
155
154
  if (!(error instanceof Error)) return false;
156
155
  return error.name === "AbortError" || error.name === "TimeoutError" || error.message === "Request was aborted";
157
156
  }
157
+ /** Local-only failure category for transport diagnostics; never provider text. */
158
+ function classifyStreamFailure(error, signal, requestTimedOut) {
159
+ if (requestTimedOut) return "timeout";
160
+ if (signal?.aborted) return "caller-abort";
161
+ return error instanceof ResponsesStreamFailure || error instanceof CodexApiError ? "provider-failure" : "transport";
162
+ }
158
163
  function formatRequestTimeoutError(timeoutMs, cause) {
159
164
  return new Error(`Request timed out after ${timeoutMs}ms`, { cause: cause instanceof Error ? cause : void 0 });
160
165
  }
@@ -172,6 +177,7 @@ function compressRequestBodyZstd(bodyJson) {
172
177
  const streamOpenAICodexResponses = (model, context, options) => {
173
178
  const stream = new AssistantMessageEventStream();
174
179
  (async () => {
180
+ const startedAt = Date.now();
175
181
  let requestTimeoutMs;
176
182
  let requestTimeoutSignal;
177
183
  let activeSignal;
@@ -218,8 +224,9 @@ const streamOpenAICodexResponses = (model, context, options) => {
218
224
  websocketRequestSent = false;
219
225
  try {
220
226
  await processWebSocketStream(resolveCodexWebSocketUrl(model.baseUrl), activeAttempt.request, websocketHeaders, output, stream, model, () => {
221
- commitSemanticAttempt(activeAttempt);
222
227
  websocketStarted = true;
228
+ }, () => {
229
+ commitSemanticAttempt(activeAttempt);
223
230
  }, requestOptions, firstEventAbort.abort, observePromptEgress, activeAttempt.kind, () => {
224
231
  websocketRequestSent = true;
225
232
  });
@@ -337,7 +344,7 @@ const streamOpenAICodexResponses = (model, context, options) => {
337
344
  stream: mapCodexEvents(parseOpenAIChatGptResponsesSse(response)),
338
345
  signal: firstEventAbort.signal,
339
346
  abort: firstEventAbort.abort,
340
- hook: createOpenAIResponseHook(options?.onResponse, response, model),
347
+ hook: createOpenAIProviderAcceptanceHook(options, response, model),
341
348
  onReady: () => stream.push({
342
349
  type: "start",
343
350
  partial: output
@@ -364,9 +371,19 @@ const streamOpenAICodexResponses = (model, context, options) => {
364
371
  });
365
372
  stream.end();
366
373
  } catch (error) {
367
- const normalizedError = isRequestTimeoutError(error, options?.signal, requestTimeoutSignal, requestTimeoutMs) && requestTimeoutMs !== void 0 ? formatRequestTimeoutError(requestTimeoutMs, error) : error;
374
+ const requestTimedOut = isRequestTimeoutError(error, options?.signal, requestTimeoutSignal, requestTimeoutMs) && requestTimeoutMs !== void 0;
375
+ const normalizedError = requestTimedOut && requestTimeoutMs !== void 0 ? formatRequestTimeoutError(requestTimeoutMs, error) : error;
368
376
  for (const block of output.content) delete block.partialJson;
369
377
  const terminal = projectProviderError(normalizedError, options?.signal);
378
+ getAiTransportHost().logWarn("openai-transport", "ChatGPT Responses stream terminated", {
379
+ provider: model.provider,
380
+ api: model.api,
381
+ model: model.id,
382
+ transport: options?.transport || "auto",
383
+ elapsedMs: Math.max(0, Date.now() - startedAt),
384
+ stopReason: terminal.stopReason,
385
+ failureKind: classifyStreamFailure(error, options?.signal, requestTimedOut)
386
+ });
370
387
  Object.assign(output, terminal);
371
388
  stream.push({
372
389
  type: "error",
@@ -872,12 +889,14 @@ function buildCachedWebSocketRequestBody(entry, body) {
872
889
  input: delta
873
890
  };
874
891
  }
875
- async function* startWebSocketOutputOnFirstEvent(events, output, stream, onStart) {
892
+ async function* startWebSocketOutputOnFirstEvent(events, output, stream, onFirstProviderEvent, reportStreamOpened, onStart) {
876
893
  let started = false;
877
894
  for await (const event of events) {
878
895
  if (!started) {
879
896
  started = true;
897
+ onFirstProviderEvent();
880
898
  onStart();
899
+ await reportStreamOpened();
881
900
  stream.push({
882
901
  type: "start",
883
902
  partial: output
@@ -886,7 +905,7 @@ async function* startWebSocketOutputOnFirstEvent(events, output, stream, onStart
886
905
  yield event;
887
906
  }
888
907
  }
889
- async function processWebSocketStream(url, body, headers, output, stream, model, onStart, options, abortFirstEventStream, observePromptEgress, payloadVariant = "initial", onRequestSent) {
908
+ async function processWebSocketStream(url, body, headers, output, stream, model, onFirstProviderEvent, onStart, options, abortFirstEventStream, observePromptEgress, payloadVariant = "initial", onRequestSent) {
890
909
  const { socket, entry, release } = await acquireWebSocket(url, headers, options?.sessionId, options?.signal);
891
910
  let keepConnection = true;
892
911
  const useCachedContext = options?.transport === "websocket-cached" || options?.transport === "auto";
@@ -903,7 +922,13 @@ async function processWebSocketStream(url, body, headers, output, stream, model,
903
922
  ...requestBody
904
923
  }));
905
924
  onRequestSent?.();
906
- await processResponsesStream(startWebSocketOutputOnFirstEvent(mapCodexEvents(parseWebSocket(socket, options?.signal)), output, stream, onStart), output, stream, model, {
925
+ await processResponsesStream(startWebSocketOutputOnFirstEvent(mapCodexEvents(parseWebSocket(socket, options?.signal)), output, stream, onFirstProviderEvent, () => notifyProviderStreamOpened({
926
+ options,
927
+ cancelStream: () => {
928
+ keepConnection = false;
929
+ closeWebSocketSilently(socket);
930
+ }
931
+ }), onStart), output, stream, model, {
907
932
  serviceTier: options?.serviceTier,
908
933
  firstEventTimeoutMs: getFirstStreamEventTimeoutMs(options),
909
934
  abortFirstEventStream,