@openclaw/ai 2026.7.1 → 2026.7.2-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/dist/{anthropic-B5gZQM5X.mjs → anthropic-BIRSg5x9.mjs} +23 -101
  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-CHi7Wo4A.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-BmsqsNwR.mjs} +4 -4
  11. package/dist/{google-shared-ZPSl2qTi.mjs → google-shared-Dx2aba47.mjs} +30 -21
  12. package/dist/{google-vertex-rDGwkoZK.mjs → google-vertex-HZ_0rTwS.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 +38 -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 +12 -2
  24. package/dist/internal/shared.mjs +2 -2
  25. package/dist/{json-parse-DzNSIQBq.mjs → json-parse-BvXNt1-7.mjs} +4 -6
  26. package/dist/{mistral-CePVNdws.mjs → mistral-DxMPt9q9.mjs} +116 -33
  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-BuH2NvsR.mjs} +40 -96
  29. package/dist/{openai-completions-B9QLIq2U.mjs → openai-completions-DPR_O2RW.mjs} +28 -28
  30. package/dist/{openai-responses-B6LylGxM.mjs → openai-responses-Cov-Vdc2.mjs} +6 -6
  31. package/dist/{openai-responses-shared-sj2YUPYc.mjs → openai-responses-shared-Befb4D6R.mjs} +240 -51
  32. package/dist/{openai-tool-projection-BknoV11q.mjs → openai-tool-projection-CFqm42J2.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-BmS70CP5.mjs} +12 -3
  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 { C as stripSystemPromptCacheBoundary, D as normalizeOptionalString, E as normalizeLowercaseStringOrEmpty, d as isRecord, i as extractToolResultText, n as describeToolResultMediaPlaceholder, o as isImageWithMediaPayload, t as transformMessages } from "./transform-messages-BmS70CP5.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-CFqm42J2.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
@@ -1030,6 +1076,82 @@ function resolveResponsesMessageSnapshotCollapse(params) {
1030
1076
  return { kind: "keep" };
1031
1077
  }
1032
1078
  //#endregion
1079
+ //#region packages/ai/src/providers/openai-responses-tool-call-tracker.ts
1080
+ function readIdentityValue(value) {
1081
+ return (typeof value === "string" ? value.trim() : "") || void 0;
1082
+ }
1083
+ function readOutputIndex(event) {
1084
+ return typeof event.output_index === "number" && Number.isInteger(event.output_index) && event.output_index >= 0 ? event.output_index : void 0;
1085
+ }
1086
+ function readEventIdentity(event) {
1087
+ return { itemId: readIdentityValue(event.item_id) };
1088
+ }
1089
+ function readResponsesToolCallItemIdentity(item) {
1090
+ return {
1091
+ itemId: readIdentityValue(item.id),
1092
+ callId: readIdentityValue(item.call_id)
1093
+ };
1094
+ }
1095
+ function createResponsesToolCallTracker() {
1096
+ const indexedCalls = /* @__PURE__ */ new Map();
1097
+ const unindexedCalls = /* @__PURE__ */ new Set();
1098
+ const identitiesConflict = (state, identity) => Boolean(state.itemId && identity.itemId && state.itemId !== identity.itemId || state.callId && identity.callId && state.callId !== identity.callId);
1099
+ const sharesIdentity = (state, identity) => Boolean(state.itemId && identity.itemId && state.itemId === identity.itemId || state.callId && identity.callId && state.callId === identity.callId);
1100
+ const adoptIdentity = (state, identity) => {
1101
+ state.itemId ??= identity.itemId;
1102
+ state.callId ??= identity.callId;
1103
+ return state;
1104
+ };
1105
+ const resolveCompatible = (candidates, identity) => {
1106
+ const uniqueCandidates = [...new Set(candidates)];
1107
+ if (!identity.itemId && !identity.callId) return uniqueCandidates.length === 1 ? uniqueCandidates.at(0) : void 0;
1108
+ const compatible = uniqueCandidates.filter((state) => !identitiesConflict(state, identity));
1109
+ const matches = compatible.filter((state) => sharesIdentity(state, identity));
1110
+ const matched = matches.length === 1 ? matches.at(0) : void 0;
1111
+ if (matched) return adoptIdentity(matched, identity);
1112
+ const soleCompatible = uniqueCandidates.length === 1 && compatible.length === 1 && matches.length === 0 ? compatible.at(0) : void 0;
1113
+ return soleCompatible ? adoptIdentity(soleCompatible, identity) : void 0;
1114
+ };
1115
+ return {
1116
+ register(event, state) {
1117
+ const outputIndex = readOutputIndex(event);
1118
+ if (outputIndex === void 0) {
1119
+ unindexedCalls.add(state);
1120
+ return;
1121
+ }
1122
+ if (indexedCalls.has(outputIndex)) throw new Error(`Responses stream reused active tool-call output index ${outputIndex}`);
1123
+ indexedCalls.set(outputIndex, state);
1124
+ },
1125
+ resolve(event, identity = readEventIdentity(event)) {
1126
+ const outputIndex = readOutputIndex(event);
1127
+ if (outputIndex !== void 0) {
1128
+ const indexed = indexedCalls.get(outputIndex);
1129
+ if (indexed) {
1130
+ if (indexed.callId && identity.callId && indexed.callId !== identity.callId) return;
1131
+ return adoptIdentity(indexed, identity);
1132
+ }
1133
+ const unindexed = resolveCompatible(unindexedCalls, identity);
1134
+ if (unindexed) {
1135
+ unindexedCalls.delete(unindexed);
1136
+ indexedCalls.set(outputIndex, unindexed);
1137
+ }
1138
+ return unindexed;
1139
+ }
1140
+ return resolveCompatible([...indexedCalls.values(), ...unindexedCalls], identity);
1141
+ },
1142
+ forget(toolCall) {
1143
+ for (const [outputIndex, tracked] of indexedCalls) if (tracked === toolCall) indexedCalls.delete(outputIndex);
1144
+ unindexedCalls.delete(toolCall);
1145
+ },
1146
+ markArgumentsUnreliable() {
1147
+ for (const toolCall of /* @__PURE__ */ new Set([...indexedCalls.values(), ...unindexedCalls])) toolCall.argumentStreamReliable = false;
1148
+ },
1149
+ hasActive() {
1150
+ return indexedCalls.size > 0 || unindexedCalls.size > 0;
1151
+ }
1152
+ };
1153
+ }
1154
+ //#endregion
1033
1155
  //#region packages/ai/src/providers/openai-tool-schema.ts
1034
1156
  /**
1035
1157
  * OpenAI strict JSON-schema normalization for tool inventories and request payloads.
@@ -1263,6 +1385,20 @@ function sortResponsesToolsByName(tools) {
1263
1385
  //#endregion
1264
1386
  //#region packages/ai/src/providers/openai-responses-shared.ts
1265
1387
  const EMPTY_TOOL_RESULT_TEXT = "(no output)";
1388
+ function splitResponsesToolCallId(id) {
1389
+ const separatorIndex = id.indexOf("|");
1390
+ return separatorIndex === -1 ? [id, void 0] : [id.slice(0, separatorIndex), id.slice(separatorIndex + 1)];
1391
+ }
1392
+ function resolveResponsesToolCallId(item, fallbackId) {
1393
+ const callId = typeof item.call_id === "string" ? item.call_id.trim() : "";
1394
+ const itemId = typeof item.id === "string" ? item.id.trim() : "";
1395
+ const [fallbackCallId, fallbackItemId = ""] = splitResponsesToolCallId(fallbackId ?? "");
1396
+ const resolvedCallId = callId || fallbackCallId;
1397
+ const resolvedItemId = itemId || fallbackItemId;
1398
+ if (resolvedCallId) return resolvedItemId ? `${resolvedCallId}|${resolvedItemId}` : resolvedCallId;
1399
+ const generatedCallId = `call_${randomUUID().replaceAll("-", "").slice(0, 24)}`;
1400
+ return resolvedItemId ? `${generatedCallId}|${resolvedItemId}` : generatedCallId;
1401
+ }
1266
1402
  function sanitizeToolResultText(text, fallback) {
1267
1403
  const sanitized = sanitizeSurrogates(text);
1268
1404
  return sanitized.trim().length > 0 ? sanitized : fallback;
@@ -1318,7 +1454,7 @@ function convertResponsesMessages(model, context, allowedToolCallProviders, opti
1318
1454
  const normalizeToolCallId = (id, targetModel, source) => {
1319
1455
  if (!allowedToolCallProviders.has(model.provider)) return normalizeIdPart(id);
1320
1456
  if (!id.includes("|")) return normalizeIdPart(id);
1321
- const [callId, itemId] = id.split("|");
1457
+ const [callId, itemId = ""] = splitResponsesToolCallId(id);
1322
1458
  const normalizedCallId = normalizeIdPart(callId);
1323
1459
  let normalizedItemId = source.provider !== model.provider || source.api !== model.api ? buildForeignResponsesItemId(itemId) : normalizeIdPart(itemId);
1324
1460
  if (!normalizedItemId.startsWith("fc_")) normalizedItemId = normalizeIdPart(`fc_${normalizedItemId}`);
@@ -1407,7 +1543,7 @@ function convertResponsesMessages(model, context, allowedToolCallProviders, opti
1407
1543
  previousReplayItemWasReasoning = false;
1408
1544
  } else if (block.type === "toolCall") {
1409
1545
  const toolCall = block;
1410
- const [callId, itemIdRaw] = toolCall.id.split("|");
1546
+ const [callId, itemIdRaw] = splitResponsesToolCallId(toolCall.id);
1411
1547
  let itemId = shouldReplayResponsesItemIds ? itemIdRaw : void 0;
1412
1548
  if (shouldReplayResponsesItemIds && isDifferentModel && itemId?.startsWith("fc_")) itemId = void 0;
1413
1549
  output.push({
@@ -1424,10 +1560,10 @@ function convertResponsesMessages(model, context, allowedToolCallProviders, opti
1424
1560
  } else if (msg.role === "toolResult") {
1425
1561
  const textResult = extractToolResultText(msg.content);
1426
1562
  const sanitizedTextResult = sanitizeSurrogates(textResult);
1427
- const hasImages = msg.content.some((c) => c.type === "image");
1563
+ const hasImages = msg.content.some(isImageWithMediaPayload);
1428
1564
  const mediaPlaceholder = describeToolResultMediaPlaceholder(msg.content);
1429
1565
  const hasText = sanitizedTextResult.trim().length > 0;
1430
- const [callId] = msg.toolCallId.split("|");
1566
+ const [callId] = splitResponsesToolCallId(msg.toolCallId);
1431
1567
  let output;
1432
1568
  if (hasImages && model.input.includes("image")) {
1433
1569
  const contentParts = [];
@@ -1439,7 +1575,7 @@ function convertResponsesMessages(model, context, allowedToolCallProviders, opti
1439
1575
  type: "input_text",
1440
1576
  text: mediaPlaceholder
1441
1577
  });
1442
- for (const block of msg.content) if (block.type === "image") contentParts.push({
1578
+ for (const block of msg.content) if (isImageWithMediaPayload(block)) contentParts.push({
1443
1579
  type: "input_image",
1444
1580
  detail: "auto",
1445
1581
  image_url: `data:${block.mimeType};base64,${block.data}`
@@ -1496,7 +1632,7 @@ function resolveResponsesReasoningEffort(model, reasoning) {
1496
1632
  }
1497
1633
  function applyCommonResponsesParams(params, model, context, options, config) {
1498
1634
  if (options?.maxTokens) params.max_output_tokens = options.maxTokens;
1499
- if (options?.temperature !== void 0) params.temperature = options.temperature;
1635
+ if (options?.temperature !== void 0 && supportsOpenAITemperature(model)) params.temperature = options.temperature;
1500
1636
  if (context.tools) {
1501
1637
  const converted = convertResponsesToolPayload(context.tools, { model });
1502
1638
  if (converted.tools.length > 0) params.tools = converted.tools;
@@ -1577,17 +1713,30 @@ async function runResponsesStreamLifecycle(params) {
1577
1713
  async function processResponsesStream(openaiStream, output, stream, model, options) {
1578
1714
  let currentItem = null;
1579
1715
  let currentBlock = null;
1716
+ const streamingToolCalls = createResponsesToolCallTracker();
1580
1717
  let lastTextBlock = null;
1581
1718
  let pendingMessageText = null;
1582
1719
  const blocks = output.content;
1583
1720
  const blockIndex = () => blocks.length - 1;
1721
+ const readIdentityValue = (value) => {
1722
+ return (typeof value === "string" ? value.trim() : "") || void 0;
1723
+ };
1724
+ const resolveCompletedToolCallName = (toolCall, value) => {
1725
+ const streamedName = readIdentityValue(toolCall?.block.name);
1726
+ const completedName = readIdentityValue(value);
1727
+ if (streamedName && completedName && streamedName !== completedName) throw new Error(`Responses stream changed tool-call function name from ${streamedName} to ${completedName}`);
1728
+ const name = completedName ?? streamedName;
1729
+ if (!name) throw new Error("Responses stream completed tool call without a function name");
1730
+ return name;
1731
+ };
1584
1732
  const appendPendingMessageDelta = (delta) => {
1585
1733
  pendingMessageText = `${pendingMessageText ?? ""}${delta}`;
1586
1734
  const priorText = lastTextBlock?.block.text ?? "";
1587
1735
  if (priorText.startsWith(pendingMessageText) || pendingMessageText.startsWith(priorText)) return;
1588
1736
  currentBlock = {
1589
1737
  type: "text",
1590
- text: pendingMessageText
1738
+ text: pendingMessageText,
1739
+ ...currentItem?.type === "message" && currentItem.phase ? { textSignature: encodeTextSignatureV1(currentItem.id, currentItem.phase ?? void 0) } : {}
1591
1740
  };
1592
1741
  blocks.push(currentBlock);
1593
1742
  stream.push({
@@ -1640,7 +1789,8 @@ async function processResponsesStream(openaiStream, output, stream, model, optio
1640
1789
  } else {
1641
1790
  currentBlock = {
1642
1791
  type: "text",
1643
- text: ""
1792
+ text: "",
1793
+ ...item.phase ? { textSignature: encodeTextSignatureV1(item.id, item.phase) } : {}
1644
1794
  };
1645
1795
  output.content.push(currentBlock);
1646
1796
  stream.push({
@@ -1650,18 +1800,27 @@ async function processResponsesStream(openaiStream, output, stream, model, optio
1650
1800
  });
1651
1801
  }
1652
1802
  } else if (item.type === "function_call") {
1653
- currentItem = item;
1654
- currentBlock = {
1803
+ const toolCallBlock = {
1655
1804
  type: "toolCall",
1656
- id: `${item.call_id}|${item.id}`,
1657
- name: item.name,
1805
+ id: resolveResponsesToolCallId(item),
1806
+ name: readIdentityValue(item.name) ?? "",
1658
1807
  arguments: {},
1659
1808
  partialJson: item.arguments || ""
1660
1809
  };
1661
- output.content.push(currentBlock);
1810
+ const contentIndex = output.content.length;
1811
+ const toolCallState = {
1812
+ block: toolCallBlock,
1813
+ contentIndex,
1814
+ argumentStreamReliable: true,
1815
+ ...readResponsesToolCallItemIdentity(item)
1816
+ };
1817
+ streamingToolCalls.register(event, toolCallState);
1818
+ currentItem = item;
1819
+ currentBlock = toolCallBlock;
1820
+ output.content.push(toolCallBlock);
1662
1821
  stream.push({
1663
1822
  type: "toolcall_start",
1664
- contentIndex: blockIndex(),
1823
+ contentIndex,
1665
1824
  partial: output
1666
1825
  });
1667
1826
  }
@@ -1775,34 +1934,37 @@ async function processResponsesStream(openaiStream, output, stream, model, optio
1775
1934
  }
1776
1935
  }
1777
1936
  } 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);
1937
+ const toolCall = streamingToolCalls.resolve(event);
1938
+ if (toolCall) {
1939
+ toolCall.block.partialJson += event.delta;
1940
+ toolCall.block.arguments = parseStreamingJson(toolCall.block.partialJson);
1781
1941
  stream.push({
1782
1942
  type: "toolcall_delta",
1783
- contentIndex: blockIndex(),
1943
+ contentIndex: toolCall.contentIndex,
1784
1944
  delta: event.delta,
1785
1945
  partial: output
1786
1946
  });
1787
- }
1947
+ } else if (streamingToolCalls.hasActive()) streamingToolCalls.markArgumentsUnreliable();
1788
1948
  } else if (event.type === "response.function_call_arguments.done") {
1789
- if (currentItem?.type === "function_call" && currentBlock?.type === "toolCall") {
1790
- const previousPartialJson = currentBlock.partialJson;
1949
+ const toolCall = streamingToolCalls.resolve(event);
1950
+ if (toolCall) {
1951
+ const previousPartialJson = toolCall.block.partialJson;
1791
1952
  const doneArguments = typeof event.arguments === "string" ? event.arguments : void 0;
1792
1953
  if (doneArguments !== void 0 && (doneArguments.length > 0 || previousPartialJson === "")) {
1793
- currentBlock.partialJson = doneArguments;
1794
- currentBlock.arguments = parseStreamingJson(currentBlock.partialJson);
1954
+ toolCall.block.partialJson = doneArguments;
1955
+ toolCall.block.arguments = parseStreamingJson(toolCall.block.partialJson);
1956
+ toolCall.argumentStreamReliable = true;
1795
1957
  }
1796
1958
  if (doneArguments?.startsWith(previousPartialJson)) {
1797
1959
  const delta = doneArguments.slice(previousPartialJson.length);
1798
1960
  if (delta.length > 0) stream.push({
1799
1961
  type: "toolcall_delta",
1800
- contentIndex: blockIndex(),
1962
+ contentIndex: toolCall.contentIndex,
1801
1963
  delta,
1802
1964
  partial: output
1803
1965
  });
1804
1966
  }
1805
- }
1967
+ } else if (streamingToolCalls.hasActive()) streamingToolCalls.markArgumentsUnreliable();
1806
1968
  } else if (event.type === "response.output_item.done") {
1807
1969
  const item = event.item;
1808
1970
  if (item.type !== "message") {
@@ -1846,7 +2008,8 @@ async function processResponsesStream(openaiStream, output, stream, model, optio
1846
2008
  if (currentBlock?.type !== "text") {
1847
2009
  currentBlock = {
1848
2010
  type: "text",
1849
- text: ""
2011
+ text: "",
2012
+ ...phase ? { textSignature: encodeTextSignatureV1(item.id, phase) } : {}
1850
2013
  };
1851
2014
  blocks.push(currentBlock);
1852
2015
  stream.push({
@@ -1871,27 +2034,52 @@ async function processResponsesStream(openaiStream, output, stream, model, optio
1871
2034
  }
1872
2035
  currentBlock = null;
1873
2036
  } else if (item.type === "function_call") {
1874
- const args = currentBlock?.type === "toolCall" && currentBlock.partialJson ? parseStreamingJson(currentBlock.partialJson) : parseStreamingJson(item.arguments || "{}");
2037
+ const streamingToolCall = streamingToolCalls.resolve(event, readResponsesToolCallItemIdentity(item));
2038
+ if (!streamingToolCall && streamingToolCalls.hasActive()) continue;
2039
+ const completedName = resolveCompletedToolCallName(streamingToolCall, item.name);
2040
+ const streamedArguments = streamingToolCall?.block.partialJson ?? "";
2041
+ const completedArguments = typeof item.arguments === "string" ? item.arguments : void 0;
2042
+ if (streamingToolCall && !streamingToolCall.argumentStreamReliable && !completedArguments) continue;
2043
+ const args = parseStreamingJson(completedArguments !== void 0 && (completedArguments.length > 0 || !streamedArguments) ? completedArguments : streamedArguments || "{}");
1875
2044
  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;
2045
+ let contentIndex;
2046
+ if (streamingToolCall) {
2047
+ const block = streamingToolCall.block;
2048
+ block.id = resolveResponsesToolCallId(item, block.id);
2049
+ block.name = completedName;
2050
+ block.arguments = args;
2051
+ delete block.partialJson;
2052
+ toolCall = block;
2053
+ contentIndex = streamingToolCall.contentIndex;
2054
+ } else {
2055
+ toolCall = {
2056
+ type: "toolCall",
2057
+ id: resolveResponsesToolCallId(item),
2058
+ name: completedName,
2059
+ arguments: args
2060
+ };
2061
+ blocks.push(toolCall);
2062
+ contentIndex = blockIndex();
2063
+ stream.push({
2064
+ type: "toolcall_start",
2065
+ contentIndex,
2066
+ partial: output
2067
+ });
2068
+ }
2069
+ if (streamingToolCall) streamingToolCalls.forget(streamingToolCall);
2070
+ if (currentBlock === toolCall) {
2071
+ currentBlock = null;
2072
+ currentItem = null;
2073
+ }
1887
2074
  stream.push({
1888
2075
  type: "toolcall_end",
1889
- contentIndex: blockIndex(),
2076
+ contentIndex,
1890
2077
  toolCall,
1891
2078
  partial: output
1892
2079
  });
1893
2080
  }
1894
2081
  } else if (event.type === "response.completed") {
2082
+ if (streamingToolCalls.hasActive()) throw new Error("Responses stream completed with unresolved tool calls");
1895
2083
  const response = event.response;
1896
2084
  if (response?.id) output.responseId = response.id;
1897
2085
  if (response?.usage) {
@@ -1927,6 +2115,7 @@ async function processResponsesStream(openaiStream, output, stream, model, optio
1927
2115
  const msg = error ? `${error.code || "unknown"}: ${error.message || "no message"}` : details?.reason ? `incomplete: ${details.reason}` : "Unknown error (no error details in response)";
1928
2116
  throw new Error(msg);
1929
2117
  }
2118
+ if (streamingToolCalls.hasActive()) throw new Error("Responses stream ended with unresolved tool calls");
1930
2119
  }
1931
2120
  function mapStopReason(status) {
1932
2121
  if (!status) return "stop";
@@ -1941,4 +2130,4 @@ function mapStopReason(status) {
1941
2130
  }
1942
2131
  }
1943
2132
  //#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 };
2133
+ export { resolveOpenAISupportedReasoningEfforts as A, isResponsesTextDeltaEventType as C, isOpenAIGpt56Model as D, isOpenAIGpt55Model as E, resolveUnsupportedToolSchemaKeywords as F, shouldOmitEmptyArrayItems as I, stripUnsupportedSchemaKeywords as L, supportsOpenAITemperature as M, extractToolSchemaModelCompat as N, normalizeOpenAIReasoningEffort as O, normalizeToolParameterSchema as P, GEMINI_UNSUPPORTED_SCHEMA_KEYWORDS as R, isResponsesTextContentPartType as S, isOpenAIGpt54MiniModel as T, AZURE_RESPONSES_TEXT_DELTA_EVENT_TYPE as _, resolveResponsesReasoningEffort as a, isAzureResponsesTextDeltaEvent as b, clearOpenAIToolSchemaCacheForTest as c, normalizeOpenAIStrictToolParameters as d, normalizeStrictOpenAIJsonSchema as f, AZURE_RESPONSES_TEXT_CONTENT_PART_TYPE as g, readResponsesToolCallItemIdentity as h, processResponsesStream as i, supportsOpenAIReasoningEffort as j, resolveOpenAIReasoningEffortForModel as k, findOpenAIStrictToolProjectionDiagnostics as l, createResponsesToolCallTracker as m, convertResponsesMessages as n, runResponsesStreamLifecycle as o, resolveOpenAIProjectedToolsStrictToolFlag as p, createResponsesAssistantOutput as r, convertResponsesToolPayload as s, applyCommonResponsesParams as t, isStrictOpenAIJsonSchemaCompatible as u, OPENAI_RESPONSES_OUTPUT_TEXT_CONTENT_PART_TYPE as v, resolveResponsesMessageSnapshotCollapse as w, isAzureResponsesTextDeltaEventType as x, OPENAI_RESPONSES_OUTPUT_TEXT_DELTA_EVENT_TYPE as y, cleanSchemaForGemini as z };
@@ -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 { d as isRecord } from "./transform-messages-BmS70CP5.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-BIRSg5x9.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-DPR_O2RW.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-DxMPt9q9.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-Cov-Vdc2.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-CHi7Wo4A.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-BuH2NvsR.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-BmsqsNwR.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-HZ_0rTwS.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() ?? "";