@openclaw/ai 2026.8.1-beta.1 → 2026.8.1-beta.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 (86) hide show
  1. package/dist/{anthropic-CE-7SkF6.mjs → anthropic-B6dLpq5L.mjs} +37 -22
  2. package/dist/{src-QkygScBs.mjs → anthropic-JsNA5KCu.mjs} +0 -1
  3. package/dist/{anthropic-usage-Ma4iX6uG.mjs → anthropic-compaction-replay-8lJNKXOE.mjs} +225 -102
  4. package/dist/anthropic-payload-policy-CiEuQS72.d.mts +49 -0
  5. package/dist/{api-registry-EpJoVwM1.d.mts → api-registry-k3zTz0cV.d.mts} +1 -1
  6. package/dist/{azure-openai-responses-Cc_kasye.mjs → azure-openai-responses-mxIOtUnn.mjs} +23 -29
  7. package/dist/diagnostics.d.mts +24 -1
  8. package/dist/diagnostics.mjs +2 -1
  9. package/dist/{event-stream-DRmDMRHH.d.mts → event-stream-BP6AWT8j.d.mts} +3 -1
  10. package/dist/{event-stream-CEV9t6da.mjs → event-stream-uSMZJ3FA.mjs} +16 -3
  11. package/dist/event-stream.d.mts +1 -1
  12. package/dist/event-stream.mjs +1 -1
  13. package/dist/{google-CGQu21aw.mjs → google-C7h2QzDX.mjs} +4 -4
  14. package/dist/{google-shared-Cq2UKx1l.mjs → google-shared-B0Qr9OR7.mjs} +9 -18
  15. package/dist/google-thinking-level-C-V3tecN.mjs +9 -0
  16. package/dist/{google-vertex-CusxWzvE.mjs → google-vertex-Bhc3TjDl.mjs} +5 -4
  17. package/dist/{llm-request-activity-BjtkplhG.mjs → headers-DdOQtGuU.mjs} +9 -1
  18. package/dist/{host-Bl7Kgddo.mjs → host-DTqNc7ad.mjs} +227 -168
  19. package/dist/{host-Dn4_SZI2.d.mts → host-vWgMMhiJ.d.mts} +9 -4
  20. package/dist/index.d.mts +6 -6
  21. package/dist/index.mjs +7 -5
  22. package/dist/internal/anthropic.d.mts +13 -5
  23. package/dist/internal/anthropic.mjs +5 -5
  24. package/dist/internal/openai-responses-payload-policy.d.mts +3 -0
  25. package/dist/internal/openai-responses-payload-policy.mjs +3 -0
  26. package/dist/internal/openai.d.mts +6 -6
  27. package/dist/internal/openai.mjs +8 -7
  28. package/dist/internal/runtime.d.mts +17 -5
  29. package/dist/internal/runtime.mjs +85 -73
  30. package/dist/internal/shared.d.mts +1 -6
  31. package/dist/internal/shared.mjs +3 -4
  32. package/dist/{json-parse-BvXNt1-7.mjs → json-parse-CDnesDM_.mjs} +4 -6
  33. package/dist/{mistral-Dx6VzNjf.mjs → mistral-CEWoQI_g.mjs} +26 -45
  34. package/dist/{number-coercion-1Miyb5MO.mjs → number-coercion-H9qHik3g.mjs} +7 -2
  35. package/dist/openai-chatgpt-jwt-KWcgd0d_.mjs +19 -0
  36. package/dist/{openai-chatgpt-responses-SC9m0FSf.mjs → openai-chatgpt-responses-CrPmqERt.mjs} +225 -144
  37. package/dist/{openai-completions-BaIpl93j.mjs → openai-completions-BPnt4Sml.mjs} +28 -43
  38. package/dist/openai-completions-compat-Dt3dcawL.d.mts +43 -0
  39. package/dist/{openai-responses-Bdx3V_Yu.mjs → openai-responses-DhIKtOup.mjs} +17 -24
  40. package/dist/openai-responses-contracts-CyfIkQi5.mjs +253 -0
  41. package/dist/openai-responses-contracts-XpZJxrRG.d.mts +68 -0
  42. package/dist/openai-responses-payload-policy-BDxV-W0c.mjs +206 -0
  43. package/dist/openai-responses-payload-policy-BSs371VM.d.mts +40 -0
  44. package/dist/{openai-responses-prompt-observer-internal-DDZPxRfr.mjs → openai-responses-prompt-observer-internal-DgNTYnRY.mjs} +3 -3
  45. package/dist/{openai-responses-stream-internal-Bl8YyVtF.mjs → openai-responses-shared-DXIt3iY5.mjs} +1211 -908
  46. package/dist/{openai-reasoning-compat-DKebnIBL.mjs → openai-stop-reason-BkFkqqK0.mjs} +198 -172
  47. package/dist/{openai-transport-shared-Cipt7egQ.mjs → openai-tool-projection-CY04OcvQ.mjs} +151 -128
  48. package/dist/provider-error-BUwEnjXq.mjs +429 -0
  49. package/dist/provider-error-CzNw4BWX.d.mts +12 -0
  50. package/dist/{provider-options-C5kYML7i.d.mts → provider-options-B96RdNpH.d.mts} +9 -3
  51. package/dist/provider-transcript-transform-ePx-Bbfr.mjs +155 -0
  52. package/dist/provider-types.d.mts +31 -0
  53. package/dist/provider-types.mjs +8 -0
  54. package/dist/providers.d.mts +1 -1
  55. package/dist/providers.mjs +17 -19
  56. package/dist/{reasoning-tag-text-partitioner-CGDyLWUR.mjs → reasoning-tag-text-partitioner-rnPwX2pg.mjs} +14 -8
  57. package/dist/record-coerce-DdXsgUd_.mjs +23 -0
  58. package/dist/{model-utils-Dau5dlgm.mjs → sanitize-unicode-BYqrYtC_.mjs} +28 -2
  59. package/dist/session-resources-CkR4WWy1.mjs +21 -0
  60. package/dist/simple-options-D58D5Kvw.mjs +117 -0
  61. package/dist/src-D2H6yKkH.mjs +2 -0
  62. package/dist/{stream-first-event-timeout-BIBomOGq.mjs → stream-first-event-timeout-MK28puvq.mjs} +2 -2
  63. package/dist/string-coerce-fsri9iCu.mjs +34 -0
  64. package/dist/{tool-schema-json-projection-B1b-XCn5.mjs → tool-schema-json-projection-q5d7QX5c.mjs} +5 -7
  65. package/dist/transport-utils-DJqkxbhC.mjs +138 -0
  66. package/dist/transports.d.mts +135 -178
  67. package/dist/transports.mjs +1732 -1294
  68. package/dist/types-BDdaOVi2.mjs +6 -0
  69. package/dist/{types-CH7ReIcU.d.mts → types-BHNrPS1l.d.mts} +19 -1
  70. package/dist/types.d.mts +4 -4
  71. package/dist/types.mjs +6 -4
  72. package/dist/utf16-slice-CvGodqok.mjs +29 -0
  73. package/dist/{validation-DAa_yFOM.mjs → validation-B61OhAio.mjs} +6 -6
  74. package/dist/{validation-CcPcuEbR.d.mts → validation-DT9SrFn3.d.mts} +1 -1
  75. package/dist/validation.d.mts +1 -1
  76. package/dist/validation.mjs +1 -1
  77. package/package.json +15 -1
  78. package/dist/headers-B_e4-1J0.mjs +0 -9
  79. package/dist/openai-chatgpt-jwt-DhAAzLkj.mjs +0 -39
  80. package/dist/openai-responses-contracts-BBKBfAqR.d.mts +0 -116
  81. package/dist/openai-responses-shared-CCyMvg7M.mjs +0 -403
  82. package/dist/provider-error-DI0Ts28U.mjs +0 -47
  83. package/dist/sanitize-unicode-DT5o51ur.mjs +0 -26
  84. package/dist/tool-result-text-Dvkp2Dus.mjs +0 -274
  85. package/dist/transform-messages-DfjpNXNQ.mjs +0 -2
  86. package/dist/transport-stream-shared-CPNv7A3r.mjs +0 -297
@@ -1,18 +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
- import { t as AssistantMessageEventStream } from "./event-stream-CEV9t6da.mjs";
4
- import { n as getAiTransportHost, r as resolveAiTransportHeaderSentinels } from "./host-Bl7Kgddo.mjs";
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";
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";
5
9
  import { n as clampOpenAIPromptCacheKey } from "./openai-prompt-cache-mZTCdRPo.mjs";
6
- import { c as buildBaseOptions, h as stripSystemPromptCacheBoundary } from "./tool-result-text-Dvkp2Dus.mjs";
7
- import { n as toErrorObject, t as createResponsesPromptEgressObserver } from "./openai-responses-prompt-observer-internal-DDZPxRfr.mjs";
8
- import { B as responsesPromptObserver, n as processResponsesStream, pt as supportsOpenAITemperature, t as ResponsesStreamFailure } from "./openai-responses-stream-internal-Bl8YyVtF.mjs";
9
- import { n as clampTimerTimeoutMs, o as resolveTimerTimeoutMs } from "./number-coercion-1Miyb5MO.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";
10
14
  import { parseRetryAfterHttpDateMs } from "./internal/retry-after.mjs";
11
- import { d as transportAbortError, f as MALFORMED_STREAMING_FRAGMENT_ERROR_MESSAGE } from "./transport-stream-shared-CPNv7A3r.mjs";
12
- import { i as getFirstStreamEventTimeoutMs, r as getFirstStreamEventTimeoutHandler, t as createFirstStreamEventAbortController } from "./stream-first-event-timeout-BIBomOGq.mjs";
13
- import { t as headersToRecord } from "./headers-B_e4-1J0.mjs";
14
- import { a as resolveResponsesReasoningEffort, i as createResponsesAssistantOutput, n as applyResponsesServiceTierPricing, r as convertResponsesMessages, s as convertResponsesToolPayload } from "./openai-responses-shared-CCyMvg7M.mjs";
15
- import { i as registerSessionResourceCleanup, n as resolveOpenAICodexAccountId } from "./openai-chatgpt-jwt-DhAAzLkj.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";
17
+ import { a as withFirstStreamEventTimeout, i as getFirstStreamEventTimeoutMs, r as getFirstStreamEventTimeoutHandler, t as createFirstStreamEventAbortController } from "./stream-first-event-timeout-MK28puvq.mjs";
18
+ import { n as registerSessionResourceCleanup } from "./session-resources-CkR4WWy1.mjs";
19
+ import "./diagnostics.mjs";
20
+ import { n as resolveOpenAICodexAccountId } from "./openai-chatgpt-jwt-KWcgd0d_.mjs";
16
21
  import { t as createSseByteGuard } from "./streaming-byte-guard-BrbkbwUu.mjs";
17
22
  import { t as inspectTlsCertificateError } from "./tls-certificate-errors-DXSpluKI.mjs";
18
23
  //#region packages/ai/src/internal/retry-sleep.ts
@@ -35,6 +40,63 @@ function sleepWithAbort(ms, signal) {
35
40
  });
36
41
  }
37
42
  //#endregion
43
+ //#region packages/ai/src/providers/openai-chatgpt-responses-protocol.ts
44
+ const OPENAI_CHATGPT_RESPONSES_SUCCESS_BODY_MAX_BYTES = 16 * 1024 * 1024;
45
+ var CodexProtocolError = class extends Error {
46
+ constructor(message, options) {
47
+ super(message);
48
+ this.name = "CodexProtocolError";
49
+ this.payload = options?.payload;
50
+ this.cause = options?.cause;
51
+ }
52
+ };
53
+ async function* parseOpenAIChatGptResponsesSse(response) {
54
+ if (!response.body) return;
55
+ const reader = response.body.getReader();
56
+ const guard = createSseByteGuard(reader, {
57
+ maxBytes: OPENAI_CHATGPT_RESPONSES_SUCCESS_BODY_MAX_BYTES,
58
+ onOverflow: ({ size, maxBytes }) => /* @__PURE__ */ new Error(`OpenAI ChatGPT Responses success body exceeded ${maxBytes} bytes (received ${size})`)
59
+ });
60
+ const decoder = new TextDecoder();
61
+ let buffer = "";
62
+ try {
63
+ while (true) {
64
+ const { done, value } = await guard.read();
65
+ if (value) buffer += decoder.decode(value, { stream: true });
66
+ if (done) buffer += decoder.decode();
67
+ while (true) {
68
+ const searchable = !done && buffer.endsWith("\r") && !buffer.endsWith("\r\r") && !buffer.endsWith("\n\r") ? buffer.slice(0, -1) : buffer;
69
+ const boundary = /(?:\r\n|\r(?!\n)|\n)(?:\r\n|\r(?!\n)|\n)/.exec(searchable);
70
+ if (!boundary) break;
71
+ const chunk = buffer.slice(0, boundary.index);
72
+ buffer = buffer.slice(boundary.index + boundary[0].length);
73
+ const dataLines = chunk.split(/\r\n|\r|\n/).filter((line) => line.startsWith("data:")).map((line) => line.slice(5).trim());
74
+ if (dataLines.length > 0) {
75
+ const data = dataLines.join("\n").trim();
76
+ if (data && data !== "[DONE]") {
77
+ let event;
78
+ try {
79
+ event = JSON.parse(data);
80
+ } catch (cause) {
81
+ if (!(cause instanceof SyntaxError)) throw cause;
82
+ throw new CodexProtocolError(MALFORMED_STREAMING_FRAGMENT_ERROR_MESSAGE, { cause });
83
+ }
84
+ yield event;
85
+ }
86
+ }
87
+ }
88
+ if (done) break;
89
+ }
90
+ } finally {
91
+ try {
92
+ await guard.cancel();
93
+ } catch {}
94
+ try {
95
+ reader.releaseLock();
96
+ } catch {}
97
+ }
98
+ }
99
+ //#endregion
38
100
  //#region packages/ai/src/providers/openai-chatgpt-responses.ts
39
101
  const dynamicImport = (specifier) => import(specifier);
40
102
  function loadNodeOs() {
@@ -50,7 +112,6 @@ const CODEX_TOOL_CALL_PROVIDERS = /* @__PURE__ */ new Set(["openai", "opencode"]
50
112
  const WEBSOCKET_MESSAGE_TOO_BIG_CLOSE_CODE = 1009;
51
113
  const WEBSOCKET_CONNECTION_LIMIT_REACHED_CODE = "websocket_connection_limit_reached";
52
114
  const OPENAI_CHATGPT_RESPONSES_ERROR_BODY_MAX_BYTES = 16 * 1024;
53
- const OPENAI_CHATGPT_RESPONSES_SUCCESS_BODY_MAX_BYTES = 16 * 1024 * 1024;
54
115
  const CODEX_RESPONSE_STATUSES = /* @__PURE__ */ new Set([
55
116
  "completed",
56
117
  "incomplete",
@@ -123,9 +184,17 @@ const streamOpenAICodexResponses = (model, context, options) => {
123
184
  const modelHeaders = resolveAiTransportHeaderSentinels(model.headers);
124
185
  const optionHeaders = resolveAiTransportHeaderSentinels(options?.headers);
125
186
  const accountId = extractOpenAICodexAccountId(apiKey);
126
- let body = buildRequestBody(model, context, options);
127
- const nextBody = await options?.onPayload?.(body, model);
128
- if (nextBody !== void 0) body = nextBody;
187
+ const buildBody = async (replayMode) => {
188
+ let body = buildRequestBody(model, context, options, replayMode);
189
+ const nextBody = await options?.onPayload?.(body, model);
190
+ if (nextBody !== void 0) body = nextBody;
191
+ return body;
192
+ };
193
+ let semanticAttempt = {
194
+ kind: "initial",
195
+ request: await buildBody("checkpoint")
196
+ };
197
+ const commitSemanticAttempt = (attempt) => commitResponsesEncryptedContentAttempt(attempt, (checkpoint) => suppressOpenAIResponsesCompaction(output, model, options, checkpoint));
129
198
  const observePromptEgress = createResponsesPromptEgressObserver(options, context.systemPrompt);
130
199
  const sessionId = clampOpenAIPromptCacheKey(options?.sessionId);
131
200
  requestTimeoutMs = resolveRequestTimeoutMs(options);
@@ -141,13 +210,19 @@ const streamOpenAICodexResponses = (model, context, options) => {
141
210
  if (transport !== "sse" && !websocketDisabledForSession) {
142
211
  const websocketHeaders = buildWebSocketHeaders(modelHeaders, optionHeaders, accountId, apiKey, sessionId || createCodexRequestId());
143
212
  let websocketStarted = false;
213
+ let websocketRequestSent = false;
144
214
  let retriedWebSocketConnectionLimit = false;
145
215
  while (true) {
216
+ const activeAttempt = semanticAttempt;
146
217
  websocketStarted = false;
218
+ websocketRequestSent = false;
147
219
  try {
148
- await processWebSocketStream(resolveCodexWebSocketUrl(model.baseUrl), body, websocketHeaders, output, stream, model, () => {
220
+ await processWebSocketStream(resolveCodexWebSocketUrl(model.baseUrl), activeAttempt.request, websocketHeaders, output, stream, model, () => {
221
+ commitSemanticAttempt(activeAttempt);
149
222
  websocketStarted = true;
150
- }, requestOptions, firstEventAbort.abort, observePromptEgress);
223
+ }, requestOptions, firstEventAbort.abort, observePromptEgress, activeAttempt.kind, () => {
224
+ websocketRequestSent = true;
225
+ });
151
226
  if (activeSignal?.aborted) throw transportAbortError(activeSignal);
152
227
  if (output.stopReason === "aborted" || output.stopReason === "error") throw new CodexApiError(output.errorMessage ?? "An unknown error occurred");
153
228
  stream.push({
@@ -159,6 +234,12 @@ const streamOpenAICodexResponses = (model, context, options) => {
159
234
  return;
160
235
  } catch (error) {
161
236
  const aborted = activeSignal?.aborted;
237
+ const nextSemanticAttempt = !aborted && websocketRequestSent && !websocketStarted && error instanceof CodexApiError && isInvalidEncryptedContentError(error) ? await resolveNextResponsesEncryptedContentAttempt(activeAttempt, error, { buildFullHistoryRequest: () => buildBody("full-history") }) : void 0;
238
+ if (nextSemanticAttempt) {
239
+ semanticAttempt = nextSemanticAttempt;
240
+ retriedWebSocketConnectionLimit = false;
241
+ continue;
242
+ }
162
243
  const connectionLimitBeforeStart = !websocketStarted && isWebSocketConnectionLimitReachedError(error);
163
244
  if (!aborted && connectionLimitBeforeStart && !retriedWebSocketConnectionLimit) {
164
245
  retriedWebSocketConnectionLimit = true;
@@ -170,7 +251,7 @@ const streamOpenAICodexResponses = (model, context, options) => {
170
251
  fallbackTransport: transport === "auto" && !websocketStarted ? "sse" : void 0,
171
252
  eventsEmitted: websocketStarted,
172
253
  phase: websocketStarted ? "after_message_stream_start" : "before_message_stream_start",
173
- requestBytes: new TextEncoder().encode(JSON.stringify(body)).byteLength
254
+ requestBytes: new TextEncoder().encode(JSON.stringify(activeAttempt.request)).byteLength
174
255
  }));
175
256
  if (transport === "auto" && options?.sessionId) websocketSseFallbackSessions.add(options.sessionId);
176
257
  if (websocketStarted || transport !== "auto") throw error;
@@ -178,64 +259,102 @@ const streamOpenAICodexResponses = (model, context, options) => {
178
259
  }
179
260
  }
180
261
  }
181
- const sseHeaders = buildSSEHeaders(modelHeaders, optionHeaders, accountId, apiKey, sessionId);
182
- const bodyJson = JSON.stringify(body);
183
- const compressedBody = model.provider === "openai" && !sseHeaders.has("content-encoding") ? compressRequestBodyZstd(bodyJson) : null;
184
- if (compressedBody) sseHeaders.set("content-encoding", "zstd");
185
- const sseBody = compressedBody ?? bodyJson;
186
262
  let response;
187
- let lastError;
188
263
  const maxRetries = options?.maxRetries ?? DEFAULT_MAX_RETRIES;
189
- for (let attempt = 0; attempt <= maxRetries; attempt++) {
190
- if (activeSignal?.aborted) throw transportAbortError(activeSignal);
191
- let attemptResponse;
192
- let errorText;
193
- try {
194
- observePromptEgress?.(body, {
264
+ while (true) {
265
+ const activeAttempt = semanticAttempt;
266
+ response = void 0;
267
+ const sseHeaders = buildSSEHeaders(modelHeaders, optionHeaders, accountId, apiKey, sessionId);
268
+ const bodyJson = JSON.stringify(activeAttempt.request);
269
+ const compressedBody = model.provider === "openai" && !sseHeaders.has("content-encoding") ? compressRequestBodyZstd(bodyJson) : null;
270
+ if (compressedBody) sseHeaders.set("content-encoding", "zstd");
271
+ const sseBody = compressedBody ?? bodyJson;
272
+ let terminalResponseError;
273
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
274
+ if (activeSignal?.aborted) throw transportAbortError(activeSignal);
275
+ observePromptEgress?.(activeAttempt.request, {
195
276
  egress: "native-codex-sse",
196
- payloadVariant: "initial"
197
- });
198
- attemptResponse = await fetch(resolveCodexUrl(model.baseUrl), {
199
- method: "POST",
200
- headers: sseHeaders,
201
- body: sseBody,
202
- signal: activeSignal
277
+ payloadVariant: activeAttempt.kind
203
278
  });
279
+ let attemptResponse;
280
+ try {
281
+ attemptResponse = await fetch(resolveCodexUrl(model.baseUrl), {
282
+ method: "POST",
283
+ headers: sseHeaders,
284
+ body: sseBody,
285
+ signal: activeSignal
286
+ });
287
+ } catch (error) {
288
+ if (error instanceof Error) {
289
+ if (isRequestTimeoutError(error, options?.signal, requestTimeoutSignal, requestTimeoutMs) && requestTimeoutMs !== void 0) throw formatRequestTimeoutError(requestTimeoutMs, error);
290
+ if (error.name === "AbortError" || error.message === "Request was aborted") throw new Error("Request was aborted", { cause: error });
291
+ if (error.name === "TimeoutError" && requestTimeoutMs !== void 0) throw new Error(`Request timed out after ${requestTimeoutMs}ms`, { cause: error });
292
+ }
293
+ const tlsCertificateError = inspectTlsCertificateError(error);
294
+ const lastError = toErrorObject(error, String(error));
295
+ if (attempt < maxRetries && !lastError.message.includes("usage limit") && !tlsCertificateError) {
296
+ await sleepWithAbort(BASE_DELAY_MS * 2 ** attempt, activeSignal);
297
+ continue;
298
+ }
299
+ throw lastError;
300
+ }
204
301
  response = attemptResponse;
205
- await options?.onResponse?.({
206
- status: attemptResponse.status,
207
- headers: headersToRecord(attemptResponse.headers)
208
- }, model);
209
302
  if (attemptResponse.ok) break;
210
- errorText = await readChatGptResponsesErrorTextLimited(attemptResponse);
211
- } catch (error) {
212
- if (error instanceof Error) {
213
- if (isRequestTimeoutError(error, options?.signal, requestTimeoutSignal, requestTimeoutMs) && requestTimeoutMs !== void 0) throw formatRequestTimeoutError(requestTimeoutMs, error);
214
- if (error.name === "AbortError" || error.message === "Request was aborted") throw new Error("Request was aborted", { cause: error });
215
- if (error.name === "TimeoutError" && requestTimeoutMs !== void 0) throw new Error(`Request timed out after ${requestTimeoutMs}ms`, { cause: error });
216
- }
217
- const tlsCertificateError = inspectTlsCertificateError(error);
218
- lastError = toErrorObject(error, String(error));
219
- if (attempt < maxRetries && !lastError.message.includes("usage limit") && !tlsCertificateError) {
220
- await sleepWithAbort(BASE_DELAY_MS * 2 ** attempt, activeSignal);
303
+ const hookStream = withFirstStreamEventTimeout(withProviderResponseHook({
304
+ signal: firstEventAbort.signal,
305
+ abort: firstEventAbort.abort,
306
+ hook: createOpenAIResponseHook(options?.onResponse, attemptResponse, model)
307
+ }), {
308
+ provider: model.provider,
309
+ api: model.api,
310
+ model: model.id,
311
+ timeoutMs: getFirstStreamEventTimeoutMs(options) ?? 0,
312
+ stage: "responses",
313
+ abort: firstEventAbort.abort,
314
+ onTimeout: getFirstStreamEventTimeoutHandler(options)
315
+ });
316
+ const [errorText] = await Promise.all([readChatGptResponsesErrorTextLimited(attemptResponse, activeSignal), hookStream[Symbol.asyncIterator]().next()]);
317
+ if (attempt < maxRetries && isRetryableError(attemptResponse.status, errorText)) {
318
+ await sleepWithAbort(resolveHttpRetryDelayMs(attemptResponse, attempt), activeSignal);
221
319
  continue;
222
320
  }
223
- throw lastError;
321
+ const info = parseErrorResponseText(errorText, attemptResponse.status, attemptResponse.statusText);
322
+ terminalResponseError = new CodexApiError(info.friendlyMessage || info.message, { code: info.code });
323
+ break;
224
324
  }
225
- if (attempt < maxRetries && isRetryableError(attemptResponse.status, errorText)) {
226
- await sleepWithAbort(resolveHttpRetryDelayMs(attemptResponse, attempt), activeSignal);
227
- continue;
325
+ if (response?.ok) {
326
+ if (!response.body) throw new Error("No response body");
327
+ if (activeSignal?.aborted) throw transportAbortError(activeSignal);
328
+ commitSemanticAttempt(activeAttempt);
329
+ break;
228
330
  }
229
- const info = parseErrorResponseText(errorText, attemptResponse.status, attemptResponse.statusText);
230
- throw new Error(info.friendlyMessage || info.message);
331
+ if (activeSignal?.aborted) throw transportAbortError(activeSignal);
332
+ const nextSemanticAttempt = terminalResponseError ? await resolveNextResponsesEncryptedContentAttempt(activeAttempt, terminalResponseError, { buildFullHistoryRequest: () => buildBody("full-history") }) : void 0;
333
+ if (!nextSemanticAttempt) throw terminalResponseError ?? /* @__PURE__ */ new Error("Failed after retries");
334
+ semanticAttempt = nextSemanticAttempt;
231
335
  }
232
- if (!response?.ok) throw lastError ?? /* @__PURE__ */ new Error("Failed after retries");
233
- if (!response.body) throw new Error("No response body");
234
- stream.push({
235
- type: "start",
236
- partial: output
336
+ await processResponsesStream(withProviderResponseHook({
337
+ stream: mapCodexEvents(parseOpenAIChatGptResponsesSse(response)),
338
+ signal: firstEventAbort.signal,
339
+ abort: firstEventAbort.abort,
340
+ hook: createOpenAIResponseHook(options?.onResponse, response, model),
341
+ onReady: () => stream.push({
342
+ type: "start",
343
+ partial: output
344
+ })
345
+ }), output, stream, model, {
346
+ serviceTier: options?.serviceTier,
347
+ firstEventTimeoutMs: getFirstStreamEventTimeoutMs(options),
348
+ abortFirstEventStream: firstEventAbort.abort,
349
+ onFirstEventTimeout: getFirstStreamEventTimeoutHandler(options),
350
+ signal: options?.signal,
351
+ reasoningReplayMetadata: buildOpenAIResponsesReasoningReplayMetadata(model, {
352
+ sessionId: options?.sessionId,
353
+ authProfileId: options?.authProfileId
354
+ }),
355
+ resolveServiceTier: resolveCodexServiceTier,
356
+ applyServiceTierPricing: (usage, serviceTier) => applyResponsesServiceTierPricing(usage, serviceTier, model)
237
357
  });
238
- await processStream(response, output, stream, model, options, firstEventAbort.abort);
239
358
  if (activeSignal?.aborted) throw transportAbortError(activeSignal);
240
359
  if (output.stopReason === "aborted" || output.stopReason === "error") throw new Error(output.errorMessage ?? "An unknown error occurred");
241
360
  stream.push({
@@ -247,11 +366,11 @@ const streamOpenAICodexResponses = (model, context, options) => {
247
366
  } catch (error) {
248
367
  const normalizedError = isRequestTimeoutError(error, options?.signal, requestTimeoutSignal, requestTimeoutMs) && requestTimeoutMs !== void 0 ? formatRequestTimeoutError(requestTimeoutMs, error) : error;
249
368
  for (const block of output.content) delete block.partialJson;
250
- output.stopReason = options?.signal?.aborted ? "aborted" : "error";
251
- output.errorMessage = normalizedError instanceof Error ? normalizedError.message : String(normalizedError);
369
+ const terminal = projectProviderError(normalizedError, options?.signal);
370
+ Object.assign(output, terminal);
252
371
  stream.push({
253
372
  type: "error",
254
- reason: output.stopReason,
373
+ reason: terminal.stopReason,
255
374
  error: output
256
375
  });
257
376
  stream.end();
@@ -266,15 +385,19 @@ const streamSimpleOpenAICodexResponses = (model, context, options) => {
266
385
  if (!apiKey) throw new Error(`No API key for provider: ${model.provider}`);
267
386
  const resolvedOptions = {
268
387
  ...buildBaseOptions(model, options, apiKey),
388
+ authProfileId: options?.authProfileId,
269
389
  reasoningEffort: resolveResponsesReasoningEffort(model, options?.reasoning)
270
390
  };
271
391
  responsesPromptObserver.copy(options, resolvedOptions);
272
392
  return streamOpenAICodexResponses(model, context, resolvedOptions);
273
393
  };
274
- function buildRequestBody(model, context, options) {
394
+ function buildRequestBody(model, context, options, replayMode = "checkpoint") {
275
395
  const messages = convertResponsesMessages(model, context, CODEX_TOOL_CALL_PROVIDERS, {
276
396
  includeSystemPrompt: false,
277
- replayResponsesItemIds: false
397
+ replayResponsesItemIds: false,
398
+ sessionId: options?.sessionId,
399
+ authProfileId: options?.authProfileId,
400
+ replayMode
278
401
  });
279
402
  const body = {
280
403
  model: model.id,
@@ -321,17 +444,6 @@ function resolveCodexWebSocketUrl(baseUrl) {
321
444
  if (url.protocol === "http:") url.protocol = "ws:";
322
445
  return url.toString();
323
446
  }
324
- async function processStream(response, output, stream, model, options, abortFirstEventStream) {
325
- await processResponsesStream(mapCodexEvents(parseSSE(response)), output, stream, model, {
326
- serviceTier: options?.serviceTier,
327
- firstEventTimeoutMs: getFirstStreamEventTimeoutMs(options),
328
- abortFirstEventStream,
329
- onFirstEventTimeout: getFirstStreamEventTimeoutHandler(options),
330
- signal: options?.signal,
331
- resolveServiceTier: resolveCodexServiceTier,
332
- applyServiceTierPricing: (usage, serviceTier) => applyResponsesServiceTierPricing(usage, serviceTier, model)
333
- });
334
- }
335
447
  var CodexApiError = class extends Error {
336
448
  constructor(message, options) {
337
449
  super(message);
@@ -341,14 +453,6 @@ var CodexApiError = class extends Error {
341
453
  this.cause = options?.cause;
342
454
  }
343
455
  };
344
- var CodexProtocolError = class extends Error {
345
- constructor(message, options) {
346
- super(message);
347
- this.name = "CodexProtocolError";
348
- this.payload = options?.payload;
349
- this.cause = options?.cause;
350
- }
351
- };
352
456
  function isCodexNonTransportError(error) {
353
457
  return error instanceof CodexApiError || error instanceof CodexProtocolError || error instanceof ResponsesStreamFailure;
354
458
  }
@@ -393,53 +497,6 @@ function normalizeCodexStatus(status) {
393
497
  if (typeof status !== "string") return;
394
498
  return CODEX_RESPONSE_STATUSES.has(status) ? status : void 0;
395
499
  }
396
- async function* parseSSE(response) {
397
- if (!response.body) return;
398
- const reader = response.body.getReader();
399
- const guard = createSseByteGuard(reader, {
400
- maxBytes: OPENAI_CHATGPT_RESPONSES_SUCCESS_BODY_MAX_BYTES,
401
- onOverflow: ({ size, maxBytes }) => /* @__PURE__ */ new Error(`OpenAI ChatGPT Responses success body exceeded ${maxBytes} bytes (received ${size})`)
402
- });
403
- const decoder = new TextDecoder();
404
- let buffer = "";
405
- try {
406
- while (true) {
407
- const { done, value } = await guard.read();
408
- if (value) buffer += decoder.decode(value, { stream: true });
409
- if (done) buffer += decoder.decode();
410
- while (true) {
411
- const searchable = !done && buffer.endsWith("\r") && !buffer.endsWith("\r\r") && !buffer.endsWith("\n\r") ? buffer.slice(0, -1) : buffer;
412
- const boundary = /(?:\r\n|\r(?!\n)|\n)(?:\r\n|\r(?!\n)|\n)/.exec(searchable);
413
- if (!boundary) break;
414
- const chunk = buffer.slice(0, boundary.index);
415
- buffer = buffer.slice(boundary.index + boundary[0].length);
416
- const dataLines = chunk.split(/\r\n|\r|\n/).filter((l) => l.startsWith("data:")).map((l) => l.slice(5).trim());
417
- if (dataLines.length > 0) {
418
- const data = dataLines.join("\n").trim();
419
- if (data && data !== "[DONE]") {
420
- let event;
421
- try {
422
- event = JSON.parse(data);
423
- } catch (cause) {
424
- if (!(cause instanceof SyntaxError)) throw cause;
425
- throw new CodexProtocolError(MALFORMED_STREAMING_FRAGMENT_ERROR_MESSAGE, { cause });
426
- }
427
- yield event;
428
- }
429
- }
430
- }
431
- if (done) break;
432
- }
433
- } finally {
434
- try {
435
- await guard.cancel();
436
- } catch {}
437
- try {
438
- reader.releaseLock();
439
- } catch {}
440
- }
441
- }
442
- const parseSSEForTest = parseSSE;
443
500
  const OPENAI_BETA_RESPONSES_WEBSOCKETS = "responses_websockets=2026-02-06";
444
501
  const SESSION_WEBSOCKET_CACHE_TTL_MS = 300 * 1e3;
445
502
  const SESSION_WEBSOCKET_MAX_AGE_MS = 3300 * 1e3;
@@ -829,7 +886,7 @@ async function* startWebSocketOutputOnFirstEvent(events, output, stream, onStart
829
886
  yield event;
830
887
  }
831
888
  }
832
- async function processWebSocketStream(url, body, headers, output, stream, model, onStart, options, abortFirstEventStream, observePromptEgress) {
889
+ async function processWebSocketStream(url, body, headers, output, stream, model, onStart, options, abortFirstEventStream, observePromptEgress, payloadVariant = "initial", onRequestSent) {
833
890
  const { socket, entry, release } = await acquireWebSocket(url, headers, options?.sessionId, options?.signal);
834
891
  let keepConnection = true;
835
892
  const useCachedContext = options?.transport === "websocket-cached" || options?.transport === "auto";
@@ -839,18 +896,23 @@ async function processWebSocketStream(url, body, headers, output, stream, model,
839
896
  if (options?.signal?.aborted) throw transportAbortError(options.signal);
840
897
  observePromptEgress?.(requestBody, {
841
898
  egress: "native-codex-websocket",
842
- payloadVariant: "initial"
899
+ payloadVariant
843
900
  });
844
901
  socket.send(JSON.stringify({
845
902
  type: "response.create",
846
903
  ...requestBody
847
904
  }));
905
+ onRequestSent?.();
848
906
  await processResponsesStream(startWebSocketOutputOnFirstEvent(mapCodexEvents(parseWebSocket(socket, options?.signal)), output, stream, onStart), output, stream, model, {
849
907
  serviceTier: options?.serviceTier,
850
908
  firstEventTimeoutMs: getFirstStreamEventTimeoutMs(options),
851
909
  abortFirstEventStream,
852
910
  onFirstEventTimeout: getFirstStreamEventTimeoutHandler(options),
853
911
  signal: options?.signal,
912
+ reasoningReplayMetadata: buildOpenAIResponsesReasoningReplayMetadata(model, {
913
+ sessionId: options?.sessionId,
914
+ authProfileId: options?.authProfileId
915
+ }),
854
916
  resolveServiceTier: resolveCodexServiceTier,
855
917
  applyServiceTierPricing: (usage, serviceTier) => applyResponsesServiceTierPricing(usage, serviceTier, model)
856
918
  });
@@ -858,7 +920,9 @@ async function processWebSocketStream(url, body, headers, output, stream, model,
858
920
  else if (useCachedContext && entry && output.responseId) {
859
921
  const responseItems = convertResponsesMessages(model, { messages: [output] }, CODEX_TOOL_CALL_PROVIDERS, {
860
922
  includeSystemPrompt: false,
861
- replayResponsesItemIds: false
923
+ replayResponsesItemIds: false,
924
+ sessionId: options?.sessionId,
925
+ authProfileId: options?.authProfileId
862
926
  }).filter((item) => item.type !== "function_call_output");
863
927
  entry.continuation = {
864
928
  lastRequestBody: fullBody,
@@ -874,17 +938,31 @@ async function processWebSocketStream(url, body, headers, output, stream, model,
874
938
  release({ keep: keepConnection });
875
939
  }
876
940
  }
877
- async function readChatGptResponsesErrorTextLimited(response) {
941
+ async function readChatGptResponsesErrorTextLimited(response, signal) {
878
942
  const reader = response.body?.getReader();
879
943
  if (!reader) return "";
880
944
  const decoder = new TextDecoder();
881
945
  let total = 0;
882
946
  let text = "";
883
947
  let reachedLimit = false;
948
+ let completed = false;
949
+ let cancelPromise;
950
+ const cancel = () => {
951
+ cancelPromise ??= reader.cancel(signal?.reason).catch(() => {});
952
+ return cancelPromise;
953
+ };
954
+ const onAbort = () => {
955
+ cancel();
956
+ };
957
+ if (signal?.aborted) onAbort();
958
+ else signal?.addEventListener("abort", onAbort, { once: true });
884
959
  try {
885
960
  while (true) {
886
961
  const { value, done } = await reader.read();
887
- if (done) break;
962
+ if (done) {
963
+ completed = true;
964
+ break;
965
+ }
888
966
  if (!value || value.byteLength === 0) continue;
889
967
  const remaining = OPENAI_CHATGPT_RESPONSES_ERROR_BODY_MAX_BYTES - total;
890
968
  if (remaining <= 0) {
@@ -901,7 +979,8 @@ async function readChatGptResponsesErrorTextLimited(response) {
901
979
  }
902
980
  if (!reachedLimit) text += decoder.decode();
903
981
  } finally {
904
- if (reachedLimit) await reader.cancel().catch(() => {});
982
+ signal?.removeEventListener("abort", onAbort);
983
+ if (!completed) await cancel();
905
984
  try {
906
985
  reader.releaseLock();
907
986
  } catch {}
@@ -911,11 +990,12 @@ async function readChatGptResponsesErrorTextLimited(response) {
911
990
  function parseErrorResponseText(raw, status, statusText) {
912
991
  let message = raw || statusText || "Request failed";
913
992
  let friendlyMessage;
993
+ let code;
914
994
  try {
915
995
  const err = JSON.parse(raw)?.error;
916
996
  if (err) {
917
- const code = err.code || err.type || "";
918
- if (/usage_limit_reached|usage_not_included|rate_limit_exceeded/i.test(code) || status === 429) {
997
+ code = err.code || err.type || void 0;
998
+ if (/usage_limit_reached|usage_not_included|rate_limit_exceeded/i.test(code ?? "") || status === 429) {
919
999
  const plan = err.plan_type ? ` (${err.plan_type.toLowerCase()} plan)` : "";
920
1000
  const mins = err.resets_at ? Math.max(0, Math.round((err.resets_at * 1e3 - Date.now()) / 6e4)) : void 0;
921
1001
  friendlyMessage = `You have hit your ChatGPT usage limit${plan}.${mins !== void 0 ? ` Try again in ~${mins} min.` : ""}`.trim();
@@ -924,6 +1004,7 @@ function parseErrorResponseText(raw, status, statusText) {
924
1004
  }
925
1005
  } catch {}
926
1006
  return {
1007
+ ...code ? { code } : {},
927
1008
  message,
928
1009
  friendlyMessage
929
1010
  };
@@ -975,4 +1056,4 @@ function buildWebSocketHeaders(initHeaders, additionalHeaders, accountId, token,
975
1056
  return headers;
976
1057
  }
977
1058
  //#endregion
978
- export { closeOpenAICodexWebSocketSessions, extractOpenAICodexAccountId, parseSSEForTest, resetOpenAICodexWebSocketStateForTest, streamOpenAICodexResponses, streamSimpleOpenAICodexResponses };
1059
+ export { closeOpenAICodexWebSocketSessions, extractOpenAICodexAccountId, resetOpenAICodexWebSocketStateForTest, streamOpenAICodexResponses, streamSimpleOpenAICodexResponses };