@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,13 +1,21 @@
1
- import { _ as normalizeLowercaseStringOrEmpty, b as isRecord, v as normalizeOptionalString } from "./host-Bl7Kgddo.mjs";
2
- import { n as calculateCost } from "./model-utils-Dau5dlgm.mjs";
3
- import { a as isImageWithMediaPayload, h as stripSystemPromptCacheBoundary, o as truncateUtf16Safe, r as extractToolResultText, t as describeToolResultMediaPlaceholder } from "./tool-result-text-Dvkp2Dus.mjs";
4
- import { c as transformTransportMessages } from "./tool-schema-json-projection-B1b-XCn5.mjs";
5
- import { n as parseStreamingJson } from "./json-parse-BvXNt1-7.mjs";
6
- import { b as redactIdentifier, d as transportAbortError, l as sanitizeNonEmptyTransportPayloadText, u as sanitizeTransportPayloadText, x as redactSensitiveText } from "./transport-stream-shared-CPNv7A3r.mjs";
7
- import { i as log, n as createModelStreamCooperativeScheduler } from "./openai-transport-shared-Cipt7egQ.mjs";
8
- import { a as withFirstStreamEventTimeout } from "./stream-first-event-timeout-BIBomOGq.mjs";
1
+ import { a as normalizeOptionalString, n as normalizeLowercaseStringOrEmpty } from "./string-coerce-fsri9iCu.mjs";
2
+ import { i as clampThinkingLevel, r as calculateCost } from "./sanitize-unicode-BYqrYtC_.mjs";
3
+ import { a as describeToolResultMediaPlaceholder, l as isImageWithMediaPayload, n as getAiTransportHost, s as extractToolResultText } from "./host-DTqNc7ad.mjs";
4
+ import { a as isRecord, n as asNullableRecord } from "./record-coerce-DdXsgUd_.mjs";
5
+ import { t as truncateUtf16Safe } from "./utf16-slice-CvGodqok.mjs";
6
+ import { n as projectProviderError } from "./provider-error-BUwEnjXq.mjs";
7
+ import { t as asFiniteNumber } from "./number-coercion-H9qHik3g.mjs";
8
+ import { C as normalizeStringEntries, S as supportsOpenAITemperature, T as uniqueValues, a as OPENAI_RESPONSES_COMPACTION_REPLAY_TYPE, f as RESPONSE_FAILED_NO_DETAILS_MESSAGE, o as OPENAI_RESPONSES_REASONING_REPLAY_BLOCK_META_KEY, s as OPENAI_RESPONSES_REASONING_REPLAY_META_KEY, x as supportsOpenAIReasoningEffort, y as resolveOpenAIReasoningEffortForModel } from "./openai-responses-contracts-CyfIkQi5.mjs";
9
+ import { f as sortPromptCacheToolsByName, l as stripSystemPromptCacheBoundary } from "./simple-options-D58D5Kvw.mjs";
10
+ import { c as transformTransportMessages } from "./tool-schema-json-projection-q5d7QX5c.mjs";
11
+ import { n as parseStreamingJson } from "./json-parse-CDnesDM_.mjs";
12
+ import { n as notifyLlmRequestActivity } from "./headers-DdOQtGuU.mjs";
9
13
  import { t as shortHash } from "./hash-CHgqbJmD.mjs";
10
- import { randomUUID } from "node:crypto";
14
+ import { d as sanitizeTransportPayloadText, f as transportAbortError, p as withProviderResponseHook, t as transformProviderMessages, u as sanitizeNonEmptyTransportPayloadText } from "./provider-transcript-transform-ePx-Bbfr.mjs";
15
+ import { l as redactIdentifier, u as redactSensitiveText } from "./transport-utils-DJqkxbhC.mjs";
16
+ import { a as createModelStreamCooperativeScheduler, c as log, o as createOpenAIResponseHook, t as projectOpenAITools } 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 { createHash, randomUUID } from "node:crypto";
11
19
  //#region packages/ai/src/transports/json-unsafe-integers.ts
12
20
  /**
13
21
  * JSON parsing helpers that preserve integer literals larger than
@@ -92,37 +100,35 @@ function parseJsonPreservingUnsafeIntegers(input) {
92
100
  }
93
101
  /** Parses or accepts an object while preserving unsafe integer literals in string input. */
94
102
  function parseJsonObjectPreservingUnsafeIntegers(value) {
95
- if (typeof value === "string") {
96
- try {
97
- const parsed = parseJsonPreservingUnsafeIntegers(value);
98
- if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) return parsed;
99
- } catch {
100
- return null;
101
- }
103
+ if (typeof value === "string") try {
104
+ return asNullableRecord(parseJsonPreservingUnsafeIntegers(value));
105
+ } catch {
102
106
  return null;
103
107
  }
104
- if (value && typeof value === "object" && !Array.isArray(value)) return value;
105
- return null;
108
+ return asNullableRecord(value);
106
109
  }
107
110
  //#endregion
108
111
  //#region packages/ai/src/transports/model-transport-debug.ts
109
- function normalizeEnv(value) {
110
- return typeof value === "string" ? value.trim().toLowerCase() : "";
111
- }
112
+ /**
113
+ * Environment-driven debug controls for model transport logging.
114
+ *
115
+ * Model adapters share these helpers so payload, SSE, and transport diagnostics
116
+ * interpret OpenClaw debug environment variables consistently.
117
+ */
112
118
  function isTruthyEnv(value) {
113
- const normalized = normalizeEnv(value);
119
+ const normalized = normalizeLowercaseStringOrEmpty(value);
114
120
  return normalized.length > 0 && normalized !== "0" && normalized !== "false" && normalized !== "off" && normalized !== "no";
115
121
  }
116
122
  /** Resolves model payload debug verbosity from `OPENCLAW_DEBUG_MODEL_PAYLOAD`. */
117
123
  function resolveModelPayloadDebugMode(env = process.env) {
118
- const normalized = normalizeEnv(env.OPENCLAW_DEBUG_MODEL_PAYLOAD);
124
+ const normalized = normalizeLowercaseStringOrEmpty(env.OPENCLAW_DEBUG_MODEL_PAYLOAD);
119
125
  if (normalized === "tools" || normalized === "full-redacted") return normalized;
120
126
  if (normalized === "summary") return "summary";
121
127
  return "off";
122
128
  }
123
129
  /** Resolves SSE stream debug verbosity from `OPENCLAW_DEBUG_SSE`. */
124
130
  function resolveModelSseDebugMode(env = process.env) {
125
- const normalized = normalizeEnv(env.OPENCLAW_DEBUG_SSE);
131
+ const normalized = normalizeLowercaseStringOrEmpty(env.OPENCLAW_DEBUG_SSE);
126
132
  if (normalized === "peek") return "peek";
127
133
  if (normalized === "events" || isTruthyEnv(normalized)) return "events";
128
134
  return "off";
@@ -143,173 +149,6 @@ function emitModelTransportDebug(log, message) {
143
149
  log.debug(message);
144
150
  }
145
151
  //#endregion
146
- //#region packages/normalization-core/src/string-normalization.ts
147
- /** Coerces entries to strings, trims them, and drops empty results. */
148
- function normalizeStringEntries(list) {
149
- return (list ?? []).map((entry) => normalizeOptionalString(String(entry)) ?? "").filter(Boolean);
150
- }
151
- /** Returns first-seen unique values while preserving insertion order. */
152
- function uniqueValues(values) {
153
- return [...new Set(values)];
154
- }
155
- /** Returns first-seen unique strings while preserving insertion order. */
156
- function uniqueStrings(values) {
157
- return uniqueValues(values);
158
- }
159
- //#endregion
160
- //#region packages/ai/src/providers/openai-reasoning-effort.ts
161
- /**
162
- * OpenAI-compatible reasoning-effort normalization. Different GPT families
163
- * expose different accepted effort enums, so callers map requested values here
164
- * before constructing provider payloads.
165
- */
166
- const GPT_5_REASONING_EFFORTS = [
167
- "minimal",
168
- "low",
169
- "medium",
170
- "high"
171
- ];
172
- const GPT_51_REASONING_EFFORTS = [
173
- "none",
174
- "low",
175
- "medium",
176
- "high"
177
- ];
178
- const GPT_52_REASONING_EFFORTS = [
179
- "none",
180
- "low",
181
- "medium",
182
- "high",
183
- "xhigh"
184
- ];
185
- const GPT_56_REASONING_EFFORTS = [
186
- "none",
187
- "low",
188
- "medium",
189
- "high",
190
- "xhigh",
191
- "max"
192
- ];
193
- const GPT_CODEX_REASONING_EFFORTS = [
194
- "low",
195
- "medium",
196
- "high",
197
- "xhigh"
198
- ];
199
- const GPT_PRO_REASONING_EFFORTS = [
200
- "medium",
201
- "high",
202
- "xhigh"
203
- ];
204
- const GPT_5_PRO_REASONING_EFFORTS = ["high"];
205
- const GPT_51_CODEX_MAX_REASONING_EFFORTS = [
206
- "none",
207
- "medium",
208
- "high",
209
- "xhigh"
210
- ];
211
- const GPT_51_CODEX_MINI_REASONING_EFFORTS = ["medium"];
212
- const GENERIC_REASONING_EFFORTS = [
213
- "low",
214
- "medium",
215
- "high"
216
- ];
217
- const CANONICAL_REASONING_EFFORTS = /* @__PURE__ */ new Set([
218
- "none",
219
- "minimal",
220
- "low",
221
- "medium",
222
- "high",
223
- "xhigh",
224
- "max",
225
- "off"
226
- ]);
227
- function normalizeModelId(id) {
228
- return normalizeLowercaseStringOrEmpty(id ?? "").replace(/-\d{4}-\d{2}-\d{2}$/u, "");
229
- }
230
- /** Return whether a model is the GPT-5.4 mini family. */
231
- function isOpenAIGpt54MiniModel(model) {
232
- const id = normalizeModelId(typeof model.id === "string" ? model.id : void 0);
233
- return /^gpt-5\.4-mini(?:-|$)/u.test(id);
234
- }
235
- /** Return whether a model is the GPT-5.5 family. */
236
- function isOpenAIGpt55Model(model) {
237
- const id = normalizeModelId(typeof model.id === "string" ? model.id : void 0);
238
- const name = normalizeModelId(typeof model.name === "string" ? model.name : void 0);
239
- return /^gpt-5\.5(?:-|$)/u.test(id) || /^gpt-5\.5(?:\s|\(|-|$)/u.test(name);
240
- }
241
- /** Return whether a model is the GPT-5.6 family. */
242
- function isOpenAIGpt56Model(model) {
243
- const id = normalizeModelId(typeof model.id === "string" ? model.id : void 0);
244
- const name = normalizeModelId(typeof model.name === "string" ? model.name : void 0);
245
- return /^gpt-5\.6(?:-|$)/u.test(id) || /^gpt-5\.6(?:\s|\(|-|$)/u.test(name);
246
- }
247
- /** Normalize user-facing reasoning effort names to API effort names. */
248
- function normalizeOpenAIReasoningEffort(effort) {
249
- const trimmed = effort.trim();
250
- const folded = trimmed.toLowerCase();
251
- return CANONICAL_REASONING_EFFORTS.has(folded) ? folded : trimmed;
252
- }
253
- function readCompatReasoningEfforts(compat) {
254
- if (!compat || typeof compat !== "object") return;
255
- if (compat.supportsReasoningEffort === false) return [];
256
- const raw = compat.supportedReasoningEfforts;
257
- if (!Array.isArray(raw)) return;
258
- const supported = uniqueStrings(normalizeStringEntries(raw.filter((value) => typeof value === "string")));
259
- return supported.length > 0 ? supported : void 0;
260
- }
261
- function isDisabledReasoningEffort(effort) {
262
- return effort === "none" || effort === "off";
263
- }
264
- /** Resolve the reasoning efforts accepted by a specific OpenAI-compatible model. */
265
- function resolveOpenAISupportedReasoningEfforts(model) {
266
- const compatEfforts = readCompatReasoningEfforts(model.compat);
267
- if (compatEfforts) return compatEfforts;
268
- const id = normalizeModelId(typeof model.id === "string" ? model.id : void 0);
269
- if (/^gpt-5\.6(?:-|$)/u.test(id)) return GPT_56_REASONING_EFFORTS;
270
- if (id === "gpt-5.1-codex-mini") return GPT_51_CODEX_MINI_REASONING_EFFORTS;
271
- if (id === "gpt-5.1-codex-max") return GPT_51_CODEX_MAX_REASONING_EFFORTS;
272
- if (/^gpt-5(?:\.\d+)?-codex(?:-|$)/u.test(id)) return GPT_CODEX_REASONING_EFFORTS;
273
- if (id === "gpt-5-pro") return GPT_5_PRO_REASONING_EFFORTS;
274
- if (/^gpt-5\.[2-9](?:\.\d+)?-pro(?:-|$)/u.test(id)) return GPT_PRO_REASONING_EFFORTS;
275
- if (/^gpt-5\.[2-9](?:\.\d+)?(?:-|$)/u.test(id)) return GPT_52_REASONING_EFFORTS;
276
- if (/^gpt-5\.1(?:-|$)/u.test(id)) return GPT_51_REASONING_EFFORTS;
277
- if (/^gpt-5(?:-|$)/u.test(id)) return GPT_5_REASONING_EFFORTS;
278
- return GENERIC_REASONING_EFFORTS;
279
- }
280
- /**
281
- * Return whether a model accepts the temperature parameter. The GPT-5.6
282
- * family rejects it with a 400; catalog compat can override per model.
283
- */
284
- function supportsOpenAITemperature(model) {
285
- const compat = model.compat;
286
- if (compat && typeof compat === "object") {
287
- const declared = compat.supportsTemperature;
288
- if (typeof declared === "boolean") return declared;
289
- }
290
- const id = normalizeModelId(typeof model.id === "string" ? model.id : void 0);
291
- return !/^gpt-5\.6(?:-|$)/u.test(id);
292
- }
293
- /** Return whether a model accepts a requested reasoning effort. */
294
- function supportsOpenAIReasoningEffort(model, effort) {
295
- return resolveOpenAISupportedReasoningEfforts(model).includes(normalizeOpenAIReasoningEffort(effort));
296
- }
297
- /** Resolve a requested reasoning effort to the closest value supported by the model. */
298
- function resolveOpenAIReasoningEffortForModel(params) {
299
- const requested = normalizeOpenAIReasoningEffort(params.effort);
300
- const mapped = params.fallbackMap?.[requested] ?? (params.fallbackMap && CANONICAL_REASONING_EFFORTS.has(requested) ? Object.entries(params.fallbackMap).find(([effort]) => normalizeOpenAIReasoningEffort(effort) === requested)?.[1] : void 0);
301
- const normalized = mapped === void 0 ? requested : mapped.trim();
302
- const supported = resolveOpenAISupportedReasoningEfforts(params.model);
303
- if (supported.includes(normalized)) return normalized;
304
- if (requested === "off" && supported.includes("none")) return "none";
305
- if (isDisabledReasoningEffort(requested) || isDisabledReasoningEffort(normalized)) return;
306
- if (requested === "minimal" && supported.includes("low")) return "low";
307
- if ((requested === "minimal" || requested === "low") && supported.includes("medium")) return "medium";
308
- if (requested === "xhigh" && supported.includes("high")) return "high";
309
- if (requested === "max" && supported.includes("xhigh")) return "xhigh";
310
- return supported.find((effort) => !isDisabledReasoningEffort(normalizeOpenAIReasoningEffort(effort)));
311
- }
312
- //#endregion
313
152
  //#region packages/ai/src/providers/clean-for-gemini.ts
314
153
  const GEMINI_UNSUPPORTED_SCHEMA_KEYWORDS = /* @__PURE__ */ new Set([
315
154
  "patternProperties",
@@ -608,9 +447,6 @@ const SCHEMA_CHILD_KEYS = /* @__PURE__ */ new Set([
608
447
  "unevaluatedItems",
609
448
  "unevaluatedProperties"
610
449
  ]);
611
- function isSchemaRecord(value) {
612
- return Boolean(value) && typeof value === "object" && !Array.isArray(value);
613
- }
614
450
  function cleanSchemaNode(node) {
615
451
  if (Array.isArray(node)) {
616
452
  let changed = false;
@@ -621,7 +457,7 @@ function cleanSchemaNode(node) {
621
457
  });
622
458
  return changed ? entries : node;
623
459
  }
624
- if (!isSchemaRecord(node)) return node;
460
+ if (!isRecord(node)) return node;
625
461
  let changed = false;
626
462
  const cleaned = {};
627
463
  for (const [key, value] of Object.entries(node)) {
@@ -634,7 +470,7 @@ function cleanSchemaNode(node) {
634
470
  continue;
635
471
  }
636
472
  let next = value;
637
- if (SCHEMA_MAP_KEYS$2.has(key) && isSchemaRecord(value)) {
473
+ if (SCHEMA_MAP_KEYS$2.has(key) && isRecord(value)) {
638
474
  let mapChanged = false;
639
475
  next = Object.fromEntries(Object.entries(value).map(([childKey, childValue]) => {
640
476
  const cleanedChild = cleanSchemaNode(childValue);
@@ -653,10 +489,10 @@ function collectSchemaViolations(node, path, violations) {
653
489
  node.forEach((entry, index) => collectSchemaViolations(entry, `${path}[${index}]`, violations));
654
490
  return;
655
491
  }
656
- if (!isSchemaRecord(node)) return;
492
+ if (!isRecord(node)) return;
657
493
  if ("pattern" in node) violations.push(`${path}.pattern`);
658
494
  if (typeof node.maxLength === "number" && node.maxLength >= 2e3) violations.push(`${path}.maxLength`);
659
- for (const [key, value] of Object.entries(node)) if (SCHEMA_MAP_KEYS$2.has(key) && isSchemaRecord(value)) for (const [childKey, childValue] of Object.entries(value)) collectSchemaViolations(childValue, `${path}.${key}.${childKey}`, violations);
495
+ for (const [key, value] of Object.entries(node)) if (SCHEMA_MAP_KEYS$2.has(key) && isRecord(value)) for (const [childKey, childValue] of Object.entries(value)) collectSchemaViolations(childValue, `${path}.${key}.${childKey}`, violations);
660
496
  else if (SCHEMA_CHILD_KEYS.has(key)) collectSchemaViolations(value, `${path}.${key}`, violations);
661
497
  }
662
498
  /** Removes JSON Schema constraints that llama.cpp cannot compile into GBNF. */
@@ -1458,7 +1294,7 @@ function findOpenAIStrictSchemaViolations(schema, path, options) {
1458
1294
  * Caches normalized object inputs by provider compatibility so repeated inventory builds preserve identity.
1459
1295
  */
1460
1296
  const MAX_STRICT_SCHEMA_CACHE_ENTRIES_PER_SCHEMA = 8;
1461
- let strictOpenAISchemaCache = /* @__PURE__ */ new WeakMap();
1297
+ const strictOpenAISchemaCache = /* @__PURE__ */ new WeakMap();
1462
1298
  function resolveToolSchemaModelCompat(compat) {
1463
1299
  if (!compat) return;
1464
1300
  const unsupportedToolSchemaKeywords = Array.isArray(compat.unsupportedToolSchemaKeywords) ? compat.unsupportedToolSchemaKeywords.filter((keyword) => typeof keyword === "string") : [];
@@ -1483,9 +1319,6 @@ function rememberStrictOpenAISchema(schema, key, value) {
1483
1319
  }, ...entries.filter((entry) => entry.key !== key)].slice(0, MAX_STRICT_SCHEMA_CACHE_ENTRIES_PER_SCHEMA));
1484
1320
  return value;
1485
1321
  }
1486
- function clearOpenAIToolSchemaCacheForTest() {
1487
- strictOpenAISchemaCache = /* @__PURE__ */ new WeakMap();
1488
- }
1489
1322
  /** Normalizes a tool parameter schema into the OpenAI strict JSON-schema subset. */
1490
1323
  function normalizeStrictOpenAIJsonSchema(schema, modelCompat) {
1491
1324
  const schemaInput = schema ?? {};
@@ -1584,308 +1417,148 @@ function resolveReplayableResponsesMessageId(params) {
1584
1417
  if (!params.textSignatureId) return params.fallbackOrdinal === 0 ? params.fallbackId : `${params.fallbackId}_${params.fallbackOrdinal}`;
1585
1418
  return params.previousReplayItemWasReasoning ? params.textSignatureId : void 0;
1586
1419
  }
1587
- const OPENAI_CODEX_RESPONSES_DEFAULT_INSTRUCTIONS = "Follow the user request.";
1588
- const AZURE_RESPONSES_FIRST_EVENT_TIMEOUT_MS = 3e4;
1589
- const RESPONSE_FAILED_NO_DETAILS_MESSAGE = "Unknown error (no error details in response)";
1590
- const OPENAI_RESPONSES_REASONING_REPLAY_META_KEY = "__openclaw_replay";
1591
- const OPENAI_RESPONSES_REASONING_REPLAY_BLOCK_META_KEY = "openclawReasoningReplay";
1592
- const PROMPT_OBSERVER = Symbol("openaiResponsesPromptObserver");
1593
- const responsesPromptObserver = {
1594
- set(options, observer) {
1595
- Reflect.set(options, PROMPT_OBSERVER, observer);
1596
- },
1597
- get(options) {
1598
- return Reflect.get(options, PROMPT_OBSERVER);
1599
- },
1600
- copy(source, target) {
1601
- const observer = source && responsesPromptObserver.get(source);
1602
- if (observer) responsesPromptObserver.set(target, observer);
1603
- }
1604
- };
1605
1420
  //#endregion
1606
- //#region packages/ai/src/transports/openai-responses-debug.ts
1607
- function stringifyUnknown(value, fallback = "") {
1608
- if (typeof value === "string") return value;
1609
- if (typeof value === "number" || typeof value === "boolean") return String(value);
1610
- return fallback;
1611
- }
1612
- function getServiceTierCostMultiplier(serviceTier) {
1613
- switch (serviceTier) {
1614
- case "flex": return .5;
1615
- case "priority": return 2;
1616
- default: return 1;
1617
- }
1421
+ //#region packages/ai/src/transports/openai-responses-compaction-replay.ts
1422
+ const OPENAI_RESPONSES_COMPACTION_SUPPRESSION_TYPE = "openai-responses-compaction-suppression";
1423
+ const OPENAI_RESPONSES_COMPACTION_SUPPRESSION_DATA = "rejected";
1424
+ function hashOptionalReplayContextValue(value) {
1425
+ const normalized = value?.trim();
1426
+ return normalized ? shortHash(normalized) : void 0;
1618
1427
  }
1619
- function applyServiceTierPricing(usage, serviceTier) {
1620
- const multiplier = getServiceTierCostMultiplier(serviceTier);
1621
- if (multiplier === 1) return;
1622
- usage.cost.input *= multiplier;
1623
- usage.cost.output *= multiplier;
1624
- usage.cost.cacheRead *= multiplier;
1625
- usage.cost.cacheWrite *= multiplier;
1626
- usage.cost.total = usage.cost.input + usage.cost.output + usage.cost.cacheRead + usage.cost.cacheWrite;
1428
+ function buildOpenAIResponsesReplayContext(model, options) {
1429
+ return {
1430
+ provider: model.provider,
1431
+ api: model.api,
1432
+ model: model.id,
1433
+ baseUrlHash: hashOptionalReplayContextValue(model.baseUrl),
1434
+ sessionHash: hashOptionalReplayContextValue(options?.sessionId),
1435
+ authProfileHash: hashOptionalReplayContextValue(options?.authProfileId)
1436
+ };
1627
1437
  }
1628
- function safeDebugValue(value) {
1629
- if (typeof value === "string") return value;
1630
- if (typeof value === "number" || typeof value === "boolean") return String(value);
1631
- if (value === null) return "null";
1632
- if (value === void 0) return "undefined";
1633
- return Array.isArray(value) ? "array" : typeof value;
1438
+ function isOpenAIResponsesReplayContext(value) {
1439
+ if (!isRecord(value)) return false;
1440
+ return typeof value.provider === "string" && typeof value.api === "string" && typeof value.model === "string" && (value.baseUrlHash === void 0 || typeof value.baseUrlHash === "string") && (value.sessionHash === void 0 || typeof value.sessionHash === "string") && (value.authProfileHash === void 0 || typeof value.authProfileHash === "string");
1634
1441
  }
1635
- function responseInputTextChars(input) {
1636
- if (typeof input === "string") return input.length;
1637
- if (Array.isArray(input)) return input.reduce((total, item) => total + responseInputTextChars(item), 0);
1638
- if (!input || typeof input !== "object") return 0;
1639
- const record = input;
1640
- let total = 0;
1641
- if (typeof record.text === "string") total += record.text.length;
1642
- if (typeof record.content === "string") total += record.content.length;
1643
- else if (Array.isArray(record.content)) total += responseInputTextChars(record.content);
1644
- return total;
1442
+ function readOpenAIResponsesCompactionReplayState(value) {
1443
+ if (!isOpenAIResponsesReplayContext(value) || typeof value.baseUrlHash !== "string" || value.v !== 1) return;
1444
+ const state = value;
1445
+ if (state.type === OPENAI_RESPONSES_COMPACTION_SUPPRESSION_TYPE) return state.data === OPENAI_RESPONSES_COMPACTION_SUPPRESSION_DATA ? state : void 0;
1446
+ return state.type === "openai-responses-compaction" && typeof state.data === "string" && state.data.length > 0 && (state.id === void 0 || typeof state.id === "string") && (state.replayIndex === void 0 || Number.isSafeInteger(state.replayIndex) && state.replayIndex >= 0) ? state : void 0;
1645
1447
  }
1646
- function responseInputRoles(input) {
1647
- if (!Array.isArray(input)) return "";
1648
- const roles = /* @__PURE__ */ new Set();
1649
- for (const item of input) if (item && typeof item === "object") {
1650
- const role = item.role;
1651
- if (typeof role === "string" && role.trim()) roles.add(role.trim());
1652
- }
1653
- return [...roles].toSorted().join(",");
1448
+ function openAIResponsesReplayContextMatches(state, context) {
1449
+ return state.provider === context.provider && state.api === context.api && state.model === context.model && state.baseUrlHash === context.baseUrlHash && state.sessionHash === context.sessionHash && state.authProfileHash === context.authProfileHash;
1654
1450
  }
1655
- function readToolPayloadField(record, field) {
1656
- try {
1657
- return record[field];
1658
- } catch {
1451
+ function captureOpenAIResponsesCompaction(output, item, replayIndex, model, captureMetadata) {
1452
+ const metadata = captureMetadata ?? buildOpenAIResponsesReasoningReplayMetadata(model);
1453
+ if (!item.encrypted_content) return;
1454
+ if (!metadata?.baseUrlHash) {
1455
+ log.debug("[responses] skipping compaction capture: missing base URL hash");
1659
1456
  return;
1660
1457
  }
1458
+ const currentReplay = readOpenAIResponsesCompactionReplayState(output.providerReplay);
1459
+ if (currentReplay?.type === "openai-responses-compaction" && (currentReplay.replayIndex ?? -1) > (replayIndex ?? Number.MAX_SAFE_INTEGER)) return;
1460
+ output.providerReplay = {
1461
+ v: 1,
1462
+ type: OPENAI_RESPONSES_COMPACTION_REPLAY_TYPE,
1463
+ ...item.id ? { id: item.id } : {},
1464
+ data: item.encrypted_content,
1465
+ ...replayIndex === void 0 ? {} : { replayIndex },
1466
+ provider: metadata.provider,
1467
+ api: metadata.api,
1468
+ model: metadata.model,
1469
+ baseUrlHash: metadata.baseUrlHash,
1470
+ ...metadata.sessionHash ? { sessionHash: metadata.sessionHash } : {},
1471
+ ...metadata.authProfileHash ? { authProfileHash: metadata.authProfileHash } : {}
1472
+ };
1661
1473
  }
1662
- function readResponsesToolDisplayName(tool) {
1663
- if (!tool || typeof tool !== "object") return "";
1664
- const record = tool;
1665
- const name = readToolPayloadField(record, "name");
1666
- if (typeof name === "string") return name;
1667
- const fn = readToolPayloadField(record, "function");
1668
- if (fn && typeof fn === "object") {
1669
- const fnName = readToolPayloadField(fn, "name");
1670
- if (typeof fnName === "string") return fnName;
1671
- }
1672
- const type = readToolPayloadField(record, "type");
1673
- return typeof type === "string" && type !== "function" ? type : "";
1674
- }
1675
- function summarizeResponsesTools(tools) {
1676
- if (!Array.isArray(tools)) return "count=0";
1677
- const names = tools.map(readResponsesToolDisplayName).filter(Boolean);
1678
- const mode = resolveModelPayloadDebugMode();
1679
- const maxNames = mode === "tools" || mode === "full-redacted" ? names.length : 12;
1680
- const label = maxNames >= names.length ? "names" : "sample";
1681
- const shown = names.slice(0, maxNames).join(",");
1682
- return `count=${tools.length}${shown ? ` ${label}=${shown}` : ""}`;
1683
- }
1684
- function stringifyRedactedPayload(value) {
1685
- try {
1686
- const encoded = JSON.stringify(value);
1687
- if (!encoded) return "<empty>";
1688
- const redacted = redactSensitiveText(encoded, { mode: "tools" });
1689
- return redacted.length > 8e3 ? `${truncateUtf16Safe(redacted, 8e3)}…<truncated>` : redacted;
1690
- } catch {
1691
- return "<unserializable>";
1692
- }
1693
- }
1694
- function stringifyRedactedEvent(value) {
1695
- const redacted = stringifyRedactedPayload(value);
1696
- return redacted.length > 2e3 ? `${truncateUtf16Safe(redacted, 2e3)}…<truncated>` : redacted;
1697
- }
1698
- const RESPONSE_FAILED_FAILURE_FIELD_KEYS = [
1699
- "error",
1700
- "incomplete_details",
1701
- "status_details",
1702
- "failure_reason",
1703
- "last_error",
1704
- "provider_error",
1705
- "error_details"
1706
- ];
1707
- function readResponseFailedString(record, key) {
1708
- return stringifyUnknown(record?.[key]);
1474
+ function suppressOpenAIResponsesCompaction(output, model, options, rejectedCheckpoint) {
1475
+ const context = buildOpenAIResponsesReplayContext(model, options);
1476
+ if (!context.baseUrlHash) return;
1477
+ output.providerReplay = {
1478
+ v: 1,
1479
+ type: OPENAI_RESPONSES_COMPACTION_SUPPRESSION_TYPE,
1480
+ data: OPENAI_RESPONSES_COMPACTION_SUPPRESSION_DATA,
1481
+ ...context,
1482
+ baseUrlHash: context.baseUrlHash
1483
+ };
1484
+ if (rejectedCheckpoint) options?.onCompactionRejected?.(rejectedCheckpoint);
1709
1485
  }
1710
- function buildResponsesFailedEventSummary(message, responseId, observation) {
1711
- const summary = { message };
1712
- if (responseId) summary.responseId = responseId;
1713
- if (observation) summary.observation = observation;
1714
- return summary;
1486
+ function createCompactionTracker(output, model, options) {
1487
+ const replayIndexes = /* @__PURE__ */ new Map();
1488
+ return {
1489
+ added(item, replayIndex) {
1490
+ if (item.type === "compaction" && item.id) replayIndexes.set(item.id, replayIndex);
1491
+ },
1492
+ completed(item, fallbackReplayIndex) {
1493
+ if (item.type !== "compaction" || !item.encrypted_content) return;
1494
+ captureOpenAIResponsesCompaction(output, {
1495
+ type: "compaction",
1496
+ ...item.id ? { id: item.id } : {},
1497
+ encrypted_content: item.encrypted_content
1498
+ }, (item.id ? replayIndexes.get(item.id) : void 0) ?? fallbackReplayIndex, model, options?.reasoningReplayMetadata);
1499
+ if (item.id) replayIndexes.delete(item.id);
1500
+ }
1501
+ };
1715
1502
  }
1716
- function isResponseFailedIdentifierKey(key) {
1717
- const normalized = key.replace(/[-_\s]/g, "").toLowerCase();
1718
- return normalized === "requestid" || normalized === "xrequestid" || normalized === "providerrequestid" || normalized === "providerresponseid" || normalized === "litellmrequestid" || normalized.includes("request") && normalized.endsWith("id") || normalized.includes("provider") && normalized.endsWith("id");
1503
+ function isSafeResponsesReplayItemId(id) {
1504
+ return typeof id === "string" && id.length > 0 && id.length <= 64;
1719
1505
  }
1720
- function collectResponseFailedIdentifierHashes(value, opts = {}) {
1721
- const path = opts.path ?? "";
1722
- const depth = opts.depth ?? 0;
1723
- const identifierKey = opts.identifierKey ?? "";
1724
- const out = opts.out ?? [];
1725
- const seen = opts.seen ?? /* @__PURE__ */ new WeakSet();
1726
- if (out.length >= 12 || depth > 4 || !value || typeof value !== "object") return out;
1727
- if (seen.has(value)) return out;
1728
- seen.add(value);
1729
- if (Array.isArray(value)) {
1730
- for (const [index, item] of value.entries()) {
1731
- if (index >= 8 || out.length >= 12) break;
1732
- const itemString = typeof item === "string" || typeof item === "number" ? String(item).trim() : "";
1733
- if (identifierKey && isResponseFailedIdentifierKey(identifierKey) && itemString) {
1734
- out.push(`${path}[${index}]=${redactIdentifier(itemString, { len: 12 })}`);
1735
- continue;
1736
- }
1737
- collectResponseFailedIdentifierHashes(item, {
1738
- path: `${path}[${index}]`,
1739
- depth: depth + 1,
1740
- identifierKey,
1741
- out,
1742
- seen
1743
- });
1506
+ function resolveNewestOpenAIResponsesCompactionReplay(messages, model, options) {
1507
+ const context = buildOpenAIResponsesReplayContext(model, options);
1508
+ for (let index = messages.length - 1; index >= 0; index -= 1) {
1509
+ const message = messages[index];
1510
+ if (message?.role !== "assistant") continue;
1511
+ const replay = readOpenAIResponsesCompactionReplayState(message.providerReplay);
1512
+ if (replay?.type === OPENAI_RESPONSES_COMPACTION_SUPPRESSION_TYPE) {
1513
+ if (openAIResponsesReplayContextMatches(replay, context)) return;
1514
+ continue;
1744
1515
  }
1745
- return out;
1746
- }
1747
- for (const [key, child] of Object.entries(value)) {
1748
- if (out.length >= 12) break;
1749
- const childPath = path ? `${path}.${key}` : key;
1750
- const childString = typeof child === "string" || typeof child === "number" ? String(child).trim() : "";
1751
- if (isResponseFailedIdentifierKey(key) && childString) {
1752
- out.push(`${childPath}=${redactIdentifier(childString, { len: 12 })}`);
1516
+ if (replay?.type !== "openai-responses-compaction") {
1517
+ if (message.providerReplay?.type === "openai-responses-compaction") return;
1753
1518
  continue;
1754
1519
  }
1755
- collectResponseFailedIdentifierHashes(child, {
1756
- path: childPath,
1757
- depth: depth + 1,
1758
- identifierKey: isResponseFailedIdentifierKey(key) ? key : void 0,
1759
- out,
1760
- seen
1761
- });
1520
+ if (!openAIResponsesReplayContextMatches(replay, context)) return;
1521
+ return {
1522
+ owner: message,
1523
+ item: {
1524
+ type: "compaction",
1525
+ ...isSafeResponsesReplayItemId(replay.id) ? { id: replay.id } : {},
1526
+ encrypted_content: replay.data
1527
+ },
1528
+ replayIndex: replay.replayIndex ?? 0
1529
+ };
1762
1530
  }
1763
- return out;
1764
- }
1765
- function redactResponseFailedDiagnosticValue(value, opts = {}) {
1766
- const key = opts.key ?? "";
1767
- const depth = opts.depth ?? 0;
1768
- if (typeof value === "string" || typeof value === "number") return key && isResponseFailedIdentifierKey(key) ? redactIdentifier(String(value), { len: 12 }) : value;
1769
- if (depth > 6 || !value || typeof value !== "object") return value;
1770
- const seen = opts.seen ?? /* @__PURE__ */ new WeakSet();
1771
- if (seen.has(value)) return "<circular>";
1772
- seen.add(value);
1773
- if (Array.isArray(value)) return value.slice(0, 16).map((item) => redactResponseFailedDiagnosticValue(item, {
1774
- key,
1775
- depth: depth + 1,
1776
- seen
1777
- }));
1778
- const out = {};
1779
- for (const [childKey, child] of Object.entries(value)) out[childKey] = redactResponseFailedDiagnosticValue(child, {
1780
- key: childKey,
1781
- depth: depth + 1,
1782
- seen
1783
- });
1784
- return out;
1785
- }
1786
- function buildResponsesFailedFailureFields(response) {
1787
- if (!response) return {};
1788
- const fields = {};
1789
- for (const key of RESPONSE_FAILED_FAILURE_FIELD_KEYS) if (response[key] !== void 0 && response[key] !== null) fields[key] = response[key];
1790
- return fields;
1791
1531
  }
1792
- function buildResponsesFailedNoDetailsObservation(event, model, response = isRecord(event.response) ? event.response : void 0) {
1793
- const failureFields = redactResponseFailedDiagnosticValue(buildResponsesFailedFailureFields(response));
1794
- const metadataKeys = isRecord(response?.metadata) ? Object.keys(response.metadata).toSorted() : [];
1795
- const responsePreview = {
1796
- id: readResponseFailedString(response, "id"),
1797
- status: readResponseFailedString(response, "status"),
1798
- model: readResponseFailedString(response, "model"),
1799
- object: readResponseFailedString(response, "object"),
1800
- failureFields,
1801
- metadataKeys
1532
+ function buildOpenAIResponsesCompactionReplayPlan(messages, model, options) {
1533
+ if (options?.mode === "full-history") return {
1534
+ messages,
1535
+ preserveUnframedToolResults: false
1536
+ };
1537
+ const compaction = resolveNewestOpenAIResponsesCompactionReplay(messages, model, options);
1538
+ if (!compaction) return {
1539
+ messages,
1540
+ preserveUnframedToolResults: false
1802
1541
  };
1542
+ const ownerIndex = messages.indexOf(compaction.owner);
1803
1543
  return {
1804
- event: "openai_responses_response_failed_without_details",
1805
- provider: model.provider,
1806
- api: model.api,
1807
- transportModel: model.id,
1808
- providerRuntimeFailureKind: "no_error_details",
1809
- responseId: responsePreview.id,
1810
- responseStatus: responsePreview.status,
1811
- responseModel: responsePreview.model,
1812
- responseObject: responsePreview.object,
1813
- metadataKeys,
1814
- requestIdHashes: collectResponseFailedIdentifierHashes(event),
1815
- failureFieldsPreview: stringifyRedactedEvent(failureFields),
1816
- responsePreview: stringifyRedactedEvent(responsePreview)
1544
+ messages: [{
1545
+ ...compaction.owner,
1546
+ content: compaction.owner.content.slice(compaction.replayIndex)
1547
+ }, ...messages.slice(ownerIndex + 1)],
1548
+ compaction: compaction.item,
1549
+ preserveUnframedToolResults: true
1817
1550
  };
1818
1551
  }
1819
- function summarizeResponsesFailedNoDetailsObservation(observation) {
1820
- const requestIds = observation.requestIdHashes.join(",");
1821
- const metadataKeys = observation.metadataKeys.join(",");
1822
- return `responseId=${safeDebugValue(observation.responseId || void 0)} responseStatus=${safeDebugValue(observation.responseStatus || void 0)} responseModel=${safeDebugValue(observation.responseModel || void 0)} requestIds=${requestIds || "none"} metadataKeys=${metadataKeys || "none"} failureFields=${observation.failureFieldsPreview}`;
1823
- }
1824
- function normalizeResponsesFailedEvent(event, model) {
1825
- const response = isRecord(event.response) ? event.response : void 0;
1826
- const responseId = readResponseFailedString(response, "id") || void 0;
1827
- const error = isRecord(response?.error) ? response.error : void 0;
1828
- if (error) {
1829
- const code = readResponseFailedString(error, "code").trim();
1830
- const message = readResponseFailedString(error, "message").trim();
1831
- if (code || message) return buildResponsesFailedEventSummary(`${code || "unknown"}: ${message || "no message"}`, responseId);
1832
- }
1833
- const incompleteReason = readResponseFailedString(isRecord(response?.incomplete_details) ? response.incomplete_details : void 0, "reason");
1834
- if (incompleteReason) return buildResponsesFailedEventSummary(`incomplete: ${incompleteReason}`, responseId);
1835
- return buildResponsesFailedEventSummary(RESPONSE_FAILED_NO_DETAILS_MESSAGE, responseId, buildResponsesFailedNoDetailsObservation(event, model, response));
1836
- }
1837
- function logResponsesFailedNoDetails(observation) {
1838
- log.warn(`[responses] response.failed missing error details provider=${observation.provider} api=${observation.api} model=${observation.transportModel} ` + summarizeResponsesFailedNoDetailsObservation(observation), observation);
1839
- }
1840
- function summarizeResponsesPayload(params) {
1841
- if (!params || typeof params !== "object") return "payload=non-object";
1842
- const record = params;
1843
- const input = record.input;
1844
- const reasoning = record.reasoning && typeof record.reasoning === "object" ? record.reasoning : void 0;
1845
- const text = record.text && typeof record.text === "object" ? record.text : void 0;
1846
- const parts = [
1847
- `fields=${Object.keys(record).toSorted().join(",")}`,
1848
- `model=${safeDebugValue(record.model)}`,
1849
- `stream=${safeDebugValue(record.stream)}`,
1850
- `inputItems=${Array.isArray(input) ? input.length : typeof input}`,
1851
- `inputRoles=${responseInputRoles(input) || "none"}`,
1852
- `inputTextChars=${responseInputTextChars(input)}`,
1853
- `tools=${summarizeResponsesTools(record.tools)}`,
1854
- `reasoningEffort=${safeDebugValue(reasoning?.effort)}`,
1855
- `reasoningSummary=${safeDebugValue(reasoning?.summary)}`,
1856
- `textVerbosity=${safeDebugValue(text?.verbosity)}`,
1857
- `serviceTier=${safeDebugValue(record.service_tier)}`,
1858
- `store=${safeDebugValue(record.store)}`,
1859
- `promptCacheKey=${record.prompt_cache_key === void 0 ? "absent" : "present"}`,
1860
- `metadataKeys=${record.metadata && typeof record.metadata === "object" ? Object.keys(record.metadata).toSorted().join(",") : "none"}`
1861
- ];
1862
- if (resolveModelPayloadDebugMode() === "full-redacted") parts.push(`payload=${stringifyRedactedPayload(record)}`);
1863
- return parts.join(" ");
1864
- }
1865
- function summarizeOpenAITransportError(error) {
1866
- if (!error || typeof error !== "object") return `type=${typeof error} message=${safeDebugValue(error)}`;
1867
- const record = error;
1868
- const cause = record.cause && typeof record.cause === "object" ? record.cause : void 0;
1869
- return [
1870
- `name=${safeDebugValue(record.name)}`,
1871
- `status=${safeDebugValue(record.status)}`,
1872
- `code=${safeDebugValue(record.code)}`,
1873
- `type=${safeDebugValue(record.type)}`,
1874
- `causeName=${safeDebugValue(cause?.name)}`,
1875
- `causeCode=${safeDebugValue(cause?.code)}`,
1876
- `message=${error instanceof Error ? error.message : safeDebugValue(error)}`
1877
- ].join(" ");
1552
+ function buildOpenAIResponsesReasoningReplayMetadata(model, options) {
1553
+ return {
1554
+ v: 1,
1555
+ source: "openai-responses",
1556
+ ...buildOpenAIResponsesReplayContext(model, options)
1557
+ };
1878
1558
  }
1879
1559
  //#endregion
1880
- //#region packages/ai/src/transports/openai-responses-replay-internal.ts
1881
- function isInvalidEncryptedContentError(error) {
1882
- if (!error || typeof error !== "object") return false;
1883
- const record = error;
1884
- if (record.code === "invalid_encrypted_content" || record.code === "thinking_signature_invalid") return true;
1885
- const message = typeof record.message === "string" ? record.message : "";
1886
- return message.includes("invalid_encrypted_content") || message.includes("thinking_signature_invalid") || record.status === 400 && message.toLowerCase().includes("could not decrypt the provided encrypted_content");
1887
- }
1888
- function stripEncryptedContentFields(value) {
1560
+ //#region packages/ai/src/transports/openai-responses-replay-messages-internal.ts
1561
+ function stripEncryptedReasoningContentFields(value) {
1889
1562
  if (!value || typeof value !== "object") return {
1890
1563
  value,
1891
1564
  changed: false
@@ -1893,7 +1566,7 @@ function stripEncryptedContentFields(value) {
1893
1566
  if (Array.isArray(value)) {
1894
1567
  let changed = false;
1895
1568
  const next = value.map((item) => {
1896
- const stripped = stripEncryptedContentFields(item);
1569
+ const stripped = stripEncryptedReasoningContentFields(item);
1897
1570
  changed ||= stripped.changed;
1898
1571
  return stripped.value;
1899
1572
  });
@@ -1905,14 +1578,19 @@ function stripEncryptedContentFields(value) {
1905
1578
  changed: false
1906
1579
  };
1907
1580
  }
1581
+ const source = value;
1582
+ if (source.type === "compaction") return {
1583
+ value,
1584
+ changed: false
1585
+ };
1908
1586
  let changed = false;
1909
1587
  const next = {};
1910
- for (const [key, child] of Object.entries(value)) {
1588
+ for (const [key, child] of Object.entries(source)) {
1911
1589
  if (key === "encrypted_content") {
1912
1590
  changed = true;
1913
1591
  continue;
1914
1592
  }
1915
- const stripped = stripEncryptedContentFields(child);
1593
+ const stripped = stripEncryptedReasoningContentFields(child);
1916
1594
  changed ||= stripped.changed;
1917
1595
  next[key] = stripped.value;
1918
1596
  }
@@ -1924,54 +1602,15 @@ function stripEncryptedContentFields(value) {
1924
1602
  changed: false
1925
1603
  };
1926
1604
  }
1927
- function stripResponsesRequestEncryptedContent(params) {
1928
- const stripped = stripEncryptedContentFields(params.input);
1929
- if (!stripped.changed) return params;
1930
- return {
1931
- ...params,
1932
- input: stripped.value
1933
- };
1934
- }
1935
- function hashOptionalReplayContextValue(value) {
1936
- const normalized = value?.trim();
1937
- return normalized ? shortHash(normalized) : void 0;
1938
- }
1939
- function buildOpenAIResponsesReplayContext(model, options) {
1940
- return {
1941
- provider: model.provider,
1942
- api: model.api,
1943
- model: model.id,
1944
- baseUrlHash: hashOptionalReplayContextValue(model.baseUrl),
1945
- sessionHash: hashOptionalReplayContextValue(options?.sessionId),
1946
- authProfileHash: hashOptionalReplayContextValue(options?.authProfileId)
1947
- };
1948
- }
1949
- function buildOpenAIResponsesReasoningReplayMetadata(model, options) {
1950
- return {
1951
- v: 1,
1952
- source: "openai-responses",
1953
- ...buildOpenAIResponsesReplayContext(model, options)
1954
- };
1955
- }
1956
- function tagOpenAIResponsesReasoningReplayItem(item, model, options) {
1957
- if (!("encrypted_content" in item)) return item;
1958
- return {
1959
- ...item,
1960
- [OPENAI_RESPONSES_REASONING_REPLAY_META_KEY]: buildOpenAIResponsesReasoningReplayMetadata(model, options)
1961
- };
1962
- }
1963
1605
  function isOpenAIResponsesReasoningReplayMetadata(value) {
1964
- if (!value || typeof value !== "object") return false;
1606
+ if (!isOpenAIResponsesReplayContext(value)) return false;
1965
1607
  const record = value;
1966
- return record.v === 1 && record.source === "openai-responses" && typeof record.provider === "string" && typeof record.api === "string" && typeof record.model === "string" && (record.baseUrlHash === void 0 || typeof record.baseUrlHash === "string") && (record.sessionHash === void 0 || typeof record.sessionHash === "string") && (record.authProfileHash === void 0 || typeof record.authProfileHash === "string");
1967
- }
1968
- function encryptedReasoningReplayMetadataMatches(metadata, context) {
1969
- if (!metadata) return false;
1970
- return metadata.provider === context.provider && metadata.api === context.api && metadata.model === context.model && metadata.baseUrlHash === context.baseUrlHash && metadata.sessionHash === context.sessionHash && metadata.authProfileHash === context.authProfileHash;
1608
+ return record.v === 1 && record.source === "openai-responses";
1971
1609
  }
1972
1610
  function readOpenAIResponsesReasoningReplayBlockMetadata(block) {
1611
+ if (!Object.hasOwn(block, "openclawReasoningReplay")) return;
1973
1612
  const value = block[OPENAI_RESPONSES_REASONING_REPLAY_BLOCK_META_KEY];
1974
- return isOpenAIResponsesReasoningReplayMetadata(value) ? value : void 0;
1613
+ return isOpenAIResponsesReasoningReplayMetadata(value) ? value : null;
1975
1614
  }
1976
1615
  function normalizeOpenAIResponsesReasoningReplayItem(item) {
1977
1616
  const record = item;
@@ -1981,49 +1620,20 @@ function normalizeOpenAIResponsesReasoningReplayItem(item) {
1981
1620
  summary: []
1982
1621
  };
1983
1622
  }
1984
- function prepareOpenAIResponsesReasoningItemForReplay(item, context, blockMetadata) {
1985
- const { [OPENAI_RESPONSES_REASONING_REPLAY_META_KEY]: rawMetadata, ...rest } = item;
1623
+ function prepareOpenAIResponsesReasoningItemForReplay(item, context, blockMetadata, options) {
1624
+ const record = item;
1625
+ const hasRawMetadata = Object.hasOwn(record, OPENAI_RESPONSES_REASONING_REPLAY_META_KEY);
1626
+ const { [OPENAI_RESPONSES_REASONING_REPLAY_META_KEY]: rawMetadata, ...rest } = record;
1986
1627
  if (!("encrypted_content" in rest)) return normalizeOpenAIResponsesReasoningReplayItem(rest);
1987
- if (encryptedReasoningReplayMetadataMatches(blockMetadata ?? (isOpenAIResponsesReasoningReplayMetadata(rawMetadata) ? rawMetadata : void 0), context)) return normalizeOpenAIResponsesReasoningReplayItem(rest);
1988
- return normalizeOpenAIResponsesReasoningReplayItem(stripEncryptedContentFields(rest).value);
1989
- }
1990
- async function createResponsesStreamWithEncryptedContentRetry(params) {
1991
- try {
1992
- params.observePrompt?.(params.request, {
1993
- egress: "responses-sdk",
1994
- payloadVariant: "initial"
1995
- });
1996
- const { data, response } = await params.client.responses.create(params.request, params.requestOptions).withResponse();
1997
- return {
1998
- stream: data,
1999
- response
2000
- };
2001
- } catch (error) {
2002
- const retryRequest = stripResponsesRequestEncryptedContent(params.request);
2003
- if (!isInvalidEncryptedContentError(error) || retryRequest === params.request) throw error;
2004
- log.warn(`[responses] retrying without encrypted reasoning content provider=${params.model.provider} api=${params.model.api} model=${params.model.id}`);
2005
- params.observePrompt?.(retryRequest, {
2006
- egress: "responses-sdk",
2007
- payloadVariant: "encrypted-content-retry"
2008
- });
2009
- const { data, response } = await params.client.responses.create(retryRequest, params.requestOptions).withResponse();
2010
- return {
2011
- stream: data,
2012
- response
2013
- };
2014
- }
2015
- }
2016
- function resolveAzureOpenAIApiVersion(env = process.env) {
2017
- return env.AZURE_OPENAI_API_VERSION?.trim() || "preview";
1628
+ const metadata = blockMetadata !== void 0 ? blockMetadata ?? void 0 : isOpenAIResponsesReasoningReplayMetadata(rawMetadata) ? rawMetadata : void 0;
1629
+ if (blockMetadata === void 0 && !hasRawMetadata && options?.preserveUnattributedEncryptedContent === true || metadata && openAIResponsesReplayContextMatches(metadata, context)) return normalizeOpenAIResponsesReasoningReplayItem(rest);
1630
+ return normalizeOpenAIResponsesReasoningReplayItem(stripEncryptedReasoningContentFields(rest).value);
2018
1631
  }
2019
1632
  function normalizeResponsesReplayItemId(id, prefix) {
2020
1633
  if (!id) return;
2021
1634
  if (id.length <= 64) return id;
2022
1635
  return `${prefix}_${shortHash(id)}`;
2023
1636
  }
2024
- function isSafeResponsesReplayItemId(id) {
2025
- return typeof id === "string" && id.length > 0 && id.length <= 64;
2026
- }
2027
1637
  function encodeTextSignatureV1(id, phase) {
2028
1638
  return JSON.stringify({
2029
1639
  v: 1,
@@ -2031,7 +1641,7 @@ function encodeTextSignatureV1(id, phase) {
2031
1641
  ...phase ? { phase } : {}
2032
1642
  });
2033
1643
  }
2034
- function parseTextSignature(signature) {
1644
+ function parseOpenAIResponsesTextSignature(signature) {
2035
1645
  if (!signature) return;
2036
1646
  if (signature.startsWith("{")) try {
2037
1647
  const parsed = JSON.parse(signature);
@@ -2054,8 +1664,34 @@ function buildResponsesInputMessage(role, content) {
2054
1664
  content
2055
1665
  };
2056
1666
  }
2057
- function convertResponsesMessages(model, context, allowedToolCallProviders, options) {
1667
+ function createOpenAIResponsesAssistantOutput(model, api = model.api) {
1668
+ return {
1669
+ role: "assistant",
1670
+ content: [],
1671
+ api,
1672
+ provider: model.provider,
1673
+ model: model.id,
1674
+ usage: {
1675
+ input: 0,
1676
+ output: 0,
1677
+ cacheRead: 0,
1678
+ cacheWrite: 0,
1679
+ totalTokens: 0,
1680
+ cost: {
1681
+ input: 0,
1682
+ output: 0,
1683
+ cacheRead: 0,
1684
+ cacheWrite: 0,
1685
+ total: 0
1686
+ }
1687
+ },
1688
+ stopReason: "stop",
1689
+ timestamp: Date.now()
1690
+ };
1691
+ }
1692
+ function convertResponsesMessagesWithStyle(model, context, allowedToolCallProviders, options, conversionStyle) {
2058
1693
  const messages = [];
1694
+ const providerStyle = conversionStyle === "provider";
2059
1695
  const shouldReplayReasoningItems = options?.replayReasoningItems ?? true;
2060
1696
  const shouldReplayResponsesItemIds = options?.replayResponsesItemIds ?? true;
2061
1697
  const replayContext = buildOpenAIResponsesReplayContext(model, {
@@ -2063,7 +1699,10 @@ function convertResponsesMessages(model, context, allowedToolCallProviders, opti
2063
1699
  authProfileId: options?.authProfileId
2064
1700
  });
2065
1701
  const shouldNormalizeSameModelToolCallIds = model.provider === "github-copilot";
2066
- const sanitizeIdPart = (part) => part.replace(/[^a-zA-Z0-9_-]/g, "_").replace(/_+$/, "");
1702
+ const sanitizeIdPart = (part) => {
1703
+ const sanitized = part.replace(/[^a-zA-Z0-9_-]/g, "_");
1704
+ return providerStyle ? sanitized : sanitized.replace(/_+$/, "");
1705
+ };
2067
1706
  const normalizeIdPart = (part) => {
2068
1707
  const sanitized = sanitizeIdPart(part);
2069
1708
  return (sanitized.length > 64 ? sanitized.slice(0, 64) : sanitized).replace(/_+$/, "");
@@ -2084,15 +1723,24 @@ function convertResponsesMessages(model, context, allowedToolCallProviders, opti
2084
1723
  const callId = id.slice(0, separatorIndex);
2085
1724
  const itemId = id.slice(separatorIndex + 1);
2086
1725
  const normalizedCallId = normalizeIdPart(callId);
2087
- let normalizedItemId = source.provider !== model.provider || source.api !== model.api ? buildForeignResponsesItemId(itemId) : model.provider === "github-copilot" ? buildSameProviderCopilotResponsesItemId(itemId) : normalizeIdPart(itemId);
1726
+ let normalizedItemId = source.provider !== model.provider || source.api !== model.api ? buildForeignResponsesItemId(itemId) : model.provider === "github-copilot" ? providerStyle ? normalizeIdPart(itemId) : buildSameProviderCopilotResponsesItemId(itemId) : normalizeIdPart(itemId);
2088
1727
  if (!normalizedItemId.startsWith("fc_")) normalizedItemId = normalizeIdPart(`fc_${normalizedItemId}`);
2089
1728
  return `${normalizedCallId}|${normalizedItemId}`;
2090
1729
  };
2091
- const transformedMessages = transformTransportMessages(context.messages, model, normalizeToolCallId, { normalizeSameModelToolCallIds: shouldNormalizeSameModelToolCallIds });
2092
- if ((options?.includeSystemPrompt ?? true) && context.systemPrompt) messages.push(buildResponsesInputMessage(model.reasoning && options?.supportsDeveloperRole !== false ? "developer" : "system", [{
1730
+ const replayPlan = buildOpenAIResponsesCompactionReplayPlan(context.messages, model, {
1731
+ sessionId: options?.sessionId,
1732
+ authProfileId: options?.authProfileId,
1733
+ mode: options?.replayMode
1734
+ });
1735
+ const transformedMessages = providerStyle ? transformProviderMessages(replayPlan.messages, model, normalizeToolCallId) : transformTransportMessages(replayPlan.messages, model, normalizeToolCallId, {
1736
+ normalizeSameModelToolCallIds: shouldNormalizeSameModelToolCallIds,
1737
+ preserveUnframedToolResults: replayPlan.preserveUnframedToolResults
1738
+ });
1739
+ if ((options?.includeSystemPrompt ?? true) && context.systemPrompt) messages.push(buildResponsesInputMessage(model.reasoning && (providerStyle ? model.compat?.supportsDeveloperRole !== false : options?.supportsDeveloperRole !== false) ? "developer" : "system", [{
2093
1740
  type: "input_text",
2094
1741
  text: sanitizeTransportPayloadText(stripSystemPromptCacheBoundary(context.systemPrompt))
2095
1742
  }]));
1743
+ if (replayPlan.compaction) messages.push(replayPlan.compaction);
2096
1744
  let msgIndex = 0;
2097
1745
  for (const msg of transformedMessages) {
2098
1746
  if (msg.role === "user") if (typeof msg.content === "string") messages.push(buildResponsesInputMessage("user", [{
@@ -2107,8 +1755,9 @@ function convertResponsesMessages(model, context, allowedToolCallProviders, opti
2107
1755
  type: "input_image",
2108
1756
  detail: "auto",
2109
1757
  image_url: `data:${item.mimeType};base64,${item.data}`
2110
- }).filter((item) => model.input.includes("image") || item.type !== "input_image");
1758
+ }).filter((item) => providerStyle || model.input.includes("image") || item.type !== "input_image");
2111
1759
  if (content.length > 0) messages.push(buildResponsesInputMessage("user", content));
1760
+ else if (providerStyle) continue;
2112
1761
  }
2113
1762
  else if (msg.role === "assistant") {
2114
1763
  const output = [];
@@ -2116,15 +1765,15 @@ function convertResponsesMessages(model, context, allowedToolCallProviders, opti
2116
1765
  let previousReplayItemWasReasoning = false;
2117
1766
  const isDifferentModel = msg.model !== model.id && msg.provider === model.provider && msg.api === model.api;
2118
1767
  for (const block of msg.content) if (block.type === "thinking") {
2119
- if (shouldReplayReasoningItems && block.thinkingSignature && block.thinkingSignature.startsWith("{")) {
2120
- const replayableReasoningItem = prepareOpenAIResponsesReasoningItemForReplay(JSON.parse(block.thinkingSignature), replayContext, readOpenAIResponsesReasoningReplayBlockMetadata(block));
1768
+ if (shouldReplayReasoningItems && block.thinkingSignature && (providerStyle || block.thinkingSignature.startsWith("{"))) {
1769
+ const replayableReasoningItem = prepareOpenAIResponsesReasoningItemForReplay(JSON.parse(block.thinkingSignature), replayContext, readOpenAIResponsesReasoningReplayBlockMetadata(block), providerStyle ? { preserveUnattributedEncryptedContent: true } : void 0);
2121
1770
  if (!shouldReplayResponsesItemIds) delete replayableReasoningItem.id;
2122
- if (shouldReplayResponsesItemIds && model.provider === "github-copilot" && !isSafeResponsesReplayItemId(replayableReasoningItem.id)) continue;
1771
+ if (shouldReplayResponsesItemIds && !providerStyle && model.provider === "github-copilot" && !isSafeResponsesReplayItemId(replayableReasoningItem.id)) continue;
2123
1772
  output.push(replayableReasoningItem);
2124
1773
  previousReplayItemWasReasoning = true;
2125
1774
  }
2126
1775
  } else if (block.type === "text") {
2127
- const textSignature = parseTextSignature(block.textSignature);
1776
+ const textSignature = parseOpenAIResponsesTextSignature(block.textSignature);
2128
1777
  let msgId = resolveReplayableResponsesMessageId({
2129
1778
  replayResponsesItemIds: shouldReplayResponsesItemIds,
2130
1779
  textSignatureId: textSignature?.id,
@@ -2158,11 +1807,12 @@ function convertResponsesMessages(model, context, allowedToolCallProviders, opti
2158
1807
  ...itemId ? { id: itemId } : {},
2159
1808
  call_id: callId,
2160
1809
  name: block.name,
2161
- arguments: typeof block.arguments === "string" ? block.arguments : JSON.stringify(block.arguments ?? {})
1810
+ arguments: providerStyle ? JSON.stringify(block.arguments) : typeof block.arguments === "string" ? block.arguments : JSON.stringify(block.arguments ?? {})
2162
1811
  });
2163
1812
  previousReplayItemWasReasoning = false;
2164
1813
  }
2165
1814
  if (output.length > 0) messages.push(...output);
1815
+ else if (providerStyle) continue;
2166
1816
  } else if (msg.role === "toolResult") {
2167
1817
  const textResult = extractToolResultText(msg.content);
2168
1818
  const sanitizedTextResult = sanitizeTransportPayloadText(textResult);
@@ -2191,6 +1841,119 @@ function convertResponsesMessages(model, context, allowedToolCallProviders, opti
2191
1841
  }
2192
1842
  return messages;
2193
1843
  }
1844
+ function convertResponsesMessages$1(model, context, allowedToolCallProviders, options) {
1845
+ return convertResponsesMessagesWithStyle(model, context, allowedToolCallProviders, options, "transport");
1846
+ }
1847
+ function convertProviderResponsesMessages(model, context, allowedToolCallProviders, options) {
1848
+ return convertResponsesMessagesWithStyle(model, context, allowedToolCallProviders, options, "provider");
1849
+ }
1850
+ //#endregion
1851
+ //#region packages/ai/src/transports/openai-responses-replay-internal.ts
1852
+ function isInvalidEncryptedContentError(error) {
1853
+ if (!error || typeof error !== "object") return false;
1854
+ const record = error;
1855
+ if (record.code === "invalid_encrypted_content" || record.code === "thinking_signature_invalid") return true;
1856
+ const message = typeof record.message === "string" ? record.message : "";
1857
+ return message.includes("invalid_encrypted_content") || message.includes("thinking_signature_invalid") || record.status === 400 && message.toLowerCase().includes("could not decrypt the provided encrypted_content");
1858
+ }
1859
+ function isOrphanedFunctionCallOutputError(error) {
1860
+ if (!error || typeof error !== "object") return false;
1861
+ const record = error;
1862
+ const message = typeof record.message === "string" ? record.message : "";
1863
+ return /No tool call found for function call output with call_id [A-Za-z0-9_-]+/.test(message);
1864
+ }
1865
+ function commitResponsesEncryptedContentAttempt(attempt, commit) {
1866
+ if (attempt.kind === "compaction-stripped") commit(attempt.rejectedCompaction);
1867
+ }
1868
+ function stripResponsesRequestEncryptedReasoning(request) {
1869
+ const stripped = stripEncryptedReasoningContentFields(request.input);
1870
+ if (!stripped.changed) return request;
1871
+ return {
1872
+ ...request,
1873
+ input: stripped.value
1874
+ };
1875
+ }
1876
+ function stripResponsesRequestCompaction(request) {
1877
+ if (!Array.isArray(request.input)) return request;
1878
+ const input = request.input.filter((item) => !(item !== null && typeof item === "object" && item.type === "compaction"));
1879
+ return input.length === request.input.length ? request : {
1880
+ ...request,
1881
+ input
1882
+ };
1883
+ }
1884
+ function readOpenAIResponsesCompactionRejection(request) {
1885
+ if (!Array.isArray(request.input)) return;
1886
+ const item = request.input.find((candidate) => candidate !== null && typeof candidate === "object" && candidate.type === "compaction" && typeof candidate.encrypted_content === "string");
1887
+ return item ? {
1888
+ data: item.encrypted_content,
1889
+ ...typeof item.id === "string" ? { id: item.id } : {}
1890
+ } : void 0;
1891
+ }
1892
+ async function resolveNextResponsesEncryptedContentAttempt(attempt, error, options) {
1893
+ const orphanedFunctionOutput = isOrphanedFunctionCallOutputError(error);
1894
+ if (!isInvalidEncryptedContentError(error) && !orphanedFunctionOutput || attempt.kind === "compaction-stripped") return;
1895
+ if (!orphanedFunctionOutput && (attempt.kind === "initial" || attempt.kind === "continuation-rejected")) {
1896
+ const reasoningStripped = stripResponsesRequestEncryptedReasoning(attempt.request);
1897
+ if (reasoningStripped !== attempt.request) return {
1898
+ kind: "reasoning-stripped",
1899
+ request: reasoningStripped
1900
+ };
1901
+ }
1902
+ const locallyStripped = stripResponsesRequestCompaction(attempt.request);
1903
+ if (locallyStripped === attempt.request) return;
1904
+ let compactionStripped = options?.buildFullHistoryRequest ? await options.buildFullHistoryRequest() : locallyStripped;
1905
+ compactionStripped = stripResponsesRequestCompaction(compactionStripped);
1906
+ if (attempt.kind === "reasoning-stripped") compactionStripped = stripResponsesRequestEncryptedReasoning(compactionStripped);
1907
+ return {
1908
+ kind: "compaction-stripped",
1909
+ request: compactionStripped,
1910
+ rejectedCompaction: readOpenAIResponsesCompactionRejection(attempt.request)
1911
+ };
1912
+ }
1913
+ async function createResponsesStreamWithEncryptedContentRetry(params) {
1914
+ const sendAttempt = async (attempt) => {
1915
+ const { data, response } = await params.client.responses.create(attempt.request, params.requestOptions).withResponse();
1916
+ commitResponsesEncryptedContentAttempt(attempt, (checkpoint) => {
1917
+ if (checkpoint) params.onCompactionRejected?.(checkpoint);
1918
+ });
1919
+ return {
1920
+ stream: data,
1921
+ response,
1922
+ attempt
1923
+ };
1924
+ };
1925
+ let attempt = {
1926
+ kind: params.initialAttemptKind ?? "initial",
1927
+ request: params.request,
1928
+ ...params.initialRejectedCompaction ? { rejectedCompaction: params.initialRejectedCompaction } : {}
1929
+ };
1930
+ while (true) {
1931
+ params.observePrompt?.(attempt.request, {
1932
+ egress: "responses-sdk",
1933
+ payloadVariant: attempt.kind
1934
+ });
1935
+ try {
1936
+ return await sendAttempt(attempt);
1937
+ } catch (error) {
1938
+ let nextAttempt = await resolveNextResponsesEncryptedContentAttempt(attempt, error, { buildFullHistoryRequest: params.buildFullHistoryRequest });
1939
+ if (!nextAttempt && attempt.request.previous_response_id && error && typeof error === "object" && typeof error.status === "number" && error.code === "previous_response_not_found") {
1940
+ const request = { ...params.buildFullHistoryRequest ? await params.buildFullHistoryRequest() : attempt.request };
1941
+ delete request.previous_response_id;
1942
+ nextAttempt = {
1943
+ kind: "continuation-rejected",
1944
+ request
1945
+ };
1946
+ }
1947
+ if (!nextAttempt) throw error;
1948
+ const retryDescription = nextAttempt.kind === "reasoning-stripped" ? "without encrypted reasoning content" : nextAttempt.kind === "compaction-stripped" ? "without encrypted compaction content" : "full history after rejected previous_response_id";
1949
+ log.warn(`[responses] retrying ${retryDescription} provider=${params.model.provider} api=${params.model.api} model=${params.model.id}`);
1950
+ attempt = nextAttempt;
1951
+ }
1952
+ }
1953
+ }
1954
+ function resolveAzureOpenAIApiVersion(env = process.env) {
1955
+ return env.AZURE_OPENAI_API_VERSION?.trim() || "preview";
1956
+ }
2194
1957
  //#endregion
2195
1958
  //#region packages/ai/src/providers/openai-responses-stream-compat.ts
2196
1959
  const OPENAI_RESPONSES_OUTPUT_TEXT_CONTENT_PART_TYPE = "output_text";
@@ -2220,19 +1983,16 @@ function resolveResponsesMessageSnapshotCollapse(params) {
2220
1983
  }
2221
1984
  //#endregion
2222
1985
  //#region packages/ai/src/providers/openai-responses-tool-call-tracker.ts
2223
- function readIdentityValue(value) {
2224
- return (typeof value === "string" ? value.trim() : "") || void 0;
2225
- }
2226
1986
  function readOutputIndex(event) {
2227
1987
  return typeof event.output_index === "number" && Number.isInteger(event.output_index) && event.output_index >= 0 ? event.output_index : void 0;
2228
1988
  }
2229
1989
  function readEventIdentity(event) {
2230
- return { itemId: readIdentityValue(event.item_id) };
1990
+ return { itemId: normalizeOptionalString(event.item_id) };
2231
1991
  }
2232
1992
  function readResponsesToolCallItemIdentity(item) {
2233
1993
  return {
2234
- itemId: readIdentityValue(item.id),
2235
- callId: readIdentityValue(item.call_id)
1994
+ itemId: normalizeOptionalString(item.id),
1995
+ callId: normalizeOptionalString(item.call_id)
2236
1996
  };
2237
1997
  }
2238
1998
  function createResponsesToolCallTracker() {
@@ -2295,6 +2055,308 @@ function createResponsesToolCallTracker() {
2295
2055
  };
2296
2056
  }
2297
2057
  //#endregion
2058
+ //#region packages/ai/src/transports/openai-responses-debug.ts
2059
+ function stringifyUnknown(value, fallback = "") {
2060
+ if (typeof value === "string") return value;
2061
+ if (typeof value === "number" || typeof value === "boolean") return String(value);
2062
+ return fallback;
2063
+ }
2064
+ function safeDebugValue(value) {
2065
+ if (typeof value === "string") return value;
2066
+ if (typeof value === "number" || typeof value === "boolean") return String(value);
2067
+ if (value === null) return "null";
2068
+ if (value === void 0) return "undefined";
2069
+ return Array.isArray(value) ? "array" : typeof value;
2070
+ }
2071
+ function responseInputTextChars(input) {
2072
+ if (typeof input === "string") return input.length;
2073
+ if (Array.isArray(input)) return input.reduce((total, item) => total + responseInputTextChars(item), 0);
2074
+ if (!input || typeof input !== "object") return 0;
2075
+ const record = input;
2076
+ let total = 0;
2077
+ if (typeof record.text === "string") total += record.text.length;
2078
+ if (typeof record.content === "string") total += record.content.length;
2079
+ else if (Array.isArray(record.content)) total += responseInputTextChars(record.content);
2080
+ return total;
2081
+ }
2082
+ function responseInputRoles(input) {
2083
+ if (!Array.isArray(input)) return "";
2084
+ const roles = /* @__PURE__ */ new Set();
2085
+ for (const item of input) if (item && typeof item === "object") {
2086
+ const role = item.role;
2087
+ if (typeof role === "string" && role.trim()) roles.add(role.trim());
2088
+ }
2089
+ return [...roles].toSorted().join(",");
2090
+ }
2091
+ function responseInputItemShape(input) {
2092
+ if (!Array.isArray(input)) return "none";
2093
+ return input.map((item) => {
2094
+ if (!isRecord(item) || typeof item.type !== "string") return "unknown";
2095
+ if (item.type === "message" && typeof item.role === "string") return `message:${item.role}`;
2096
+ return item.type;
2097
+ }).join(",") || "none";
2098
+ }
2099
+ function hashOpaqueResponsesValue(value) {
2100
+ return createHash("sha256").update(value).digest("hex");
2101
+ }
2102
+ function summarizeResponsesCompactionItems(input) {
2103
+ if (!Array.isArray(input)) return [
2104
+ "compactionItems=0",
2105
+ "compactionIdHashes=none",
2106
+ "compactionPayloadHashes=none",
2107
+ "compactionInputIndexes=none"
2108
+ ];
2109
+ const compactions = input.flatMap((item, inputIndex) => {
2110
+ if (!isRecord(item) || item.type !== "compaction") return [];
2111
+ return [{
2112
+ idHash: typeof item.id === "string" ? hashOpaqueResponsesValue(item.id) : void 0,
2113
+ inputIndex,
2114
+ payloadHash: typeof item.encrypted_content === "string" ? hashOpaqueResponsesValue(item.encrypted_content) : void 0
2115
+ }];
2116
+ });
2117
+ return [
2118
+ `compactionItems=${compactions.length}`,
2119
+ `compactionIdHashes=${compactions.flatMap((item) => item.idHash ?? []).join(",") || "none"}`,
2120
+ `compactionPayloadHashes=${compactions.flatMap((item) => item.payloadHash ?? []).join(",") || "none"}`,
2121
+ `compactionInputIndexes=${compactions.map((item) => item.inputIndex).join(",") || "none"}`
2122
+ ];
2123
+ }
2124
+ function readToolPayloadField(record, field) {
2125
+ try {
2126
+ return record[field];
2127
+ } catch {
2128
+ return;
2129
+ }
2130
+ }
2131
+ function readResponsesToolDisplayName(tool) {
2132
+ if (!tool || typeof tool !== "object") return "";
2133
+ const record = tool;
2134
+ const name = readToolPayloadField(record, "name");
2135
+ if (typeof name === "string") return name;
2136
+ const fn = readToolPayloadField(record, "function");
2137
+ if (fn && typeof fn === "object") {
2138
+ const fnName = readToolPayloadField(fn, "name");
2139
+ if (typeof fnName === "string") return fnName;
2140
+ }
2141
+ const type = readToolPayloadField(record, "type");
2142
+ return typeof type === "string" && type !== "function" ? type : "";
2143
+ }
2144
+ function summarizeResponsesTools(tools) {
2145
+ if (!Array.isArray(tools)) return "count=0";
2146
+ const names = tools.map(readResponsesToolDisplayName).filter(Boolean);
2147
+ const mode = resolveModelPayloadDebugMode();
2148
+ const maxNames = mode === "tools" || mode === "full-redacted" ? names.length : 12;
2149
+ const label = maxNames >= names.length ? "names" : "sample";
2150
+ const shown = names.slice(0, maxNames).join(",");
2151
+ return `count=${tools.length}${shown ? ` ${label}=${shown}` : ""}`;
2152
+ }
2153
+ function stringifyRedactedPayload(value) {
2154
+ try {
2155
+ const encoded = JSON.stringify(value, (key, child) => key === "encrypted_content" ? "<opaque data omitted>" : child);
2156
+ if (!encoded) return "<empty>";
2157
+ const redacted = redactSensitiveText(encoded, { mode: "tools" });
2158
+ return redacted.length > 8e3 ? `${truncateUtf16Safe(redacted, 8e3)}…<truncated>` : redacted;
2159
+ } catch {
2160
+ return "<unserializable>";
2161
+ }
2162
+ }
2163
+ function stringifyRedactedEvent(value) {
2164
+ const redacted = stringifyRedactedPayload(value);
2165
+ return redacted.length > 2e3 ? `${truncateUtf16Safe(redacted, 2e3)}…<truncated>` : redacted;
2166
+ }
2167
+ const RESPONSE_FAILED_FAILURE_FIELD_KEYS = [
2168
+ "error",
2169
+ "incomplete_details",
2170
+ "status_details",
2171
+ "failure_reason",
2172
+ "last_error",
2173
+ "provider_error",
2174
+ "error_details"
2175
+ ];
2176
+ function readResponseFailedString(record, key) {
2177
+ return stringifyUnknown(record?.[key]);
2178
+ }
2179
+ function buildResponsesFailedEventSummary(message, responseId, observation) {
2180
+ const summary = { message };
2181
+ if (responseId) summary.responseId = responseId;
2182
+ if (observation) summary.observation = observation;
2183
+ return summary;
2184
+ }
2185
+ function isResponseFailedIdentifierKey(key) {
2186
+ const normalized = key.replace(/[-_\s]/g, "").toLowerCase();
2187
+ return normalized === "requestid" || normalized === "xrequestid" || normalized === "providerrequestid" || normalized === "providerresponseid" || normalized === "litellmrequestid" || normalized.includes("request") && normalized.endsWith("id") || normalized.includes("provider") && normalized.endsWith("id");
2188
+ }
2189
+ function collectResponseFailedIdentifierHashes(value, opts = {}) {
2190
+ const path = opts.path ?? "";
2191
+ const depth = opts.depth ?? 0;
2192
+ const identifierKey = opts.identifierKey ?? "";
2193
+ const out = opts.out ?? [];
2194
+ const seen = opts.seen ?? /* @__PURE__ */ new WeakSet();
2195
+ if (out.length >= 12 || depth > 4 || !value || typeof value !== "object") return out;
2196
+ if (seen.has(value)) return out;
2197
+ seen.add(value);
2198
+ if (Array.isArray(value)) {
2199
+ for (const [index, item] of value.entries()) {
2200
+ if (index >= 8 || out.length >= 12) break;
2201
+ const itemString = typeof item === "string" || typeof item === "number" ? String(item).trim() : "";
2202
+ if (identifierKey && isResponseFailedIdentifierKey(identifierKey) && itemString) {
2203
+ out.push(`${path}[${index}]=${redactIdentifier(itemString, { len: 12 })}`);
2204
+ continue;
2205
+ }
2206
+ collectResponseFailedIdentifierHashes(item, {
2207
+ path: `${path}[${index}]`,
2208
+ depth: depth + 1,
2209
+ identifierKey,
2210
+ out,
2211
+ seen
2212
+ });
2213
+ }
2214
+ return out;
2215
+ }
2216
+ for (const [key, child] of Object.entries(value)) {
2217
+ if (out.length >= 12) break;
2218
+ const childPath = path ? `${path}.${key}` : key;
2219
+ const childString = typeof child === "string" || typeof child === "number" ? String(child).trim() : "";
2220
+ if (isResponseFailedIdentifierKey(key) && childString) {
2221
+ out.push(`${childPath}=${redactIdentifier(childString, { len: 12 })}`);
2222
+ continue;
2223
+ }
2224
+ collectResponseFailedIdentifierHashes(child, {
2225
+ path: childPath,
2226
+ depth: depth + 1,
2227
+ identifierKey: isResponseFailedIdentifierKey(key) ? key : void 0,
2228
+ out,
2229
+ seen
2230
+ });
2231
+ }
2232
+ return out;
2233
+ }
2234
+ function redactResponseFailedDiagnosticValue(value, opts = {}) {
2235
+ const key = opts.key ?? "";
2236
+ const depth = opts.depth ?? 0;
2237
+ if (typeof value === "string" || typeof value === "number") return key && isResponseFailedIdentifierKey(key) ? redactIdentifier(String(value), { len: 12 }) : value;
2238
+ if (depth > 6 || !value || typeof value !== "object") return value;
2239
+ const seen = opts.seen ?? /* @__PURE__ */ new WeakSet();
2240
+ if (seen.has(value)) return "<circular>";
2241
+ seen.add(value);
2242
+ if (Array.isArray(value)) return value.slice(0, 16).map((item) => redactResponseFailedDiagnosticValue(item, {
2243
+ key,
2244
+ depth: depth + 1,
2245
+ seen
2246
+ }));
2247
+ const out = {};
2248
+ for (const [childKey, child] of Object.entries(value)) out[childKey] = redactResponseFailedDiagnosticValue(child, {
2249
+ key: childKey,
2250
+ depth: depth + 1,
2251
+ seen
2252
+ });
2253
+ return out;
2254
+ }
2255
+ function buildResponsesFailedFailureFields(response) {
2256
+ if (!response) return {};
2257
+ const fields = {};
2258
+ for (const key of RESPONSE_FAILED_FAILURE_FIELD_KEYS) if (response[key] !== void 0 && response[key] !== null) fields[key] = response[key];
2259
+ return fields;
2260
+ }
2261
+ function buildResponsesFailedNoDetailsObservation(event, model, response = isRecord(event.response) ? event.response : void 0) {
2262
+ const failureFields = redactResponseFailedDiagnosticValue(buildResponsesFailedFailureFields(response));
2263
+ const metadataKeys = isRecord(response?.metadata) ? Object.keys(response.metadata).toSorted() : [];
2264
+ const responsePreview = {
2265
+ id: readResponseFailedString(response, "id"),
2266
+ status: readResponseFailedString(response, "status"),
2267
+ model: readResponseFailedString(response, "model"),
2268
+ object: readResponseFailedString(response, "object"),
2269
+ failureFields,
2270
+ metadataKeys
2271
+ };
2272
+ return {
2273
+ event: "openai_responses_response_failed_without_details",
2274
+ provider: model.provider,
2275
+ api: model.api,
2276
+ transportModel: model.id,
2277
+ providerRuntimeFailureKind: "no_error_details",
2278
+ responseId: responsePreview.id,
2279
+ responseStatus: responsePreview.status,
2280
+ responseModel: responsePreview.model,
2281
+ responseObject: responsePreview.object,
2282
+ metadataKeys,
2283
+ requestIdHashes: collectResponseFailedIdentifierHashes(event),
2284
+ failureFieldsPreview: stringifyRedactedEvent(failureFields),
2285
+ responsePreview: stringifyRedactedEvent(responsePreview)
2286
+ };
2287
+ }
2288
+ function summarizeResponsesFailedNoDetailsObservation(observation) {
2289
+ const requestIds = observation.requestIdHashes.join(",");
2290
+ const metadataKeys = observation.metadataKeys.join(",");
2291
+ return `responseId=${safeDebugValue(observation.responseId || void 0)} responseStatus=${safeDebugValue(observation.responseStatus || void 0)} responseModel=${safeDebugValue(observation.responseModel || void 0)} requestIds=${requestIds || "none"} metadataKeys=${metadataKeys || "none"} failureFields=${observation.failureFieldsPreview}`;
2292
+ }
2293
+ function normalizeResponsesFailedEvent(event, model) {
2294
+ const response = isRecord(event.response) ? event.response : void 0;
2295
+ const responseId = readResponseFailedString(response, "id") || void 0;
2296
+ const error = isRecord(response?.error) ? response.error : void 0;
2297
+ if (error) {
2298
+ const code = readResponseFailedString(error, "code").trim();
2299
+ const message = readResponseFailedString(error, "message").trim();
2300
+ if (code || message) return buildResponsesFailedEventSummary(`${code || "unknown"}: ${message || "no message"}`, responseId);
2301
+ }
2302
+ const incompleteReason = readResponseFailedString(isRecord(response?.incomplete_details) ? response.incomplete_details : void 0, "reason");
2303
+ if (incompleteReason) return buildResponsesFailedEventSummary(`incomplete: ${incompleteReason}`, responseId);
2304
+ return buildResponsesFailedEventSummary(RESPONSE_FAILED_NO_DETAILS_MESSAGE, responseId, buildResponsesFailedNoDetailsObservation(event, model, response));
2305
+ }
2306
+ var ResponsesStreamFailure = class extends Error {
2307
+ constructor(failure, response) {
2308
+ super(failure.message);
2309
+ this.name = "ResponsesStreamFailure";
2310
+ this.responseId = failure.responseId;
2311
+ this.response = response;
2312
+ this.observation = failure.observation;
2313
+ }
2314
+ };
2315
+ function logResponsesFailedNoDetails(observation) {
2316
+ log.warn(`[responses] response.failed missing error details provider=${observation.provider} api=${observation.api} model=${observation.transportModel} ` + summarizeResponsesFailedNoDetailsObservation(observation), observation);
2317
+ }
2318
+ function summarizeResponsesPayload(params) {
2319
+ if (!params || typeof params !== "object") return "payload=non-object";
2320
+ const record = params;
2321
+ const input = record.input;
2322
+ const reasoning = record.reasoning && typeof record.reasoning === "object" ? record.reasoning : void 0;
2323
+ const text = record.text && typeof record.text === "object" ? record.text : void 0;
2324
+ const parts = [
2325
+ `fields=${Object.keys(record).toSorted().join(",")}`,
2326
+ `model=${safeDebugValue(record.model)}`,
2327
+ `stream=${safeDebugValue(record.stream)}`,
2328
+ `inputItems=${Array.isArray(input) ? input.length : typeof input}`,
2329
+ `inputItemShape=${responseInputItemShape(input)}`,
2330
+ `inputRoles=${responseInputRoles(input) || "none"}`,
2331
+ `inputTextChars=${responseInputTextChars(input)}`,
2332
+ `tools=${summarizeResponsesTools(record.tools)}`,
2333
+ `reasoningEffort=${safeDebugValue(reasoning?.effort)}`,
2334
+ `reasoningSummary=${safeDebugValue(reasoning?.summary)}`,
2335
+ `textVerbosity=${safeDebugValue(text?.verbosity)}`,
2336
+ `serviceTier=${safeDebugValue(record.service_tier)}`,
2337
+ ...summarizeResponsesCompactionItems(input),
2338
+ `store=${safeDebugValue(record.store)}`,
2339
+ `promptCacheKey=${record.prompt_cache_key === void 0 ? "absent" : "present"}`,
2340
+ `metadataKeys=${record.metadata && typeof record.metadata === "object" ? Object.keys(record.metadata).toSorted().join(",") : "none"}`
2341
+ ];
2342
+ if (resolveModelPayloadDebugMode() === "full-redacted") parts.push(`payload=${stringifyRedactedPayload(record)}`);
2343
+ return parts.join(" ");
2344
+ }
2345
+ function summarizeOpenAITransportError(error) {
2346
+ if (!error || typeof error !== "object") return `type=${typeof error} message=${safeDebugValue(error)}`;
2347
+ const record = error;
2348
+ const cause = record.cause && typeof record.cause === "object" ? record.cause : void 0;
2349
+ return [
2350
+ `name=${safeDebugValue(record.name)}`,
2351
+ `status=${safeDebugValue(record.status)}`,
2352
+ `code=${safeDebugValue(record.code)}`,
2353
+ `type=${safeDebugValue(record.type)}`,
2354
+ `causeName=${safeDebugValue(cause?.name)}`,
2355
+ `causeCode=${safeDebugValue(cause?.code)}`,
2356
+ `message=${error instanceof Error ? error.message : safeDebugValue(error)}`
2357
+ ].join(" ");
2358
+ }
2359
+ //#endregion
2298
2360
  //#region packages/ai/src/transports/openai-responses-stream-observer-internal.ts
2299
2361
  const STRING_DELTA_EVENTS = /* @__PURE__ */ new Set([
2300
2362
  "response.function_call_arguments.delta",
@@ -2316,7 +2378,7 @@ async function* adaptResponsesStream(stream, signal) {
2316
2378
  await scheduler.afterEvent();
2317
2379
  }
2318
2380
  }
2319
- async function* observeResponsesStream(stream, model) {
2381
+ async function* observeResponsesStream(stream, model, requestStartedAt) {
2320
2382
  const startedAt = Date.now();
2321
2383
  const eventTypes = /* @__PURE__ */ new Map();
2322
2384
  const debugMode = resolveModelSseDebugMode();
@@ -2326,7 +2388,7 @@ async function* observeResponsesStream(stream, model) {
2326
2388
  const type = isRecord(event) && typeof event.type === "string" ? event.type : "unknown";
2327
2389
  eventCount += 1;
2328
2390
  eventTypes.set(type, (eventTypes.get(type) ?? 0) + 1);
2329
- if (eventCount === 1) emitModelTransportDebug(log, `[responses] first_event provider=${model.provider} api=${model.api} model=${model.id} elapsedMs=${Date.now() - startedAt} type=${type}`);
2391
+ if (eventCount === 1) emitModelTransportDebug(log, `[responses] first_event provider=${model.provider} api=${model.api} model=${model.id} elapsedMs=${Date.now() - (requestStartedAt ?? startedAt)} headersToEventMs=${Date.now() - startedAt} type=${type}`);
2330
2392
  if (debugMode === "peek" && eventCount <= 5) emitModelTransportDebug(log, `[responses] event_peek provider=${model.provider} api=${model.api} model=${model.id} index=${eventCount} type=${type} event=${stringifyRedactedEvent(event)}`);
2331
2393
  yield event;
2332
2394
  }
@@ -2337,6 +2399,23 @@ async function* observeResponsesStream(stream, model) {
2337
2399
  }
2338
2400
  //#endregion
2339
2401
  //#region packages/ai/src/transports/openai-responses-stream-slots-internal.ts
2402
+ function createResponsesOutputContentIndex() {
2403
+ const indexes = /* @__PURE__ */ new Map();
2404
+ const identity = (item) => {
2405
+ if ((item.type === "reasoning" || item.type === "message") && item.id) return `${item.type}:${item.id}`;
2406
+ return item.type === "function_call" ? `function_call:${item.call_id ?? item.id ?? ""}` : void 0;
2407
+ };
2408
+ return {
2409
+ get(item) {
2410
+ const key = identity(item);
2411
+ return key === void 0 ? void 0 : indexes.get(key);
2412
+ },
2413
+ set(item, contentIndex) {
2414
+ const key = identity(item);
2415
+ if (key !== void 0) indexes.set(key, contentIndex);
2416
+ }
2417
+ };
2418
+ }
2340
2419
  function appendResponsesPendingTextDelta(slot, delta, materialize) {
2341
2420
  slot.pendingText = `${slot.pendingText ?? ""}${delta}`;
2342
2421
  const priorText = slot.collapseCandidate?.block.text ?? "";
@@ -2385,6 +2464,14 @@ function createResponsesOutputSlotTracker() {
2385
2464
  }
2386
2465
  //#endregion
2387
2466
  //#region packages/ai/src/providers/openai-responses-terminal-usage.ts
2467
+ /**
2468
+ * Canonical mapping for terminal OpenAI Responses events.
2469
+ *
2470
+ * `response.completed`, `response.incomplete`, and `response.failed` are terminal and can carry
2471
+ * usage, so every Responses path finalizes through the helpers here. Keeping one owner prevents
2472
+ * package and managed transports from drifting on token buckets, service-tier pricing, or future
2473
+ * terminal-event semantics.
2474
+ */
2388
2475
  function readCount(value) {
2389
2476
  return typeof value === "number" && Number.isFinite(value) ? value : 0;
2390
2477
  }
@@ -2414,8 +2501,7 @@ function mapResponsesTerminalUsage(usage) {
2414
2501
  }
2415
2502
  /** Reasoning tokens are reported by the agent path only; the package path does not track them. */
2416
2503
  function readResponsesReasoningTokens(usage) {
2417
- const reasoningTokens = usage?.output_tokens_details?.reasoning_tokens;
2418
- return typeof reasoningTokens === "number" && Number.isFinite(reasoningTokens) ? reasoningTokens : void 0;
2504
+ return asFiniteNumber(usage?.output_tokens_details?.reasoning_tokens);
2419
2505
  }
2420
2506
  function mapResponsesTerminalStopReason(status) {
2421
2507
  if (!status) return "stop";
@@ -2522,7 +2608,7 @@ function createResponsesTerminalController(params) {
2522
2608
  content: text,
2523
2609
  partial: output
2524
2610
  });
2525
- return;
2611
+ return started.index;
2526
2612
  }
2527
2613
  const previous = params.getLastTextBlock();
2528
2614
  const collapse = resolveResponsesMessageSnapshotCollapse({
@@ -2542,7 +2628,7 @@ function createResponsesTerminalController(params) {
2542
2628
  content: collapse.text,
2543
2629
  partial: output
2544
2630
  });
2545
- return;
2631
+ return previous.index;
2546
2632
  }
2547
2633
  const block = {
2548
2634
  type: "text",
@@ -2567,6 +2653,7 @@ function createResponsesTerminalController(params) {
2567
2653
  content: text,
2568
2654
  partial: output
2569
2655
  });
2656
+ return index;
2570
2657
  };
2571
2658
  const appendToolCall = (item) => {
2572
2659
  const validated = resolveCompletedResponsesToolCall(item);
@@ -2589,17 +2676,17 @@ function createResponsesTerminalController(params) {
2589
2676
  toolCall,
2590
2677
  partial: output
2591
2678
  });
2679
+ return contentIndex;
2592
2680
  };
2593
2681
  const recoverTerminalOutput = (items, includeToolCalls) => {
2594
2682
  let hasCompletedLaterOutput = false;
2595
2683
  for (const item of items.toReversed()) {
2596
2684
  if (item.type === "reasoning") {
2597
- hasCompletedLaterOutput ||= params.reasoningBlocksById.has(item.id);
2685
+ hasCompletedLaterOutput ||= params.outputItemContentIndexes.get(item) !== void 0;
2598
2686
  continue;
2599
2687
  }
2600
2688
  if (item.type !== "message" && item.type !== "function_call") continue;
2601
- const identity = item.type === "message" ? `message:${item.id}` : `function_call:${item.call_id}`;
2602
- if (params.completedOutputItemIdentities.has(identity) || item.type === "message" && params.startedTextBlocksByItemId.has(item.id)) {
2689
+ if (params.outputItemContentIndexes.get(item) !== void 0 || item.type === "message" && params.startedTextBlocksByItemId.has(item.id)) {
2603
2690
  hasCompletedLaterOutput = true;
2604
2691
  continue;
2605
2692
  }
@@ -2607,25 +2694,32 @@ function createResponsesTerminalController(params) {
2607
2694
  if (hasCompletedLaterOutput) throw new Error("Responses stream omitted an output item before completed output");
2608
2695
  if (item.type === "function_call") resolveCompletedResponsesToolCall(item);
2609
2696
  }
2610
- for (const item of items) if (item.type === "message") {
2611
- const identity = `message:${item.id}`;
2612
- if (params.completedOutputItemIdentities.has(identity)) continue;
2613
- appendText(item);
2614
- params.completedOutputItemIdentities.add(identity);
2697
+ for (const [terminalIndex, item] of items.entries()) if (item.type === "message") {
2698
+ if (params.outputItemContentIndexes.get(item) !== void 0 && !params.startedTextBlocksByItemId.has(item.id)) continue;
2699
+ const appendedIndex = appendText(item);
2700
+ if (appendedIndex !== void 0) params.outputItemContentIndexes.set(item, appendedIndex);
2615
2701
  } else {
2616
2702
  params.setLastTextBlock(null);
2617
- if (includeToolCalls && item.type === "function_call") {
2618
- const identity = `function_call:${item.call_id}`;
2619
- if (params.completedOutputItemIdentities.has(identity)) continue;
2620
- appendToolCall(item);
2621
- params.completedOutputItemIdentities.add(identity);
2703
+ const alreadyCapturedCompaction = item.type === "compaction" && output.providerReplay?.type === "openai-responses-compaction" && output.providerReplay.id === item.id && output.providerReplay.data === item.encrypted_content;
2704
+ if (item.type === "compaction" && !alreadyCapturedCompaction) {
2705
+ let replayIndex = blocks.length;
2706
+ for (const laterItem of items.slice(terminalIndex + 1)) {
2707
+ const laterContentIndex = params.outputItemContentIndexes.get(laterItem);
2708
+ if (laterContentIndex !== void 0) {
2709
+ replayIndex = laterContentIndex;
2710
+ break;
2711
+ }
2712
+ }
2713
+ captureOpenAIResponsesCompaction(output, item, replayIndex, model, options?.reasoningReplayMetadata);
2714
+ } else if (includeToolCalls && item.type === "function_call") {
2715
+ if (params.outputItemContentIndexes.get(item) !== void 0) continue;
2716
+ params.outputItemContentIndexes.set(item, appendToolCall(item));
2622
2717
  }
2623
2718
  }
2624
2719
  };
2625
- const finalizeResponse = (response, terminalEventType) => {
2626
- params.markFinalized();
2627
- backfillReasoning(response.output ?? []);
2628
- output.responseId = response.id || output.responseId;
2720
+ const finalizeTerminalFacts = (response, responseId = response.id) => {
2721
+ output.responseId = responseId || output.responseId;
2722
+ output.responseModel = response.model?.trim() || void 0;
2629
2723
  const usage = mapResponsesTerminalUsage(response.usage);
2630
2724
  const reasoningTokens = readResponsesReasoningTokens(response.usage);
2631
2725
  if (usage) output.usage = {
@@ -2644,6 +2738,11 @@ function createResponsesTerminalController(params) {
2644
2738
  const tier = options.resolveServiceTier ? options.resolveServiceTier(response.service_tier, options.serviceTier) : response.service_tier ?? options.serviceTier;
2645
2739
  options.applyServiceTierPricing(output.usage, tier);
2646
2740
  }
2741
+ };
2742
+ const finalizeResponse = (response, terminalEventType) => {
2743
+ params.markFinalized();
2744
+ backfillReasoning(response.output ?? []);
2745
+ finalizeTerminalFacts(response);
2647
2746
  const terminal = resolveResponsesTerminalStopReason({
2648
2747
  status: response.status,
2649
2748
  terminalEventType,
@@ -2655,30 +2754,22 @@ function createResponsesTerminalController(params) {
2655
2754
  };
2656
2755
  return {
2657
2756
  finalizeResponse,
2757
+ finalizeFailedResponse: finalizeTerminalFacts,
2658
2758
  recoverTerminalOutput
2659
2759
  };
2660
2760
  }
2661
2761
  //#endregion
2662
2762
  //#region packages/ai/src/transports/openai-responses-stream-internal.ts
2663
- var ResponsesStreamFailure = class extends Error {
2664
- constructor(failure, response) {
2665
- super(failure.message);
2666
- this.name = "ResponsesStreamFailure";
2667
- this.responseId = failure.responseId;
2668
- this.response = response;
2669
- this.observation = failure.observation;
2670
- }
2671
- };
2672
2763
  async function processResponsesStream(openaiStream, output, stream, model, options) {
2673
2764
  const streamingToolCalls = createResponsesToolCallTracker();
2674
2765
  const outputSlots = createResponsesOutputSlotTracker();
2675
2766
  const reasoningBlocksById = /* @__PURE__ */ new Map();
2676
- const completedOutputItemIdentities = /* @__PURE__ */ new Set();
2767
+ const outputItemContentIndexes = createResponsesOutputContentIndex();
2677
2768
  const startedTextBlocksByItemId = /* @__PURE__ */ new Map();
2678
- let terminalResponseEvent;
2769
+ let terminalResponse;
2679
2770
  let lastTextBlock = null;
2680
2771
  const blocks = output.content;
2681
- const blockIndex = () => blocks.length - 1;
2772
+ const compactionTracker = createCompactionTracker(output, model, options);
2682
2773
  const createOutputSlot = (event, item) => {
2683
2774
  if (item.type === "reasoning") {
2684
2775
  const block = {
@@ -2693,6 +2784,7 @@ async function processResponsesStream(openaiStream, output, stream, model, optio
2693
2784
  };
2694
2785
  blocks.push(block);
2695
2786
  reasoningBlocksById.set(item.id, block);
2787
+ outputItemContentIndexes.set(item, slot.contentIndex);
2696
2788
  outputSlots.register(event, slot);
2697
2789
  stream.push({
2698
2790
  type: "thinking_start",
@@ -2719,6 +2811,7 @@ async function processResponsesStream(openaiStream, output, stream, model, optio
2719
2811
  };
2720
2812
  if (block) {
2721
2813
  blocks.push(block);
2814
+ outputItemContentIndexes.set(messageItem, slot.contentIndex ?? blocks.length - 1);
2722
2815
  startedTextBlocksByItemId.set(messageItem.id, {
2723
2816
  block,
2724
2817
  index: slot.contentIndex ?? blocks.length - 1,
@@ -2751,7 +2844,8 @@ async function processResponsesStream(openaiStream, output, stream, model, optio
2751
2844
  ...slot.item.phase ? { textSignature: encodeTextSignatureV1(slot.item.id, slot.item.phase) } : {}
2752
2845
  };
2753
2846
  blocks.push(slot.block);
2754
- slot.contentIndex = blockIndex();
2847
+ slot.contentIndex = blocks.length - 1;
2848
+ outputItemContentIndexes.set(slot.item, slot.contentIndex);
2755
2849
  startedTextBlocksByItemId.set(slot.item.id, {
2756
2850
  block: slot.block,
2757
2851
  index: slot.contentIndex,
@@ -2774,21 +2868,19 @@ async function processResponsesStream(openaiStream, output, stream, model, optio
2774
2868
  const materializeDeferredTextSlots = (except) => {
2775
2869
  for (const slot of outputSlots.values()) if (slot !== except && slot.type === "text") materializeDeferredTextSlot(slot);
2776
2870
  };
2777
- const { finalizeResponse, recoverTerminalOutput } = createResponsesTerminalController({
2871
+ const { finalizeResponse, finalizeFailedResponse, recoverTerminalOutput } = createResponsesTerminalController({
2778
2872
  output,
2779
2873
  stream,
2780
2874
  model,
2781
2875
  options,
2782
2876
  reasoningBlocksById,
2783
- completedOutputItemIdentities,
2784
2877
  startedTextBlocksByItemId,
2878
+ outputItemContentIndexes,
2785
2879
  getLastTextBlock: () => lastTextBlock,
2786
2880
  setLastTextBlock: (block) => {
2787
2881
  lastTextBlock = block;
2788
2882
  },
2789
- markFinalized: () => {
2790
- terminalResponseEvent = "finalized";
2791
- }
2883
+ markFinalized: () => void 0
2792
2884
  });
2793
2885
  const guardedStream = adaptResponsesStream(withFirstStreamEventTimeout(openaiStream, {
2794
2886
  provider: model.provider,
@@ -2801,327 +2893,538 @@ async function processResponsesStream(openaiStream, output, stream, model, optio
2801
2893
  hint: "The provider may be stalled while parsing the tool payload; retry with a smaller tool surface or enable OPENCLAW_DEBUG_MODEL_PAYLOAD=tools to inspect exposed tools."
2802
2894
  }), options?.signal);
2803
2895
  try {
2804
- for await (const event of guardedStream) if (event.type === "response.created") output.responseId = event.response.id;
2805
- else if (event.type === "response.output_item.added") {
2806
- materializeDeferredTextSlots();
2807
- const item = event.item;
2808
- if (item.type !== "message") lastTextBlock = null;
2809
- if (item.type === "reasoning" || item.type === "message") createOutputSlot(event, item);
2810
- else if (item.type === "function_call") {
2811
- const toolCallBlock = {
2812
- type: "toolCall",
2813
- id: resolveResponsesToolCallId(item),
2814
- name: typeof item.name === "string" ? item.name.trim() : "",
2815
- arguments: {},
2816
- partialJson: item.arguments || ""
2817
- };
2818
- const contentIndex = output.content.length;
2819
- const toolCallState = {
2820
- block: toolCallBlock,
2821
- contentIndex,
2822
- argumentStreamReliable: true,
2823
- ...readResponsesToolCallItemIdentity(item)
2824
- };
2825
- streamingToolCalls.register(event, toolCallState);
2826
- if (readResponsesOutputIndex(event) !== void 0) outputSlots.register(event, {
2827
- type: "toolCall",
2828
- toolCall: toolCallState
2829
- });
2830
- output.content.push(toolCallBlock);
2831
- stream.push({
2832
- type: "toolcall_start",
2833
- contentIndex,
2834
- partial: output
2835
- });
2836
- }
2837
- } else if (event.type === "response.reasoning_summary_part.added") {
2838
- const slot = outputSlots.resolve(event, "thinking");
2839
- if (!slot) continue;
2840
- slot.item.summary = slot.item.summary || [];
2841
- slot.item.summary.push(event.part);
2842
- } else if (event.type === "response.reasoning_summary_text.delta") {
2843
- const slot = outputSlots.resolve(event, "thinking");
2844
- if (!slot) continue;
2845
- slot.item.summary = slot.item.summary || [];
2846
- const lastPart = slot.item.summary[slot.item.summary.length - 1];
2847
- if (!lastPart) continue;
2848
- slot.block.thinking += event.delta;
2849
- lastPart.text += event.delta;
2850
- stream.push({
2851
- type: "thinking_delta",
2852
- contentIndex: slot.contentIndex,
2853
- delta: event.delta,
2854
- partial: output
2855
- });
2856
- } else if (event.type === "response.reasoning_summary_part.done") {
2857
- const slot = outputSlots.resolve(event, "thinking");
2858
- if (!slot) continue;
2859
- slot.item.summary = slot.item.summary || [];
2860
- const lastPart = slot.item.summary[slot.item.summary.length - 1];
2861
- if (!lastPart) continue;
2862
- slot.block.thinking += "\n\n";
2863
- lastPart.text += "\n\n";
2864
- stream.push({
2865
- type: "thinking_delta",
2866
- contentIndex: slot.contentIndex,
2867
- delta: "\n\n",
2868
- partial: output
2869
- });
2870
- } else if (event.type === "response.reasoning_text.delta") {
2871
- const slot = outputSlots.resolve(event, "thinking");
2872
- if (!slot) continue;
2873
- slot.block.thinking += event.delta;
2874
- stream.push({
2875
- type: "thinking_delta",
2876
- contentIndex: slot.contentIndex,
2877
- delta: event.delta,
2878
- partial: output
2879
- });
2880
- } else if (event.type === "response.content_part.added") {
2881
- const slot = outputSlots.resolve(event, "text");
2882
- if (!slot) continue;
2883
- slot.item.content = slot.item.content || [];
2884
- if (event.part.type === "output_text" || event.part.type === "text" || event.part.type === "refusal") slot.item.content.push(event.part);
2885
- } else if (event.type === "response.output_text.delta") {
2886
- const slot = outputSlots.resolve(event, "text");
2887
- if (!slot) continue;
2888
- slot.item.content ||= [];
2889
- let lastPart = slot.item.content[slot.item.content.length - 1];
2890
- if (!isResponsesTextContentPartType(lastPart?.type)) {
2891
- lastPart = {
2892
- type: "output_text",
2893
- text: "",
2894
- annotations: []
2895
- };
2896
- slot.item.content.push(lastPart);
2897
- }
2898
- lastPart.text += event.delta;
2899
- if (slot.pendingText !== null) appendResponsesPendingTextDelta(slot, event.delta, materializeDeferredTextSlot);
2900
- else if (slot.block && slot.contentIndex !== void 0) {
2901
- slot.block.text += event.delta;
2896
+ for await (const event of guardedStream) {
2897
+ notifyLlmRequestActivity(options?.signal);
2898
+ if (event.type === "response.created") output.responseId = event.response.id;
2899
+ else if (event.type === "response.output_item.added") {
2900
+ materializeDeferredTextSlots();
2901
+ const item = event.item;
2902
+ compactionTracker.added(item, blocks.length);
2903
+ if (item.type !== "message") lastTextBlock = null;
2904
+ if (item.type === "reasoning" || item.type === "message") createOutputSlot(event, item);
2905
+ else if (item.type === "function_call") {
2906
+ const toolCallBlock = {
2907
+ type: "toolCall",
2908
+ id: resolveResponsesToolCallId(item),
2909
+ name: typeof item.name === "string" ? item.name.trim() : "",
2910
+ arguments: {},
2911
+ partialJson: item.arguments || ""
2912
+ };
2913
+ const contentIndex = output.content.length;
2914
+ const toolCallState = {
2915
+ block: toolCallBlock,
2916
+ contentIndex,
2917
+ argumentStreamReliable: true,
2918
+ ...readResponsesToolCallItemIdentity(item)
2919
+ };
2920
+ streamingToolCalls.register(event, toolCallState);
2921
+ if (readResponsesOutputIndex(event) !== void 0) outputSlots.register(event, {
2922
+ type: "toolCall",
2923
+ toolCall: toolCallState
2924
+ });
2925
+ output.content.push(toolCallBlock);
2926
+ outputItemContentIndexes.set(item, contentIndex);
2927
+ stream.push({
2928
+ type: "toolcall_start",
2929
+ contentIndex,
2930
+ partial: output
2931
+ });
2932
+ }
2933
+ } else if (event.type === "response.reasoning_summary_part.added") {
2934
+ const slot = outputSlots.resolve(event, "thinking");
2935
+ if (!slot) continue;
2936
+ slot.item.summary = slot.item.summary || [];
2937
+ slot.item.summary.push(event.part);
2938
+ } else if (event.type === "response.reasoning_summary_text.delta") {
2939
+ const slot = outputSlots.resolve(event, "thinking");
2940
+ if (!slot) continue;
2941
+ slot.item.summary = slot.item.summary || [];
2942
+ const lastPart = slot.item.summary[slot.item.summary.length - 1];
2943
+ if (!lastPart) continue;
2944
+ slot.block.thinking += event.delta;
2945
+ lastPart.text += event.delta;
2902
2946
  stream.push({
2903
- type: "text_delta",
2947
+ type: "thinking_delta",
2904
2948
  contentIndex: slot.contentIndex,
2905
- delta: event.delta
2949
+ delta: event.delta,
2950
+ partial: output
2906
2951
  });
2907
- }
2908
- } else if (isAzureResponsesTextDeltaEvent(event)) {
2909
- const slot = outputSlots.resolve(event, "text");
2910
- if (!slot) continue;
2911
- slot.item.content = slot.item.content || [];
2912
- let lastPart = slot.item.content[slot.item.content.length - 1];
2913
- if (lastPart?.type !== "text") {
2914
- lastPart = {
2915
- type: "text",
2916
- text: ""
2917
- };
2918
- slot.item.content.push(lastPart);
2919
- }
2920
- lastPart.text += event.delta;
2921
- if (slot.pendingText !== null) appendResponsesPendingTextDelta(slot, event.delta, materializeDeferredTextSlot);
2922
- else if (slot.block && slot.contentIndex !== void 0) {
2923
- slot.block.text += event.delta;
2952
+ } else if (event.type === "response.reasoning_summary_part.done") {
2953
+ const slot = outputSlots.resolve(event, "thinking");
2954
+ if (!slot) continue;
2955
+ slot.item.summary = slot.item.summary || [];
2956
+ const lastPart = slot.item.summary[slot.item.summary.length - 1];
2957
+ if (!lastPart) continue;
2958
+ slot.block.thinking += "\n\n";
2959
+ lastPart.text += "\n\n";
2924
2960
  stream.push({
2925
- type: "text_delta",
2961
+ type: "thinking_delta",
2926
2962
  contentIndex: slot.contentIndex,
2927
- delta: event.delta
2963
+ delta: "\n\n",
2964
+ partial: output
2928
2965
  });
2929
- }
2930
- } else if (event.type === "response.refusal.delta") {
2931
- const slot = outputSlots.resolve(event, "text");
2932
- if (!slot) continue;
2933
- slot.item.content ||= [];
2934
- let lastPart = slot.item.content[slot.item.content.length - 1];
2935
- if (lastPart?.type !== "refusal") {
2936
- lastPart = {
2937
- type: "refusal",
2938
- refusal: ""
2939
- };
2940
- slot.item.content.push(lastPart);
2941
- }
2942
- lastPart.refusal += event.delta;
2943
- if (slot.pendingText !== null) appendResponsesPendingTextDelta(slot, event.delta, materializeDeferredTextSlot);
2944
- else if (slot.block && slot.contentIndex !== void 0) {
2945
- slot.block.text += event.delta;
2966
+ } else if (event.type === "response.reasoning_text.delta") {
2967
+ const slot = outputSlots.resolve(event, "thinking");
2968
+ if (!slot) continue;
2969
+ slot.block.thinking += event.delta;
2946
2970
  stream.push({
2947
- type: "text_delta",
2971
+ type: "thinking_delta",
2948
2972
  contentIndex: slot.contentIndex,
2949
- delta: event.delta
2950
- });
2951
- }
2952
- } else if (event.type === "response.function_call_arguments.delta") {
2953
- const toolCall = streamingToolCalls.resolve(event);
2954
- if (toolCall) {
2955
- toolCall.block.partialJson += event.delta;
2956
- toolCall.block.arguments = parseStreamingJson(toolCall.block.partialJson);
2957
- stream.push({
2958
- type: "toolcall_delta",
2959
- contentIndex: toolCall.contentIndex,
2960
2973
  delta: event.delta,
2961
2974
  partial: output
2962
2975
  });
2963
- } else if (streamingToolCalls.hasActive()) streamingToolCalls.markArgumentsUnreliable();
2964
- } else if (event.type === "response.function_call_arguments.done") {
2965
- const toolCall = streamingToolCalls.resolve(event);
2966
- if (toolCall) {
2967
- const previousPartialJson = toolCall.block.partialJson;
2968
- const doneArguments = typeof event.arguments === "string" ? event.arguments : void 0;
2969
- if (doneArguments !== void 0 && (doneArguments.length > 0 || previousPartialJson === "")) {
2970
- toolCall.block.partialJson = doneArguments;
2971
- toolCall.block.arguments = parseStreamingJson(toolCall.block.partialJson);
2972
- toolCall.argumentStreamReliable = true;
2976
+ } else if (event.type === "response.content_part.added") {
2977
+ const slot = outputSlots.resolve(event, "text");
2978
+ if (!slot) continue;
2979
+ slot.item.content = slot.item.content || [];
2980
+ if (event.part.type === "output_text" || event.part.type === "text" || event.part.type === "refusal") slot.item.content.push(event.part);
2981
+ } else if (event.type === "response.output_text.delta") {
2982
+ const slot = outputSlots.resolve(event, "text");
2983
+ if (!slot) continue;
2984
+ slot.item.content ||= [];
2985
+ let lastPart = slot.item.content[slot.item.content.length - 1];
2986
+ if (!isResponsesTextContentPartType(lastPart?.type)) {
2987
+ lastPart = {
2988
+ type: "output_text",
2989
+ text: "",
2990
+ annotations: []
2991
+ };
2992
+ slot.item.content.push(lastPart);
2993
+ }
2994
+ lastPart.text += event.delta;
2995
+ if (slot.pendingText !== null) appendResponsesPendingTextDelta(slot, event.delta, materializeDeferredTextSlot);
2996
+ else if (slot.block && slot.contentIndex !== void 0) {
2997
+ slot.block.text += event.delta;
2998
+ stream.push({
2999
+ type: "text_delta",
3000
+ contentIndex: slot.contentIndex,
3001
+ delta: event.delta
3002
+ });
3003
+ }
3004
+ } else if (isAzureResponsesTextDeltaEvent(event)) {
3005
+ const slot = outputSlots.resolve(event, "text");
3006
+ if (!slot) continue;
3007
+ slot.item.content = slot.item.content || [];
3008
+ let lastPart = slot.item.content[slot.item.content.length - 1];
3009
+ if (lastPart?.type !== "text") {
3010
+ lastPart = {
3011
+ type: "text",
3012
+ text: ""
3013
+ };
3014
+ slot.item.content.push(lastPart);
3015
+ }
3016
+ lastPart.text += event.delta;
3017
+ if (slot.pendingText !== null) appendResponsesPendingTextDelta(slot, event.delta, materializeDeferredTextSlot);
3018
+ else if (slot.block && slot.contentIndex !== void 0) {
3019
+ slot.block.text += event.delta;
3020
+ stream.push({
3021
+ type: "text_delta",
3022
+ contentIndex: slot.contentIndex,
3023
+ delta: event.delta
3024
+ });
3025
+ }
3026
+ } else if (event.type === "response.refusal.delta") {
3027
+ const slot = outputSlots.resolve(event, "text");
3028
+ if (!slot) continue;
3029
+ slot.item.content ||= [];
3030
+ let lastPart = slot.item.content[slot.item.content.length - 1];
3031
+ if (lastPart?.type !== "refusal") {
3032
+ lastPart = {
3033
+ type: "refusal",
3034
+ refusal: ""
3035
+ };
3036
+ slot.item.content.push(lastPart);
3037
+ }
3038
+ lastPart.refusal += event.delta;
3039
+ if (slot.pendingText !== null) appendResponsesPendingTextDelta(slot, event.delta, materializeDeferredTextSlot);
3040
+ else if (slot.block && slot.contentIndex !== void 0) {
3041
+ slot.block.text += event.delta;
3042
+ stream.push({
3043
+ type: "text_delta",
3044
+ contentIndex: slot.contentIndex,
3045
+ delta: event.delta
3046
+ });
2973
3047
  }
2974
- if (doneArguments?.startsWith(previousPartialJson)) {
2975
- const delta = doneArguments.slice(previousPartialJson.length);
2976
- if (delta.length > 0) stream.push({
3048
+ } else if (event.type === "response.function_call_arguments.delta") {
3049
+ const toolCall = streamingToolCalls.resolve(event);
3050
+ if (toolCall) {
3051
+ toolCall.block.partialJson += event.delta;
3052
+ toolCall.block.arguments = parseStreamingJson(toolCall.block.partialJson);
3053
+ stream.push({
2977
3054
  type: "toolcall_delta",
2978
3055
  contentIndex: toolCall.contentIndex,
2979
- delta,
3056
+ delta: event.delta,
2980
3057
  partial: output
2981
3058
  });
2982
- }
2983
- } else if (streamingToolCalls.hasActive()) streamingToolCalls.markArgumentsUnreliable();
2984
- } else if (event.type === "response.output_item.done") {
2985
- const item = event.item;
2986
- if (item.type !== "message") lastTextBlock = null;
2987
- const existingOutputSlot = resolveOutputItemSlot(event, item);
2988
- materializeDeferredTextSlots(existingOutputSlot);
2989
- const outputSlot = existingOutputSlot ?? getOrCreateOutputSlot(event, item);
2990
- if (item.type === "reasoning" && outputSlot?.type === "thinking") {
2991
- const summaryText = item.summary?.map((s) => s.text).join("\n\n") || "";
2992
- const contentText = item.content?.map((c) => c.text).join("\n\n") || "";
2993
- outputSlot.block.thinking = summaryText || contentText || outputSlot.block.thinking;
2994
- outputSlot.block.thinkingSignature = JSON.stringify(item);
2995
- if (item.encrypted_content && options?.reasoningReplayMetadata) outputSlot.block[OPENAI_RESPONSES_REASONING_REPLAY_BLOCK_META_KEY] = options.reasoningReplayMetadata;
2996
- stream.push({
2997
- type: "thinking_end",
2998
- contentIndex: outputSlot.contentIndex,
2999
- content: outputSlot.block.thinking,
3000
- partial: output
3001
- });
3002
- outputSlots.forget(outputSlot);
3003
- } else if (item.type === "message" && outputSlot?.type === "text" && (outputSlot.block || outputSlot.pendingText !== null)) {
3004
- const streamedText = outputSlot.pendingText ?? outputSlot.block?.text ?? "";
3005
- const finalText = item.content == null ? streamedText : item.content.map((c) => c.type === "output_text" || c.type === "text" ? c.text : c.refusal).join("");
3006
- const phase = item.phase ?? void 0;
3007
- const collapse = outputSlot.pendingText !== null ? resolveResponsesMessageSnapshotCollapse({
3008
- prior: outputSlot.collapseCandidate && {
3009
- text: outputSlot.collapseCandidate.block.text,
3010
- phase: outputSlot.collapseCandidate.phase
3011
- },
3012
- nextText: finalText,
3013
- nextPhase: phase
3014
- }) : { kind: "keep" };
3015
- outputSlot.pendingText = null;
3016
- if (collapse.kind === "extend" && outputSlot.collapseCandidate) {
3017
- outputSlot.collapseCandidate.block.text = collapse.text;
3018
- outputSlot.collapseCandidate.block.textSignature = encodeTextSignatureV1(item.id, phase);
3059
+ } else if (streamingToolCalls.hasActive()) streamingToolCalls.markArgumentsUnreliable();
3060
+ } else if (event.type === "response.function_call_arguments.done") {
3061
+ const toolCall = streamingToolCalls.resolve(event);
3062
+ if (toolCall) {
3063
+ const previousPartialJson = toolCall.block.partialJson;
3064
+ const doneArguments = typeof event.arguments === "string" ? event.arguments : void 0;
3065
+ if (doneArguments !== void 0 && (doneArguments.length > 0 || previousPartialJson === "")) {
3066
+ toolCall.block.partialJson = doneArguments;
3067
+ toolCall.block.arguments = parseStreamingJson(toolCall.block.partialJson);
3068
+ toolCall.argumentStreamReliable = true;
3069
+ }
3070
+ if (doneArguments?.startsWith(previousPartialJson)) {
3071
+ const delta = doneArguments.slice(previousPartialJson.length);
3072
+ if (delta.length > 0) stream.push({
3073
+ type: "toolcall_delta",
3074
+ contentIndex: toolCall.contentIndex,
3075
+ delta,
3076
+ partial: output
3077
+ });
3078
+ }
3079
+ } else if (streamingToolCalls.hasActive()) streamingToolCalls.markArgumentsUnreliable();
3080
+ } else if (event.type === "response.output_item.done") {
3081
+ const item = event.item;
3082
+ if (item.type !== "message") lastTextBlock = null;
3083
+ const existingOutputSlot = resolveOutputItemSlot(event, item);
3084
+ materializeDeferredTextSlots(existingOutputSlot);
3085
+ const outputSlot = existingOutputSlot ?? getOrCreateOutputSlot(event, item);
3086
+ compactionTracker.completed(item, blocks.length);
3087
+ if (item.type === "reasoning" && outputSlot?.type === "thinking") {
3088
+ const summaryText = item.summary?.map((s) => s.text).join("\n\n") || "";
3089
+ const contentText = item.content?.map((c) => c.text).join("\n\n") || "";
3090
+ outputSlot.block.thinking = summaryText || contentText || outputSlot.block.thinking;
3091
+ outputSlot.block.thinkingSignature = JSON.stringify(item);
3092
+ if (item.encrypted_content && options?.reasoningReplayMetadata) outputSlot.block[OPENAI_RESPONSES_REASONING_REPLAY_BLOCK_META_KEY] = options.reasoningReplayMetadata;
3019
3093
  stream.push({
3020
- type: "text_end",
3021
- contentIndex: outputSlot.collapseCandidate.index,
3022
- content: collapse.text,
3094
+ type: "thinking_end",
3095
+ contentIndex: outputSlot.contentIndex,
3096
+ content: outputSlot.block.thinking,
3023
3097
  partial: output
3024
3098
  });
3025
- lastTextBlock = outputSlot.collapseCandidate;
3026
- } else {
3027
- if (!outputSlot.block) {
3028
- outputSlot.block = {
3029
- type: "text",
3030
- text: "",
3031
- ...phase ? { textSignature: encodeTextSignatureV1(item.id, phase) } : {}
3099
+ outputSlots.forget(outputSlot);
3100
+ } else if (item.type === "message" && outputSlot?.type === "text" && (outputSlot.block || outputSlot.pendingText !== null)) {
3101
+ const streamedText = outputSlot.pendingText ?? outputSlot.block?.text ?? "";
3102
+ const finalText = item.content == null ? streamedText : item.content.map((c) => c.type === "output_text" || c.type === "text" ? c.text : c.refusal).join("");
3103
+ const phase = item.phase ?? void 0;
3104
+ const collapse = outputSlot.pendingText !== null ? resolveResponsesMessageSnapshotCollapse({
3105
+ prior: outputSlot.collapseCandidate && {
3106
+ text: outputSlot.collapseCandidate.block.text,
3107
+ phase: outputSlot.collapseCandidate.phase
3108
+ },
3109
+ nextText: finalText,
3110
+ nextPhase: phase
3111
+ }) : { kind: "keep" };
3112
+ outputSlot.pendingText = null;
3113
+ if (collapse.kind === "extend" && outputSlot.collapseCandidate) {
3114
+ outputSlot.collapseCandidate.block.text = collapse.text;
3115
+ outputSlot.collapseCandidate.block.textSignature = encodeTextSignatureV1(item.id, phase);
3116
+ stream.push({
3117
+ type: "text_end",
3118
+ contentIndex: outputSlot.collapseCandidate.index,
3119
+ content: collapse.text,
3120
+ partial: output
3121
+ });
3122
+ lastTextBlock = outputSlot.collapseCandidate;
3123
+ outputItemContentIndexes.set(item, outputSlot.collapseCandidate.index);
3124
+ } else {
3125
+ if (!outputSlot.block) {
3126
+ outputSlot.block = {
3127
+ type: "text",
3128
+ text: "",
3129
+ ...phase ? { textSignature: encodeTextSignatureV1(item.id, phase) } : {}
3130
+ };
3131
+ blocks.push(outputSlot.block);
3132
+ outputSlot.contentIndex = blocks.length - 1;
3133
+ stream.push({
3134
+ type: "text_start",
3135
+ contentIndex: outputSlot.contentIndex,
3136
+ partial: output
3137
+ });
3138
+ }
3139
+ outputSlot.block.text = finalText;
3140
+ outputSlot.block.textSignature = encodeTextSignatureV1(item.id, phase);
3141
+ const contentIndex = outputSlot.contentIndex;
3142
+ if (contentIndex === void 0) throw new Error("Responses stream finalized text without a content index");
3143
+ lastTextBlock = {
3144
+ block: outputSlot.block,
3145
+ index: contentIndex,
3146
+ phase
3032
3147
  };
3033
- blocks.push(outputSlot.block);
3034
- outputSlot.contentIndex = blockIndex();
3148
+ outputItemContentIndexes.set(item, contentIndex);
3035
3149
  stream.push({
3036
- type: "text_start",
3037
- contentIndex: outputSlot.contentIndex,
3150
+ type: "text_end",
3151
+ contentIndex,
3152
+ content: outputSlot.block.text,
3038
3153
  partial: output
3039
3154
  });
3040
3155
  }
3041
- outputSlot.block.text = finalText;
3042
- outputSlot.block.textSignature = encodeTextSignatureV1(item.id, phase);
3043
- const contentIndex = outputSlot.contentIndex;
3044
- if (contentIndex === void 0) throw new Error("Responses stream finalized text without a content index");
3045
- lastTextBlock = {
3046
- block: outputSlot.block,
3047
- index: contentIndex,
3048
- phase
3049
- };
3050
- stream.push({
3051
- type: "text_end",
3052
- contentIndex,
3053
- content: outputSlot.block.text,
3054
- partial: output
3156
+ outputSlots.forget(outputSlot);
3157
+ startedTextBlocksByItemId.delete(item.id);
3158
+ } else if (item.type === "function_call") {
3159
+ const streamingToolCall = streamingToolCalls.resolve(event, readResponsesToolCallItemIdentity(item));
3160
+ if (!streamingToolCall && streamingToolCalls.hasActive()) continue;
3161
+ const streamedArguments = streamingToolCall?.block.partialJson ?? "";
3162
+ const completedArguments = typeof item.arguments === "string" ? item.arguments : void 0;
3163
+ if (streamingToolCall && !streamingToolCall.argumentStreamReliable && !completedArguments) continue;
3164
+ const finalArguments = completedArguments !== void 0 && (completedArguments.length > 0 || !streamedArguments) ? completedArguments : streamedArguments;
3165
+ const validated = resolveCompletedResponsesToolCall(item, {
3166
+ name: streamingToolCall?.block.name,
3167
+ arguments: finalArguments
3055
3168
  });
3056
- }
3057
- outputSlots.forget(outputSlot);
3058
- startedTextBlocksByItemId.delete(item.id);
3059
- completedOutputItemIdentities.add(`message:${item.id}`);
3060
- } else if (item.type === "function_call") {
3061
- const streamingToolCall = streamingToolCalls.resolve(event, readResponsesToolCallItemIdentity(item));
3062
- if (!streamingToolCall && streamingToolCalls.hasActive()) continue;
3063
- const streamedArguments = streamingToolCall?.block.partialJson ?? "";
3064
- const completedArguments = typeof item.arguments === "string" ? item.arguments : void 0;
3065
- if (streamingToolCall && !streamingToolCall.argumentStreamReliable && !completedArguments) continue;
3066
- const finalArguments = completedArguments !== void 0 && (completedArguments.length > 0 || !streamedArguments) ? completedArguments : streamedArguments;
3067
- const validated = resolveCompletedResponsesToolCall(item, {
3068
- name: streamingToolCall?.block.name,
3069
- arguments: finalArguments
3070
- });
3071
- let toolCall;
3072
- let contentIndex;
3073
- if (streamingToolCall) {
3074
- const block = streamingToolCall.block;
3075
- block.id = resolveResponsesToolCallId(item, block.id);
3076
- block.name = validated.name;
3077
- block.arguments = validated.arguments;
3078
- delete block.partialJson;
3079
- toolCall = block;
3080
- contentIndex = streamingToolCall.contentIndex;
3081
- } else {
3082
- toolCall = {
3083
- type: "toolCall",
3084
- id: resolveResponsesToolCallId(item),
3085
- name: validated.name,
3086
- arguments: validated.arguments
3087
- };
3088
- blocks.push(toolCall);
3089
- contentIndex = blockIndex();
3169
+ let toolCall;
3170
+ let contentIndex;
3171
+ if (streamingToolCall) {
3172
+ const block = streamingToolCall.block;
3173
+ block.id = resolveResponsesToolCallId(item, block.id);
3174
+ block.name = validated.name;
3175
+ block.arguments = validated.arguments;
3176
+ delete block.partialJson;
3177
+ toolCall = block;
3178
+ contentIndex = streamingToolCall.contentIndex;
3179
+ } else {
3180
+ toolCall = {
3181
+ type: "toolCall",
3182
+ id: resolveResponsesToolCallId(item),
3183
+ name: validated.name,
3184
+ arguments: validated.arguments
3185
+ };
3186
+ blocks.push(toolCall);
3187
+ contentIndex = blocks.length - 1;
3188
+ stream.push({
3189
+ type: "toolcall_start",
3190
+ contentIndex,
3191
+ partial: output
3192
+ });
3193
+ }
3194
+ if (streamingToolCall) {
3195
+ streamingToolCalls.forget(streamingToolCall);
3196
+ for (const slot of outputSlots.values()) if (slot.type === "toolCall" && slot.toolCall === streamingToolCall) outputSlots.forget(slot);
3197
+ }
3090
3198
  stream.push({
3091
- type: "toolcall_start",
3199
+ type: "toolcall_end",
3092
3200
  contentIndex,
3201
+ toolCall,
3093
3202
  partial: output
3094
3203
  });
3204
+ outputItemContentIndexes.set(item, contentIndex);
3095
3205
  }
3096
- if (streamingToolCall) {
3097
- streamingToolCalls.forget(streamingToolCall);
3098
- for (const slot of outputSlots.values()) if (slot.type === "toolCall" && slot.toolCall === streamingToolCall) outputSlots.forget(slot);
3099
- }
3100
- stream.push({
3101
- type: "toolcall_end",
3102
- contentIndex,
3103
- toolCall,
3104
- partial: output
3105
- });
3106
- completedOutputItemIdentities.add(`function_call:${item.call_id}`);
3206
+ } else if (event.type === "response.completed" || event.type === "response.incomplete") {
3207
+ if (streamingToolCalls.hasActive()) throw new Error("Responses stream completed with unresolved tool calls");
3208
+ finalizeResponse(event.response, event.type);
3209
+ if (event.type === "response.completed" || output.stopReason === "length") recoverTerminalOutput(event.response.output ?? [], event.type === "response.completed");
3210
+ terminalResponse = event.type === "response.completed" ? event.response : null;
3211
+ if (output.stopReason === "stop" && output.content.some((block) => block.type === "toolCall")) output.stopReason = "toolUse";
3212
+ break;
3213
+ } else if (event.type === "error") throw new Error(event.message ? `Error Code ${event.code}: ${event.message}` : "Unknown error");
3214
+ else if (event.type === "response.failed") {
3215
+ const failure = normalizeResponsesFailedEvent(event, model);
3216
+ finalizeFailedResponse(event.response, failure.responseId);
3217
+ throw new ResponsesStreamFailure(failure, event.response);
3107
3218
  }
3108
- } else if (event.type === "response.completed" || event.type === "response.incomplete") {
3109
- if (streamingToolCalls.hasActive()) throw new Error("Responses stream completed with unresolved tool calls");
3110
- finalizeResponse(event.response, event.type);
3111
- if (event.type === "response.completed" || output.stopReason === "length") recoverTerminalOutput(event.response.output ?? [], event.type === "response.completed");
3112
- if (output.stopReason === "stop" && output.content.some((block) => block.type === "toolCall")) output.stopReason = "toolUse";
3113
- break;
3114
- } else if (event.type === "error") throw new Error(event.message ? `Error Code ${event.code}: ${event.message}` : "Unknown error");
3115
- else if (event.type === "response.failed") {
3116
- const failure = normalizeResponsesFailedEvent(event, model);
3117
- if (failure.responseId) output.responseId = failure.responseId;
3118
- throw new ResponsesStreamFailure(failure, event.response);
3119
3219
  }
3220
+ if (options?.signal?.aborted) throw transportAbortError(options.signal);
3120
3221
  if (streamingToolCalls.hasActive()) throw new Error("Responses stream ended with unresolved tool calls");
3121
- if (!terminalResponseEvent) throw new Error("OpenAI Responses stream ended before a terminal response event");
3222
+ if (terminalResponse === void 0) throw new Error("OpenAI Responses stream ended before a terminal response event");
3223
+ return terminalResponse ?? void 0;
3122
3224
  } finally {
3123
3225
  for (const block of output.content) delete block.partialJson;
3124
3226
  }
3125
3227
  }
3126
3228
  //#endregion
3127
- export { shouldOmitEmptyArrayItems as $, normalizeResponsesFailedEvent as A, responsesPromptObserver as B, prepareOpenAIResponsesReasoningItemForReplay as C, applyServiceTierPricing as D, tagOpenAIResponsesReasoningReplayItem as E, summarizeResponsesFailedNoDetailsObservation as F, normalizeOpenAIStrictToolParameters as G, clearOpenAIToolSchemaCacheForTest as H, summarizeResponsesPayload as I, findOpenAIStrictSchemaViolations as J, normalizeStrictOpenAIJsonSchema as K, summarizeResponsesTools as L, stringifyRedactedEvent as M, stringifyRedactedPayload as N, buildResponsesFailedNoDetailsObservation as O, summarizeOpenAITransportError as P, resolveUnsupportedToolSchemaKeywords as Q, AZURE_RESPONSES_FIRST_EVENT_TIMEOUT_MS as R, isInvalidEncryptedContentError as S, stripResponsesRequestEncryptedContent as T, findOpenAIStrictToolProjectionDiagnostics as U, resolveReplayableResponsesMessageId as V, isStrictOpenAIJsonSchemaCompatible as W, extractToolSchemaModelCompat as X, normalizeOpenAIStrictCompatSchema as Y, normalizeToolParameterSchema as Z, resolveResponsesMessageSnapshotCollapse as _, resolveModelSseDebugMode as _t, resolveResponsesTerminalStopReason as a, cleanSchemaForGemini as at, convertResponsesMessages as b, quoteUnsafeIntegerLiterals as bt, readResponsesToolCallItemIdentity as c, isOpenAIGpt56Model as ct, OPENAI_RESPONSES_OUTPUT_TEXT_CONTENT_PART_TYPE as d, resolveOpenAISupportedReasoningEfforts as dt, stripUnsupportedSchemaKeywords as et, OPENAI_RESPONSES_OUTPUT_TEXT_DELTA_EVENT_TYPE as f, supportsOpenAIReasoningEffort as ft, isResponsesTextDeltaEventType as g, resolveModelPayloadDebugMode as gt, isResponsesTextContentPartType as h, emitModelTransportDebug as ht, readResponsesReasoningTokens as i, GEMINI_UNSUPPORTED_SCHEMA_KEYWORDS as it, safeDebugValue as j, logResponsesFailedNoDetails as k, AZURE_RESPONSES_TEXT_CONTENT_PART_TYPE as l, normalizeOpenAIReasoningEffort as lt, isAzureResponsesTextDeltaEventType as m, uniqueStrings as mt, processResponsesStream as n, cleanSchemaForLlamacppGbnf as nt, observeResponsesStream as o, isOpenAIGpt54MiniModel as ot, isAzureResponsesTextDeltaEvent as p, supportsOpenAITemperature as pt, resolveOpenAIProjectedToolsStrictToolFlag as q, mapResponsesTerminalUsage as r, findLlamacppGbnfSchemaViolations as rt, createResponsesToolCallTracker as s, isOpenAIGpt55Model as st, ResponsesStreamFailure as t, LLAMACPP_GBNF_MAX_REPETITION_THRESHOLD as tt, AZURE_RESPONSES_TEXT_DELTA_EVENT_TYPE as u, resolveOpenAIReasoningEffortForModel as ut, buildOpenAIResponsesReasoningReplayMetadata as v, parseJsonObjectPreservingUnsafeIntegers as vt, resolveAzureOpenAIApiVersion as w, createResponsesStreamWithEncryptedContentRetry as x, buildResponsesInputMessage as y, parseJsonPreservingUnsafeIntegers as yt, OPENAI_CODEX_RESPONSES_DEFAULT_INSTRUCTIONS as z };
3229
+ //#region packages/ai/src/providers/openai-responses-tools.ts
3230
+ const LOG_SUBSYSTEM = "llm/openai-responses";
3231
+ const MAX_STRICT_TOOL_DOWNGRADE_DIAGNOSTIC_KEYS = 64;
3232
+ const loggedStrictToolDowngradeDiagnosticKeys = /* @__PURE__ */ new Set();
3233
+ /** Converts and returns the projection used to reconcile tool choices. */
3234
+ function convertResponsesToolPayload(tools, options) {
3235
+ const projection = projectOpenAITools(tools);
3236
+ const strict = resolveResponsesStrictToolFlag(projection, resolveResponsesStrictToolSetting(options), options?.model);
3237
+ return {
3238
+ projection,
3239
+ tools: sortPromptCacheToolsByName(projection.tools).map((tool) => {
3240
+ const result = {
3241
+ type: "function",
3242
+ name: tool.name,
3243
+ description: tool.description,
3244
+ parameters: normalizeOpenAIStrictToolParameters(tool.parameters, strict === true, options?.model?.compat)
3245
+ };
3246
+ if (strict !== void 0) result.strict = strict;
3247
+ return result;
3248
+ })
3249
+ };
3250
+ }
3251
+ function resolveResponsesStrictToolSetting(options) {
3252
+ if (options?.strict !== void 0) return options.strict;
3253
+ if (options?.model) return getAiTransportHost().resolveOpenAIStrictToolSetting(options.model, {
3254
+ transport: "stream",
3255
+ supportsStrictMode: options.supportsStrictMode
3256
+ });
3257
+ return false;
3258
+ }
3259
+ function resolveResponsesStrictToolFlag(projection, strictSetting, model) {
3260
+ const strict = resolveOpenAIProjectedToolsStrictToolFlag(projection, strictSetting);
3261
+ if (strictSetting === true && strict === false && model) getAiTransportHost().logDebug(LOG_SUBSYSTEM, () => {
3262
+ const diagnostics = findOpenAIStrictToolProjectionDiagnostics(projection);
3263
+ if (!shouldLogStrictToolDowngradeDiagnostic(diagnostics, model)) return null;
3264
+ const sample = diagnostics.slice(0, 5).map((entry) => ({
3265
+ tool: entry.toolName ?? `tool[${entry.toolIndex}]`,
3266
+ violations: entry.violations.slice(0, 8)
3267
+ }));
3268
+ return {
3269
+ message: `OpenAI responses tool schema strict mode downgraded to strict=false for ${model.provider ?? "unknown"}/${model.id ?? "unknown"} because ${diagnostics.length} tool schema(s) are not strict-compatible`,
3270
+ data: {
3271
+ provider: model.provider,
3272
+ model: model.id,
3273
+ incompatibleToolCount: diagnostics.length,
3274
+ sample
3275
+ }
3276
+ };
3277
+ });
3278
+ return strict;
3279
+ }
3280
+ function shouldLogStrictToolDowngradeDiagnostic(diagnostics, model) {
3281
+ const key = createHash("sha256").update(JSON.stringify({
3282
+ provider: model.provider,
3283
+ model: model.id,
3284
+ diagnostics: diagnostics.map((entry) => ({
3285
+ toolIndex: entry.toolIndex,
3286
+ toolName: entry.toolName ?? null,
3287
+ violations: entry.violations
3288
+ }))
3289
+ })).digest("hex");
3290
+ if (loggedStrictToolDowngradeDiagnosticKeys.has(key)) return false;
3291
+ if (loggedStrictToolDowngradeDiagnosticKeys.size >= MAX_STRICT_TOOL_DOWNGRADE_DIAGNOSTIC_KEYS) loggedStrictToolDowngradeDiagnosticKeys.clear();
3292
+ loggedStrictToolDowngradeDiagnosticKeys.add(key);
3293
+ return true;
3294
+ }
3295
+ //#endregion
3296
+ //#region packages/ai/src/providers/openai-responses-shared.ts
3297
+ function isResponsesReasoningEffort(effort) {
3298
+ return effort === "minimal" || effort === "low" || effort === "medium" || effort === "high" || effort === "xhigh" || effort === "max";
3299
+ }
3300
+ function convertResponsesMessages(model, context, allowedToolCallProviders, options) {
3301
+ return convertProviderResponsesMessages(model, context, allowedToolCallProviders, options);
3302
+ }
3303
+ const createResponsesAssistantOutput = createOpenAIResponsesAssistantOutput;
3304
+ function applyResponsesServiceTierPricing(usage, serviceTier, model) {
3305
+ let multiplier = 1;
3306
+ if (serviceTier === "flex") multiplier = .5;
3307
+ else if (serviceTier === "priority") multiplier = model.id === "gpt-5.5" ? 2.5 : 2;
3308
+ if (multiplier === 1) return;
3309
+ usage.cost.input *= multiplier;
3310
+ usage.cost.output *= multiplier;
3311
+ usage.cost.cacheRead *= multiplier;
3312
+ usage.cost.cacheWrite *= multiplier;
3313
+ usage.cost.total = usage.cost.input + usage.cost.output + usage.cost.cacheRead + usage.cost.cacheWrite;
3314
+ }
3315
+ function resolveResponsesReasoningEffort(model, reasoning) {
3316
+ const clampedReasoning = reasoning ? clampThinkingLevel(model, reasoning) : void 0;
3317
+ if (!clampedReasoning || clampedReasoning === "off") return;
3318
+ if (clampedReasoning === "max") return supportsOpenAIReasoningEffort(model, "max") ? "max" : "xhigh";
3319
+ if (clampedReasoning === "minimal" && model.provider === "openai" && supportsOpenAIReasoningEffort(model, "max")) {
3320
+ const effort = resolveOpenAIReasoningEffortForModel({
3321
+ model,
3322
+ effort: "minimal"
3323
+ });
3324
+ return isResponsesReasoningEffort(effort) ? effort : void 0;
3325
+ }
3326
+ return clampedReasoning;
3327
+ }
3328
+ function applyCommonResponsesParams(params, model, context, options, config) {
3329
+ if (options?.maxTokens) params.max_output_tokens = Math.max(options.maxTokens, 16);
3330
+ if (options?.temperature !== void 0 && supportsOpenAITemperature(model)) params.temperature = options.temperature;
3331
+ if (context.tools) {
3332
+ const converted = convertResponsesToolPayload(context.tools, { model });
3333
+ if (converted.tools.length > 0) params.tools = converted.tools;
3334
+ }
3335
+ if (!model.reasoning) return;
3336
+ if (options?.reasoningEffort || options?.reasoningSummary) {
3337
+ params.reasoning = {
3338
+ effort: options?.reasoningEffort ? model.thinkingLevelMap?.[options.reasoningEffort] ?? options.reasoningEffort : "medium",
3339
+ summary: options?.reasoningSummary || "auto"
3340
+ };
3341
+ params.include = ["reasoning.encrypted_content"];
3342
+ } else if ((config?.setDefaultReasoningOff ?? true) && model.thinkingLevelMap?.off !== null) params.reasoning = { effort: model.thinkingLevelMap?.off ?? "none" };
3343
+ }
3344
+ function buildResponsesRequestOptions(options) {
3345
+ return {
3346
+ ...options?.signal ? { signal: options.signal } : {},
3347
+ ...options?.timeoutMs !== void 0 ? { timeout: options.timeoutMs } : {},
3348
+ maxRetries: options?.maxRetries ?? 0
3349
+ };
3350
+ }
3351
+ function cleanStreamingScratchBuffers(output) {
3352
+ for (const block of output.content) {
3353
+ delete block.index;
3354
+ delete block.partialJson;
3355
+ }
3356
+ }
3357
+ async function runResponsesStreamLifecycle(params) {
3358
+ const { stream, output, options } = params;
3359
+ let firstEventAbort;
3360
+ try {
3361
+ const model = params.resolveRequestModel?.(params.model) ?? params.model;
3362
+ const client = params.createClient(model);
3363
+ const buildRequest = async (replayMode) => {
3364
+ let request = params.buildParams(model, replayMode);
3365
+ const nextRequest = await options?.onPayload?.(request, model);
3366
+ if (nextRequest !== void 0) request = nextRequest;
3367
+ return request;
3368
+ };
3369
+ const requestParams = await buildRequest("checkpoint");
3370
+ firstEventAbort = createFirstStreamEventAbortController(options?.signal);
3371
+ const { stream: openaiStream, response } = await createResponsesStreamWithEncryptedContentRetry({
3372
+ client,
3373
+ request: requestParams,
3374
+ requestOptions: {
3375
+ ...buildResponsesRequestOptions(options),
3376
+ signal: firstEventAbort.signal
3377
+ },
3378
+ model,
3379
+ buildFullHistoryRequest: () => buildRequest("full-history"),
3380
+ onCompactionRejected: (checkpoint) => suppressOpenAIResponsesCompaction(output, model, options, checkpoint)
3381
+ });
3382
+ const hookedOpenAIStream = withProviderResponseHook({
3383
+ stream: openaiStream,
3384
+ signal: firstEventAbort.signal,
3385
+ abort: firstEventAbort.abort,
3386
+ hook: createOpenAIResponseHook(options?.onResponse, response, model),
3387
+ onReady: () => stream.push({
3388
+ type: "start",
3389
+ partial: output
3390
+ })
3391
+ });
3392
+ const firstEventTimeoutMs = getFirstStreamEventTimeoutMs(options);
3393
+ const onFirstEventTimeout = getFirstStreamEventTimeoutHandler(options);
3394
+ await processResponsesStream(hookedOpenAIStream, output, stream, model, {
3395
+ ...params.processStreamOptions || firstEventTimeoutMs !== void 0 || onFirstEventTimeout !== void 0 ? {
3396
+ ...params.processStreamOptions,
3397
+ firstEventTimeoutMs: params.processStreamOptions?.firstEventTimeoutMs ?? firstEventTimeoutMs,
3398
+ abortFirstEventStream: params.processStreamOptions?.abortFirstEventStream ?? firstEventAbort.abort,
3399
+ onFirstEventTimeout: params.processStreamOptions?.onFirstEventTimeout ?? onFirstEventTimeout,
3400
+ signal: params.processStreamOptions?.signal ?? options?.signal
3401
+ } : void 0,
3402
+ reasoningReplayMetadata: buildOpenAIResponsesReasoningReplayMetadata(model, {
3403
+ sessionId: options?.sessionId,
3404
+ authProfileId: options?.authProfileId
3405
+ })
3406
+ });
3407
+ if (options?.signal?.aborted) throw transportAbortError(options.signal);
3408
+ if (output.stopReason === "aborted" || output.stopReason === "error") throw new Error(output.errorMessage ?? "An unknown error occurred");
3409
+ stream.push({
3410
+ type: "done",
3411
+ reason: output.stopReason,
3412
+ message: output
3413
+ });
3414
+ stream.end();
3415
+ } catch (error) {
3416
+ cleanStreamingScratchBuffers(output);
3417
+ const terminal = projectProviderError(error, options?.signal);
3418
+ Object.assign(output, terminal);
3419
+ stream.push({
3420
+ type: "error",
3421
+ reason: terminal.stopReason,
3422
+ error: output
3423
+ });
3424
+ stream.end();
3425
+ } finally {
3426
+ firstEventAbort?.dispose();
3427
+ }
3428
+ }
3429
+ //#endregion
3430
+ export { normalizeOpenAIStrictCompatSchema as $, isAzureResponsesTextDeltaEvent as A, buildResponsesInputMessage as B, summarizeResponsesTools as C, AZURE_RESPONSES_TEXT_DELTA_EVENT_TYPE as D, AZURE_RESPONSES_TEXT_CONTENT_PART_TYPE as E, commitResponsesEncryptedContentAttempt as F, suppressOpenAIResponsesCompaction as G, createOpenAIResponsesAssistantOutput as H, createResponsesStreamWithEncryptedContentRetry as I, isStrictOpenAIJsonSchemaCompatible as J, resolveReplayableResponsesMessageId as K, isInvalidEncryptedContentError as L, isResponsesTextContentPartType as M, isResponsesTextDeltaEventType as N, OPENAI_RESPONSES_OUTPUT_TEXT_CONTENT_PART_TYPE as O, resolveResponsesMessageSnapshotCollapse as P, findOpenAIStrictSchemaViolations as Q, resolveAzureOpenAIApiVersion as R, summarizeResponsesPayload as S, readResponsesToolCallItemIdentity as T, buildOpenAIResponsesReasoningReplayMetadata as U, convertResponsesMessages$1 as V, captureOpenAIResponsesCompaction as W, normalizeStrictOpenAIJsonSchema as X, normalizeOpenAIStrictToolParameters as Y, resolveOpenAIProjectedToolsStrictToolFlag as Z, safeDebugValue as _, resolveResponsesReasoningEffort as a, LLAMACPP_GBNF_MAX_REPETITION_THRESHOLD as at, summarizeOpenAITransportError as b, processResponsesStream as c, GEMINI_UNSUPPORTED_SCHEMA_KEYWORDS as ct, resolveResponsesTerminalStopReason as d, resolveModelPayloadDebugMode as dt, extractToolSchemaModelCompat as et, observeResponsesStream as f, resolveModelSseDebugMode as ft, normalizeResponsesFailedEvent as g, logResponsesFailedNoDetails as h, quoteUnsafeIntegerLiterals as ht, createResponsesAssistantOutput as i, stripUnsupportedSchemaKeywords as it, isAzureResponsesTextDeltaEventType as j, OPENAI_RESPONSES_OUTPUT_TEXT_DELTA_EVENT_TYPE as k, mapResponsesTerminalUsage as l, cleanSchemaForGemini as lt, buildResponsesFailedNoDetailsObservation as m, parseJsonPreservingUnsafeIntegers as mt, applyResponsesServiceTierPricing as n, resolveUnsupportedToolSchemaKeywords as nt, runResponsesStreamLifecycle as o, cleanSchemaForLlamacppGbnf as ot, ResponsesStreamFailure as p, parseJsonObjectPreservingUnsafeIntegers as pt, findOpenAIStrictToolProjectionDiagnostics as q, convertResponsesMessages as r, shouldOmitEmptyArrayItems as rt, convertResponsesToolPayload as s, findLlamacppGbnfSchemaViolations as st, applyCommonResponsesParams as t, normalizeToolParameterSchema as tt, readResponsesReasoningTokens as u, emitModelTransportDebug as ut, stringifyRedactedEvent as v, createResponsesToolCallTracker as w, summarizeResponsesFailedNoDetailsObservation as x, stringifyRedactedPayload as y, resolveNextResponsesEncryptedContentAttempt as z };