@openclaw/ai 2026.7.1 → 2026.7.2-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 (47) hide show
  1. package/dist/{anthropic-B5gZQM5X.mjs → anthropic-Cvm71xlk.mjs} +19 -97
  2. package/dist/{api-registry-BXYnCOIR.d.mts → api-registry-Byvoz8Ha.d.mts} +1 -1
  3. package/dist/{azure-openai-responses-DNoSk8Uy.mjs → azure-openai-responses-b4lfJxYS.mjs} +6 -6
  4. package/dist/{azure-openai-responses-client-compat-a_O_GVQV.mjs → azure-openai-responses-client-compat-C7K7QfUE.mjs} +23 -2
  5. package/dist/{env-api-keys-CtMlqaQ4.mjs → env-api-keys-DnhYpc27.mjs} +4 -3
  6. package/dist/{event-stream-ReMmOTzX.mjs → event-stream-D8n2uFee.mjs} +14 -6
  7. package/dist/{event-stream-0nZeBKl2.d.mts → event-stream-uQspnL8S.d.mts} +1 -1
  8. package/dist/event-stream.d.mts +1 -1
  9. package/dist/event-stream.mjs +1 -1
  10. package/dist/{google-D6sIQ1bL.mjs → google-C7PoDjpW.mjs} +4 -4
  11. package/dist/{google-shared-ZPSl2qTi.mjs → google-shared-C7ohrmOI.mjs} +29 -20
  12. package/dist/{google-vertex-rDGwkoZK.mjs → google-vertex-L_ABazIA.mjs} +5 -18
  13. package/dist/index.d.mts +4 -4
  14. package/dist/index.mjs +3 -3
  15. package/dist/internal/anthropic.d.mts +1 -1
  16. package/dist/internal/anthropic.mjs +3 -3
  17. package/dist/internal/openai.d.mts +14 -3
  18. package/dist/internal/openai.mjs +7 -7
  19. package/dist/internal/retry-after.d.mts +5 -0
  20. package/dist/internal/retry-after.mjs +101 -0
  21. package/dist/internal/runtime.d.mts +2 -2
  22. package/dist/internal/runtime.mjs +6 -5
  23. package/dist/internal/shared.d.mts +2 -1
  24. package/dist/internal/shared.mjs +1 -1
  25. package/dist/{json-parse-DzNSIQBq.mjs → json-parse-BvXNt1-7.mjs} +4 -6
  26. package/dist/{mistral-CePVNdws.mjs → mistral-D-39Trax.mjs} +114 -31
  27. package/dist/{model-utils-DgmOla96.mjs → model-utils-Q1LSRIdo.mjs} +5 -12
  28. package/dist/{openai-chatgpt-responses-DVC4Bk_A.mjs → openai-chatgpt-responses-DCA0K85L.mjs} +40 -96
  29. package/dist/{openai-completions-B9QLIq2U.mjs → openai-completions-B2jr3vtJ.mjs} +24 -21
  30. package/dist/{openai-responses-B6LylGxM.mjs → openai-responses-DTpD8YVy.mjs} +6 -6
  31. package/dist/{openai-responses-shared-sj2YUPYc.mjs → openai-responses-shared-B9mtGvXq.mjs} +207 -46
  32. package/dist/{openai-tool-projection-BknoV11q.mjs → openai-tool-projection-cTLC4F65.mjs} +8 -3
  33. package/dist/providers.d.mts +1 -1
  34. package/dist/providers.mjs +9 -9
  35. package/dist/{reasoning-tag-text-partitioner-axhAdUwg.mjs → reasoning-tag-text-partitioner-BlVe67g6.mjs} +14 -8
  36. package/dist/{src-CZ503MYJ.mjs → src-CXno1H5g.mjs} +1 -1
  37. package/dist/{tool-schema-json-projection-BXtBc_mD.mjs → tool-schema-json-projection-BwNu3nDi.mjs} +22 -2
  38. package/dist/{transform-messages-BhGF_fF4.mjs → transform-messages-DNWpwvXA.mjs} +2 -2
  39. package/dist/{types-DRgdPqaZ.d.mts → types-Cx2zJtyz.d.mts} +5 -0
  40. package/dist/types.d.mts +3 -3
  41. package/dist/types.mjs +3 -3
  42. package/dist/{validation-BDMWOr8d.d.mts → validation-Cej7htKc.d.mts} +1 -1
  43. package/dist/{validation-FrchoOlv.mjs → validation-DAa_yFOM.mjs} +2 -7
  44. package/dist/validation.d.mts +1 -1
  45. package/dist/validation.mjs +1 -1
  46. package/npm-shrinkwrap.json +2 -2
  47. package/package.json +1 -1
@@ -1,13 +1,13 @@
1
1
  import { n as getAiTransportHost } from "./host-4t713IeR.mjs";
2
- import { n as calculateCost, r as clampThinkingLevel } from "./model-utils-DgmOla96.mjs";
2
+ import { n as calculateCost, r as clampThinkingLevel } from "./model-utils-Q1LSRIdo.mjs";
3
3
  import { t as headersToRecord } from "./headers-B_e4-1J0.mjs";
4
- import { n as parseStreamingJson } from "./json-parse-DzNSIQBq.mjs";
4
+ import { n as parseStreamingJson } from "./json-parse-BvXNt1-7.mjs";
5
5
  import { t as sanitizeSurrogates } from "./sanitize-unicode-DT5o51ur.mjs";
6
- import { C as normalizeLowercaseStringOrEmpty, b as stripSystemPromptCacheBoundary, c as isRecord, i as extractToolResultText, n as describeToolResultMediaPlaceholder, t as transformMessages, w as normalizeOptionalString } from "./transform-messages-BhGF_fF4.mjs";
6
+ import { T as normalizeOptionalString, i as extractToolResultText, l as isRecord, n as describeToolResultMediaPlaceholder, t as transformMessages, w as normalizeLowercaseStringOrEmpty, x as stripSystemPromptCacheBoundary } from "./transform-messages-DNWpwvXA.mjs";
7
7
  import { a as withFirstStreamEventTimeout, i as getFirstStreamEventTimeoutMs, r as getFirstStreamEventTimeoutHandler, t as createFirstStreamEventAbortController } from "./stream-first-event-timeout-RjWszj8c.mjs";
8
- import { t as projectOpenAITools } from "./openai-tool-projection-BknoV11q.mjs";
8
+ import { t as projectOpenAITools } from "./openai-tool-projection-cTLC4F65.mjs";
9
9
  import { t as shortHash } from "./hash-CHgqbJmD.mjs";
10
- import { createHash } from "node:crypto";
10
+ import { createHash, randomUUID } from "node:crypto";
11
11
  //#region packages/normalization-core/src/string-normalization.ts
12
12
  /** Coerces entries to strings, trims them, and drops empty results. */
13
13
  function normalizeStringEntries(list) {
@@ -54,6 +54,20 @@ const SCHEMA_META_KEYS = [
54
54
  function copySchemaMeta$1(from, to) {
55
55
  for (const key of SCHEMA_META_KEYS) if (key in from && from[key] !== void 0) to[key] = from[key];
56
56
  }
57
+ function stringifyGeminiEnumValue(value) {
58
+ if (typeof value === "string") return value;
59
+ if (typeof value === "number" && Number.isFinite(value)) return String(value);
60
+ if (typeof value === "boolean") return String(value);
61
+ }
62
+ function cleanGeminiEnumValues(value) {
63
+ if (!Array.isArray(value)) return;
64
+ const values = value.flatMap((entry) => {
65
+ const stringified = stringifyGeminiEnumValue(entry);
66
+ return stringified === void 0 ? [] : [stringified];
67
+ });
68
+ const unique = [...new Set(values)];
69
+ return unique.length > 0 ? unique : void 0;
70
+ }
57
71
  function tryFlattenLiteralAnyOf(variants) {
58
72
  if (variants.length === 0) return null;
59
73
  const allValues = [];
@@ -208,7 +222,13 @@ function cleanSchemaForGeminiWithDefs(schema, defs, refStack) {
208
222
  for (const [key, value] of Object.entries(obj)) {
209
223
  if (GEMINI_UNSUPPORTED_SCHEMA_KEYWORDS.has(key)) continue;
210
224
  if (key === "const") {
211
- cleaned.enum = [value];
225
+ const enumValues = cleanGeminiEnumValues([value]);
226
+ if (enumValues) cleaned.enum = enumValues;
227
+ continue;
228
+ }
229
+ if (key === "enum") {
230
+ const enumValues = cleanGeminiEnumValues(value);
231
+ if (enumValues) cleaned.enum = enumValues;
212
232
  continue;
213
233
  }
214
234
  if (key === "required" && Array.isArray(value) && value.length === 0) continue;
@@ -583,8 +603,8 @@ function resolveJsonPointerPath(value, segments) {
583
603
  if (!current || typeof current !== "object") return;
584
604
  const key = decodeJsonPointerSegment(segment);
585
605
  if (Array.isArray(current)) {
586
- const index = Number(key);
587
- if (!Number.isInteger(index) || index < 0 || index >= current.length) return;
606
+ const index = /^(?:0|[1-9]\d*)$/.test(key) ? Number(key) : -1;
607
+ if (index < 0 || index >= current.length) return;
588
608
  current = current[index];
589
609
  continue;
590
610
  }
@@ -933,6 +953,16 @@ const GENERIC_REASONING_EFFORTS = [
933
953
  "medium",
934
954
  "high"
935
955
  ];
956
+ const CANONICAL_REASONING_EFFORTS = /* @__PURE__ */ new Set([
957
+ "none",
958
+ "minimal",
959
+ "low",
960
+ "medium",
961
+ "high",
962
+ "xhigh",
963
+ "max",
964
+ "off"
965
+ ]);
936
966
  function normalizeModelId(id) {
937
967
  return normalizeLowercaseStringOrEmpty(id ?? "").replace(/-\d{4}-\d{2}-\d{2}$/u, "");
938
968
  }
@@ -955,7 +985,9 @@ function isOpenAIGpt56Model(model) {
955
985
  }
956
986
  /** Normalize user-facing reasoning effort names to API effort names. */
957
987
  function normalizeOpenAIReasoningEffort(effort) {
958
- return effort === "minimal" ? "minimal" : effort;
988
+ const trimmed = effort.trim();
989
+ const folded = trimmed.toLowerCase();
990
+ return CANONICAL_REASONING_EFFORTS.has(folded) ? folded : trimmed;
959
991
  }
960
992
  function readCompatReasoningEfforts(compat) {
961
993
  if (!compat || typeof compat !== "object") return;
@@ -984,6 +1016,19 @@ function resolveOpenAISupportedReasoningEfforts(model) {
984
1016
  if (/^gpt-5(?:-|$)/u.test(id)) return GPT_5_REASONING_EFFORTS;
985
1017
  return GENERIC_REASONING_EFFORTS;
986
1018
  }
1019
+ /**
1020
+ * Return whether a model accepts the temperature parameter. The GPT-5.6
1021
+ * family rejects it with a 400; catalog compat can override per model.
1022
+ */
1023
+ function supportsOpenAITemperature(model) {
1024
+ const compat = model.compat;
1025
+ if (compat && typeof compat === "object") {
1026
+ const declared = compat.supportsTemperature;
1027
+ if (typeof declared === "boolean") return declared;
1028
+ }
1029
+ const id = normalizeModelId(typeof model.id === "string" ? model.id : void 0);
1030
+ return !/^gpt-5\.6(?:-|$)/u.test(id);
1031
+ }
987
1032
  /** Return whether a model accepts a requested reasoning effort. */
988
1033
  function supportsOpenAIReasoningEffort(model, effort) {
989
1034
  return resolveOpenAISupportedReasoningEfforts(model).includes(normalizeOpenAIReasoningEffort(effort));
@@ -991,7 +1036,8 @@ function supportsOpenAIReasoningEffort(model, effort) {
991
1036
  /** Resolve a requested reasoning effort to the closest value supported by the model. */
992
1037
  function resolveOpenAIReasoningEffortForModel(params) {
993
1038
  const requested = normalizeOpenAIReasoningEffort(params.effort);
994
- const normalized = normalizeOpenAIReasoningEffort(params.fallbackMap?.[requested] ?? requested);
1039
+ const mapped = params.fallbackMap?.[requested] ?? (params.fallbackMap && CANONICAL_REASONING_EFFORTS.has(requested) ? Object.entries(params.fallbackMap).find(([effort]) => normalizeOpenAIReasoningEffort(effort) === requested)?.[1] : void 0);
1040
+ const normalized = mapped === void 0 ? requested : mapped.trim();
995
1041
  const supported = resolveOpenAISupportedReasoningEfforts(params.model);
996
1042
  if (supported.includes(normalized)) return normalized;
997
1043
  if (requested === "off" && supported.includes("none")) return "none";
@@ -1000,7 +1046,7 @@ function resolveOpenAIReasoningEffortForModel(params) {
1000
1046
  if ((requested === "minimal" || requested === "low") && supported.includes("medium")) return "medium";
1001
1047
  if (requested === "xhigh" && supported.includes("high")) return "high";
1002
1048
  if (requested === "max" && supported.includes("xhigh")) return "xhigh";
1003
- return supported.find((effort) => effort !== "none");
1049
+ return supported.find((effort) => !isDisabledReasoningEffort(normalizeOpenAIReasoningEffort(effort)));
1004
1050
  }
1005
1051
  //#endregion
1006
1052
  //#region packages/ai/src/providers/openai-responses-stream-compat.ts
@@ -1263,6 +1309,20 @@ function sortResponsesToolsByName(tools) {
1263
1309
  //#endregion
1264
1310
  //#region packages/ai/src/providers/openai-responses-shared.ts
1265
1311
  const EMPTY_TOOL_RESULT_TEXT = "(no output)";
1312
+ function splitResponsesToolCallId(id) {
1313
+ const separatorIndex = id.indexOf("|");
1314
+ return separatorIndex === -1 ? [id, void 0] : [id.slice(0, separatorIndex), id.slice(separatorIndex + 1)];
1315
+ }
1316
+ function resolveResponsesToolCallId(item, fallbackId) {
1317
+ const callId = typeof item.call_id === "string" ? item.call_id.trim() : "";
1318
+ const itemId = typeof item.id === "string" ? item.id.trim() : "";
1319
+ const [fallbackCallId, fallbackItemId = ""] = splitResponsesToolCallId(fallbackId ?? "");
1320
+ const resolvedCallId = callId || fallbackCallId;
1321
+ const resolvedItemId = itemId || fallbackItemId;
1322
+ if (resolvedCallId) return resolvedItemId ? `${resolvedCallId}|${resolvedItemId}` : resolvedCallId;
1323
+ const generatedCallId = `call_${randomUUID().replaceAll("-", "").slice(0, 24)}`;
1324
+ return resolvedItemId ? `${generatedCallId}|${resolvedItemId}` : generatedCallId;
1325
+ }
1266
1326
  function sanitizeToolResultText(text, fallback) {
1267
1327
  const sanitized = sanitizeSurrogates(text);
1268
1328
  return sanitized.trim().length > 0 ? sanitized : fallback;
@@ -1318,7 +1378,7 @@ function convertResponsesMessages(model, context, allowedToolCallProviders, opti
1318
1378
  const normalizeToolCallId = (id, targetModel, source) => {
1319
1379
  if (!allowedToolCallProviders.has(model.provider)) return normalizeIdPart(id);
1320
1380
  if (!id.includes("|")) return normalizeIdPart(id);
1321
- const [callId, itemId] = id.split("|");
1381
+ const [callId, itemId = ""] = splitResponsesToolCallId(id);
1322
1382
  const normalizedCallId = normalizeIdPart(callId);
1323
1383
  let normalizedItemId = source.provider !== model.provider || source.api !== model.api ? buildForeignResponsesItemId(itemId) : normalizeIdPart(itemId);
1324
1384
  if (!normalizedItemId.startsWith("fc_")) normalizedItemId = normalizeIdPart(`fc_${normalizedItemId}`);
@@ -1407,7 +1467,7 @@ function convertResponsesMessages(model, context, allowedToolCallProviders, opti
1407
1467
  previousReplayItemWasReasoning = false;
1408
1468
  } else if (block.type === "toolCall") {
1409
1469
  const toolCall = block;
1410
- const [callId, itemIdRaw] = toolCall.id.split("|");
1470
+ const [callId, itemIdRaw] = splitResponsesToolCallId(toolCall.id);
1411
1471
  let itemId = shouldReplayResponsesItemIds ? itemIdRaw : void 0;
1412
1472
  if (shouldReplayResponsesItemIds && isDifferentModel && itemId?.startsWith("fc_")) itemId = void 0;
1413
1473
  output.push({
@@ -1427,7 +1487,7 @@ function convertResponsesMessages(model, context, allowedToolCallProviders, opti
1427
1487
  const hasImages = msg.content.some((c) => c.type === "image");
1428
1488
  const mediaPlaceholder = describeToolResultMediaPlaceholder(msg.content);
1429
1489
  const hasText = sanitizedTextResult.trim().length > 0;
1430
- const [callId] = msg.toolCallId.split("|");
1490
+ const [callId] = splitResponsesToolCallId(msg.toolCallId);
1431
1491
  let output;
1432
1492
  if (hasImages && model.input.includes("image")) {
1433
1493
  const contentParts = [];
@@ -1496,7 +1556,7 @@ function resolveResponsesReasoningEffort(model, reasoning) {
1496
1556
  }
1497
1557
  function applyCommonResponsesParams(params, model, context, options, config) {
1498
1558
  if (options?.maxTokens) params.max_output_tokens = options.maxTokens;
1499
- if (options?.temperature !== void 0) params.temperature = options.temperature;
1559
+ if (options?.temperature !== void 0 && supportsOpenAITemperature(model)) params.temperature = options.temperature;
1500
1560
  if (context.tools) {
1501
1561
  const converted = convertResponsesToolPayload(context.tools, { model });
1502
1562
  if (converted.tools.length > 0) params.tools = converted.tools;
@@ -1577,17 +1637,76 @@ async function runResponsesStreamLifecycle(params) {
1577
1637
  async function processResponsesStream(openaiStream, output, stream, model, options) {
1578
1638
  let currentItem = null;
1579
1639
  let currentBlock = null;
1640
+ const toolCallsByOutputIndex = /* @__PURE__ */ new Map();
1641
+ const unindexedToolCalls = /* @__PURE__ */ new Set();
1580
1642
  let lastTextBlock = null;
1581
1643
  let pendingMessageText = null;
1582
1644
  const blocks = output.content;
1583
1645
  const blockIndex = () => blocks.length - 1;
1646
+ const readOutputIndex = (event) => typeof event.output_index === "number" && Number.isInteger(event.output_index) && event.output_index >= 0 ? event.output_index : void 0;
1647
+ const readIdentityValue = (value) => {
1648
+ return (typeof value === "string" ? value.trim() : "") || void 0;
1649
+ };
1650
+ const readEventToolCallIdentity = (event) => ({ itemId: readIdentityValue(event.item_id) });
1651
+ const readItemToolCallIdentity = (item) => ({
1652
+ itemId: readIdentityValue(item.id),
1653
+ callId: readIdentityValue(item.call_id)
1654
+ });
1655
+ const identitiesConflict = (state, identity) => Boolean(state.itemId && identity.itemId && state.itemId !== identity.itemId || state.callId && identity.callId && state.callId !== identity.callId);
1656
+ const sharesIdentity = (state, identity) => Boolean(state.itemId && identity.itemId && state.itemId === identity.itemId || state.callId && identity.callId && state.callId === identity.callId);
1657
+ const adoptToolCallIdentity = (state, identity) => {
1658
+ state.itemId ??= identity.itemId;
1659
+ state.callId ??= identity.callId;
1660
+ return state;
1661
+ };
1662
+ const resolveCompatibleToolCall = (candidates, identity) => {
1663
+ const uniqueCandidates = [...new Set(candidates)];
1664
+ if (!identity.itemId && !identity.callId) return uniqueCandidates.length === 1 ? uniqueCandidates.at(0) : void 0;
1665
+ const compatible = uniqueCandidates.filter((state) => !identitiesConflict(state, identity));
1666
+ const matches = compatible.filter((state) => sharesIdentity(state, identity));
1667
+ const matched = matches.length === 1 ? matches.at(0) : void 0;
1668
+ if (matched) return adoptToolCallIdentity(matched, identity);
1669
+ const soleCompatible = uniqueCandidates.length === 1 && compatible.length === 1 && matches.length === 0 ? compatible.at(0) : void 0;
1670
+ return soleCompatible ? adoptToolCallIdentity(soleCompatible, identity) : void 0;
1671
+ };
1672
+ const resolveStreamingToolCall = (event, identity = readEventToolCallIdentity(event)) => {
1673
+ const outputIndex = readOutputIndex(event);
1674
+ if (outputIndex !== void 0) {
1675
+ const indexed = toolCallsByOutputIndex.get(outputIndex);
1676
+ if (indexed) return !identitiesConflict(indexed, identity) ? adoptToolCallIdentity(indexed, identity) : void 0;
1677
+ const unindexed = resolveCompatibleToolCall(unindexedToolCalls, identity);
1678
+ if (unindexed) {
1679
+ unindexedToolCalls.delete(unindexed);
1680
+ toolCallsByOutputIndex.set(outputIndex, unindexed);
1681
+ }
1682
+ return unindexed;
1683
+ }
1684
+ return resolveCompatibleToolCall([...toolCallsByOutputIndex.values(), ...unindexedToolCalls], identity);
1685
+ };
1686
+ const forgetStreamingToolCall = (toolCall) => {
1687
+ for (const [trackedIndex, tracked] of toolCallsByOutputIndex) if (tracked === toolCall) toolCallsByOutputIndex.delete(trackedIndex);
1688
+ unindexedToolCalls.delete(toolCall);
1689
+ };
1690
+ const markActiveToolCallArgumentsUnreliable = () => {
1691
+ for (const toolCall of /* @__PURE__ */ new Set([...toolCallsByOutputIndex.values(), ...unindexedToolCalls])) toolCall.argumentStreamReliable = false;
1692
+ };
1693
+ const hasActiveStreamingToolCall = () => toolCallsByOutputIndex.size > 0 || unindexedToolCalls.size > 0;
1694
+ const resolveCompletedToolCallName = (toolCall, value) => {
1695
+ const streamedName = readIdentityValue(toolCall?.block.name);
1696
+ const completedName = readIdentityValue(value);
1697
+ if (streamedName && completedName && streamedName !== completedName) throw new Error(`Responses stream changed tool-call function name from ${streamedName} to ${completedName}`);
1698
+ const name = completedName ?? streamedName;
1699
+ if (!name) throw new Error("Responses stream completed tool call without a function name");
1700
+ return name;
1701
+ };
1584
1702
  const appendPendingMessageDelta = (delta) => {
1585
1703
  pendingMessageText = `${pendingMessageText ?? ""}${delta}`;
1586
1704
  const priorText = lastTextBlock?.block.text ?? "";
1587
1705
  if (priorText.startsWith(pendingMessageText) || pendingMessageText.startsWith(priorText)) return;
1588
1706
  currentBlock = {
1589
1707
  type: "text",
1590
- text: pendingMessageText
1708
+ text: pendingMessageText,
1709
+ ...currentItem?.type === "message" && currentItem.phase ? { textSignature: encodeTextSignatureV1(currentItem.id, currentItem.phase ?? void 0) } : {}
1591
1710
  };
1592
1711
  blocks.push(currentBlock);
1593
1712
  stream.push({
@@ -1640,7 +1759,8 @@ async function processResponsesStream(openaiStream, output, stream, model, optio
1640
1759
  } else {
1641
1760
  currentBlock = {
1642
1761
  type: "text",
1643
- text: ""
1762
+ text: "",
1763
+ ...item.phase ? { textSignature: encodeTextSignatureV1(item.id, item.phase) } : {}
1644
1764
  };
1645
1765
  output.content.push(currentBlock);
1646
1766
  stream.push({
@@ -1650,18 +1770,29 @@ async function processResponsesStream(openaiStream, output, stream, model, optio
1650
1770
  });
1651
1771
  }
1652
1772
  } else if (item.type === "function_call") {
1773
+ const outputIndex = readOutputIndex(event);
1774
+ if (outputIndex !== void 0 && toolCallsByOutputIndex.has(outputIndex)) throw new Error(`Responses stream reused active tool-call output index ${outputIndex}`);
1653
1775
  currentItem = item;
1654
1776
  currentBlock = {
1655
1777
  type: "toolCall",
1656
- id: `${item.call_id}|${item.id}`,
1657
- name: item.name,
1778
+ id: resolveResponsesToolCallId(item),
1779
+ name: readIdentityValue(item.name) ?? "",
1658
1780
  arguments: {},
1659
1781
  partialJson: item.arguments || ""
1660
1782
  };
1661
1783
  output.content.push(currentBlock);
1784
+ const contentIndex = blockIndex();
1785
+ const toolCallState = {
1786
+ block: currentBlock,
1787
+ contentIndex,
1788
+ argumentStreamReliable: true,
1789
+ ...readItemToolCallIdentity(item)
1790
+ };
1791
+ if (outputIndex !== void 0) toolCallsByOutputIndex.set(outputIndex, toolCallState);
1792
+ else unindexedToolCalls.add(toolCallState);
1662
1793
  stream.push({
1663
1794
  type: "toolcall_start",
1664
- contentIndex: blockIndex(),
1795
+ contentIndex,
1665
1796
  partial: output
1666
1797
  });
1667
1798
  }
@@ -1775,34 +1906,37 @@ async function processResponsesStream(openaiStream, output, stream, model, optio
1775
1906
  }
1776
1907
  }
1777
1908
  } else if (event.type === "response.function_call_arguments.delta") {
1778
- if (currentItem?.type === "function_call" && currentBlock?.type === "toolCall") {
1779
- currentBlock.partialJson += event.delta;
1780
- currentBlock.arguments = parseStreamingJson(currentBlock.partialJson);
1909
+ const toolCall = resolveStreamingToolCall(event);
1910
+ if (toolCall) {
1911
+ toolCall.block.partialJson += event.delta;
1912
+ toolCall.block.arguments = parseStreamingJson(toolCall.block.partialJson);
1781
1913
  stream.push({
1782
1914
  type: "toolcall_delta",
1783
- contentIndex: blockIndex(),
1915
+ contentIndex: toolCall.contentIndex,
1784
1916
  delta: event.delta,
1785
1917
  partial: output
1786
1918
  });
1787
- }
1919
+ } else if (hasActiveStreamingToolCall()) markActiveToolCallArgumentsUnreliable();
1788
1920
  } else if (event.type === "response.function_call_arguments.done") {
1789
- if (currentItem?.type === "function_call" && currentBlock?.type === "toolCall") {
1790
- const previousPartialJson = currentBlock.partialJson;
1921
+ const toolCall = resolveStreamingToolCall(event);
1922
+ if (toolCall) {
1923
+ const previousPartialJson = toolCall.block.partialJson;
1791
1924
  const doneArguments = typeof event.arguments === "string" ? event.arguments : void 0;
1792
1925
  if (doneArguments !== void 0 && (doneArguments.length > 0 || previousPartialJson === "")) {
1793
- currentBlock.partialJson = doneArguments;
1794
- currentBlock.arguments = parseStreamingJson(currentBlock.partialJson);
1926
+ toolCall.block.partialJson = doneArguments;
1927
+ toolCall.block.arguments = parseStreamingJson(toolCall.block.partialJson);
1928
+ toolCall.argumentStreamReliable = true;
1795
1929
  }
1796
1930
  if (doneArguments?.startsWith(previousPartialJson)) {
1797
1931
  const delta = doneArguments.slice(previousPartialJson.length);
1798
1932
  if (delta.length > 0) stream.push({
1799
1933
  type: "toolcall_delta",
1800
- contentIndex: blockIndex(),
1934
+ contentIndex: toolCall.contentIndex,
1801
1935
  delta,
1802
1936
  partial: output
1803
1937
  });
1804
1938
  }
1805
- }
1939
+ } else if (hasActiveStreamingToolCall()) markActiveToolCallArgumentsUnreliable();
1806
1940
  } else if (event.type === "response.output_item.done") {
1807
1941
  const item = event.item;
1808
1942
  if (item.type !== "message") {
@@ -1846,7 +1980,8 @@ async function processResponsesStream(openaiStream, output, stream, model, optio
1846
1980
  if (currentBlock?.type !== "text") {
1847
1981
  currentBlock = {
1848
1982
  type: "text",
1849
- text: ""
1983
+ text: "",
1984
+ ...phase ? { textSignature: encodeTextSignatureV1(item.id, phase) } : {}
1850
1985
  };
1851
1986
  blocks.push(currentBlock);
1852
1987
  stream.push({
@@ -1871,27 +2006,52 @@ async function processResponsesStream(openaiStream, output, stream, model, optio
1871
2006
  }
1872
2007
  currentBlock = null;
1873
2008
  } else if (item.type === "function_call") {
1874
- const args = currentBlock?.type === "toolCall" && currentBlock.partialJson ? parseStreamingJson(currentBlock.partialJson) : parseStreamingJson(item.arguments || "{}");
2009
+ const streamingToolCall = resolveStreamingToolCall(event, readItemToolCallIdentity(item));
2010
+ if (!streamingToolCall && hasActiveStreamingToolCall()) continue;
2011
+ const completedName = resolveCompletedToolCallName(streamingToolCall, item.name);
2012
+ const streamedArguments = streamingToolCall?.block.partialJson ?? "";
2013
+ const completedArguments = typeof item.arguments === "string" ? item.arguments : void 0;
2014
+ if (streamingToolCall && !streamingToolCall.argumentStreamReliable && !completedArguments) continue;
2015
+ const args = parseStreamingJson(completedArguments !== void 0 && (completedArguments.length > 0 || !streamedArguments) ? completedArguments : streamedArguments || "{}");
1875
2016
  let toolCall;
1876
- if (currentBlock?.type === "toolCall") {
1877
- currentBlock.arguments = args;
1878
- delete currentBlock.partialJson;
1879
- toolCall = currentBlock;
1880
- } else toolCall = {
1881
- type: "toolCall",
1882
- id: `${item.call_id}|${item.id}`,
1883
- name: item.name,
1884
- arguments: args
1885
- };
1886
- currentBlock = null;
2017
+ let contentIndex;
2018
+ if (streamingToolCall) {
2019
+ const block = streamingToolCall.block;
2020
+ block.id = resolveResponsesToolCallId(item, block.id);
2021
+ block.name = completedName;
2022
+ block.arguments = args;
2023
+ delete block.partialJson;
2024
+ toolCall = block;
2025
+ contentIndex = streamingToolCall.contentIndex;
2026
+ } else {
2027
+ toolCall = {
2028
+ type: "toolCall",
2029
+ id: resolveResponsesToolCallId(item),
2030
+ name: completedName,
2031
+ arguments: args
2032
+ };
2033
+ blocks.push(toolCall);
2034
+ contentIndex = blockIndex();
2035
+ stream.push({
2036
+ type: "toolcall_start",
2037
+ contentIndex,
2038
+ partial: output
2039
+ });
2040
+ }
2041
+ if (streamingToolCall) forgetStreamingToolCall(streamingToolCall);
2042
+ if (currentBlock === toolCall) {
2043
+ currentBlock = null;
2044
+ currentItem = null;
2045
+ }
1887
2046
  stream.push({
1888
2047
  type: "toolcall_end",
1889
- contentIndex: blockIndex(),
2048
+ contentIndex,
1890
2049
  toolCall,
1891
2050
  partial: output
1892
2051
  });
1893
2052
  }
1894
2053
  } else if (event.type === "response.completed") {
2054
+ if (hasActiveStreamingToolCall()) throw new Error("Responses stream completed with unresolved tool calls");
1895
2055
  const response = event.response;
1896
2056
  if (response?.id) output.responseId = response.id;
1897
2057
  if (response?.usage) {
@@ -1927,6 +2087,7 @@ async function processResponsesStream(openaiStream, output, stream, model, optio
1927
2087
  const msg = error ? `${error.code || "unknown"}: ${error.message || "no message"}` : details?.reason ? `incomplete: ${details.reason}` : "Unknown error (no error details in response)";
1928
2088
  throw new Error(msg);
1929
2089
  }
2090
+ if (hasActiveStreamingToolCall()) throw new Error("Responses stream ended with unresolved tool calls");
1930
2091
  }
1931
2092
  function mapStopReason(status) {
1932
2093
  if (!status) return "stop";
@@ -1941,4 +2102,4 @@ function mapStopReason(status) {
1941
2102
  }
1942
2103
  }
1943
2104
  //#endregion
1944
- export { extractToolSchemaModelCompat as A, isOpenAIGpt54MiniModel as C, resolveOpenAIReasoningEffortForModel as D, normalizeOpenAIReasoningEffort as E, GEMINI_UNSUPPORTED_SCHEMA_KEYWORDS as F, cleanSchemaForGemini as I, resolveUnsupportedToolSchemaKeywords as M, shouldOmitEmptyArrayItems as N, resolveOpenAISupportedReasoningEfforts as O, stripUnsupportedSchemaKeywords as P, resolveResponsesMessageSnapshotCollapse as S, isOpenAIGpt56Model as T, OPENAI_RESPONSES_OUTPUT_TEXT_DELTA_EVENT_TYPE as _, resolveResponsesReasoningEffort as a, isResponsesTextContentPartType as b, clearOpenAIToolSchemaCacheForTest as c, normalizeOpenAIStrictToolParameters as d, normalizeStrictOpenAIJsonSchema as f, OPENAI_RESPONSES_OUTPUT_TEXT_CONTENT_PART_TYPE as g, AZURE_RESPONSES_TEXT_DELTA_EVENT_TYPE as h, processResponsesStream as i, normalizeToolParameterSchema as j, supportsOpenAIReasoningEffort as k, findOpenAIStrictToolProjectionDiagnostics as l, AZURE_RESPONSES_TEXT_CONTENT_PART_TYPE as m, convertResponsesMessages as n, runResponsesStreamLifecycle as o, resolveOpenAIProjectedToolsStrictToolFlag as p, createResponsesAssistantOutput as r, convertResponsesToolPayload as s, applyCommonResponsesParams as t, isStrictOpenAIJsonSchemaCompatible as u, isAzureResponsesTextDeltaEvent as v, isOpenAIGpt55Model as w, isResponsesTextDeltaEventType as x, isAzureResponsesTextDeltaEventType as y };
2105
+ export { supportsOpenAITemperature as A, isOpenAIGpt54MiniModel as C, resolveOpenAIReasoningEffortForModel as D, normalizeOpenAIReasoningEffort as E, stripUnsupportedSchemaKeywords as F, GEMINI_UNSUPPORTED_SCHEMA_KEYWORDS as I, cleanSchemaForGemini as L, normalizeToolParameterSchema as M, resolveUnsupportedToolSchemaKeywords as N, resolveOpenAISupportedReasoningEfforts as O, shouldOmitEmptyArrayItems as P, resolveResponsesMessageSnapshotCollapse as S, isOpenAIGpt56Model as T, OPENAI_RESPONSES_OUTPUT_TEXT_DELTA_EVENT_TYPE as _, resolveResponsesReasoningEffort as a, isResponsesTextContentPartType as b, clearOpenAIToolSchemaCacheForTest as c, normalizeOpenAIStrictToolParameters as d, normalizeStrictOpenAIJsonSchema as f, OPENAI_RESPONSES_OUTPUT_TEXT_CONTENT_PART_TYPE as g, AZURE_RESPONSES_TEXT_DELTA_EVENT_TYPE as h, processResponsesStream as i, extractToolSchemaModelCompat as j, supportsOpenAIReasoningEffort as k, findOpenAIStrictToolProjectionDiagnostics as l, AZURE_RESPONSES_TEXT_CONTENT_PART_TYPE as m, convertResponsesMessages as n, runResponsesStreamLifecycle as o, resolveOpenAIProjectedToolsStrictToolFlag as p, createResponsesAssistantOutput as r, convertResponsesToolPayload as s, applyCommonResponsesParams as t, isStrictOpenAIJsonSchemaCompatible as u, isAzureResponsesTextDeltaEvent as v, isOpenAIGpt55Model as w, isResponsesTextDeltaEventType as x, isAzureResponsesTextDeltaEventType as y };
@@ -1,5 +1,5 @@
1
- import { c as isRecord } from "./transform-messages-BhGF_fF4.mjs";
2
- import { t as projectRuntimeToolInputSchema } from "./tool-schema-json-projection-BXtBc_mD.mjs";
1
+ import { l as isRecord } from "./transform-messages-DNWpwvXA.mjs";
2
+ import { t as projectRuntimeToolInputSchema } from "./tool-schema-json-projection-BwNu3nDi.mjs";
3
3
  //#region packages/ai/src/providers/openai-prompt-cache.ts
4
4
  /** Maximum prompt cache key length accepted by OpenAI-compatible request metadata. */
5
5
  const OPENAI_PROMPT_CACHE_KEY_MAX_LENGTH = 64;
@@ -35,7 +35,12 @@ function projectOpenAITools(tools) {
35
35
  for (let toolIndex = 0; toolIndex < inputToolCount; toolIndex += 1) {
36
36
  let tool;
37
37
  try {
38
- tool = tools[toolIndex];
38
+ const candidate = tools[toolIndex];
39
+ if (!candidate) {
40
+ diagnostics.push(unreadableToolDiagnostic(toolIndex));
41
+ continue;
42
+ }
43
+ tool = candidate;
39
44
  } catch {
40
45
  diagnostics.push(unreadableToolDiagnostic(toolIndex));
41
46
  continue;
@@ -1,4 +1,4 @@
1
- import { n as ApiRegistry } from "./api-registry-BXYnCOIR.mjs";
1
+ import { n as ApiRegistry } from "./api-registry-Byvoz8Ha.mjs";
2
2
 
3
3
  //#region packages/ai/src/providers/register-builtins.d.ts
4
4
  /** Source id used for built-in API provider registrations. */
@@ -1,4 +1,4 @@
1
- import { t as AssistantMessageEventStream } from "./event-stream-ReMmOTzX.mjs";
1
+ import { t as AssistantMessageEventStream } from "./event-stream-D8n2uFee.mjs";
2
2
  //#region packages/ai/src/providers/register-builtins.ts
3
3
  /** Source id used for built-in API provider registrations. */
4
4
  const BUILT_IN_API_PROVIDER_SOURCE_ID = "core:built-in";
@@ -63,35 +63,35 @@ function createLazyRegistration(api, importModule, select) {
63
63
  };
64
64
  }
65
65
  const registerBuiltIns = [
66
- createLazyRegistration("anthropic-messages", () => import("./anthropic-B5gZQM5X.mjs").then((n) => n.t), (module) => ({
66
+ createLazyRegistration("anthropic-messages", () => import("./anthropic-Cvm71xlk.mjs").then((n) => n.t), (module) => ({
67
67
  stream: module.streamAnthropic,
68
68
  streamSimple: module.streamSimpleAnthropic
69
69
  })),
70
- createLazyRegistration("openai-completions", () => import("./openai-completions-B9QLIq2U.mjs").then((n) => n.n), (module) => ({
70
+ createLazyRegistration("openai-completions", () => import("./openai-completions-B2jr3vtJ.mjs").then((n) => n.n), (module) => ({
71
71
  stream: module.streamOpenAICompletions,
72
72
  streamSimple: module.streamSimpleOpenAICompletions
73
73
  })),
74
- createLazyRegistration("mistral-conversations", () => import("./mistral-CePVNdws.mjs"), (module) => ({
74
+ createLazyRegistration("mistral-conversations", () => import("./mistral-D-39Trax.mjs"), (module) => ({
75
75
  stream: module.streamMistral,
76
76
  streamSimple: module.streamSimpleMistral
77
77
  })),
78
- createLazyRegistration("openai-responses", () => import("./openai-responses-B6LylGxM.mjs").then((n) => n.t), (module) => ({
78
+ createLazyRegistration("openai-responses", () => import("./openai-responses-DTpD8YVy.mjs").then((n) => n.t), (module) => ({
79
79
  stream: module.streamOpenAIResponses,
80
80
  streamSimple: module.streamSimpleOpenAIResponses
81
81
  })),
82
- createLazyRegistration("azure-openai-responses", () => import("./azure-openai-responses-DNoSk8Uy.mjs"), (module) => ({
82
+ createLazyRegistration("azure-openai-responses", () => import("./azure-openai-responses-b4lfJxYS.mjs"), (module) => ({
83
83
  stream: module.streamAzureOpenAIResponses,
84
84
  streamSimple: module.streamSimpleAzureOpenAIResponses
85
85
  })),
86
- createLazyRegistration("openai-chatgpt-responses", () => import("./openai-chatgpt-responses-DVC4Bk_A.mjs"), (module) => ({
86
+ createLazyRegistration("openai-chatgpt-responses", () => import("./openai-chatgpt-responses-DCA0K85L.mjs"), (module) => ({
87
87
  stream: module.streamOpenAICodexResponses,
88
88
  streamSimple: module.streamSimpleOpenAICodexResponses
89
89
  })),
90
- createLazyRegistration("google-generative-ai", () => import("./google-D6sIQ1bL.mjs"), (module) => ({
90
+ createLazyRegistration("google-generative-ai", () => import("./google-C7PoDjpW.mjs"), (module) => ({
91
91
  stream: module.streamGoogle,
92
92
  streamSimple: module.streamSimpleGoogle
93
93
  })),
94
- createLazyRegistration("google-vertex", () => import("./google-vertex-rDGwkoZK.mjs"), (module) => ({
94
+ createLazyRegistration("google-vertex", () => import("./google-vertex-L_ABazIA.mjs"), (module) => ({
95
95
  stream: module.streamGoogleVertex,
96
96
  streamSimple: module.streamSimpleGoogleVertex
97
97
  }))
@@ -14,9 +14,13 @@ function scanFenceSpans(buffer, state) {
14
14
  const line = buffer.slice(offset, lineEnd).replace(/\r$/, "");
15
15
  const match = line.match(/^( {0,3})(`{3,}|~{3,})(.*)$/);
16
16
  if (match && (offset > 0 || startsAtLineStart)) {
17
- const indent = match[1];
18
- const marker = match[2];
19
- const markerChar = marker[0];
17
+ const [, indent, marker, trailing] = match;
18
+ if (indent === void 0 || marker === void 0 || trailing === void 0) {
19
+ if (nextNewline === -1) break;
20
+ offset = nextNewline + 1;
21
+ continue;
22
+ }
23
+ const markerChar = marker.charAt(0);
20
24
  const markerLen = marker.length;
21
25
  if (!open) open = {
22
26
  start: offset,
@@ -26,7 +30,7 @@ function scanFenceSpans(buffer, state) {
26
30
  marker,
27
31
  indent
28
32
  };
29
- else if (open.markerChar === markerChar && markerLen >= open.markerLen && /^[ \t]*$/.test(match[3])) {
33
+ else if (open.markerChar === markerChar && markerLen >= open.markerLen && /^[ \t]*$/.test(trailing)) {
30
34
  const end = lineEnd;
31
35
  spans.push({
32
36
  start: open.start,
@@ -351,13 +355,13 @@ function findOpenInlineCodeStart(text) {
351
355
  let openTicks = 0;
352
356
  let index = 0;
353
357
  while (index < text.length) {
354
- if (text[index] !== "`") {
358
+ if (text.charAt(index) !== "`") {
355
359
  index += 1;
356
360
  continue;
357
361
  }
358
362
  const runStart = index;
359
363
  let runLength = 0;
360
- while (index < text.length && text[index] === "`") {
364
+ while (index < text.length && text.charAt(index) === "`") {
361
365
  runLength += 1;
362
366
  index += 1;
363
367
  }
@@ -375,8 +379,10 @@ function findOpenFenceStart(text) {
375
379
  const fenceRe = /(^|\n)(```|~~~)[^\n]*(?:\n|$)/g;
376
380
  let open = null;
377
381
  for (const match of text.matchAll(fenceRe)) {
378
- const index = (match.index ?? 0) + match[1].length;
379
- const marker = match[2] ?? "";
382
+ const prefix = match.at(1);
383
+ const marker = match.at(2);
384
+ if (prefix === void 0 || marker === void 0) continue;
385
+ const index = (match.index ?? 0) + prefix.length;
380
386
  if (open !== null && open.marker === marker) open = null;
381
387
  else if (!open) open = {
382
388
  marker,
@@ -1,4 +1,4 @@
1
- import "./validation-FrchoOlv.mjs";
1
+ import "./validation-DAa_yFOM.mjs";
2
2
  //#region packages/llm-core/src/model-contracts/anthropic.ts
3
3
  function normalizeClaudeModelId(modelId) {
4
4
  const normalized = modelId?.trim().toLowerCase() ?? "";
@@ -1,10 +1,11 @@
1
+ import { types } from "node:util";
1
2
  //#region packages/ai/src/providers/tool-schema-json-projection.ts
2
3
  function isJsonValue(value) {
3
4
  if (value === null) return true;
4
5
  switch (typeof value) {
5
6
  case "boolean":
6
- case "number":
7
7
  case "string": return true;
8
+ case "number": return Number.isFinite(value);
8
9
  case "object":
9
10
  if (Array.isArray(value)) return value.every(isJsonValue);
10
11
  return Object.values(value).every(isJsonValue);
@@ -14,10 +15,25 @@ function isJsonValue(value) {
14
15
  function isJsonObject(value) {
15
16
  return value !== null && typeof value === "object" && !Array.isArray(value);
16
17
  }
18
+ function isNonFiniteNumberValue(value) {
19
+ if (typeof value === "number") return !Number.isFinite(value);
20
+ if (value === null || typeof value !== "object" || !types.isNumberObject(value)) return false;
21
+ return !Number.isFinite(Number.prototype.valueOf.call(value));
22
+ }
17
23
  function serializeToolInputSchema(value, path) {
24
+ const nonFiniteNumber = { path: null };
25
+ const paths = /* @__PURE__ */ new WeakMap();
26
+ let isRoot = true;
18
27
  let text;
19
28
  try {
20
- text = JSON.stringify(value);
29
+ text = JSON.stringify(value, function(key, entry) {
30
+ const holderPath = paths.get(this);
31
+ const entryPath = isRoot ? path : holderPath === void 0 ? `${path}.${key}` : Array.isArray(this) ? `${holderPath}[${key}]` : `${holderPath}.${key}`;
32
+ isRoot = false;
33
+ if (nonFiniteNumber.path === null && isNonFiniteNumberValue(entry)) nonFiniteNumber.path = entryPath;
34
+ else if (entry && typeof entry === "object") paths.set(entry, entryPath);
35
+ return entry;
36
+ });
21
37
  } catch {
22
38
  return {
23
39
  schema: {},
@@ -28,6 +44,10 @@ function serializeToolInputSchema(value, path) {
28
44
  schema: {},
29
45
  violations: [`${path} is not JSON-serializable`]
30
46
  };
47
+ if (nonFiniteNumber.path !== null) return {
48
+ schema: {},
49
+ violations: [`${nonFiniteNumber.path} is not JSON-serializable`]
50
+ };
31
51
  const parsed = JSON.parse(text);
32
52
  if (!isJsonValue(parsed)) return {
33
53
  schema: {},