@openclaw/ai 2026.7.2-beta.7 → 2026.8.1-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/dist/{anthropic-CH4UUnZr.mjs → anthropic-CE-7SkF6.mjs} +28 -191
  2. package/dist/{anthropic-usage-DWU-x8MI.mjs → anthropic-usage-Ma4iX6uG.mjs} +262 -4
  3. package/dist/{api-registry-DlMgPR39.d.mts → api-registry-EpJoVwM1.d.mts} +1 -1
  4. package/dist/{azure-openai-responses-CImcwB83.mjs → azure-openai-responses-Cc_kasye.mjs} +4 -4
  5. package/dist/{event-stream-D8n2uFee.mjs → event-stream-CEV9t6da.mjs} +10 -2
  6. package/dist/{event-stream-YjaPW20U.d.mts → event-stream-DRmDMRHH.d.mts} +2 -1
  7. package/dist/event-stream.d.mts +1 -1
  8. package/dist/event-stream.mjs +1 -1
  9. package/dist/{google-CtSg0iTS.mjs → google-CGQu21aw.mjs} +5 -5
  10. package/dist/{google-shared-DNBz5rcD.mjs → google-shared-Cq2UKx1l.mjs} +151 -85
  11. package/dist/{google-vertex-31f1uS9L.mjs → google-vertex-CusxWzvE.mjs} +10 -7
  12. package/dist/{host-Dog2WQiR.mjs → host-Bl7Kgddo.mjs} +40 -2
  13. package/dist/{host-B9GUmcra.d.mts → host-Dn4_SZI2.d.mts} +2 -2
  14. package/dist/index.d.mts +5 -5
  15. package/dist/index.mjs +2 -2
  16. package/dist/internal/anthropic.d.mts +19 -3
  17. package/dist/internal/anthropic.mjs +4 -4
  18. package/dist/internal/openai.d.mts +4 -4
  19. package/dist/internal/openai.mjs +7 -7
  20. package/dist/internal/runtime.d.mts +2 -2
  21. package/dist/internal/runtime.mjs +3 -3
  22. package/dist/internal/shared.d.mts +1 -1
  23. package/dist/internal/shared.mjs +3 -4
  24. package/dist/{mistral-CWmpvWYh.mjs → mistral-Dx6VzNjf.mjs} +25 -9
  25. package/dist/model-utils-Dau5dlgm.mjs +64 -0
  26. package/dist/number-coercion-1Miyb5MO.mjs +66 -0
  27. package/dist/{openai-chatgpt-responses-B84Ibtrd.mjs → openai-chatgpt-responses-SC9m0FSf.mjs} +94 -131
  28. package/dist/{openai-completions-DsOxhOD1.mjs → openai-completions-BaIpl93j.mjs} +47 -66
  29. package/dist/{openai-reasoning-compat-YgeLncHw.mjs → openai-reasoning-compat-DKebnIBL.mjs} +147 -6
  30. package/dist/{openai-responses-BT7A3sLu.mjs → openai-responses-Bdx3V_Yu.mjs} +6 -22
  31. package/dist/openai-responses-contracts-BBKBfAqR.d.mts +116 -0
  32. package/dist/openai-responses-prompt-observer-internal-DDZPxRfr.mjs +46 -0
  33. package/dist/{openai-responses-shared-pXl6Wd8S.mjs → openai-responses-shared-CCyMvg7M.mjs} +21 -10
  34. package/dist/{openai-responses-stream-internal-Cw5txaGW.mjs → openai-responses-stream-internal-Bl8YyVtF.mjs} +244 -81
  35. package/dist/{openai-tool-projection-OhX64DoP.mjs → openai-transport-shared-Cipt7egQ.mjs} +129 -29
  36. package/dist/{provider-error-CAEvRjry.mjs → provider-error-DI0Ts28U.mjs} +1 -1
  37. package/dist/{provider-options-D8bB3z9b.d.mts → provider-options-C5kYML7i.d.mts} +1 -1
  38. package/dist/providers.d.mts +1 -1
  39. package/dist/providers.mjs +9 -9
  40. package/dist/{stream-first-event-timeout-BBys9hSb.mjs → stream-first-event-timeout-BIBomOGq.mjs} +1 -1
  41. package/dist/{tool-result-text-CTpIRbYd.mjs → tool-result-text-Dvkp2Dus.mjs} +51 -2
  42. package/dist/{tool-schema-json-projection-BwNu3nDi.mjs → tool-schema-json-projection-B1b-XCn5.mjs} +28 -1
  43. package/dist/transform-messages-DfjpNXNQ.mjs +2 -0
  44. package/dist/{transport-stream-shared-D81p90xq.mjs → transport-stream-shared-CPNv7A3r.mjs} +4 -4
  45. package/dist/transports.d.mts +41 -73
  46. package/dist/transports.mjs +317 -601
  47. package/dist/{types-bzp5k29J.d.mts → types-CH7ReIcU.d.mts} +4 -0
  48. package/dist/types.d.mts +3 -3
  49. package/dist/types.mjs +1 -1
  50. package/dist/{validation-B-j7cOYp.d.mts → validation-CcPcuEbR.d.mts} +1 -1
  51. package/dist/validation.d.mts +1 -1
  52. package/package.json +1 -1
  53. package/dist/error-coercion-DgxlWC0n.mjs +0 -15
  54. package/dist/number-coercion-DvG7SNMg.mjs +0 -129
  55. package/dist/openai-completions-compat-DBWjXoMZ.d.mts +0 -43
  56. package/dist/simple-options-9lhRrN73.mjs +0 -50
  57. package/dist/transform-messages-C8mBqZxF.mjs +0 -2
@@ -1,13 +1,110 @@
1
- import { g as isRecord, m as normalizeOptionalString, n as getAiTransportHost, p as normalizeLowercaseStringOrEmpty } from "./host-Dog2WQiR.mjs";
2
- import { n as clampOpenAIPromptCacheKey } from "./openai-prompt-cache-mZTCdRPo.mjs";
3
- import { a as isImageWithMediaPayload, d as stripSystemPromptCacheBoundary, o as truncateUtf16Safe, r as extractToolResultText, t as describeToolResultMediaPlaceholder } from "./tool-result-text-CTpIRbYd.mjs";
4
- import { u as transformTransportMessages } from "./openai-tool-projection-OhX64DoP.mjs";
5
- import { c as calculateCost } from "./number-coercion-DvG7SNMg.mjs";
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";
6
5
  import { n as parseStreamingJson } from "./json-parse-BvXNt1-7.mjs";
7
- import { b as redactIdentifier, d as transportAbortError, l as sanitizeNonEmptyTransportPayloadText, u as sanitizeTransportPayloadText, x as redactSensitiveText } from "./transport-stream-shared-D81p90xq.mjs";
8
- import { a as withFirstStreamEventTimeout } from "./stream-first-event-timeout-BBys9hSb.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";
9
9
  import { t as shortHash } from "./hash-CHgqbJmD.mjs";
10
10
  import { randomUUID } from "node:crypto";
11
+ //#region packages/ai/src/transports/json-unsafe-integers.ts
12
+ /**
13
+ * JSON parsing helpers that preserve integer literals larger than
14
+ * Number.MAX_SAFE_INTEGER as strings before JSON.parse can round them.
15
+ */
16
+ const MAX_SAFE_INTEGER_ABS_STR = String(Number.MAX_SAFE_INTEGER);
17
+ function isAsciiDigit(ch) {
18
+ return ch !== void 0 && ch >= "0" && ch <= "9";
19
+ }
20
+ function parseJsonNumberToken(input, start) {
21
+ let idx = start;
22
+ if (input[idx] === "-") idx += 1;
23
+ if (idx >= input.length) return null;
24
+ if (input[idx] === "0") idx += 1;
25
+ else if (isAsciiDigit(input[idx]) && input[idx] !== "0") while (isAsciiDigit(input[idx])) idx += 1;
26
+ else return null;
27
+ let isInteger = true;
28
+ if (input[idx] === ".") {
29
+ isInteger = false;
30
+ idx += 1;
31
+ if (!isAsciiDigit(input[idx])) return null;
32
+ while (isAsciiDigit(input[idx])) idx += 1;
33
+ }
34
+ if (input[idx] === "e" || input[idx] === "E") {
35
+ isInteger = false;
36
+ idx += 1;
37
+ if (input[idx] === "+" || input[idx] === "-") idx += 1;
38
+ if (!isAsciiDigit(input[idx])) return null;
39
+ while (isAsciiDigit(input[idx])) idx += 1;
40
+ }
41
+ return {
42
+ token: input.slice(start, idx),
43
+ end: idx,
44
+ isInteger
45
+ };
46
+ }
47
+ function isUnsafeIntegerLiteral(token) {
48
+ const digits = token[0] === "-" ? token.slice(1) : token;
49
+ if (digits.length < MAX_SAFE_INTEGER_ABS_STR.length) return false;
50
+ if (digits.length > MAX_SAFE_INTEGER_ABS_STR.length) return true;
51
+ return digits > MAX_SAFE_INTEGER_ABS_STR;
52
+ }
53
+ /** Quotes integer literals above Number.MAX_SAFE_INTEGER before JSON.parse. */
54
+ function quoteUnsafeIntegerLiterals(input) {
55
+ let out = "";
56
+ let inString = false;
57
+ let escaped = false;
58
+ let idx = 0;
59
+ while (idx < input.length) {
60
+ const ch = input[idx] ?? "";
61
+ if (inString) {
62
+ out += ch;
63
+ if (escaped) escaped = false;
64
+ else if (ch === "\\") escaped = true;
65
+ else if (ch === "\"") inString = false;
66
+ idx += 1;
67
+ continue;
68
+ }
69
+ if (ch === "\"") {
70
+ inString = true;
71
+ out += ch;
72
+ idx += 1;
73
+ continue;
74
+ }
75
+ if (ch === "-" || isAsciiDigit(ch)) {
76
+ const parsed = parseJsonNumberToken(input, idx);
77
+ if (parsed) {
78
+ if (parsed.isInteger && isUnsafeIntegerLiteral(parsed.token)) out += `"${parsed.token}"`;
79
+ else out += parsed.token;
80
+ idx = parsed.end;
81
+ continue;
82
+ }
83
+ }
84
+ out += ch;
85
+ idx += 1;
86
+ }
87
+ return out;
88
+ }
89
+ /** Parses JSON while preserving unsafe integer literals as strings. */
90
+ function parseJsonPreservingUnsafeIntegers(input) {
91
+ return JSON.parse(quoteUnsafeIntegerLiterals(input));
92
+ }
93
+ /** Parses or accepts an object while preserving unsafe integer literals in string input. */
94
+ 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
+ }
102
+ return null;
103
+ }
104
+ if (value && typeof value === "object" && !Array.isArray(value)) return value;
105
+ return null;
106
+ }
107
+ //#endregion
11
108
  //#region packages/ai/src/transports/model-transport-debug.ts
12
109
  function normalizeEnv(value) {
13
110
  return typeof value === "string" ? value.trim().toLowerCase() : "";
@@ -1480,49 +1577,6 @@ function resolveOpenAIProjectedToolsStrictToolFlag(projection, strict) {
1480
1577
  return projection.tools.every((tool) => isStrictOpenAIJsonSchemaCompatible(tool.parameters));
1481
1578
  }
1482
1579
  //#endregion
1483
- //#region packages/ai/src/transports/openai-transport-shared.ts
1484
- /** Shared options, usage shape, cache identity, ordering, and stream scheduling for OpenAI APIs. */
1485
- const MODEL_STREAM_COOPERATIVE_YIELD_INTERVAL_MS = 12;
1486
- const MODEL_STREAM_COOPERATIVE_YIELD_MAX_EVENTS = 64;
1487
- const GEMINI_THOUGHT_SIGNATURE_VALIDATOR_SKIP = "skip_thought_signature_validator";
1488
- const log = {
1489
- debug(message, data) {
1490
- getAiTransportHost().logDebug("openai-transport", () => ({
1491
- message,
1492
- data
1493
- }));
1494
- },
1495
- info(message, data) {
1496
- getAiTransportHost().logInfo("openai-transport", message, data);
1497
- },
1498
- warn(message, data) {
1499
- getAiTransportHost().logWarn("openai-transport", message, data);
1500
- }
1501
- };
1502
- function throwIfModelStreamAborted(signal) {
1503
- if (signal?.aborted) throw transportAbortError(signal);
1504
- }
1505
- function createModelStreamCooperativeScheduler(signal) {
1506
- let lastYieldedAt = Date.now();
1507
- let eventsSinceYield = 0;
1508
- return { async afterEvent() {
1509
- throwIfModelStreamAborted(signal);
1510
- eventsSinceYield += 1;
1511
- const now = Date.now();
1512
- if (eventsSinceYield < MODEL_STREAM_COOPERATIVE_YIELD_MAX_EVENTS && now - lastYieldedAt < MODEL_STREAM_COOPERATIVE_YIELD_INTERVAL_MS) return;
1513
- eventsSinceYield = 0;
1514
- lastYieldedAt = now;
1515
- await new Promise((resolve) => {
1516
- setTimeout(resolve, 0);
1517
- });
1518
- throwIfModelStreamAborted(signal);
1519
- } };
1520
- }
1521
- function resolvePromptCacheKey(options, cacheRetention) {
1522
- if (cacheRetention === "none") return;
1523
- return clampOpenAIPromptCacheKey(options?.promptCacheKey ?? options?.sessionId);
1524
- }
1525
- //#endregion
1526
1580
  //#region packages/ai/src/transports/openai-responses-replay.ts
1527
1581
  /** Resolves the assistant message id that can be replayed to OpenAI Responses. */
1528
1582
  function resolveReplayableResponsesMessageId(params) {
@@ -1535,6 +1589,19 @@ const AZURE_RESPONSES_FIRST_EVENT_TIMEOUT_MS = 3e4;
1535
1589
  const RESPONSE_FAILED_NO_DETAILS_MESSAGE = "Unknown error (no error details in response)";
1536
1590
  const OPENAI_RESPONSES_REASONING_REPLAY_META_KEY = "__openclaw_replay";
1537
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
+ };
1538
1605
  //#endregion
1539
1606
  //#region packages/ai/src/transports/openai-responses-debug.ts
1540
1607
  function stringifyUnknown(value, fallback = "") {
@@ -1922,12 +1989,28 @@ function prepareOpenAIResponsesReasoningItemForReplay(item, context, blockMetada
1922
1989
  }
1923
1990
  async function createResponsesStreamWithEncryptedContentRetry(params) {
1924
1991
  try {
1925
- return await params.client.responses.create(params.request, params.requestOptions);
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
+ };
1926
2001
  } catch (error) {
1927
2002
  const retryRequest = stripResponsesRequestEncryptedContent(params.request);
1928
2003
  if (!isInvalidEncryptedContentError(error) || retryRequest === params.request) throw error;
1929
2004
  log.warn(`[responses] retrying without encrypted reasoning content provider=${params.model.provider} api=${params.model.api} model=${params.model.id}`);
1930
- return await params.client.responses.create(retryRequest, params.requestOptions);
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
+ };
1931
2014
  }
1932
2015
  }
1933
2016
  function resolveAzureOpenAIApiVersion(env = process.env) {
@@ -2254,6 +2337,12 @@ async function* observeResponsesStream(stream, model) {
2254
2337
  }
2255
2338
  //#endregion
2256
2339
  //#region packages/ai/src/transports/openai-responses-stream-slots-internal.ts
2340
+ function appendResponsesPendingTextDelta(slot, delta, materialize) {
2341
+ slot.pendingText = `${slot.pendingText ?? ""}${delta}`;
2342
+ const priorText = slot.collapseCandidate?.block.text ?? "";
2343
+ if (priorText.startsWith(slot.pendingText) || slot.pendingText.startsWith(priorText)) return;
2344
+ materialize(slot);
2345
+ }
2257
2346
  function readResponsesOutputIndex(event) {
2258
2347
  const outputIndex = event.output_index;
2259
2348
  return typeof outputIndex === "number" && Number.isInteger(outputIndex) && outputIndex >= 0 ? outputIndex : void 0;
@@ -2371,13 +2460,19 @@ function resolveResponsesToolCallId(item, fallbackId) {
2371
2460
  const generated = `call_${randomUUID().replaceAll("-", "").slice(0, 24)}`;
2372
2461
  return resolvedItemId ? `${generated}|${resolvedItemId}` : generated;
2373
2462
  }
2374
- function resolveCompletedToolCallName(toolCall, value) {
2375
- const streamedName = toolCall?.block.name.trim() || void 0;
2376
- const completedName = typeof value === "string" ? value.trim() || void 0 : void 0;
2463
+ function resolveCompletedResponsesToolCall(item, streamed) {
2464
+ if (item.status && item.status !== "completed") throw new Error("Responses stream completed with an incomplete terminal tool call");
2465
+ const streamedName = streamed?.name?.trim() || void 0;
2466
+ const completedName = typeof item.name === "string" ? item.name.trim() || void 0 : void 0;
2377
2467
  if (streamedName && completedName && streamedName !== completedName) throw new Error(`Responses stream changed tool-call function name from ${streamedName} to ${completedName}`);
2378
2468
  const name = completedName ?? streamedName;
2379
2469
  if (!name) throw new Error("Responses stream completed tool call without a function name");
2380
- return name;
2470
+ const argumentsValue = parseJsonObjectPreservingUnsafeIntegers(streamed?.arguments ?? item.arguments);
2471
+ if (!argumentsValue) throw new Error("Responses stream completed tool call with invalid JSON arguments");
2472
+ return {
2473
+ name,
2474
+ arguments: argumentsValue
2475
+ };
2381
2476
  }
2382
2477
  function createResponsesTerminalController(params) {
2383
2478
  const { output, stream, model, options } = params;
@@ -2400,8 +2495,35 @@ function createResponsesTerminalController(params) {
2400
2495
  const content = part;
2401
2496
  return content.type === "output_text" || content.type === "text" ? content.text ?? "" : content.refusal ?? "";
2402
2497
  }).join("");
2403
- if (!text) return;
2498
+ const started = params.startedTextBlocksByItemId.get(item.id);
2499
+ if (!text && !started) return;
2404
2500
  const phase = item.phase ?? void 0;
2501
+ if (started) {
2502
+ const previousText = started.block.text;
2503
+ started.block.text = text;
2504
+ started.block.textSignature = encodeTextSignatureV1(item.id, phase);
2505
+ params.setLastTextBlock({
2506
+ block: started.block,
2507
+ index: started.index,
2508
+ phase
2509
+ });
2510
+ params.startedTextBlocksByItemId.delete(item.id);
2511
+ if (text.startsWith(previousText)) {
2512
+ const delta = text.slice(previousText.length);
2513
+ if (delta) stream.push({
2514
+ type: "text_delta",
2515
+ contentIndex: started.index,
2516
+ delta
2517
+ });
2518
+ }
2519
+ stream.push({
2520
+ type: "text_end",
2521
+ contentIndex: started.index,
2522
+ content: text,
2523
+ partial: output
2524
+ });
2525
+ return;
2526
+ }
2405
2527
  const previous = params.getLastTextBlock();
2406
2528
  const collapse = resolveResponsesMessageSnapshotCollapse({
2407
2529
  prior: previous && {
@@ -2447,11 +2569,12 @@ function createResponsesTerminalController(params) {
2447
2569
  });
2448
2570
  };
2449
2571
  const appendToolCall = (item) => {
2572
+ const validated = resolveCompletedResponsesToolCall(item);
2450
2573
  const toolCall = {
2451
2574
  type: "toolCall",
2452
2575
  id: resolveResponsesToolCallId(item),
2453
- name: resolveCompletedToolCallName(void 0, item.name),
2454
- arguments: parseStreamingJson(item.arguments || "{}")
2576
+ name: validated.name,
2577
+ arguments: validated.arguments
2455
2578
  };
2456
2579
  blocks.push(toolCall);
2457
2580
  const contentIndex = blocks.length - 1;
@@ -2468,11 +2591,35 @@ function createResponsesTerminalController(params) {
2468
2591
  });
2469
2592
  };
2470
2593
  const recoverTerminalOutput = (items, includeToolCalls) => {
2471
- if (blocks.some((block) => block.type !== "thinking")) return;
2472
- for (const item of items) if (item.type === "message") appendText(item);
2473
- else {
2594
+ let hasCompletedLaterOutput = false;
2595
+ for (const item of items.toReversed()) {
2596
+ if (item.type === "reasoning") {
2597
+ hasCompletedLaterOutput ||= params.reasoningBlocksById.has(item.id);
2598
+ continue;
2599
+ }
2600
+ 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)) {
2603
+ hasCompletedLaterOutput = true;
2604
+ continue;
2605
+ }
2606
+ if (item.type === "function_call" && !includeToolCalls) continue;
2607
+ if (hasCompletedLaterOutput) throw new Error("Responses stream omitted an output item before completed output");
2608
+ if (item.type === "function_call") resolveCompletedResponsesToolCall(item);
2609
+ }
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);
2615
+ } else {
2474
2616
  params.setLastTextBlock(null);
2475
- if (includeToolCalls && item.type === "function_call") appendToolCall(item);
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);
2622
+ }
2476
2623
  }
2477
2624
  };
2478
2625
  const finalizeResponse = (response, terminalEventType) => {
@@ -2526,6 +2673,8 @@ async function processResponsesStream(openaiStream, output, stream, model, optio
2526
2673
  const streamingToolCalls = createResponsesToolCallTracker();
2527
2674
  const outputSlots = createResponsesOutputSlotTracker();
2528
2675
  const reasoningBlocksById = /* @__PURE__ */ new Map();
2676
+ const completedOutputItemIdentities = /* @__PURE__ */ new Set();
2677
+ const startedTextBlocksByItemId = /* @__PURE__ */ new Map();
2529
2678
  let terminalResponseEvent;
2530
2679
  let lastTextBlock = null;
2531
2680
  const blocks = output.content;
@@ -2543,6 +2692,7 @@ async function processResponsesStream(openaiStream, output, stream, model, optio
2543
2692
  contentIndex: blocks.length
2544
2693
  };
2545
2694
  blocks.push(block);
2695
+ reasoningBlocksById.set(item.id, block);
2546
2696
  outputSlots.register(event, slot);
2547
2697
  stream.push({
2548
2698
  type: "thinking_start",
@@ -2567,7 +2717,14 @@ async function processResponsesStream(openaiStream, output, stream, model, optio
2567
2717
  pendingText: collapseCandidate ? "" : null,
2568
2718
  collapseCandidate
2569
2719
  };
2570
- if (block) blocks.push(block);
2720
+ if (block) {
2721
+ blocks.push(block);
2722
+ startedTextBlocksByItemId.set(messageItem.id, {
2723
+ block,
2724
+ index: slot.contentIndex ?? blocks.length - 1,
2725
+ phase: messageItem.phase ?? void 0
2726
+ });
2727
+ }
2571
2728
  outputSlots.register(event, slot);
2572
2729
  if (slot.contentIndex !== void 0) stream.push({
2573
2730
  type: "text_start",
@@ -2595,6 +2752,11 @@ async function processResponsesStream(openaiStream, output, stream, model, optio
2595
2752
  };
2596
2753
  blocks.push(slot.block);
2597
2754
  slot.contentIndex = blockIndex();
2755
+ startedTextBlocksByItemId.set(slot.item.id, {
2756
+ block: slot.block,
2757
+ index: slot.contentIndex,
2758
+ phase: slot.item.phase ?? void 0
2759
+ });
2598
2760
  stream.push({
2599
2761
  type: "text_start",
2600
2762
  contentIndex: slot.contentIndex,
@@ -2612,18 +2774,14 @@ async function processResponsesStream(openaiStream, output, stream, model, optio
2612
2774
  const materializeDeferredTextSlots = (except) => {
2613
2775
  for (const slot of outputSlots.values()) if (slot !== except && slot.type === "text") materializeDeferredTextSlot(slot);
2614
2776
  };
2615
- const appendPendingMessageDelta = (slot, delta) => {
2616
- slot.pendingText = `${slot.pendingText ?? ""}${delta}`;
2617
- const priorText = slot.collapseCandidate?.block.text ?? "";
2618
- if (priorText.startsWith(slot.pendingText) || slot.pendingText.startsWith(priorText)) return;
2619
- materializeDeferredTextSlot(slot);
2620
- };
2621
2777
  const { finalizeResponse, recoverTerminalOutput } = createResponsesTerminalController({
2622
2778
  output,
2623
2779
  stream,
2624
2780
  model,
2625
2781
  options,
2626
2782
  reasoningBlocksById,
2783
+ completedOutputItemIdentities,
2784
+ startedTextBlocksByItemId,
2627
2785
  getLastTextBlock: () => lastTextBlock,
2628
2786
  setLastTextBlock: (block) => {
2629
2787
  lastTextBlock = block;
@@ -2738,7 +2896,7 @@ async function processResponsesStream(openaiStream, output, stream, model, optio
2738
2896
  slot.item.content.push(lastPart);
2739
2897
  }
2740
2898
  lastPart.text += event.delta;
2741
- if (slot.pendingText !== null) appendPendingMessageDelta(slot, event.delta);
2899
+ if (slot.pendingText !== null) appendResponsesPendingTextDelta(slot, event.delta, materializeDeferredTextSlot);
2742
2900
  else if (slot.block && slot.contentIndex !== void 0) {
2743
2901
  slot.block.text += event.delta;
2744
2902
  stream.push({
@@ -2760,7 +2918,7 @@ async function processResponsesStream(openaiStream, output, stream, model, optio
2760
2918
  slot.item.content.push(lastPart);
2761
2919
  }
2762
2920
  lastPart.text += event.delta;
2763
- if (slot.pendingText !== null) appendPendingMessageDelta(slot, event.delta);
2921
+ if (slot.pendingText !== null) appendResponsesPendingTextDelta(slot, event.delta, materializeDeferredTextSlot);
2764
2922
  else if (slot.block && slot.contentIndex !== void 0) {
2765
2923
  slot.block.text += event.delta;
2766
2924
  stream.push({
@@ -2782,7 +2940,7 @@ async function processResponsesStream(openaiStream, output, stream, model, optio
2782
2940
  slot.item.content.push(lastPart);
2783
2941
  }
2784
2942
  lastPart.refusal += event.delta;
2785
- if (slot.pendingText !== null) appendPendingMessageDelta(slot, event.delta);
2943
+ if (slot.pendingText !== null) appendResponsesPendingTextDelta(slot, event.delta, materializeDeferredTextSlot);
2786
2944
  else if (slot.block && slot.contentIndex !== void 0) {
2787
2945
  slot.block.text += event.delta;
2788
2946
  stream.push({
@@ -2835,7 +2993,6 @@ async function processResponsesStream(openaiStream, output, stream, model, optio
2835
2993
  outputSlot.block.thinking = summaryText || contentText || outputSlot.block.thinking;
2836
2994
  outputSlot.block.thinkingSignature = JSON.stringify(item);
2837
2995
  if (item.encrypted_content && options?.reasoningReplayMetadata) outputSlot.block[OPENAI_RESPONSES_REASONING_REPLAY_BLOCK_META_KEY] = options.reasoningReplayMetadata;
2838
- if (typeof item.id === "string") reasoningBlocksById.set(item.id, outputSlot.block);
2839
2996
  stream.push({
2840
2997
  type: "thinking_end",
2841
2998
  contentIndex: outputSlot.contentIndex,
@@ -2898,21 +3055,26 @@ async function processResponsesStream(openaiStream, output, stream, model, optio
2898
3055
  });
2899
3056
  }
2900
3057
  outputSlots.forget(outputSlot);
3058
+ startedTextBlocksByItemId.delete(item.id);
3059
+ completedOutputItemIdentities.add(`message:${item.id}`);
2901
3060
  } else if (item.type === "function_call") {
2902
3061
  const streamingToolCall = streamingToolCalls.resolve(event, readResponsesToolCallItemIdentity(item));
2903
3062
  if (!streamingToolCall && streamingToolCalls.hasActive()) continue;
2904
- const completedName = resolveCompletedToolCallName(streamingToolCall, item.name);
2905
3063
  const streamedArguments = streamingToolCall?.block.partialJson ?? "";
2906
3064
  const completedArguments = typeof item.arguments === "string" ? item.arguments : void 0;
2907
3065
  if (streamingToolCall && !streamingToolCall.argumentStreamReliable && !completedArguments) continue;
2908
- const args = parseStreamingJson(completedArguments !== void 0 && (completedArguments.length > 0 || !streamedArguments) ? completedArguments : streamedArguments || "{}");
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
+ });
2909
3071
  let toolCall;
2910
3072
  let contentIndex;
2911
3073
  if (streamingToolCall) {
2912
3074
  const block = streamingToolCall.block;
2913
3075
  block.id = resolveResponsesToolCallId(item, block.id);
2914
- block.name = completedName;
2915
- block.arguments = args;
3076
+ block.name = validated.name;
3077
+ block.arguments = validated.arguments;
2916
3078
  delete block.partialJson;
2917
3079
  toolCall = block;
2918
3080
  contentIndex = streamingToolCall.contentIndex;
@@ -2920,8 +3082,8 @@ async function processResponsesStream(openaiStream, output, stream, model, optio
2920
3082
  toolCall = {
2921
3083
  type: "toolCall",
2922
3084
  id: resolveResponsesToolCallId(item),
2923
- name: completedName,
2924
- arguments: args
3085
+ name: validated.name,
3086
+ arguments: validated.arguments
2925
3087
  };
2926
3088
  blocks.push(toolCall);
2927
3089
  contentIndex = blockIndex();
@@ -2941,6 +3103,7 @@ async function processResponsesStream(openaiStream, output, stream, model, optio
2941
3103
  toolCall,
2942
3104
  partial: output
2943
3105
  });
3106
+ completedOutputItemIdentities.add(`function_call:${item.call_id}`);
2944
3107
  }
2945
3108
  } else if (event.type === "response.completed" || event.type === "response.incomplete") {
2946
3109
  if (streamingToolCalls.hasActive()) throw new Error("Responses stream completed with unresolved tool calls");
@@ -2961,4 +3124,4 @@ async function processResponsesStream(openaiStream, output, stream, model, optio
2961
3124
  }
2962
3125
  }
2963
3126
  //#endregion
2964
- export { normalizeOpenAIStrictCompatSchema as $, normalizeResponsesFailedEvent as A, resolveReplayableResponsesMessageId as B, prepareOpenAIResponsesReasoningItemForReplay as C, applyServiceTierPricing as D, tagOpenAIResponsesReasoningReplayItem as E, summarizeResponsesFailedNoDetailsObservation as F, throwIfModelStreamAborted as G, createModelStreamCooperativeScheduler as H, summarizeResponsesPayload as I, isStrictOpenAIJsonSchemaCompatible as J, clearOpenAIToolSchemaCacheForTest as K, summarizeResponsesTools as L, stringifyRedactedEvent as M, stringifyRedactedPayload as N, buildResponsesFailedNoDetailsObservation as O, summarizeOpenAITransportError as P, findOpenAIStrictSchemaViolations as Q, AZURE_RESPONSES_FIRST_EVENT_TIMEOUT_MS as R, isInvalidEncryptedContentError as S, stripResponsesRequestEncryptedContent as T, log as U, GEMINI_THOUGHT_SIGNATURE_VALIDATOR_SKIP as V, resolvePromptCacheKey as W, normalizeStrictOpenAIJsonSchema as X, normalizeOpenAIStrictToolParameters as Y, resolveOpenAIProjectedToolsStrictToolFlag as Z, resolveResponsesMessageSnapshotCollapse as _, supportsOpenAITemperature as _t, resolveResponsesTerminalStopReason as a, LLAMACPP_GBNF_MAX_REPETITION_THRESHOLD as at, convertResponsesMessages as b, resolveModelPayloadDebugMode as bt, readResponsesToolCallItemIdentity as c, GEMINI_UNSUPPORTED_SCHEMA_KEYWORDS as ct, OPENAI_RESPONSES_OUTPUT_TEXT_CONTENT_PART_TYPE as d, isOpenAIGpt55Model as dt, extractToolSchemaModelCompat as et, OPENAI_RESPONSES_OUTPUT_TEXT_DELTA_EVENT_TYPE as f, isOpenAIGpt56Model as ft, isResponsesTextDeltaEventType as g, supportsOpenAIReasoningEffort as gt, isResponsesTextContentPartType as h, resolveOpenAISupportedReasoningEfforts as ht, readResponsesReasoningTokens as i, stripUnsupportedSchemaKeywords as it, safeDebugValue as j, logResponsesFailedNoDetails as k, AZURE_RESPONSES_TEXT_CONTENT_PART_TYPE as l, cleanSchemaForGemini as lt, isAzureResponsesTextDeltaEventType as m, resolveOpenAIReasoningEffortForModel as mt, processResponsesStream as n, resolveUnsupportedToolSchemaKeywords as nt, observeResponsesStream as o, cleanSchemaForLlamacppGbnf as ot, isAzureResponsesTextDeltaEvent as p, normalizeOpenAIReasoningEffort as pt, findOpenAIStrictToolProjectionDiagnostics as q, mapResponsesTerminalUsage as r, shouldOmitEmptyArrayItems as rt, createResponsesToolCallTracker as s, findLlamacppGbnfSchemaViolations as st, ResponsesStreamFailure as t, normalizeToolParameterSchema as tt, AZURE_RESPONSES_TEXT_DELTA_EVENT_TYPE as u, isOpenAIGpt54MiniModel as ut, buildOpenAIResponsesReasoningReplayMetadata as v, uniqueStrings as vt, resolveAzureOpenAIApiVersion as w, createResponsesStreamWithEncryptedContentRetry as x, resolveModelSseDebugMode as xt, buildResponsesInputMessage as y, emitModelTransportDebug as yt, OPENAI_CODEX_RESPONSES_DEFAULT_INSTRUCTIONS as z };
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 };
@@ -1,31 +1,8 @@
1
- import { g as isRecord, n as getAiTransportHost } from "./host-Dog2WQiR.mjs";
2
- import { t as projectRuntimeToolInputSchema } from "./tool-schema-json-projection-BwNu3nDi.mjs";
3
- //#region packages/ai/src/transports/host-policy.ts
4
- function buildGuardedModelFetch(model, timeoutMs, options) {
5
- const host = getAiTransportHost();
6
- if (options !== void 0) return host.buildModelFetch(model, timeoutMs, options) ?? globalThis.fetch;
7
- if (timeoutMs !== void 0) return host.buildModelFetch(model, timeoutMs) ?? globalThis.fetch;
8
- return host.buildModelFetch(model) ?? globalThis.fetch;
9
- }
10
- function resolveProviderEndpoint(baseUrl) {
11
- return { endpointClass: getAiTransportHost().resolveProviderEndpointClass(baseUrl) };
12
- }
13
- function resolveProviderRequestCapabilities(input) {
14
- return getAiTransportHost().resolveProviderRequestCapabilities(input);
15
- }
16
- function resolveProviderRequestPolicyConfig(input) {
17
- return { headers: getAiTransportHost().resolveProviderRequestHeaders(input) };
18
- }
19
- function resolveModelRequestTimeoutMs(model, timeoutMs) {
20
- return timeoutMs ?? getAiTransportHost().resolveModelRequestTimeoutMs(model);
21
- }
22
- function resolveOpenAIStrictToolSetting(model, options) {
23
- return getAiTransportHost().resolveOpenAIStrictToolSetting(model, options);
24
- }
25
- function transformTransportMessages(messages, model, normalizeToolCallId, options) {
26
- return getAiTransportHost().transformTransportMessages(messages, model, normalizeToolCallId, options);
27
- }
28
- //#endregion
1
+ import { b as isRecord, n as getAiTransportHost } from "./host-Bl7Kgddo.mjs";
2
+ import { n as calculateCost, t as applyProviderReportedUsageCost } from "./model-utils-Dau5dlgm.mjs";
3
+ import { n as clampOpenAIPromptCacheKey } from "./openai-prompt-cache-mZTCdRPo.mjs";
4
+ import { t as projectRuntimeToolInputSchema } from "./tool-schema-json-projection-B1b-XCn5.mjs";
5
+ import { d as transportAbortError } from "./transport-stream-shared-CPNv7A3r.mjs";
29
6
  //#region packages/ai/src/providers/openai-tool-projection.ts
30
7
  function unreadableToolDiagnostic(toolIndex) {
31
8
  return {
@@ -212,4 +189,127 @@ function reconcileOpenAICompletionsToolChoice(choice, projection) {
212
189
  };
213
190
  }
214
191
  //#endregion
215
- export { resolveModelRequestTimeoutMs as a, resolveProviderRequestCapabilities as c, buildGuardedModelFetch as i, resolveProviderRequestPolicyConfig as l, reconcileOpenAICompletionsToolChoice as n, resolveOpenAIStrictToolSetting as o, reconcileOpenAIResponsesToolChoice as r, resolveProviderEndpoint as s, projectOpenAITools as t, transformTransportMessages as u };
192
+ //#region packages/ai/src/transports/openai-transport-shared.ts
193
+ /** Shared options, usage shape, cache identity, ordering, and stream scheduling for OpenAI APIs. */
194
+ const MODEL_STREAM_COOPERATIVE_YIELD_INTERVAL_MS = 12;
195
+ const MODEL_STREAM_COOPERATIVE_YIELD_MAX_EVENTS = 64;
196
+ const GEMINI_THOUGHT_SIGNATURE_VALIDATOR_SKIP = "skip_thought_signature_validator";
197
+ const log = {
198
+ debug(message, data) {
199
+ getAiTransportHost().logDebug("openai-transport", () => ({
200
+ message,
201
+ data
202
+ }));
203
+ },
204
+ info(message, data) {
205
+ getAiTransportHost().logInfo("openai-transport", message, data);
206
+ },
207
+ warn(message, data) {
208
+ getAiTransportHost().logWarn("openai-transport", message, data);
209
+ }
210
+ };
211
+ function parseOpenAICompletionsUsage(rawUsage, model, options) {
212
+ const cacheRead = rawUsage.prompt_tokens_details?.cached_tokens ?? rawUsage.prompt_cache_hit_tokens ?? 0;
213
+ const cacheWrite = rawUsage.prompt_tokens_details?.cache_write_tokens || 0;
214
+ const input = Math.max(0, (rawUsage.prompt_tokens || 0) - cacheRead - cacheWrite);
215
+ const output = rawUsage.completion_tokens || 0;
216
+ const reasoningTokens = rawUsage.completion_tokens_details?.reasoning_tokens;
217
+ const usage = {
218
+ input,
219
+ output,
220
+ cacheRead,
221
+ cacheWrite,
222
+ ...options?.includeReasoningTokens !== false && typeof reasoningTokens === "number" && Number.isFinite(reasoningTokens) ? { reasoningTokens } : {},
223
+ totalTokens: input + output + cacheRead + cacheWrite,
224
+ cost: {
225
+ input: 0,
226
+ output: 0,
227
+ cacheRead: 0,
228
+ cacheWrite: 0,
229
+ total: 0
230
+ }
231
+ };
232
+ calculateCost(model, usage);
233
+ applyProviderReportedUsageCost(usage, rawUsage.cost);
234
+ return usage;
235
+ }
236
+ function throwIfModelStreamAborted(signal) {
237
+ if (signal?.aborted) throw transportAbortError(signal);
238
+ }
239
+ function createModelStreamCooperativeScheduler(signal) {
240
+ let lastYieldedAt = Date.now();
241
+ let eventsSinceYield = 0;
242
+ return { async afterEvent() {
243
+ throwIfModelStreamAborted(signal);
244
+ eventsSinceYield += 1;
245
+ const now = Date.now();
246
+ if (eventsSinceYield < MODEL_STREAM_COOPERATIVE_YIELD_MAX_EVENTS && now - lastYieldedAt < MODEL_STREAM_COOPERATIVE_YIELD_INTERVAL_MS) return;
247
+ eventsSinceYield = 0;
248
+ lastYieldedAt = now;
249
+ await new Promise((resolve) => {
250
+ setTimeout(resolve, 0);
251
+ });
252
+ throwIfModelStreamAborted(signal);
253
+ } };
254
+ }
255
+ function resolvePromptCacheKey(options, cacheRetention) {
256
+ if (cacheRetention === "none") return;
257
+ return clampOpenAIPromptCacheKey(options?.promptCacheKey ?? options?.sessionId);
258
+ }
259
+ function isOpenAICompletionsThinkingEnabled(effort) {
260
+ const normalized = effort.trim().toLowerCase();
261
+ return normalized !== "off" && normalized !== "none";
262
+ }
263
+ function readOpenAICompletionsContentDeltas(content, topLevelRefusal, mirroredThinking = []) {
264
+ let deltas = readOpenAICompletionsContentPartDeltas(content);
265
+ if (mirroredThinking.length > 0) {
266
+ const structuredThinking = deltas.filter((delta) => delta.kind === "thinking").map((delta) => delta.text);
267
+ const mirrorsCombinedThinking = structuredThinking.length > 1 && mirroredThinking.includes(structuredThinking.join(""));
268
+ deltas = deltas.filter((delta) => delta.kind !== "thinking" || !mirrorsCombinedThinking && !mirroredThinking.includes(delta.text));
269
+ }
270
+ if (typeof topLevelRefusal !== "string" || !topLevelRefusal) return deltas;
271
+ const structuredRefusals = deltas.filter((delta) => delta.kind === "text" && delta.source === "refusal").map((delta) => delta.text);
272
+ if (structuredRefusals.some((refusal) => refusal === topLevelRefusal) || structuredRefusals.length > 1 && structuredRefusals.join("") === topLevelRefusal) return deltas;
273
+ return [...deltas, {
274
+ kind: "text",
275
+ text: topLevelRefusal,
276
+ source: "refusal"
277
+ }];
278
+ }
279
+ function readOpenAICompletionsContentPartDeltas(content) {
280
+ if (typeof content === "string") return content ? [{
281
+ kind: "text",
282
+ text: content
283
+ }] : [];
284
+ if (Array.isArray(content)) return content.flatMap(readOpenAICompletionsContentPartDeltas);
285
+ if (!content || typeof content !== "object") return [];
286
+ const record = content;
287
+ const type = typeof record.type === "string" ? record.type.toLowerCase() : "";
288
+ const extractText = (value) => {
289
+ if (typeof value === "string") return value;
290
+ if (Array.isArray(value)) return value.map(extractText).join("");
291
+ if (value && typeof value === "object") {
292
+ const nested = value;
293
+ return extractText(nested.text ?? nested.content ?? nested.thinking ?? nested.refusal);
294
+ }
295
+ return "";
296
+ };
297
+ const text = extractText(record.text ?? record.content ?? record.thinking ?? record.refusal);
298
+ if (!text) return [];
299
+ if (type.includes("thinking") || type.includes("reasoning")) return [{
300
+ kind: "thinking",
301
+ text
302
+ }];
303
+ if (type === "refusal") return [{
304
+ kind: "text",
305
+ text,
306
+ source: "refusal"
307
+ }];
308
+ if (["text", "output_text"].includes(type) || type.endsWith(".output_text")) return [{
309
+ kind: "text",
310
+ text
311
+ }];
312
+ return [];
313
+ }
314
+ //#endregion
315
+ export { parseOpenAICompletionsUsage as a, throwIfModelStreamAborted as c, reconcileOpenAIResponsesToolChoice as d, log as i, projectOpenAITools as l, createModelStreamCooperativeScheduler as n, readOpenAICompletionsContentDeltas as o, isOpenAICompletionsThinkingEnabled as r, resolvePromptCacheKey as s, GEMINI_THOUGHT_SIGNATURE_VALIDATOR_SKIP as t, reconcileOpenAICompletionsToolChoice as u };