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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/dist/{anthropic-B6dLpq5L.mjs → anthropic-B8KwTtlb.mjs} +37 -27
  2. package/dist/{anthropic-SrGtwsJu.d.mts → anthropic-BECQCNdF.d.mts} +0 -2
  3. package/dist/{anthropic-JsNA5KCu.mjs → anthropic-BQXQudmA.mjs} +0 -1
  4. package/dist/{anthropic-compaction-replay-8lJNKXOE.mjs → anthropic-compaction-replay-4Zx7-aCr.mjs} +14 -15
  5. package/dist/{anthropic-payload-policy-CiEuQS72.d.mts → anthropic-payload-policy-CSx7MoKH.d.mts} +2 -1
  6. package/dist/{api-registry-k3zTz0cV.d.mts → api-registry-DFxSnFqG.d.mts} +1 -1
  7. package/dist/{azure-openai-responses-mxIOtUnn.mjs → azure-openai-responses-Aa4mVcYG.mjs} +3 -3
  8. package/dist/diagnostics.mjs +1 -1
  9. package/dist/event-stream-BVVgDSdq.d.mts +1 -0
  10. package/dist/{event-stream-BP6AWT8j.d.mts → event-stream-D91-ohD_.d.mts} +1 -1
  11. package/dist/event-stream.d.mts +1 -1
  12. package/dist/{google-shared-B0Qr9OR7.mjs → google-shared-M1dl64nz.mjs} +12 -5
  13. package/dist/{google-vertex-Bhc3TjDl.mjs → google-vertex-DCJHM_a5.mjs} +3 -3
  14. package/dist/{google-C7h2QzDX.mjs → google-yDRnipeq.mjs} +3 -3
  15. package/dist/headers-B_e4-1J0.mjs +9 -0
  16. package/dist/{host-DTqNc7ad.mjs → host-DF_yxOsA.mjs} +40 -29
  17. package/dist/{host-vWgMMhiJ.d.mts → host-DJq_FGcz.d.mts} +6 -6
  18. package/dist/index.d.mts +7 -7
  19. package/dist/index.mjs +2 -2
  20. package/dist/internal/anthropic.d.mts +11 -5
  21. package/dist/internal/anthropic.mjs +4 -4
  22. package/dist/internal/openai-responses-payload-policy.d.mts +2 -2
  23. package/dist/internal/openai-responses-payload-policy.mjs +2 -2
  24. package/dist/internal/openai.d.mts +5 -5
  25. package/dist/internal/openai.mjs +9 -8
  26. package/dist/internal/runtime.d.mts +4 -2
  27. package/dist/internal/runtime.mjs +4 -3
  28. package/dist/internal/shared.d.mts +17 -3
  29. package/dist/internal/shared.mjs +4 -4
  30. package/dist/{headers-DdOQtGuU.mjs → llm-request-activity-BjtkplhG.mjs} +1 -9
  31. package/dist/{mistral-CEWoQI_g.mjs → mistral-D6hRXI7A.mjs} +47 -33
  32. package/dist/{openai-chatgpt-responses-CrPmqERt.mjs → openai-chatgpt-responses-C339VIfT.mjs} +23 -15
  33. package/dist/{openai-completions-BPnt4Sml.mjs → openai-completions-D88orSJ9.mjs} +71 -35
  34. package/dist/{openai-completions-compat-Dt3dcawL.d.mts → openai-completions-compat-B0KTleXp.d.mts} +2 -2
  35. package/dist/{openai-responses-DhIKtOup.mjs → openai-responses-BXEcr-Tp.mjs} +4 -4
  36. package/dist/{openai-responses-contracts-XpZJxrRG.d.mts → openai-responses-contracts-CD75pQ0m.d.mts} +2 -2
  37. package/dist/{openai-responses-contracts-CyfIkQi5.mjs → openai-responses-contracts-DvILoqBk.mjs} +3 -9
  38. package/dist/{openai-responses-payload-policy-BDxV-W0c.mjs → openai-responses-payload-policy-BDo8CQsx.mjs} +4 -2
  39. package/dist/{openai-responses-payload-policy-BSs371VM.d.mts → openai-responses-payload-policy-CNGFT9zr.d.mts} +1 -0
  40. package/dist/{openai-responses-prompt-observer-internal-DgNTYnRY.mjs → openai-responses-prompt-observer-internal-BG-1AsBI.mjs} +2 -3
  41. package/dist/{openai-responses-shared-DXIt3iY5.mjs → openai-responses-shared-Cvt5MgEm.mjs} +81 -136
  42. package/dist/{openai-stop-reason-BkFkqqK0.mjs → openai-stop-reason-9OONKyAm.mjs} +47 -31
  43. package/dist/{openai-tool-projection-CY04OcvQ.mjs → openai-tool-projection-CHGLt03m.mjs} +94 -6
  44. package/dist/{provider-error-BUwEnjXq.mjs → provider-error-C8mBRJDl.mjs} +19 -24
  45. package/dist/provider-options-AvldWZt8.mjs +21 -0
  46. package/dist/{provider-options-B96RdNpH.d.mts → provider-options-Cc5ZQ6Aa.d.mts} +12 -2
  47. package/dist/provider-transcript-transform--gtf0ZbR.mjs +32 -0
  48. package/dist/provider-types.d.mts +5 -5
  49. package/dist/providers.d.mts +1 -1
  50. package/dist/providers.mjs +9 -9
  51. package/dist/{reasoning-tag-text-partitioner-rnPwX2pg.mjs → reasoning-tag-text-partitioner-5ygO2rZc.mjs} +3 -0
  52. package/dist/{sanitize-unicode-BYqrYtC_.mjs → sanitize-unicode-BP7HLLZn.mjs} +1 -1
  53. package/dist/simple-options-oqsXB6U3.mjs +450 -0
  54. package/dist/{tool-schema-json-projection-q5d7QX5c.mjs → tool-schema-json-projection-FEr-jOoZ.mjs} +16 -7
  55. package/dist/{transport-utils-DJqkxbhC.mjs → transport-utils-Bv0FHkd0.mjs} +1 -1
  56. package/dist/transports.d.mts +77 -44
  57. package/dist/transports.mjs +207 -167
  58. package/dist/{types-BHNrPS1l.d.mts → types-DTAP49HF.d.mts} +17 -2
  59. package/dist/types.d.mts +5 -5
  60. package/dist/types.mjs +1 -1
  61. package/dist/{validation-DT9SrFn3.d.mts → validation-DYNNrU9u.d.mts} +1 -1
  62. package/dist/validation.d.mts +1 -1
  63. package/package.json +1 -1
  64. package/dist/provider-transcript-transform-ePx-Bbfr.mjs +0 -155
  65. package/dist/simple-options-D58D5Kvw.mjs +0 -117
@@ -1,113 +1,21 @@
1
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";
2
+ import { i as clampThinkingLevel, r as calculateCost } from "./sanitize-unicode-BP7HLLZn.mjs";
3
+ import { a as describeToolResultMediaPlaceholder, c as extractToolResultText, d as isImageWithMediaPayload, n as getAiTransportHost } from "./host-DF_yxOsA.mjs";
4
+ import { a as isRecord } from "./record-coerce-DdXsgUd_.mjs";
5
5
  import { t as truncateUtf16Safe } from "./utf16-slice-CvGodqok.mjs";
6
- import { n as projectProviderError } from "./provider-error-BUwEnjXq.mjs";
6
+ import { n as projectProviderError } from "./provider-error-C8mBRJDl.mjs";
7
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";
8
+ import { C as normalizeStringEntries, S as supportsOpenAITemperature, T as uniqueValues, a as OPENAI_RESPONSES_COMPACTION_REPLAY_TYPE, c as OPENAI_RESPONSES_RETAINED_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-DvILoqBk.mjs";
9
+ import { C as withProviderResponseHook, P as sortPromptCacheToolsByName, b as sanitizeTransportPayloadText, j as stripSystemPromptCacheBoundary, v as parseTerminalToolCallArguments, x as transportAbortError, y as sanitizeNonEmptyTransportPayloadText } from "./simple-options-oqsXB6U3.mjs";
10
+ import { c as transformTransportMessages } from "./tool-schema-json-projection-FEr-jOoZ.mjs";
11
11
  import { n as parseStreamingJson } from "./json-parse-CDnesDM_.mjs";
12
- import { n as notifyLlmRequestActivity } from "./headers-DdOQtGuU.mjs";
12
+ import { t as notifyLlmRequestActivity } from "./llm-request-activity-BjtkplhG.mjs";
13
13
  import { t as shortHash } from "./hash-CHgqbJmD.mjs";
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";
14
+ import { l as redactIdentifier, u as redactSensitiveText } from "./transport-utils-Bv0FHkd0.mjs";
15
+ import { a as createModelStreamCooperativeScheduler, l as log, o as createOpenAIProviderAcceptanceHook, t as projectOpenAITools } from "./openai-tool-projection-CHGLt03m.mjs";
17
16
  import { a as withFirstStreamEventTimeout, i as getFirstStreamEventTimeoutMs, r as getFirstStreamEventTimeoutHandler, t as createFirstStreamEventAbortController } from "./stream-first-event-timeout-MK28puvq.mjs";
17
+ import { t as transformProviderMessages } from "./provider-transcript-transform--gtf0ZbR.mjs";
18
18
  import { createHash, randomUUID } from "node:crypto";
19
- //#region packages/ai/src/transports/json-unsafe-integers.ts
20
- /**
21
- * JSON parsing helpers that preserve integer literals larger than
22
- * Number.MAX_SAFE_INTEGER as strings before JSON.parse can round them.
23
- */
24
- const MAX_SAFE_INTEGER_ABS_STR = String(Number.MAX_SAFE_INTEGER);
25
- function isAsciiDigit(ch) {
26
- return ch !== void 0 && ch >= "0" && ch <= "9";
27
- }
28
- function parseJsonNumberToken(input, start) {
29
- let idx = start;
30
- if (input[idx] === "-") idx += 1;
31
- if (idx >= input.length) return null;
32
- if (input[idx] === "0") idx += 1;
33
- else if (isAsciiDigit(input[idx]) && input[idx] !== "0") while (isAsciiDigit(input[idx])) idx += 1;
34
- else return null;
35
- let isInteger = true;
36
- if (input[idx] === ".") {
37
- isInteger = false;
38
- idx += 1;
39
- if (!isAsciiDigit(input[idx])) return null;
40
- while (isAsciiDigit(input[idx])) idx += 1;
41
- }
42
- if (input[idx] === "e" || input[idx] === "E") {
43
- isInteger = false;
44
- idx += 1;
45
- if (input[idx] === "+" || input[idx] === "-") idx += 1;
46
- if (!isAsciiDigit(input[idx])) return null;
47
- while (isAsciiDigit(input[idx])) idx += 1;
48
- }
49
- return {
50
- token: input.slice(start, idx),
51
- end: idx,
52
- isInteger
53
- };
54
- }
55
- function isUnsafeIntegerLiteral(token) {
56
- const digits = token[0] === "-" ? token.slice(1) : token;
57
- if (digits.length < MAX_SAFE_INTEGER_ABS_STR.length) return false;
58
- if (digits.length > MAX_SAFE_INTEGER_ABS_STR.length) return true;
59
- return digits > MAX_SAFE_INTEGER_ABS_STR;
60
- }
61
- /** Quotes integer literals above Number.MAX_SAFE_INTEGER before JSON.parse. */
62
- function quoteUnsafeIntegerLiterals(input) {
63
- let out = "";
64
- let inString = false;
65
- let escaped = false;
66
- let idx = 0;
67
- while (idx < input.length) {
68
- const ch = input[idx] ?? "";
69
- if (inString) {
70
- out += ch;
71
- if (escaped) escaped = false;
72
- else if (ch === "\\") escaped = true;
73
- else if (ch === "\"") inString = false;
74
- idx += 1;
75
- continue;
76
- }
77
- if (ch === "\"") {
78
- inString = true;
79
- out += ch;
80
- idx += 1;
81
- continue;
82
- }
83
- if (ch === "-" || isAsciiDigit(ch)) {
84
- const parsed = parseJsonNumberToken(input, idx);
85
- if (parsed) {
86
- if (parsed.isInteger && isUnsafeIntegerLiteral(parsed.token)) out += `"${parsed.token}"`;
87
- else out += parsed.token;
88
- idx = parsed.end;
89
- continue;
90
- }
91
- }
92
- out += ch;
93
- idx += 1;
94
- }
95
- return out;
96
- }
97
- /** Parses JSON while preserving unsafe integer literals as strings. */
98
- function parseJsonPreservingUnsafeIntegers(input) {
99
- return JSON.parse(quoteUnsafeIntegerLiterals(input));
100
- }
101
- /** Parses or accepts an object while preserving unsafe integer literals in string input. */
102
- function parseJsonObjectPreservingUnsafeIntegers(value) {
103
- if (typeof value === "string") try {
104
- return asNullableRecord(parseJsonPreservingUnsafeIntegers(value));
105
- } catch {
106
- return null;
107
- }
108
- return asNullableRecord(value);
109
- }
110
- //#endregion
111
19
  //#region packages/ai/src/transports/model-transport-debug.ts
112
20
  /**
113
21
  * Environment-driven debug controls for model transport logging.
@@ -270,8 +178,8 @@ function simplifyUnionVariants(params) {
270
178
  };
271
179
  copySchemaMeta$1(obj, result);
272
180
  return {
273
- variants: nonNullVariants,
274
- simplified: result
181
+ kind: "simplified",
182
+ value: result
275
183
  };
276
184
  }
277
185
  if (stripped && nonNullVariants.length === 1) {
@@ -280,16 +188,19 @@ function simplifyUnionVariants(params) {
280
188
  const result = { ...lone };
281
189
  copySchemaMeta$1(obj, result);
282
190
  return {
283
- variants: nonNullVariants,
284
- simplified: result
191
+ kind: "simplified",
192
+ value: result
285
193
  };
286
194
  }
287
195
  return {
288
- variants: nonNullVariants,
289
- simplified: lone
196
+ kind: "simplified",
197
+ value: lone
290
198
  };
291
199
  }
292
- return { variants: stripped ? nonNullVariants : variants };
200
+ return {
201
+ kind: "variants",
202
+ value: stripped ? nonNullVariants : variants
203
+ };
293
204
  }
294
205
  function sanitizeRequiredFields(schema) {
295
206
  if (!Array.isArray(schema.required)) return schema;
@@ -334,16 +245,16 @@ function cleanSchemaForGeminiWithDefs(schema, defs, refStack) {
334
245
  obj,
335
246
  variants: cleanedAnyOf ?? []
336
247
  });
337
- cleanedAnyOf = simplified.variants;
338
- if ("simplified" in simplified) return simplified.simplified;
248
+ if (simplified.kind === "simplified") return simplified.value;
249
+ cleanedAnyOf = simplified.value;
339
250
  }
340
251
  if (hasOneOf) {
341
252
  const simplified = simplifyUnionVariants({
342
253
  obj,
343
254
  variants: cleanedOneOf ?? []
344
255
  });
345
- cleanedOneOf = simplified.variants;
346
- if ("simplified" in simplified) return simplified.simplified;
256
+ if (simplified.kind === "simplified") return simplified.value;
257
+ cleanedOneOf = simplified.value;
347
258
  }
348
259
  const cleaned = {};
349
260
  for (const [key, value] of Object.entries(obj)) {
@@ -1439,16 +1350,19 @@ function isOpenAIResponsesReplayContext(value) {
1439
1350
  if (!isRecord(value)) return false;
1440
1351
  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");
1441
1352
  }
1353
+ function isOpenAIResponsesCompactionState(state) {
1354
+ if (typeof state.baseUrlHash !== "string" || state.v !== 1) return false;
1355
+ if (state.type === OPENAI_RESPONSES_COMPACTION_SUPPRESSION_TYPE) return state.data === OPENAI_RESPONSES_COMPACTION_SUPPRESSION_DATA;
1356
+ if (state.type === "openai-responses-retained-compaction") return typeof state.data === "string" && state.data.length > 0 && (state.id === void 0 || typeof state.id === "string") && state.replayIndex === void 0;
1357
+ 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 || typeof state.replayIndex === "number" && Number.isSafeInteger(state.replayIndex) && state.replayIndex >= 0);
1358
+ }
1442
1359
  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;
1360
+ return isRecord(value) && isOpenAIResponsesReplayContext(value) && isOpenAIResponsesCompactionState(value) ? value : void 0;
1447
1361
  }
1448
1362
  function openAIResponsesReplayContextMatches(state, context) {
1449
1363
  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;
1450
1364
  }
1451
- function captureOpenAIResponsesCompaction(output, item, replayIndex, model, captureMetadata) {
1365
+ function captureOpenAIResponsesCompaction(output, item, boundary, model, captureMetadata) {
1452
1366
  const metadata = captureMetadata ?? buildOpenAIResponsesReasoningReplayMetadata(model);
1453
1367
  if (!item.encrypted_content) return;
1454
1368
  if (!metadata?.baseUrlHash) {
@@ -1456,13 +1370,13 @@ function captureOpenAIResponsesCompaction(output, item, replayIndex, model, capt
1456
1370
  return;
1457
1371
  }
1458
1372
  const currentReplay = readOpenAIResponsesCompactionReplayState(output.providerReplay);
1459
- if (currentReplay?.type === "openai-responses-compaction" && (currentReplay.replayIndex ?? -1) > (replayIndex ?? Number.MAX_SAFE_INTEGER)) return;
1373
+ if (typeof boundary === "number" && currentReplay?.type === "openai-responses-compaction" && (currentReplay.replayIndex ?? -1) > boundary) return;
1460
1374
  output.providerReplay = {
1461
1375
  v: 1,
1462
- type: OPENAI_RESPONSES_COMPACTION_REPLAY_TYPE,
1376
+ type: boundary === "retained-users" ? OPENAI_RESPONSES_RETAINED_COMPACTION_REPLAY_TYPE : OPENAI_RESPONSES_COMPACTION_REPLAY_TYPE,
1463
1377
  ...item.id ? { id: item.id } : {},
1464
1378
  data: item.encrypted_content,
1465
- ...replayIndex === void 0 ? {} : { replayIndex },
1379
+ ...typeof boundary === "number" ? { replayIndex: boundary } : {},
1466
1380
  provider: metadata.provider,
1467
1381
  api: metadata.api,
1468
1382
  model: metadata.model,
@@ -1513,8 +1427,8 @@ function resolveNewestOpenAIResponsesCompactionReplay(messages, model, options)
1513
1427
  if (openAIResponsesReplayContextMatches(replay, context)) return;
1514
1428
  continue;
1515
1429
  }
1516
- if (replay?.type !== "openai-responses-compaction") {
1517
- if (message.providerReplay?.type === "openai-responses-compaction") return;
1430
+ if (replay?.type !== "openai-responses-compaction" && replay?.type !== "openai-responses-retained-compaction") {
1431
+ if (message.providerReplay?.type === "openai-responses-compaction" || message.providerReplay?.type === "openai-responses-retained-compaction") return;
1518
1432
  continue;
1519
1433
  }
1520
1434
  if (!openAIResponsesReplayContextMatches(replay, context)) return;
@@ -1525,7 +1439,10 @@ function resolveNewestOpenAIResponsesCompactionReplay(messages, model, options)
1525
1439
  ...isSafeResponsesReplayItemId(replay.id) ? { id: replay.id } : {},
1526
1440
  encrypted_content: replay.data
1527
1441
  },
1528
- replayIndex: replay.replayIndex ?? 0
1442
+ ...replay.type === "openai-responses-retained-compaction" ? { mode: "retained-users" } : {
1443
+ mode: "compacted-prefix",
1444
+ replayIndex: replay.replayIndex ?? 0
1445
+ }
1529
1446
  };
1530
1447
  }
1531
1448
  }
@@ -1540,11 +1457,20 @@ function buildOpenAIResponsesCompactionReplayPlan(messages, model, options) {
1540
1457
  preserveUnframedToolResults: false
1541
1458
  };
1542
1459
  const ownerIndex = messages.indexOf(compaction.owner);
1460
+ const collectRetainedUserMessages = (prefix) => {
1461
+ const previous = resolveNewestOpenAIResponsesCompactionReplay(prefix, model, options);
1462
+ if (!previous) return prefix.filter((message) => message.role === "user");
1463
+ const previousOwnerIndex = prefix.indexOf(previous.owner);
1464
+ const laterUsers = prefix.slice(previousOwnerIndex + 1).filter((message) => message.role === "user");
1465
+ return previous.mode === "retained-users" ? [...collectRetainedUserMessages(prefix.slice(0, previousOwnerIndex)), ...laterUsers] : laterUsers;
1466
+ };
1467
+ const retainedMessages = compaction.mode === "retained-users" ? collectRetainedUserMessages(messages.slice(0, ownerIndex)) : void 0;
1543
1468
  return {
1544
1469
  messages: [{
1545
1470
  ...compaction.owner,
1546
- content: compaction.owner.content.slice(compaction.replayIndex)
1471
+ content: compaction.mode === "retained-users" ? [] : compaction.owner.content.slice(compaction.replayIndex)
1547
1472
  }, ...messages.slice(ownerIndex + 1)],
1473
+ ...retainedMessages?.length ? { retainedMessages } : {},
1548
1474
  compaction: compaction.item,
1549
1475
  preserveUnframedToolResults: true
1550
1476
  };
@@ -1732,17 +1658,27 @@ function convertResponsesMessagesWithStyle(model, context, allowedToolCallProvid
1732
1658
  authProfileId: options?.authProfileId,
1733
1659
  mode: options?.replayMode
1734
1660
  });
1735
- const transformedMessages = providerStyle ? transformProviderMessages(replayPlan.messages, model, normalizeToolCallId) : transformTransportMessages(replayPlan.messages, model, normalizeToolCallId, {
1661
+ const transformMessages = (source) => providerStyle ? transformProviderMessages(source, model, normalizeToolCallId) : transformTransportMessages(source, model, normalizeToolCallId, {
1736
1662
  normalizeSameModelToolCallIds: shouldNormalizeSameModelToolCallIds,
1737
1663
  preserveUnframedToolResults: replayPlan.preserveUnframedToolResults
1738
1664
  });
1665
+ const transformedMessages = transformMessages(replayPlan.messages);
1666
+ const transformedRetainedMessages = replayPlan.retainedMessages ? transformMessages(replayPlan.retainedMessages) : [];
1739
1667
  if ((options?.includeSystemPrompt ?? true) && context.systemPrompt) messages.push(buildResponsesInputMessage(model.reasoning && (providerStyle ? model.compat?.supportsDeveloperRole !== false : options?.supportsDeveloperRole !== false) ? "developer" : "system", [{
1740
1668
  type: "input_text",
1741
1669
  text: sanitizeTransportPayloadText(stripSystemPromptCacheBoundary(context.systemPrompt))
1742
1670
  }]));
1743
- if (replayPlan.compaction) messages.push(replayPlan.compaction);
1671
+ const replayMessages = replayPlan.compaction ? [
1672
+ ...transformedRetainedMessages,
1673
+ replayPlan.compaction,
1674
+ ...transformedMessages
1675
+ ] : transformedMessages;
1744
1676
  let msgIndex = 0;
1745
- for (const msg of transformedMessages) {
1677
+ for (const msg of replayMessages) {
1678
+ if (!("role" in msg)) {
1679
+ messages.push(msg);
1680
+ continue;
1681
+ }
1746
1682
  if (msg.role === "user") if (typeof msg.content === "string") messages.push(buildResponsesInputMessage("user", [{
1747
1683
  type: "input_text",
1748
1684
  text: sanitizeTransportPayloadText(msg.content)
@@ -1766,7 +1702,14 @@ function convertResponsesMessagesWithStyle(model, context, allowedToolCallProvid
1766
1702
  const isDifferentModel = msg.model !== model.id && msg.provider === model.provider && msg.api === model.api;
1767
1703
  for (const block of msg.content) if (block.type === "thinking") {
1768
1704
  if (shouldReplayReasoningItems && block.thinkingSignature && (providerStyle || block.thinkingSignature.startsWith("{"))) {
1769
- const replayableReasoningItem = prepareOpenAIResponsesReasoningItemForReplay(JSON.parse(block.thinkingSignature), replayContext, readOpenAIResponsesReasoningReplayBlockMetadata(block), providerStyle ? { preserveUnattributedEncryptedContent: true } : void 0);
1705
+ let reasoningItem;
1706
+ try {
1707
+ reasoningItem = JSON.parse(block.thinkingSignature);
1708
+ } catch {
1709
+ continue;
1710
+ }
1711
+ if (!isRecord(reasoningItem) || reasoningItem.type !== "reasoning") continue;
1712
+ const replayableReasoningItem = prepareOpenAIResponsesReasoningItemForReplay(reasoningItem, replayContext, readOpenAIResponsesReasoningReplayBlockMetadata(isRecord(block) ? block : {}), providerStyle ? { preserveUnattributedEncryptedContent: true } : void 0);
1770
1713
  if (!shouldReplayResponsesItemIds) delete replayableReasoningItem.id;
1771
1714
  if (shouldReplayResponsesItemIds && !providerStyle && model.provider === "github-copilot" && !isSafeResponsesReplayItemId(replayableReasoningItem.id)) continue;
1772
1715
  output.push(replayableReasoningItem);
@@ -1849,6 +1792,9 @@ function convertProviderResponsesMessages(model, context, allowedToolCallProvide
1849
1792
  }
1850
1793
  //#endregion
1851
1794
  //#region packages/ai/src/transports/openai-responses-replay-internal.ts
1795
+ function isAsyncIterable(value) {
1796
+ return (typeof value === "object" && value !== null || typeof value === "function") && Symbol.asyncIterator in value;
1797
+ }
1852
1798
  function isInvalidEncryptedContentError(error) {
1853
1799
  if (!error || typeof error !== "object") return false;
1854
1800
  const record = error;
@@ -1916,6 +1862,7 @@ async function createResponsesStreamWithEncryptedContentRetry(params) {
1916
1862
  commitResponsesEncryptedContentAttempt(attempt, (checkpoint) => {
1917
1863
  if (checkpoint) params.onCompactionRejected?.(checkpoint);
1918
1864
  });
1865
+ if (!isAsyncIterable(data)) throw new Error("OpenAI Responses streaming request returned a non-stream response");
1919
1866
  return {
1920
1867
  stream: data,
1921
1868
  response,
@@ -2553,11 +2500,9 @@ function resolveCompletedResponsesToolCall(item, streamed) {
2553
2500
  if (streamedName && completedName && streamedName !== completedName) throw new Error(`Responses stream changed tool-call function name from ${streamedName} to ${completedName}`);
2554
2501
  const name = completedName ?? streamedName;
2555
2502
  if (!name) throw new Error("Responses stream completed tool call without a function name");
2556
- const argumentsValue = parseJsonObjectPreservingUnsafeIntegers(streamed?.arguments ?? item.arguments);
2557
- if (!argumentsValue) throw new Error("Responses stream completed tool call with invalid JSON arguments");
2558
2503
  return {
2559
2504
  name,
2560
- arguments: argumentsValue
2505
+ arguments: parseTerminalToolCallArguments(streamed?.arguments ?? item.arguments, "Responses stream completed tool call with invalid JSON arguments")
2561
2506
  };
2562
2507
  }
2563
2508
  function createResponsesTerminalController(params) {
@@ -3212,7 +3157,7 @@ async function processResponsesStream(openaiStream, output, stream, model, optio
3212
3157
  break;
3213
3158
  } else if (event.type === "error") throw new Error(event.message ? `Error Code ${event.code}: ${event.message}` : "Unknown error");
3214
3159
  else if (event.type === "response.failed") {
3215
- const failure = normalizeResponsesFailedEvent(event, model);
3160
+ const failure = normalizeResponsesFailedEvent(isRecord(event) ? event : {}, model);
3216
3161
  finalizeFailedResponse(event.response, failure.responseId);
3217
3162
  throw new ResponsesStreamFailure(failure, event.response);
3218
3163
  }
@@ -3383,7 +3328,7 @@ async function runResponsesStreamLifecycle(params) {
3383
3328
  stream: openaiStream,
3384
3329
  signal: firstEventAbort.signal,
3385
3330
  abort: firstEventAbort.abort,
3386
- hook: createOpenAIResponseHook(options?.onResponse, response, model),
3331
+ hook: createOpenAIProviderAcceptanceHook(options, response, model),
3387
3332
  onReady: () => stream.push({
3388
3333
  type: "start",
3389
3334
  partial: output
@@ -3427,4 +3372,4 @@ async function runResponsesStreamLifecycle(params) {
3427
3372
  }
3428
3373
  }
3429
3374
  //#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 };
3375
+ 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, 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, applyResponsesServiceTierPricing as n, resolveUnsupportedToolSchemaKeywords as nt, runResponsesStreamLifecycle as o, cleanSchemaForLlamacppGbnf as ot, ResponsesStreamFailure as p, 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 };
@@ -1,14 +1,15 @@
1
1
  import { n as normalizeLowercaseStringOrEmpty } from "./string-coerce-fsri9iCu.mjs";
2
- import { t as sanitizeSurrogates } from "./sanitize-unicode-BYqrYtC_.mjs";
3
- import { a as describeToolResultMediaPlaceholder, l as isImageWithMediaPayload, s as extractToolResultText } from "./host-DTqNc7ad.mjs";
2
+ import { t as sanitizeSurrogates } from "./sanitize-unicode-BP7HLLZn.mjs";
3
+ import { a as describeToolResultMediaPlaceholder, c as extractToolResultText, d as isImageWithMediaPayload } from "./host-DF_yxOsA.mjs";
4
4
  import { a as isRecord, r as asOptionalObjectRecord } from "./record-coerce-DdXsgUd_.mjs";
5
5
  import { t as truncateUtf16Safe } from "./utf16-slice-CvGodqok.mjs";
6
- import { l as stripSystemPromptCacheBoundary } from "./simple-options-D58D5Kvw.mjs";
7
- import { o as resolveProviderRequestCapabilities } from "./tool-schema-json-projection-q5d7QX5c.mjs";
8
- import { t as transformProviderMessages } from "./provider-transcript-transform-ePx-Bbfr.mjs";
9
- import { l as measureUtf8AppendBytes } from "./openai-tool-projection-CY04OcvQ.mjs";
6
+ import { d as finalizeTerminalToolCallArguments, j as stripSystemPromptCacheBoundary } from "./simple-options-oqsXB6U3.mjs";
7
+ import { o as resolveProviderRequestCapabilities } from "./tool-schema-json-projection-FEr-jOoZ.mjs";
8
+ import { u as measureUtf8AppendBytes } from "./openai-tool-projection-CHGLt03m.mjs";
9
+ import { t as transformProviderMessages } from "./provider-transcript-transform--gtf0ZbR.mjs";
10
10
  import { randomUUID } from "node:crypto";
11
11
  //#region packages/ai/src/utils/assistant-text-phase.ts
12
+ const EMPTY_ASSISTANT_TEXT_BLOCK_SET = /* @__PURE__ */ new Set();
12
13
  function isAssistantTextPhaseBlock(block) {
13
14
  if (!block || typeof block !== "object") return false;
14
15
  const record = block;
@@ -21,20 +22,36 @@ function encodeAssistantTextSignatureV1(id, phase) {
21
22
  ...phase ? { phase } : {}
22
23
  });
23
24
  }
24
- /** Tags unphased narration before a tool-call event becomes consumer-visible. */
25
- function tagPendingCommentaryText(content) {
25
+ function tagUnphasedText(content, phase, idPrefix) {
26
26
  const textBlocks = content.filter(isAssistantTextPhaseBlock);
27
- let commentaryIndex = textBlocks.filter((block) => block.textSignature !== void 0).length;
27
+ let phaseIndex = textBlocks.filter((block) => block.textSignature !== void 0).length;
28
28
  const tagged = /* @__PURE__ */ new Map();
29
29
  for (const block of textBlocks) {
30
30
  if (block.text.trim().length === 0 || block.textSignature !== void 0) continue;
31
- const signature = encodeAssistantTextSignatureV1(`commentary-${commentaryIndex}`, "commentary");
31
+ const signature = encodeAssistantTextSignatureV1(`${idPrefix}-${phaseIndex}`, phase);
32
32
  block.textSignature = signature;
33
33
  tagged.set(block, signature);
34
- commentaryIndex += 1;
34
+ phaseIndex += 1;
35
35
  }
36
36
  return tagged;
37
37
  }
38
+ /** Tags unphased narration before a tool-call event becomes consumer-visible. */
39
+ function tagPendingCommentaryText(content) {
40
+ return tagUnphasedText(content, "commentary", "commentary");
41
+ }
42
+ /** Records the confirmed final-answer boundary after reasoning resumes. */
43
+ function tagInterruptedTextPhases(content, interruptedText, preservedVisibleText = EMPTY_ASSISTANT_TEXT_BLOCK_SET) {
44
+ const interruptedTextIndex = content.indexOf(interruptedText);
45
+ if (interruptedTextIndex === -1) return;
46
+ const finalAnswerIndex = content.findIndex((block, index) => index > interruptedTextIndex && isAssistantTextPhaseBlock(block) && block.text.trim().length > 0);
47
+ if (finalAnswerIndex === -1) return;
48
+ tagUnphasedText(content.slice(0, finalAnswerIndex).filter((block) => !preservedVisibleText.has(block)), "commentary", "commentary");
49
+ tagUnphasedText(content.filter((block, index) => index >= finalAnswerIndex || preservedVisibleText.has(block)), "final_answer", "final-answer");
50
+ }
51
+ /** Prevents unresolved completion text from becoming a fallback answer after stream failure. */
52
+ function tagUnresolvedTextAsCommentary(message) {
53
+ if (message.openclawDelivery?.textPhaseRequiresTerminal) tagUnphasedText(message.content, "commentary", "commentary");
54
+ }
38
55
  /** Rolls back only the exact provisional signatures created by this transport turn. */
39
56
  function clearPendingCommentaryText(tags) {
40
57
  for (const [block, signature] of tags) if (block.textSignature === signature) delete block.textSignature;
@@ -127,8 +144,8 @@ function resolveOpenAICompletionsCompatDefaultsFromCapabilities(input) {
127
144
  return resolveOpenAICompletionsCompatDefaults(input);
128
145
  }
129
146
  /** Detects endpoint capabilities and defaults for an OpenAI-completions model. */
130
- function detectOpenAICompletionsCompat(model, resolveCapabilities = resolveProviderRequestCapabilities) {
131
- const capabilities = resolveCapabilities({
147
+ function detectOpenAICompletionsCompat(model, resolveCapabilities) {
148
+ const capabilities = (resolveCapabilities ?? ((input) => resolveProviderRequestCapabilities(input, model)))({
132
149
  provider: model.provider,
133
150
  api: "openai-completions",
134
151
  baseUrl: model.baseUrl,
@@ -153,7 +170,7 @@ function resolveSessionAffinity(model, detectedFormat) {
153
170
  return "openai";
154
171
  }
155
172
  /** Applies explicit model overrides once on top of the canonical transport defaults. */
156
- function resolveOpenAICompletionsCompat(model, resolveCapabilities = resolveProviderRequestCapabilities) {
173
+ function resolveOpenAICompletionsCompat(model, resolveCapabilities) {
157
174
  const { defaults } = detectOpenAICompletionsCompat(model, resolveCapabilities);
158
175
  const configured = model.compat;
159
176
  return {
@@ -310,22 +327,21 @@ function finalizeOpenAICompletionsToolCalls(output, options = {}) {
310
327
  if (hasToolCalls) output.content = output.content.filter((block) => !isToolCall(block));
311
328
  return;
312
329
  }
313
- for (const block of output.content) {
314
- if (!isToolCall(block)) continue;
315
- const toolCall = block;
316
- let completeArguments;
317
- try {
318
- completeArguments = typeof toolCall.partialArgs === "string" && toolCall.partialArgs.trim().length > 0 ? JSON.parse(toolCall.partialArgs) : void 0;
319
- } catch {
320
- completeArguments = void 0;
321
- }
322
- if (typeof toolCall.name !== "string" || toolCall.name.trim().length === 0 || !isRecord(completeArguments)) {
323
- output.stopReason = "error";
324
- output.errorMessage = "Provider returned an incomplete or malformed tool call";
325
- output.content = output.content.filter((candidate) => !isToolCall(candidate));
326
- return;
327
- }
328
- toolCall.arguments = completeArguments;
330
+ const toolCalls = output.content.filter(isToolCall);
331
+ const rejectToolCalls = () => {
332
+ output.stopReason = "error";
333
+ output.errorMessage = "Provider returned an incomplete or malformed tool call";
334
+ output.content = output.content.filter((candidate) => !isToolCall(candidate));
335
+ };
336
+ if (toolCalls.some((call) => typeof call.name !== "string" || call.name.trim().length === 0 || typeof call.partialArgs !== "string" || call.partialArgs.trim().length === 0)) {
337
+ rejectToolCalls();
338
+ return;
339
+ }
340
+ try {
341
+ finalizeTerminalToolCallArguments(toolCalls, (call) => call.partialArgs);
342
+ } catch {
343
+ rejectToolCalls();
344
+ return;
329
345
  }
330
346
  for (let contentIndex = 0; contentIndex < output.content.length; contentIndex += 1) {
331
347
  const block = output.content[contentIndex];
@@ -560,4 +576,4 @@ function mapOpenAIStopReason(reason, options) {
560
576
  };
561
577
  }
562
578
  //#endregion
563
- export { createOpenAICompletionsToolCallDeltaNormalizer as a, resolveOpenAICompletionsCompat as c, clearPendingCommentaryText as d, rememberPendingCommentaryTags as f, hasToolCallHistory as i, resolveOpenAICompletionsResponseFormat as l, resolveOpenAIReasoningEffortMap as n, finalizeOpenAICompletionsToolCalls as o, tagPendingCommentaryText as p, convertMessages as r, detectOpenAICompletionsCompat as s, mapOpenAIStopReason as t, shouldOmitOllamaCompatResponseFormat as u };
579
+ export { createOpenAICompletionsToolCallDeltaNormalizer as a, resolveOpenAICompletionsCompat as c, clearPendingCommentaryText as d, rememberPendingCommentaryTags as f, tagUnresolvedTextAsCommentary as h, hasToolCallHistory as i, resolveOpenAICompletionsResponseFormat as l, tagPendingCommentaryText as m, resolveOpenAIReasoningEffortMap as n, finalizeOpenAICompletionsToolCalls as o, tagInterruptedTextPhases as p, convertMessages as r, detectOpenAICompletionsCompat as s, mapOpenAIStopReason as t, shouldOmitOllamaCompatResponseFormat as u };
@@ -1,10 +1,10 @@
1
- import { n as applyProviderReportedUsageCost, r as calculateCost } from "./sanitize-unicode-BYqrYtC_.mjs";
2
- import { n as getAiTransportHost } from "./host-DTqNc7ad.mjs";
1
+ import { n as applyProviderReportedUsageCost, r as calculateCost } from "./sanitize-unicode-BP7HLLZn.mjs";
2
+ import { n as getAiTransportHost } from "./host-DF_yxOsA.mjs";
3
3
  import { a as isRecord } from "./record-coerce-DdXsgUd_.mjs";
4
4
  import { n as clampOpenAIPromptCacheKey } from "./openai-prompt-cache-mZTCdRPo.mjs";
5
- import { t as projectRuntimeToolInputSchema } from "./tool-schema-json-projection-q5d7QX5c.mjs";
6
- import { t as headersToRecord } from "./headers-DdOQtGuU.mjs";
7
- import { f as transportAbortError } from "./provider-transcript-transform-ePx-Bbfr.mjs";
5
+ import { g as notifyProviderHttpResponse, x as transportAbortError } from "./simple-options-oqsXB6U3.mjs";
6
+ import { t as projectRuntimeToolInputSchema } from "./tool-schema-json-projection-FEr-jOoZ.mjs";
7
+ import { t as headersToRecord } from "./headers-B_e4-1J0.mjs";
8
8
  //#region packages/ai/src/transports/openai-transport-shared.ts
9
9
  /** Shared options, usage shape, cache identity, ordering, and stream scheduling for OpenAI APIs. */
10
10
  const MODEL_STREAM_COOPERATIVE_YIELD_INTERVAL_MS = 12;
@@ -24,6 +24,87 @@ const log = {
24
24
  getAiTransportHost().logWarn("openai-transport", message, data);
25
25
  }
26
26
  };
27
+ const EMPTY_OPENAI_COMPLETIONS_REASONING_BATCH = {
28
+ deltas: [],
29
+ mirroredThinking: [],
30
+ hasThinking: false,
31
+ hasVisibleText: false
32
+ };
33
+ const OPENAI_COMPLETIONS_REASONING_FIELDS = [
34
+ "reasoning_content",
35
+ "reasoning",
36
+ "reasoning_text"
37
+ ];
38
+ function appendOpenAICompletionsReasoningDelta(batch, next) {
39
+ if (next.kind === "thinking") batch.hasThinking = true;
40
+ else batch.hasVisibleText = true;
41
+ const previous = batch.deltas[batch.deltas.length - 1];
42
+ if (!previous || previous.kind !== next.kind) {
43
+ batch.deltas.push(next);
44
+ if (next.kind === "thinking") batch.mirroredThinking.push(next.text);
45
+ return;
46
+ }
47
+ if (next.kind === "thinking" && previous.kind === "thinking") {
48
+ if (previous.signature !== next.signature) {
49
+ batch.deltas.push(next);
50
+ batch.mirroredThinking.push(next.text);
51
+ return;
52
+ }
53
+ previous.text += next.text;
54
+ batch.mirroredThinking[batch.mirroredThinking.length - 1] += next.text;
55
+ return;
56
+ }
57
+ previous.text += next.text;
58
+ }
59
+ function createOpenAICompletionsReasoningBatch() {
60
+ return {
61
+ deltas: [],
62
+ mirroredThinking: [],
63
+ hasThinking: false,
64
+ hasVisibleText: false
65
+ };
66
+ }
67
+ function readOpenAICompletionsReasoningBatch(delta, visibleReasoningDetailTypes) {
68
+ let batch;
69
+ const reasoningDetails = delta.reasoning_details;
70
+ let usedReasoningThinkingDetails = false;
71
+ if (Array.isArray(reasoningDetails)) for (const item of reasoningDetails) {
72
+ if (!isRecord(item)) continue;
73
+ const detail = item;
74
+ if (typeof detail.text !== "string" || !detail.text) continue;
75
+ if (detail.type === "reasoning.text") {
76
+ usedReasoningThinkingDetails = true;
77
+ batch ??= createOpenAICompletionsReasoningBatch();
78
+ appendOpenAICompletionsReasoningDelta(batch, {
79
+ kind: "thinking",
80
+ signature: "reasoning_details",
81
+ text: detail.text
82
+ });
83
+ continue;
84
+ }
85
+ if (typeof detail.type === "string" && visibleReasoningDetailTypes.has(detail.type)) {
86
+ batch ??= createOpenAICompletionsReasoningBatch();
87
+ appendOpenAICompletionsReasoningDelta(batch, {
88
+ kind: "text",
89
+ text: detail.text,
90
+ source: "reasoning_detail"
91
+ });
92
+ }
93
+ }
94
+ if (!usedReasoningThinkingDetails) for (const field of OPENAI_COMPLETIONS_REASONING_FIELDS) {
95
+ const value = delta[field];
96
+ if (typeof value === "string" && value.length > 0) {
97
+ batch ??= createOpenAICompletionsReasoningBatch();
98
+ appendOpenAICompletionsReasoningDelta(batch, {
99
+ kind: "thinking",
100
+ signature: field,
101
+ text: value
102
+ });
103
+ break;
104
+ }
105
+ }
106
+ return batch ?? EMPTY_OPENAI_COMPLETIONS_REASONING_BATCH;
107
+ }
27
108
  function parseOpenAICompletionsUsage(rawUsage, model, options) {
28
109
  const cacheRead = rawUsage.prompt_tokens_details?.cached_tokens ?? rawUsage.prompt_cache_hit_tokens ?? 0;
29
110
  const cacheWrite = rawUsage.prompt_tokens_details?.cache_write_tokens || 0;
@@ -55,6 +136,13 @@ function createOpenAIResponseHook(onResponse, response, model) {
55
136
  headers: headersToRecord(response.headers)
56
137
  }, model) : void 0;
57
138
  }
139
+ function createOpenAIProviderAcceptanceHook(options, response, model) {
140
+ return () => notifyProviderHttpResponse({
141
+ options,
142
+ response,
143
+ model
144
+ });
145
+ }
58
146
  function throwIfModelStreamAborted(signal) {
59
147
  if (signal?.aborted) throw transportAbortError(signal);
60
148
  }
@@ -335,4 +423,4 @@ function reconcileOpenAICompletionsToolChoice(choice, projection) {
335
423
  };
336
424
  }
337
425
  //#endregion
338
- export { createModelStreamCooperativeScheduler as a, log as c, readOpenAICompletionsContentDeltas as d, resolvePromptCacheKey as f, GEMINI_THOUGHT_SIGNATURE_VALIDATOR_SKIP as i, measureUtf8AppendBytes as l, reconcileOpenAICompletionsToolChoice as n, createOpenAIResponseHook as o, throwIfModelStreamAborted as p, reconcileOpenAIResponsesToolChoice as r, isOpenAICompletionsThinkingEnabled as s, projectOpenAITools as t, parseOpenAICompletionsUsage as u };
426
+ export { createModelStreamCooperativeScheduler as a, isOpenAICompletionsThinkingEnabled as c, parseOpenAICompletionsUsage as d, readOpenAICompletionsContentDeltas as f, throwIfModelStreamAborted as h, GEMINI_THOUGHT_SIGNATURE_VALIDATOR_SKIP as i, log as l, resolvePromptCacheKey as m, reconcileOpenAICompletionsToolChoice as n, createOpenAIProviderAcceptanceHook as o, readOpenAICompletionsReasoningBatch as p, reconcileOpenAIResponsesToolChoice as r, createOpenAIResponseHook as s, projectOpenAITools as t, measureUtf8AppendBytes as u };