@openclaw/ai 2026.10.1-beta.2 → 2026.10.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 (74) hide show
  1. package/dist/{anthropic-CZv6XFER.mjs → anthropic-C4qygbtf.mjs} +12 -11
  2. package/dist/{anthropic-payload-policy-BhCcgNdm.d.mts → anthropic-payload-policy-DD7vzpxE.d.mts} +5 -2
  3. package/dist/{anthropic-stream-reducer-BQ1tjd7x.mjs → anthropic-stream-reducer-CWyWE21W.mjs} +48 -54
  4. package/dist/{api-registry-DpU0Rj-I.d.mts → api-registry-B3rC2qu3.d.mts} +1 -1
  5. package/dist/{assistant-output-OLm-Oln0.mjs → assistant-output-D5762GPH.mjs} +2 -2
  6. package/dist/{assistant-text-phase-Bl1aDCB7.mjs → assistant-text-phase-DVZOxbuR.mjs} +1 -1
  7. package/dist/{azure-openai-responses-DH7bd3QT.mjs → azure-openai-responses-DO-Fv8ha.mjs} +5 -5
  8. package/dist/diagnostics.d.mts +3 -3
  9. package/dist/env-api-keys-BR0MUYYD.d.mts +17 -0
  10. package/dist/{google-1WLOtb8w.mjs → google-B2g_Xn4d.mjs} +6 -6
  11. package/dist/{google-interactions-wrnE6MLw.mjs → google-interactions-DNXzPPwQ.mjs} +6 -6
  12. package/dist/{google-messages-BwPPycw6.mjs → google-messages-l7wgIF5I.mjs} +3 -3
  13. package/dist/{google-shared-Eql1OMPU.mjs → google-shared-V8jogVPq.mjs} +5 -5
  14. package/dist/{google-vertex-0LrlRoO3.mjs → google-vertex-_khoip47.mjs} +5 -5
  15. package/dist/{host-BinBeGcQ.d.mts → host-DiPhRjrc.d.mts} +2 -2
  16. package/dist/{host-policy-B3jc4Rpn.mjs → host-policy-BwhNNGQR.mjs} +1 -1
  17. package/dist/{host-DCW52iHe.mjs → host-u3o8XiAp.mjs} +10 -7
  18. package/dist/{index-a8e_oKnu.d.mts → index-D27wAoOr.d.mts} +23 -3
  19. package/dist/index.d.mts +4 -4
  20. package/dist/index.mjs +4 -4
  21. package/dist/internal/anthropic.d.mts +5 -5
  22. package/dist/internal/anthropic.mjs +5 -5
  23. package/dist/internal/env-api-keys.d.mts +2 -0
  24. package/dist/internal/env-api-keys.mjs +2 -0
  25. package/dist/internal/openai-completions-compat.d.mts +1 -1
  26. package/dist/internal/openai-completions-compat.mjs +1 -1
  27. package/dist/internal/openai-responses-payload-policy.d.mts +9 -2
  28. package/dist/internal/openai-responses-payload-policy.mjs +3 -2
  29. package/dist/internal/openai.d.mts +8 -8
  30. package/dist/internal/openai.mjs +7 -7
  31. package/dist/internal/runtime.d.mts +7 -22
  32. package/dist/internal/runtime.mjs +3 -3
  33. package/dist/internal/shared.d.mts +1 -1
  34. package/dist/internal/shared.mjs +3 -3
  35. package/dist/internal/tool-schema.mjs +1 -1
  36. package/dist/{mistral-DSt4vQAO.mjs → mistral-cnoBDSIg.mjs} +4 -4
  37. package/dist/{openai-chatgpt-responses-BC2x0Oqx.mjs → openai-chatgpt-responses-CHdn8YJ_.mjs} +70 -63
  38. package/dist/{openai-completions-DNyHnXKg.mjs → openai-completions-BZfHIaZ7.mjs} +3 -3
  39. package/dist/{openai-completions-compat-BYdYpXhU.d.mts → openai-completions-compat-BgPg1BRs.d.mts} +2 -2
  40. package/dist/{openai-completions-compat-BdmlhD4u.mjs → openai-completions-compat-GMN8A0fm.mjs} +1 -1
  41. package/dist/{openai-completions-transport-DWM2mQDB.mjs → openai-completions-transport-CuoQfnKV.mjs} +123 -20
  42. package/dist/{openai-prompt-cache-I8YQTzf8.mjs → openai-prompt-cache-BK6E2g4Q.mjs} +1 -1
  43. package/dist/{openai-prompt-cache-45-AH_xv.d.mts → openai-prompt-cache-CFviG_D4.d.mts} +1 -1
  44. package/dist/{openai-responses-uZ5oWSp7.mjs → openai-responses-BhAZFsL9.mjs} +7 -7
  45. package/dist/{openai-responses-compaction-replay-BClApUIf.d.mts → openai-responses-compaction-replay-BBNo098-.d.mts} +3 -3
  46. package/dist/{openai-responses-compaction-window-m878aVpU.mjs → openai-responses-compaction-window-tA4QkU0o.mjs} +3 -3
  47. package/dist/{openai-responses-contracts-Br5IIw_h.d.mts → openai-responses-contracts-D5yVZBp-.d.mts} +3 -3
  48. package/dist/openai-responses-endpoint-TV0y50fb.mjs +11 -0
  49. package/dist/{openai-responses-payload-policy-C7GsA1y0.d.mts → openai-responses-payload-policy-s1apQlZZ.d.mts} +4 -2
  50. package/dist/{openai-responses-prompt-observer-internal-CCg7B6l4.mjs → openai-responses-prompt-observer-internal-CefUzh8M.mjs} +2 -2
  51. package/dist/{openai-responses-shared-C7oVyjED.mjs → openai-responses-shared-CKNmC3vC.mjs} +11 -11
  52. package/dist/{openai-responses-terminal-usage-DgImcyJu.d.mts → openai-responses-terminal-usage-CempLedn.d.mts} +1 -1
  53. package/dist/{openai-tool-schema-DYNePiF8.mjs → openai-tool-schema-BIrI0mrA.mjs} +18 -1
  54. package/dist/{openai-transport-params-JFsnIyto.mjs → openai-transport-params-D7JMUPjf.mjs} +7 -7
  55. package/dist/{provider-options-D5ABCV_l.d.mts → provider-options-CkieKvNJ.d.mts} +9 -4
  56. package/dist/{provider-replay-context-C7Bmi84a.mjs → provider-replay-context-CO_Eplnc.mjs} +1 -1
  57. package/dist/{provider-transport-turn-state-_M2kLdUE.mjs → provider-transport-turn-state-BX6TfCyW.mjs} +2 -2
  58. package/dist/{provider-types-F8Mqc9Ma.d.mts → provider-types-v3bmqsfg.d.mts} +2 -2
  59. package/dist/provider-types.d.mts +3 -3
  60. package/dist/providers.d.mts +2 -2
  61. package/dist/providers.mjs +10 -10
  62. package/dist/{simple-options-BkKTXxhp.mjs → simple-options-7QuSKriJ.mjs} +2 -2
  63. package/dist/{src-B0NIt2UK.mjs → src-VWy9E7DZ.mjs} +21 -7
  64. package/dist/{stream-DSdzKsDK.mjs → stream-DFaRxi2D.mjs} +1 -1
  65. package/dist/{text-signature-MLwfi6fq.mjs → text-signature-D_vRrx-z.mjs} +2 -2
  66. package/dist/{transport-stream-shared-CxXXz_Dd.mjs → transport-stream-shared-CCR7hSW0.mjs} +24 -5
  67. package/dist/{transport-stream-shared-BcAKh2XH.d.mts → transport-stream-shared-DW-7-qLR.d.mts} +1 -1
  68. package/dist/transports.d.mts +13 -13
  69. package/dist/transports.mjs +170 -172
  70. package/dist/types-UlNana-2.d.mts +1 -0
  71. package/dist/types.d.mts +3 -3
  72. package/dist/types.mjs +2 -2
  73. package/package.json +6 -1
  74. package/dist/types-BuiEBM3u.d.mts +0 -1
@@ -2,23 +2,22 @@ import { i as formatThrownValue, n as createAssistantMessageDiagnostic, t as app
2
2
  import { t as AssistantMessageEventStream } from "./event-stream-C5AbCAaZ.mjs";
3
3
  import { o as isRecord } from "./record-coerce-CNDovvft.mjs";
4
4
  import { r as clampPositiveTimerTimeoutMs } from "./number-coercion-V8-BhME4.mjs";
5
- import { E as headersToRecord, a as resolveAiTransportHeaderSentinels, r as getAiTransportHost } from "./host-DCW52iHe.mjs";
5
+ import { E as headersToRecord, a as resolveAiTransportHeaderSentinels, r as getAiTransportHost } from "./host-u3o8XiAp.mjs";
6
6
  import { D as supportsOpenAITemperature, h as responsesPromptObserver } from "./openai-responses-contracts-BKu8O7l4.mjs";
7
7
  import { r as registerSessionResourceCleanup } from "./session-resources-D1wgDQ8C.mjs";
8
- import { n as clampOpenAIPromptCacheKey } from "./openai-prompt-cache-I8YQTzf8.mjs";
8
+ import { n as clampOpenAIPromptCacheKey } from "./openai-prompt-cache-BK6E2g4Q.mjs";
9
9
  import { _ as extractErrorCodeOrErrno, o as WEBSOCKET_NON_RETRYABLE_CLOSE_ERROR_CODE, v as toErrorObject } from "./diagnostics-Caj-4RBA.mjs";
10
- import { n as MALFORMED_STREAMING_FRAGMENT_ERROR_MESSAGE } from "./text-signature-MLwfi6fq.mjs";
10
+ import { n as MALFORMED_STREAMING_FRAGMENT_ERROR_MESSAGE } from "./text-signature-D_vRrx-z.mjs";
11
11
  import { parseRetryAfterHeadersSeconds } from "./internal/retry-after.mjs";
12
- import { c as resolveOpenAIResponsesTextFormat } from "./openai-completions-compat-BdmlhD4u.mjs";
13
- import { n as buildManagedModelFetch } from "./host-policy-B3jc4Rpn.mjs";
14
- import { S as withProviderResponseHook, b as transportAbortError, h as notifyProviderStreamOpened, n as assignTransportErrorDetails } from "./transport-stream-shared-CxXXz_Dd.mjs";
15
- import { C as stripSystemPromptCacheBoundary, n as buildBaseOptions } from "./simple-options-BkKTXxhp.mjs";
16
- import { b as createOpenAIResponseHook, g as resolveOpenAISimpleReasoningEffort, h as resolveOpenAIRequestReasoning, x as createResponseModelTracker, y as createOpenAIProviderAcceptanceHook } from "./openai-transport-params-JFsnIyto.mjs";
17
- import { t as createAssistantOutput } from "./assistant-output-OLm-Oln0.mjs";
12
+ import { c as resolveOpenAIResponsesTextFormat } from "./openai-completions-compat-GMN8A0fm.mjs";
13
+ import { n as buildManagedModelFetch } from "./host-policy-BwhNNGQR.mjs";
14
+ import { S as withProviderResponseHook, b as transportAbortError, h as notifyProviderStreamOpened, n as assignTransportErrorDetails } from "./transport-stream-shared-CCR7hSW0.mjs";
15
+ import { C as stripSystemPromptCacheBoundary, n as buildBaseOptions } from "./simple-options-7QuSKriJ.mjs";
16
+ import { b as createOpenAIResponseHook, g as resolveOpenAISimpleReasoningEffort, h as resolveOpenAIRequestReasoning, x as createResponseModelTracker, y as createOpenAIProviderAcceptanceHook } from "./openai-transport-params-D7JMUPjf.mjs";
17
+ import { t as createAssistantOutput } from "./assistant-output-D5762GPH.mjs";
18
18
  import { a as withFirstStreamEventTimeout, i as getFirstStreamEventTimeoutMs, r as getFirstStreamEventTimeoutHandler, t as createFirstStreamEventAbortController } from "./stream-first-event-timeout-D9ZmL_s9.mjs";
19
- import { A as recordResponsesContextUsage, J as buildOpenAIResponsesReasoningReplayMetadata, P as convertProviderResponsesMessages, S as isInvalidEncryptedContentError, T as ResponsesStreamFailure, Z as suppressOpenAIResponsesCompaction, b as commitResponsesEncryptedContentAttempt, i as convertResponsesToolPayload, n as applyResponsesServiceTierPricing, o as readOpenAIMisalignmentReview, s as processResponsesStream, w as resolveNextResponsesEncryptedContentAttempt } from "./openai-responses-shared-C7oVyjED.mjs";
20
- import { t as createSseByteGuard } from "./streaming-byte-guard-CC-HMn_u.mjs";
21
- import { t as createResponsesPromptEgressObserver } from "./openai-responses-prompt-observer-internal-CCg7B6l4.mjs";
19
+ import { A as recordResponsesContextUsage, J as buildOpenAIResponsesReasoningReplayMetadata, P as convertProviderResponsesMessages, S as isInvalidEncryptedContentError, T as ResponsesStreamFailure, Z as suppressOpenAIResponsesCompaction, b as commitResponsesEncryptedContentAttempt, i as convertResponsesToolPayload, n as applyResponsesServiceTierPricing, o as readOpenAIMisalignmentReview, s as processResponsesStream, w as resolveNextResponsesEncryptedContentAttempt } from "./openai-responses-shared-CKNmC3vC.mjs";
20
+ import { t as createResponsesPromptEgressObserver } from "./openai-responses-prompt-observer-internal-CefUzh8M.mjs";
22
21
  import { n as withResponsesRequestAcceptance, t as responsesRequestLifecycle } from "./openai-responses-request-lifecycle-Fsag-IGZ.mjs";
23
22
  import { t as requireApiKey } from "./required-api-key-D4kn3252.mjs";
24
23
  import { n as resolveOpenAICodexAccountId } from "./openai-chatgpt-jwt-KWcgd0d_.mjs";
@@ -84,7 +83,7 @@ function normalizeCodexStatus(status) {
84
83
  }
85
84
  //#endregion
86
85
  //#region packages/ai/src/providers/openai-chatgpt-responses-protocol.ts
87
- const OPENAI_CHATGPT_RESPONSES_SUCCESS_BODY_MAX_BYTES = 16777216;
86
+ const OPENAI_CHATGPT_RESPONSES_SSE_FRAME_MAX_BYTES = 16777216;
88
87
  var CodexProtocolError = class extends Error {
89
88
  constructor(message, options) {
90
89
  super(message);
@@ -96,44 +95,53 @@ var CodexProtocolError = class extends Error {
96
95
  async function* parseOpenAIChatGptResponsesSse(response) {
97
96
  if (!response.body) return;
98
97
  const reader = response.body.getReader();
99
- const guard = createSseByteGuard(reader, {
100
- maxBytes: OPENAI_CHATGPT_RESPONSES_SUCCESS_BODY_MAX_BYTES,
101
- onOverflow: ({ size, maxBytes }) => /* @__PURE__ */ new Error(`OpenAI ChatGPT Responses success body exceeded ${maxBytes} bytes (received ${size})`)
102
- });
103
98
  const decoder = new TextDecoder();
104
- let buffer = "";
99
+ let buffer = /* @__PURE__ */ new Uint8Array(1024);
100
+ let size = 0;
101
+ let lineEmpty = true;
102
+ let skipLf = false;
103
+ let cancelReason;
105
104
  try {
106
105
  while (true) {
107
- const { done, value } = await guard.read();
108
- if (value) buffer += decoder.decode(value, { stream: true });
109
- if (done) buffer += decoder.decode();
110
- while (true) {
111
- const searchable = !done && buffer.endsWith("\r") && !buffer.endsWith("\r\r") && !buffer.endsWith("\n\r") ? buffer.slice(0, -1) : buffer;
112
- const boundary = /(?:\r\n|\r(?!\n)|\n)(?:\r\n|\r(?!\n)|\n)/.exec(searchable);
113
- if (!boundary && (!done || buffer.length === 0)) break;
114
- const chunk = boundary ? buffer.slice(0, boundary.index) : buffer;
115
- buffer = boundary ? buffer.slice(boundary.index + boundary[0].length) : "";
116
- const dataLines = chunk.split(/\r\n|\r|\n/).filter((line) => line.startsWith("data:")).map((line) => line.slice(5).trim());
117
- if (dataLines.length > 0) {
118
- const data = dataLines.join("\n").trim();
119
- if (data && data !== "[DONE]") {
120
- let event;
121
- try {
122
- event = JSON.parse(data);
123
- } catch (cause) {
124
- if (!(cause instanceof SyntaxError)) throw cause;
125
- throw new CodexProtocolError(MALFORMED_STREAMING_FRAGMENT_ERROR_MESSAGE, { cause });
126
- }
127
- yield event;
106
+ const { done, value } = await reader.read();
107
+ for (let index = 0; index < (value?.length ?? 0) + (done ? 1 : 0); index++) {
108
+ const byte = value?.[index];
109
+ if (byte !== void 0) {
110
+ const crlf = skipLf && byte === 10;
111
+ skipLf = byte === 13;
112
+ const lineEnding = byte === 10 || byte === 13;
113
+ const boundary = !crlf && lineEnding && lineEmpty;
114
+ lineEmpty = lineEnding;
115
+ if (crlf && size === 0) continue;
116
+ if (size >= OPENAI_CHATGPT_RESPONSES_SSE_FRAME_MAX_BYTES) throw new Error(`OpenAI ChatGPT Responses SSE frame exceeded ${OPENAI_CHATGPT_RESPONSES_SSE_FRAME_MAX_BYTES} bytes`);
117
+ if (size === buffer.length) {
118
+ const grown = new Uint8Array(Math.min(buffer.length * 2, OPENAI_CHATGPT_RESPONSES_SSE_FRAME_MAX_BYTES));
119
+ grown.set(buffer);
120
+ buffer = grown;
128
121
  }
122
+ buffer[size++] = byte;
123
+ if (!boundary) continue;
129
124
  }
125
+ const chunk = decoder.decode(buffer.subarray(0, size), { stream: !done });
126
+ size = 0;
127
+ const data = chunk.split(/\r\n|\r|\n/).filter((line) => line.startsWith("data:")).map((line) => line.slice(5).trim()).join("\n").trim();
128
+ if (!data || data === "[DONE]") continue;
129
+ let event;
130
+ try {
131
+ event = JSON.parse(data);
132
+ } catch (cause) {
133
+ if (!(cause instanceof SyntaxError)) throw cause;
134
+ throw new CodexProtocolError(MALFORMED_STREAMING_FRAGMENT_ERROR_MESSAGE, { cause });
135
+ }
136
+ yield event;
130
137
  }
131
138
  if (done) break;
132
139
  }
140
+ } catch (error) {
141
+ cancelReason = error;
142
+ throw error;
133
143
  } finally {
134
- try {
135
- await guard.cancel();
136
- } catch {}
144
+ reader.cancel(cancelReason).catch(() => void 0);
137
145
  try {
138
146
  reader.releaseLock();
139
147
  } catch {}
@@ -298,13 +306,8 @@ const RETRYABLE_WEBSOCKET_CLOSE_CODES = /* @__PURE__ */ new Set([
298
306
  ]);
299
307
  const WEBSOCKET_MESSAGE_TOO_BIG_CLOSE_CODE = 1009;
300
308
  const WEBSOCKET_CONNECTION_LIMIT_REACHED_CODE = "websocket_connection_limit_reached";
309
+ const WEBSOCKET_REPLAY_REJECTION = "Codex error: Persisted response contains hosted-tool, compaction, or unverifiable hidden reasoning state that Rustponses cannot replay. Start a new response or use the Python Responses service for this continuation.";
301
310
  const OPENAI_CHATGPT_RESPONSES_ERROR_BODY_MAX_BYTES = 16384;
302
- function buildRequestSignal(baseSignal, timeoutMs) {
303
- if (timeoutMs === void 0) return baseSignal;
304
- const timeoutSignal = AbortSignal.timeout(timeoutMs);
305
- if (!baseSignal) return timeoutSignal;
306
- return AbortSignal.any([baseSignal, timeoutSignal]);
307
- }
308
311
  function isRequestTimeoutError(error, callerSignal, requestSignal, timeoutMs) {
309
312
  if (timeoutMs === void 0 || callerSignal?.aborted || !requestSignal?.aborted) return false;
310
313
  if (!(error instanceof Error)) return false;
@@ -361,7 +364,11 @@ const streamOpenAICodexResponses = (model, context, options) => {
361
364
  const observePromptEgress = createResponsesPromptEgressObserver(options, context.systemPrompt);
362
365
  const sessionId = clampOpenAIPromptCacheKey(options?.sessionId);
363
366
  requestTimeoutMs = clampPositiveTimerTimeoutMs(options?.timeoutMs);
364
- requestTimeoutSignal = buildRequestSignal(options?.signal, requestTimeoutMs);
367
+ requestTimeoutSignal = options?.signal;
368
+ if (requestTimeoutMs !== void 0) {
369
+ const timeoutSignal = AbortSignal.timeout(requestTimeoutMs);
370
+ requestTimeoutSignal = options?.signal ? AbortSignal.any([options.signal, timeoutSignal]) : timeoutSignal;
371
+ }
365
372
  firstEventAbort = createFirstStreamEventAbortController(requestTimeoutSignal);
366
373
  activeSignal = firstEventAbort.signal;
367
374
  const requestOptions = activeSignal === options?.signal ? options : {
@@ -389,19 +396,18 @@ const streamOpenAICodexResponses = (model, context, options) => {
389
396
  const websocketDisabledForSession = transport === "auto" && websocketAuthority !== void 0 && hasCodexWebSocketSseFallback(websocketState.sseFallbacks, options?.sessionId, websocketAuthority);
390
397
  if (websocketAuthority && !websocketDisabledForSession) {
391
398
  let websocketStarted = false;
392
- let websocketRequestSent = false;
393
- let retriedWebSocketConnectionLimit = false;
399
+ let retriedWebSocketRejection = false;
394
400
  while (true) {
395
401
  const activeAttempt = semanticAttempt;
402
+ const dispatch = {};
396
403
  websocketStarted = false;
397
- websocketRequestSent = false;
398
404
  try {
399
405
  const terminal = await processWebSocketStream(websocketState, websocketAuthority, activeAttempt.request, output, stream, model, () => {
400
406
  websocketStarted = true;
401
407
  }, () => {
402
408
  commitSemanticAttempt(activeAttempt);
403
- }, requestOptions, firstEventAbort.abort, observePromptEgress, activeAttempt.kind, () => {
404
- websocketRequestSent = true;
409
+ }, requestOptions, firstEventAbort.abort, observePromptEgress, activeAttempt.kind, (request) => {
410
+ dispatch.request = request;
405
411
  }, options?.signal);
406
412
  if (activeSignal?.aborted) throw transportAbortError(activeSignal);
407
413
  if (output.stopReason === "aborted" || output.stopReason === "error") throw new CodexApiError(output.errorMessage ?? "An unknown error occurred");
@@ -415,19 +421,20 @@ const streamOpenAICodexResponses = (model, context, options) => {
415
421
  return;
416
422
  } catch (error) {
417
423
  const aborted = activeSignal?.aborted;
418
- const nextSemanticAttempt = !aborted && websocketRequestSent && !websocketStarted && error instanceof CodexApiError && isInvalidEncryptedContentError(error) ? await resolveNextResponsesEncryptedContentAttempt(activeAttempt, error, { buildFullHistoryRequest: () => buildBody("full-history") }) : void 0;
424
+ const nextSemanticAttempt = !aborted && dispatch.request && !websocketStarted && error instanceof CodexApiError && isInvalidEncryptedContentError(error) ? await resolveNextResponsesEncryptedContentAttempt(activeAttempt, error, { buildFullHistoryRequest: () => buildBody("full-history") }) : void 0;
419
425
  if (nextSemanticAttempt) {
420
426
  semanticAttempt = nextSemanticAttempt;
421
- retriedWebSocketConnectionLimit = false;
427
+ retriedWebSocketRejection = false;
422
428
  continue;
423
429
  }
424
- const connectionLimitBeforeStart = !websocketStarted && isWebSocketConnectionLimitReachedError(error);
425
- if (!aborted && connectionLimitBeforeStart && !retriedWebSocketConnectionLimit) {
426
- retriedWebSocketConnectionLimit = true;
430
+ const reconnectBeforeStart = !websocketStarted && isWebSocketConnectionLimitReachedError(error) || !websocketStarted && dispatch.request?.previous_response_id && error instanceof CodexApiError && error.message === WEBSOCKET_REPLAY_REJECTION;
431
+ if (!aborted && reconnectBeforeStart && !retriedWebSocketRejection) {
432
+ retriedWebSocketRejection = true;
427
433
  continue;
428
434
  }
429
- if (aborted || isCodexNonTransportError(error) && !connectionLimitBeforeStart) throw error;
430
- appendAssistantMessageDiagnostic(output, createAssistantMessageDiagnostic("provider_transport_failure", error, {
435
+ const transportError = isWebSocketConnectionLimitReachedError(error) ? Object.assign(new Error(error.message, { cause: error }), { code: WEBSOCKET_TRANSPORT_ERROR_CODE }) : error;
436
+ if (aborted || isCodexNonTransportError(transportError)) throw transportError;
437
+ appendAssistantMessageDiagnostic(output, createAssistantMessageDiagnostic("provider_transport_failure", transportError, {
431
438
  configuredTransport: transport,
432
439
  fallbackTransport: transport === "auto" && !websocketStarted ? "sse" : void 0,
433
440
  eventsEmitted: websocketStarted,
@@ -435,7 +442,7 @@ const streamOpenAICodexResponses = (model, context, options) => {
435
442
  requestBytes: new TextEncoder().encode(JSON.stringify(activeAttempt.request)).byteLength
436
443
  }));
437
444
  if (transport === "auto" && options?.sessionId) addCodexWebSocketSseFallback(websocketState.sseFallbacks, options.sessionId, websocketAuthority);
438
- if (websocketStarted || transport !== "auto") throw error;
445
+ if (websocketStarted || transport !== "auto") throw transportError;
439
446
  break;
440
447
  }
441
448
  }
@@ -987,7 +994,7 @@ async function processWebSocketStream(state, authority, body, output, stream, mo
987
994
  type: "response.create",
988
995
  ...requestBody
989
996
  }));
990
- onRequestSent?.();
997
+ onRequestSent?.(requestBody);
991
998
  const terminal = await processResponsesStream(startWebSocketOutputOnFirstEvent(mapCodexEvents(parseWebSocket(socket, options?.signal), void 0, options), output, stream, onFirstProviderEvent, () => notifyProviderStreamOpened({
992
999
  options,
993
1000
  cancelStream: () => {
@@ -1,7 +1,7 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-BhDjJH2R.mjs";
2
- import { k as clampThinkingLevel } from "./host-DCW52iHe.mjs";
3
- import { n as buildBaseOptions } from "./simple-options-BkKTXxhp.mjs";
4
- import { i as convertMessages, n as streamOpenAICompletionsRequest } from "./openai-completions-transport-DWM2mQDB.mjs";
2
+ import { k as clampThinkingLevel } from "./host-u3o8XiAp.mjs";
3
+ import { n as buildBaseOptions } from "./simple-options-7QuSKriJ.mjs";
4
+ import { i as convertMessages, n as streamOpenAICompletionsRequest } from "./openai-completions-transport-CuoQfnKV.mjs";
5
5
  import { t as requireApiKey } from "./required-api-key-D4kn3252.mjs";
6
6
  //#region packages/ai/src/providers/openai-completions.ts
7
7
  var openai_completions_exports = /* @__PURE__ */ __exportAll({
@@ -1,6 +1,6 @@
1
- import "./index-a8e_oKnu.mjs";
1
+ import "./index-D27wAoOr.mjs";
2
2
  import { N as OpenAICompletionsCompat, k as Model } from "./types-DvzmWW8J.mjs";
3
- import { a as AiProviderRequestPolicyInput, i as AiProviderRequestCapabilities } from "./host-BinBeGcQ.mjs";
3
+ import { a as AiProviderRequestPolicyInput, i as AiProviderRequestCapabilities } from "./host-DiPhRjrc.mjs";
4
4
  //#region packages/ai/src/transports/openai-completions-compat.d.ts
5
5
  type ProviderRequestCapabilities = AiProviderRequestCapabilities;
6
6
  type OpenAICompletionsSessionAffinity = "none" | "openai" | "openrouter";
@@ -1,5 +1,5 @@
1
1
  import { o as isRecord } from "./record-coerce-CNDovvft.mjs";
2
- import { a as resolveProviderRequestCapabilities } from "./host-policy-B3jc4Rpn.mjs";
2
+ import { a as resolveProviderRequestCapabilities } from "./host-policy-BwhNNGQR.mjs";
3
3
  //#region packages/ai/src/providers/openai-response-format.ts
4
4
  const JSON_SCHEMA_RESPONSE_FORMAT_NAME = "openclaw_response";
5
5
  const OLLAMA_CLOUD_ORIGIN = "https://ollama.com";
@@ -3,28 +3,28 @@ import { r as appendAssistantThinking } from "./event-stream-C5AbCAaZ.mjs";
3
3
  import { o as isRecord } from "./record-coerce-CNDovvft.mjs";
4
4
  import { s as readNonEmptyStringPreservingWhitespace, t as hasNonEmptyString } from "./string-coerce-CtgOVOSv.mjs";
5
5
  import { n as asNonNegativeFiniteNumber } from "./number-coercion-V8-BhME4.mjs";
6
- import { N as isImageWithMediaPayload, r as getAiTransportHost } from "./host-DCW52iHe.mjs";
6
+ import { N as isImageWithMediaPayload, r as getAiTransportHost } from "./host-u3o8XiAp.mjs";
7
7
  import { _ as isOpenAIGpt54MiniModel, v as isOpenAIGpt55Model, y as isOpenAIGpt56Model } from "./openai-responses-contracts-BKu8O7l4.mjs";
8
8
  import { r as uniqueStrings } from "./string-normalization-PN10hf6d.mjs";
9
9
  import { o as truncateUtf16Safe } from "./provider-error-DQBE1bUQ.mjs";
10
- import { r as resolveOpenAIPromptCacheParams } from "./openai-prompt-cache-I8YQTzf8.mjs";
10
+ import { r as resolveOpenAIPromptCacheParams } from "./openai-prompt-cache-BK6E2g4Q.mjs";
11
11
  import { r as emitModelTransportDebug } from "./diagnostics-Caj-4RBA.mjs";
12
- import { c as supportsModelTools, r as estimateStringChars } from "./text-signature-MLwfi6fq.mjs";
13
- import { i as resolveOpenAICompletionsCompat, l as shouldOmitOllamaCompatResponseFormat, n as isNativeOpenAIEndpoint, s as resolveOpenAICompletionsResponseFormat, t as detectOpenAICompletionsCompat } from "./openai-completions-compat-BdmlhD4u.mjs";
14
- import { i as resolveProviderEndpoint, t as buildGuardedModelFetch } from "./host-policy-B3jc4Rpn.mjs";
12
+ import { c as supportsModelTools, r as estimateStringChars } from "./text-signature-D_vRrx-z.mjs";
13
+ import { i as resolveOpenAICompletionsCompat, l as shouldOmitOllamaCompatResponseFormat, n as isNativeOpenAIEndpoint, s as resolveOpenAICompletionsResponseFormat, t as detectOpenAICompletionsCompat } from "./openai-completions-compat-GMN8A0fm.mjs";
14
+ import { i as resolveProviderEndpoint, t as buildGuardedModelFetch } from "./host-policy-BwhNNGQR.mjs";
15
15
  import { i as resolveCacheRetention, r as buildCopilotDynamicHeaders } from "./cloudflare-5qSGvIUH.mjs";
16
- import { E as createToolArgumentPreviewSchedule, O as parseStreamingJson, P as sanitizeSurrogates, S as withProviderResponseHook, _ as sanitizeNonEmptyTransportPayloadText, b as transportAbortError, c as failTransportStream, d as iterateModelStream, l as finalizeTerminalToolCallArguments, s as createWritableTransportEventStream, u as finalizeTransportStream, y as throwIfModelStreamAborted } from "./transport-stream-shared-CxXXz_Dd.mjs";
17
- import { C as stripSystemPromptCacheBoundary, D as sortPromptCacheToolsByName, S as splitSystemPromptRelocatableBoundary, d as describeToolResultMediaPlaceholder, l as codeModeToolSurfaceObserver, m as extractToolResultText, s as prepareModelRequestBody, u as reasoningTagTextPolicy, w as stripSystemPromptRelocatableBoundary, x as splitSystemPromptCacheBoundary } from "./simple-options-BkKTXxhp.mjs";
18
- import { C as log, D as readOpenAICompletionsReasoningBatch, E as readOpenAICompletionsContentDeltas, O as resolveOpenAIClientBaseUrl, S as isOpenAICompletionsThinkingEnabled, T as parseOpenAICompletionsUsage, a as enforceCodeModeResponsesToolSurface, d as prepareOpenAITools, f as projectOpenAITools, g as resolveOpenAISimpleReasoningEffort, h as resolveOpenAIRequestReasoning, i as buildOpenAISdkRequestOptions, k as resolvePromptCacheKey, l as resolveCodeModeResponsesVisibleToolNames, n as buildOpenAIClientHeaders, p as reconcileOpenAICompletionsToolChoice, r as buildOpenAISdkClientOptions, s as getCompat, t as assertCodeModeResponsesToolSurface, u as resolveOpenAIStrictToolFlagWithDiagnostics, v as GEMINI_THOUGHT_SIGNATURE_VALIDATOR_SKIP, w as measureUtf8AppendBytes, y as createOpenAIProviderAcceptanceHook } from "./openai-transport-params-JFsnIyto.mjs";
16
+ import { E as createToolArgumentPreviewSchedule, O as parseStreamingJson, P as sanitizeSurrogates, S as withProviderResponseHook, _ as sanitizeNonEmptyTransportPayloadText, b as transportAbortError, c as failTransportStream, d as iterateModelStream, l as finalizeTerminalToolCallArguments, s as createWritableTransportEventStream, u as finalizeTransportStream, y as throwIfModelStreamAborted } from "./transport-stream-shared-CCR7hSW0.mjs";
17
+ import { C as stripSystemPromptCacheBoundary, D as sortPromptCacheToolsByName, S as splitSystemPromptRelocatableBoundary, d as describeToolResultMediaPlaceholder, l as codeModeToolSurfaceObserver, m as extractToolResultText, s as prepareModelRequestBody, u as reasoningTagTextPolicy, w as stripSystemPromptRelocatableBoundary, x as splitSystemPromptCacheBoundary } from "./simple-options-7QuSKriJ.mjs";
18
+ import { C as log, D as readOpenAICompletionsReasoningBatch, E as readOpenAICompletionsContentDeltas, O as resolveOpenAIClientBaseUrl, S as isOpenAICompletionsThinkingEnabled, T as parseOpenAICompletionsUsage, a as enforceCodeModeResponsesToolSurface, d as prepareOpenAITools, f as projectOpenAITools, g as resolveOpenAISimpleReasoningEffort, h as resolveOpenAIRequestReasoning, i as buildOpenAISdkRequestOptions, k as resolvePromptCacheKey, l as resolveCodeModeResponsesVisibleToolNames, n as buildOpenAIClientHeaders, p as reconcileOpenAICompletionsToolChoice, r as buildOpenAISdkClientOptions, s as getCompat, t as assertCodeModeResponsesToolSurface, u as resolveOpenAIStrictToolFlagWithDiagnostics, v as GEMINI_THOUGHT_SIGNATURE_VALIDATOR_SKIP, w as measureUtf8AppendBytes, y as createOpenAIProviderAcceptanceHook } from "./openai-transport-params-D7JMUPjf.mjs";
19
19
  import { n as getEnvApiKey } from "./env-api-keys-CyX4VKGO.mjs";
20
- import { n as transformProviderMessages, t as createAssistantOutput } from "./assistant-output-OLm-Oln0.mjs";
21
- import { a as tagUnresolvedTextAsCommentary, i as tagPendingCommentaryText, n as rememberPendingCommentaryTags, r as tagInterruptedTextPhases, t as clearPendingCommentaryText } from "./assistant-text-phase-Bl1aDCB7.mjs";
20
+ import { n as transformProviderMessages, t as createAssistantOutput } from "./assistant-output-D5762GPH.mjs";
21
+ import { a as tagUnresolvedTextAsCommentary, i as tagPendingCommentaryText, n as rememberPendingCommentaryTags, r as tagInterruptedTextPhases, t as clearPendingCommentaryText } from "./assistant-text-phase-DVZOxbuR.mjs";
22
22
  import { t as notifyLlmRequestActivity } from "./llm-request-activity-D8f_oxHj.mjs";
23
23
  import { n as resolveOpencodeSessionHeaders } from "./session-affinity-DA4WHv1h.mjs";
24
24
  import "./types.mjs";
25
- import { i as createOpenAIProviderClient, n as resolveProviderSimpleCompletionHeaders, r as resolveProviderTransportTurnState, t as filterProviderTurnHeadersForExplicitOpencodeSession } from "./provider-transport-turn-state-_M2kLdUE.mjs";
25
+ import { i as createOpenAIProviderClient, n as resolveProviderSimpleCompletionHeaders, r as resolveProviderTransportTurnState, t as filterProviderTurnHeadersForExplicitOpencodeSession } from "./provider-transport-turn-state-BX6TfCyW.mjs";
26
26
  import { a as withFirstStreamEventTimeout, i as getFirstStreamEventTimeoutMs, r as getFirstStreamEventTimeoutHandler, t as createFirstStreamEventAbortController } from "./stream-first-event-timeout-D9ZmL_s9.mjs";
27
- import { f as withPreparedToolSchemaNormalization, r as normalizeOpenAIStrictToolParameters } from "./openai-tool-schema-DYNePiF8.mjs";
27
+ import { f as withPreparedToolSchemaNormalization, r as normalizeOpenAIStrictToolParameters } from "./openai-tool-schema-BIrI0mrA.mjs";
28
28
  import { isGoogleGemini3ThinkingLevelModel } from "./internal/google-model-family.mjs";
29
29
  import { t as mapOpenAIStopReason } from "./openai-stop-reason-8s70vDXj.mjs";
30
30
  import { t as createReasoningTagTextPartitioner } from "./reasoning-tag-text-partitioner-Ju9VpUGl.mjs";
@@ -519,7 +519,7 @@ function convertMessages(model, context, compat, options = {}) {
519
519
  });
520
520
  if (isRuntimeContextMessage(msg)) {
521
521
  params.push({
522
- role: model.reasoning && compat.supportsDeveloperRole ? "developer" : "system",
522
+ role: compat.supportsDeveloperRole ? "developer" : "user",
523
523
  content: sanitizeSurrogates(runtimeContextContentToText(msg.content))
524
524
  });
525
525
  options.cacheOptOutIndexes?.add(params.length - 1);
@@ -1091,14 +1091,11 @@ function buildOpenAICompletionsRequest(model, context, options, policy) {
1091
1091
  }
1092
1092
  if (compatDetection?.capabilities.usesExplicitProxyLikeEndpoint && clampedMaxTokens !== void 0 && effectiveContextTokens !== void 0) {
1093
1093
  const estimatedInputTokens = estimateOpenAICompletionsInputTokens(params);
1094
- const remainingBudget = Math.max(1, effectiveContextTokens - estimatedInputTokens - 1);
1094
+ const remainingBudget = Math.max(0, effectiveContextTokens - estimatedInputTokens - 1);
1095
1095
  if (clampedMaxTokens > remainingBudget) {
1096
+ if (remainingBudget < MIN_USEFUL_OUTPUT_TOKENS) throw Object.assign(/* @__PURE__ */ new Error(`Context window exceeded: estimated input ${estimatedInputTokens} leaves only ${remainingBudget} output tokens within the ${effectiveContextTokens}-token context.`), { code: "context_length_exceeded" });
1096
1097
  clampedMaxTokens = remainingBudget;
1097
1098
  emitModelTransportDebug(log, `[completions] clamp_max_tokens provider=${model.provider} api=${model.api} model=${model.id} requested=${effectiveMaxTokens} output=${clampedMaxTokens} effectiveContext=${effectiveContextTokens} estimatedInput=${estimatedInputTokens}`);
1098
- if (remainingBudget < MIN_USEFUL_OUTPUT_TOKENS) {
1099
- if (model.reasoning && thinkingEnabled !== false) throw Object.assign(/* @__PURE__ */ new Error(`Context window exceeded: estimated input ${estimatedInputTokens} leaves only ${remainingBudget} output tokens within the ${effectiveContextTokens}-token context.`), { code: "context_length_exceeded" });
1100
- log.warn(`[completions] insufficient_output_budget provider=${model.provider} api=${model.api} model=${model.id} output=${clampedMaxTokens} effectiveContext=${effectiveContextTokens} estimatedInput=${estimatedInputTokens}`);
1101
- }
1102
1099
  }
1103
1100
  }
1104
1101
  if (policy.mode === "direct" ? options?.maxTokens : clampedMaxTokens) {
@@ -1383,6 +1380,102 @@ function scanDeepSeekDsmlToolBlock(text, closeToken, contentStartIndex, state) {
1383
1380
  return { kind: "incomplete" };
1384
1381
  }
1385
1382
  //#endregion
1383
+ //#region packages/ai/src/transports/openai-completions-gemma.ts
1384
+ const OPEN = "<|tool_call>";
1385
+ const CLOSE = "<tool_call|>";
1386
+ const QUOTE = "<|\"|>";
1387
+ const MAX_RECOVERY_BYTES = 256e3;
1388
+ function recoverGemmaCalls(text) {
1389
+ const parts = [];
1390
+ const opener = /\s*<\|tool_call>\s*call:([\w.-]+)\s*/y;
1391
+ const token = /\s*(<\|"\|>[\s\S]*?<\|"\|>|[\w.+-]+|[{}[\],:])\s*/y;
1392
+ let offset = 0;
1393
+ while (offset < text.length) {
1394
+ if (!text.slice(offset).trim()) {
1395
+ parts.push({
1396
+ kind: "text",
1397
+ text: text.slice(offset)
1398
+ });
1399
+ break;
1400
+ }
1401
+ opener.lastIndex = offset;
1402
+ const head = opener.exec(text);
1403
+ const name = head?.[1];
1404
+ if (!head || !name) return;
1405
+ const leading = /^\s*/.exec(head[0])?.[0] ?? "";
1406
+ if (leading) parts.push({
1407
+ kind: "text",
1408
+ text: leading
1409
+ });
1410
+ token.lastIndex = opener.lastIndex;
1411
+ let depth = 0;
1412
+ const json = [];
1413
+ do {
1414
+ const value = token.exec(text)?.[1];
1415
+ if (!value || json.length === 0 && value !== "{") return;
1416
+ if (value === "{") depth += 1;
1417
+ else if (value === "}") depth -= 1;
1418
+ json.push(value.startsWith(QUOTE) ? JSON.stringify(value.slice(5, -5)) : text[token.lastIndex] === ":" && /^[A-Za-z_][\w.-]*$/.test(value) ? JSON.stringify(value) : value);
1419
+ } while (depth > 0);
1420
+ if (!text.startsWith(CLOSE, token.lastIndex)) return;
1421
+ try {
1422
+ const argumentsValue = JSON.parse(json.join(" "));
1423
+ if (!isRecord(argumentsValue)) return;
1424
+ parts.push({
1425
+ kind: "toolCall",
1426
+ name,
1427
+ arguments: argumentsValue,
1428
+ partialArgs: JSON.stringify(argumentsValue)
1429
+ });
1430
+ } catch {
1431
+ return;
1432
+ }
1433
+ offset = token.lastIndex + 12;
1434
+ }
1435
+ return parts;
1436
+ }
1437
+ /** Buffer only a possible standalone call batch; prose and examples stay text. */
1438
+ function createGemmaToolCallRecoverer() {
1439
+ let buffer = "";
1440
+ let bytes = 0;
1441
+ let highSurrogate = false;
1442
+ let passthrough = false;
1443
+ return {
1444
+ push(text) {
1445
+ if (passthrough) return [{
1446
+ kind: "text",
1447
+ text
1448
+ }];
1449
+ const append = measureUtf8AppendBytes(highSurrogate, text);
1450
+ bytes += append.bytes;
1451
+ highSurrogate = append.endsWithHighSurrogate;
1452
+ buffer += text;
1453
+ const candidate = buffer.trimStart();
1454
+ if (OPEN.startsWith(candidate) || candidate.startsWith(OPEN)) {
1455
+ if (bytes > MAX_RECOVERY_BYTES) throw new Error("Exceeded Gemma tool-call recovery buffer limit");
1456
+ return [];
1457
+ }
1458
+ passthrough = true;
1459
+ const result = [{
1460
+ kind: "text",
1461
+ text: buffer
1462
+ }];
1463
+ buffer = "";
1464
+ return result;
1465
+ },
1466
+ flush(allowRecovery = true) {
1467
+ const text = buffer;
1468
+ buffer = "";
1469
+ passthrough ||= !allowRecovery;
1470
+ const recovered = allowRecovery ? recoverGemmaCalls(text) : void 0;
1471
+ return text ? recovered ?? [{
1472
+ kind: "text",
1473
+ text
1474
+ }] : [];
1475
+ }
1476
+ };
1477
+ }
1478
+ //#endregion
1386
1479
  //#region packages/ai/src/transports/openai-completions-stream.ts
1387
1480
  function extractToolCallThoughtSignature(toolCall) {
1388
1481
  const tc = toolCall;
@@ -1399,6 +1492,7 @@ async function processCompletionsStream(responseStream, output, model, stream, o
1399
1492
  const shouldFilterDeepSeekDsmlText = !directMode && compat.thinkingFormat === "deepseek";
1400
1493
  const deepSeekTextFilter = shouldFilterDeepSeekDsmlText ? createDeepSeekTextFilter() : null;
1401
1494
  const deepSeekToolCallRecoverer = shouldFilterDeepSeekDsmlText ? createDsmlRecoverer() : null;
1495
+ const gemmaToolCallRecoverer = !directMode && /gemma-?4/i.test(model.id) ? createGemmaToolCallRecoverer() : null;
1402
1496
  const reasoningTagTextPartitioner = createReasoningTagTextPartitioner();
1403
1497
  if (options?.strictReasoningTags) reasoningTagTextPartitioner.markStrict();
1404
1498
  let currentBlock = null;
@@ -1601,6 +1695,10 @@ async function processCompletionsStream(responseStream, output, model, stream, o
1601
1695
  const flushReasoningTagTextPartitioner = () => {
1602
1696
  for (const delta of reasoningTagTextPartitioner.flush()) appendPartitionedVisibleDelta(delta);
1603
1697
  };
1698
+ const flushGemmaToolCallRecoverer = (allowRecovery = true) => {
1699
+ for (const part of gemmaToolCallRecoverer?.flush(allowRecovery) ?? []) if (part.kind === "toolCall") appendRecoveredToolCall(part);
1700
+ else for (const delta of reasoningTagTextPartitioner.pushVisible(part.text)) appendPartitionedVisibleDelta(delta);
1701
+ };
1604
1702
  const sealTextBeforeReasoning = () => {
1605
1703
  if (currentBlock?.type !== "text" && !reasoningTagTextPartitioner.hasPending()) return;
1606
1704
  flushReasoningTagTextPartitioner();
@@ -1677,8 +1775,11 @@ async function processCompletionsStream(responseStream, output, model, stream, o
1677
1775
  appendReasoningDeltas(reasoningDeltas);
1678
1776
  }
1679
1777
  for (const [contentDeltaIndex, contentDelta] of contentDeltas.entries()) if (contentDelta.kind === "text") {
1680
- const routedDeltas = hasReasoningThinking ? reasoningTagTextPartitioner.push(contentDelta.text) : reasoningTagTextPartitioner.pushVisible(contentDelta.text);
1681
- for (const routedDelta of routedDeltas) appendPartitionedVisibleDelta(routedDelta);
1778
+ const parts = gemmaToolCallRecoverer?.push(contentDelta.text) ?? [contentDelta];
1779
+ for (const part of parts) {
1780
+ const routedDeltas = hasReasoningThinking ? reasoningTagTextPartitioner.push(part.text) : reasoningTagTextPartitioner.pushVisible(part.text);
1781
+ for (const routedDelta of routedDeltas) appendPartitionedVisibleDelta(routedDelta);
1782
+ }
1682
1783
  } else {
1683
1784
  beginReasoning(contentDeltaIndex < lastVisibleTextIndex);
1684
1785
  if (emitReasoning) {
@@ -1689,6 +1790,7 @@ async function processCompletionsStream(responseStream, output, model, stream, o
1689
1790
  if (!hasReasoningThinking) appendReasoningDeltas(reasoningDeltas);
1690
1791
  const toolCallDeltas = normalizedDelta.toolCalls;
1691
1792
  if (toolCallDeltas.length > 0) {
1793
+ flushGemmaToolCallRecoverer(false);
1692
1794
  sawNativeToolCallDelta = true;
1693
1795
  flushReasoningTagTextPartitioner();
1694
1796
  rememberPendingCommentaryTags(provisionalCommentaryTags, tagPendingCommentaryText(output.content));
@@ -1754,6 +1856,7 @@ async function processCompletionsStream(responseStream, output, model, stream, o
1754
1856
  }
1755
1857
  throwIfModelStreamAborted(options?.signal);
1756
1858
  if (!finishReason && (directMode || options?.sawStreamDONE?.() === false)) throw new Error("Stream ended without finish_reason");
1859
+ flushGemmaToolCallRecoverer();
1757
1860
  flushReasoningTagTextPartitioner();
1758
1861
  appendRecoveredParts(deepSeekToolCallRecoverer?.flush() ?? []);
1759
1862
  for (const part of deepSeekTextFilter?.flush() ?? []) appendVisibleTextDelta(part);
@@ -1,4 +1,4 @@
1
- import { n as isNativeOpenAIEndpoint } from "./openai-completions-compat-BdmlhD4u.mjs";
1
+ import { n as isNativeOpenAIEndpoint } from "./openai-completions-compat-GMN8A0fm.mjs";
2
2
  //#region packages/normalization-core/src/code-points.ts
3
3
  /** Truncates to a nonnegative code-point budget; grapheme clusters may be split. */
4
4
  function truncateCodePoints(text, maxCodePoints) {
@@ -1,5 +1,5 @@
1
1
  import { N as OpenAICompletionsCompat, k as Model, l as CacheRetention } from "./types-DvzmWW8J.mjs";
2
- import "./types-BuiEBM3u.mjs";
2
+ import "./types-UlNana-2.mjs";
3
3
  //#region packages/ai/src/providers/openai-prompt-cache.d.ts
4
4
  /** Selects documented lifetime fields shared by Responses and Chat Completions. */
5
5
  declare function resolveOpenAIPromptCacheParams(model: Pick<Model, "id" | "provider" | "baseUrl">, cacheRetention: CacheRetention, compat: Required<Pick<OpenAICompletionsCompat, "supportsPromptCacheKey" | "supportsLongCacheRetention">>): {
@@ -1,14 +1,14 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-BhDjJH2R.mjs";
2
2
  import { t as AssistantMessageEventStream } from "./event-stream-C5AbCAaZ.mjs";
3
- import { n as clampOpenAIPromptCacheKey, r as resolveOpenAIPromptCacheParams } from "./openai-prompt-cache-I8YQTzf8.mjs";
4
- import { i as resolveOpenAICompletionsCompat } from "./openai-completions-compat-BdmlhD4u.mjs";
3
+ import { n as clampOpenAIPromptCacheKey, r as resolveOpenAIPromptCacheParams } from "./openai-prompt-cache-BK6E2g4Q.mjs";
4
+ import { i as resolveOpenAICompletionsCompat } from "./openai-completions-compat-GMN8A0fm.mjs";
5
5
  import { i as resolveCacheRetention, r as buildCopilotDynamicHeaders } from "./cloudflare-5qSGvIUH.mjs";
6
- import { n as buildBaseOptions } from "./simple-options-BkKTXxhp.mjs";
7
- import { g as resolveOpenAISimpleReasoningEffort } from "./openai-transport-params-JFsnIyto.mjs";
6
+ import { n as buildBaseOptions } from "./simple-options-7QuSKriJ.mjs";
7
+ import { g as resolveOpenAISimpleReasoningEffort } from "./openai-transport-params-D7JMUPjf.mjs";
8
8
  import { n as getEnvApiKey } from "./env-api-keys-CyX4VKGO.mjs";
9
- import { t as createAssistantOutput } from "./assistant-output-OLm-Oln0.mjs";
10
- import { i as createOpenAIProviderClient, n as resolveProviderSimpleCompletionHeaders } from "./provider-transport-turn-state-_M2kLdUE.mjs";
11
- import { P as convertProviderResponsesMessages, n as applyResponsesServiceTierPricing, r as runResponsesStreamLifecycle, t as applyCommonResponsesParams } from "./openai-responses-shared-C7oVyjED.mjs";
9
+ import { t as createAssistantOutput } from "./assistant-output-D5762GPH.mjs";
10
+ import { i as createOpenAIProviderClient, n as resolveProviderSimpleCompletionHeaders } from "./provider-transport-turn-state-BX6TfCyW.mjs";
11
+ import { P as convertProviderResponsesMessages, n as applyResponsesServiceTierPricing, r as runResponsesStreamLifecycle, t as applyCommonResponsesParams } from "./openai-responses-shared-CKNmC3vC.mjs";
12
12
  import { t as requireApiKey } from "./required-api-key-D4kn3252.mjs";
13
13
  //#region packages/ai/src/providers/openai-responses.ts
14
14
  var openai_responses_exports = /* @__PURE__ */ __exportAll({
@@ -1,7 +1,7 @@
1
- import "./index-a8e_oKnu.mjs";
1
+ import "./index-D27wAoOr.mjs";
2
2
  import { a as AssistantMessage, k as Model } from "./types-DvzmWW8J.mjs";
3
- import "./provider-options-D5ABCV_l.mjs";
4
- import { i as ReplayableResponseCompactionItem, l as OpenAIResponsesCompactionOutput, r as OpenAIResponsesReasoningReplayMetadata } from "./openai-responses-contracts-Br5IIw_h.mjs";
3
+ import "./provider-options-CkieKvNJ.mjs";
4
+ import { i as ReplayableResponseCompactionItem, l as OpenAIResponsesCompactionOutput, r as OpenAIResponsesReasoningReplayMetadata } from "./openai-responses-contracts-D5yVZBp-.mjs";
5
5
  import "openai/resources/responses/responses.js";
6
6
  //#region packages/ai/src/transports/openai-responses-compaction-replay.d.ts
7
7
  declare function captureOpenAIResponsesCompaction(output: Pick<AssistantMessage, "providerReplay">, item: ReplayableResponseCompactionItem, boundary: number | "retained-users", model: Model, captureMetadata?: OpenAIResponsesReasoningReplayMetadata, compactedOutput?: OpenAIResponsesCompactionOutput): void;
@@ -94,13 +94,13 @@ function resolveOpenAIResponsesServerCompactionPlan(model, extraParams) {
94
94
  threshold: enabled ? parsePositiveInteger(extraParams?.responsesCompactThreshold) ?? resolveOpenAIResponsesCompactThreshold(model) : void 0
95
95
  };
96
96
  }
97
- /** Resolve the Responses compact-endpoint gate for one route and compaction purpose. */
98
- function resolveOpenAIResponsesCompactEndpointPlan(model, extraParams, purpose = "manual") {
97
+ /** Resolve the Responses compact-endpoint gate for one route. */
98
+ function resolveOpenAIResponsesCompactEndpointPlan(model, extraParams, _purpose) {
99
99
  const configured = extraParams?.responsesCompactEndpoint;
100
100
  const provider = typeof model.provider === "string" ? normalizeProviderId(model.provider) : "";
101
101
  const api = normalizeOptionalLowercaseString(model.api);
102
102
  const endpointClass = resolveOpenAIResponsesEndpointClass(model.baseUrl);
103
- const enabledByDefault = (provider === "xai" || provider === "x-ai") && endpointClass === "xai-native" || purpose === "budget" && provider === "openai" && api === "openai-responses" && endpointClass === "openai-public";
103
+ const enabledByDefault = (provider === "xai" || provider === "x-ai") && endpointClass === "xai-native" || provider === "openai" && api === "openai-responses" && endpointClass === "openai-public";
104
104
  return { enabled: isOpenAIResponsesApi(api) && configured !== false && (configured === true || enabledByDefault) };
105
105
  }
106
106
  function stripDisabledOpenAIReasoningPayload(payloadObj) {
@@ -1,7 +1,7 @@
1
- import "./index-a8e_oKnu.mjs";
1
+ import "./index-D27wAoOr.mjs";
2
2
  import { M as ModelThinkingLevel, k as Model, n as Api } from "./types-DvzmWW8J.mjs";
3
- import { a as BaseOpenAIStreamOptions, f as OpenAIReasoningEffort } from "./provider-options-D5ABCV_l.mjs";
4
- import "./types-BuiEBM3u.mjs";
3
+ import { a as BaseOpenAIStreamOptions, p as OpenAIReasoningEffort } from "./provider-options-CkieKvNJ.mjs";
4
+ import "./types-UlNana-2.mjs";
5
5
  import { ResponseCompactionItem, ResponseCreateParamsStreaming, ResponseInputItem } from "openai/resources/responses/responses.js";
6
6
  //#region packages/ai/src/providers/openai-request-reasoning.d.ts
7
7
  type OpenAIRequestReasoningEffort = ModelThinkingLevel | "none";
@@ -0,0 +1,11 @@
1
+ //#region packages/ai/src/transports/openai-responses-endpoint.ts
2
+ function isOfficialOpenAIResponsesBaseUrl(baseUrl) {
3
+ if (!baseUrl) return false;
4
+ const url = URL.parse(baseUrl);
5
+ return url !== null && url.origin === "https://api.openai.com" && url.username === "" && url.password === "" && url.search === "" && url.hash === "" && url.pathname.replace(/\/+$/, "") === "/v1";
6
+ }
7
+ function supportsNativeOpenAIResponsesEndpoint(params) {
8
+ return params.provider.trim().toLowerCase() === "openai" && params.api === "openai-responses" && isOfficialOpenAIResponsesBaseUrl(params.baseUrl);
9
+ }
10
+ //#endregion
11
+ export { supportsNativeOpenAIResponsesEndpoint as n, isOfficialOpenAIResponsesBaseUrl as t };
@@ -32,8 +32,10 @@ declare function resolveOpenAIResponsesServerCompactionPlan(model: OpenAIRespons
32
32
  enabled: boolean;
33
33
  threshold: number | undefined;
34
34
  };
35
- /** Resolve the Responses compact-endpoint gate for one route and compaction purpose. */
36
- declare function resolveOpenAIResponsesCompactEndpointPlan(model: OpenAIResponsesPayloadModel, extraParams?: Record<string, unknown>, purpose?: "manual" | "budget"): {
35
+ /** Resolve the Responses compact-endpoint gate for one route. */
36
+ declare function resolveOpenAIResponsesCompactEndpointPlan(model: OpenAIResponsesPayloadModel, extraParams?: Record<string, unknown>,
37
+ /** @deprecated The policy no longer depends on purpose. */
38
+ _purpose?: "manual" | "budget"): {
37
39
  enabled: boolean;
38
40
  };
39
41
  /** Resolve payload mutation policy for one OpenAI Responses-style model endpoint. */
@@ -1,6 +1,6 @@
1
1
  import { h as responsesPromptObserver } from "./openai-responses-contracts-BKu8O7l4.mjs";
2
- import { v as sanitizeTransportPayloadText } from "./transport-stream-shared-CxXXz_Dd.mjs";
3
- import { C as stripSystemPromptCacheBoundary } from "./simple-options-BkKTXxhp.mjs";
2
+ import { v as sanitizeTransportPayloadText } from "./transport-stream-shared-CCR7hSW0.mjs";
3
+ import { C as stripSystemPromptCacheBoundary } from "./simple-options-7QuSKriJ.mjs";
4
4
  //#region packages/ai/src/transports/openai-responses-prompt-observer-internal.ts
5
5
  function readFinalResponsesPrompt(request) {
6
6
  if (typeof request.instructions === "string") return ["instructions", request.instructions];