@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.
- package/dist/{anthropic-B5gZQM5X.mjs → anthropic-BIRSg5x9.mjs} +23 -101
- package/dist/{api-registry-BXYnCOIR.d.mts → api-registry-Byvoz8Ha.d.mts} +1 -1
- package/dist/{azure-openai-responses-DNoSk8Uy.mjs → azure-openai-responses-CHi7Wo4A.mjs} +6 -6
- package/dist/{azure-openai-responses-client-compat-a_O_GVQV.mjs → azure-openai-responses-client-compat-C7K7QfUE.mjs} +23 -2
- package/dist/{env-api-keys-CtMlqaQ4.mjs → env-api-keys-DnhYpc27.mjs} +4 -3
- package/dist/{event-stream-ReMmOTzX.mjs → event-stream-D8n2uFee.mjs} +14 -6
- package/dist/{event-stream-0nZeBKl2.d.mts → event-stream-uQspnL8S.d.mts} +1 -1
- package/dist/event-stream.d.mts +1 -1
- package/dist/event-stream.mjs +1 -1
- package/dist/{google-D6sIQ1bL.mjs → google-BmsqsNwR.mjs} +4 -4
- package/dist/{google-shared-ZPSl2qTi.mjs → google-shared-Dx2aba47.mjs} +30 -21
- package/dist/{google-vertex-rDGwkoZK.mjs → google-vertex-HZ_0rTwS.mjs} +5 -18
- package/dist/index.d.mts +4 -4
- package/dist/index.mjs +3 -3
- package/dist/internal/anthropic.d.mts +1 -1
- package/dist/internal/anthropic.mjs +3 -3
- package/dist/internal/openai.d.mts +38 -3
- package/dist/internal/openai.mjs +7 -7
- package/dist/internal/retry-after.d.mts +5 -0
- package/dist/internal/retry-after.mjs +101 -0
- package/dist/internal/runtime.d.mts +2 -2
- package/dist/internal/runtime.mjs +6 -5
- package/dist/internal/shared.d.mts +12 -2
- package/dist/internal/shared.mjs +2 -2
- package/dist/{json-parse-DzNSIQBq.mjs → json-parse-BvXNt1-7.mjs} +4 -6
- package/dist/{mistral-CePVNdws.mjs → mistral-DxMPt9q9.mjs} +116 -33
- package/dist/{model-utils-DgmOla96.mjs → model-utils-Q1LSRIdo.mjs} +5 -12
- package/dist/{openai-chatgpt-responses-DVC4Bk_A.mjs → openai-chatgpt-responses-BuH2NvsR.mjs} +40 -96
- package/dist/{openai-completions-B9QLIq2U.mjs → openai-completions-DPR_O2RW.mjs} +28 -28
- package/dist/{openai-responses-B6LylGxM.mjs → openai-responses-Cov-Vdc2.mjs} +6 -6
- package/dist/{openai-responses-shared-sj2YUPYc.mjs → openai-responses-shared-Befb4D6R.mjs} +240 -51
- package/dist/{openai-tool-projection-BknoV11q.mjs → openai-tool-projection-CFqm42J2.mjs} +8 -3
- package/dist/providers.d.mts +1 -1
- package/dist/providers.mjs +9 -9
- package/dist/{reasoning-tag-text-partitioner-axhAdUwg.mjs → reasoning-tag-text-partitioner-BlVe67g6.mjs} +14 -8
- package/dist/{src-CZ503MYJ.mjs → src-CXno1H5g.mjs} +1 -1
- package/dist/{tool-schema-json-projection-BXtBc_mD.mjs → tool-schema-json-projection-BwNu3nDi.mjs} +22 -2
- package/dist/{transform-messages-BhGF_fF4.mjs → transform-messages-BmS70CP5.mjs} +12 -3
- package/dist/{types-DRgdPqaZ.d.mts → types-Cx2zJtyz.d.mts} +5 -0
- package/dist/types.d.mts +3 -3
- package/dist/types.mjs +3 -3
- package/dist/{validation-BDMWOr8d.d.mts → validation-Cej7htKc.d.mts} +1 -1
- package/dist/{validation-FrchoOlv.mjs → validation-DAa_yFOM.mjs} +2 -7
- package/dist/validation.d.mts +1 -1
- package/dist/validation.mjs +1 -1
- package/npm-shrinkwrap.json +2 -2
- 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-
|
|
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-
|
|
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
|
|
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-
|
|
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
|
-
|
|
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 (
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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(
|
|
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
|
|
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
|
|
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
|
-
|
|
1654
|
-
currentBlock = {
|
|
1803
|
+
const toolCallBlock = {
|
|
1655
1804
|
type: "toolCall",
|
|
1656
|
-
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.
|
|
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
|
|
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
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
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:
|
|
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
|
-
|
|
1790
|
-
|
|
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
|
-
|
|
1794
|
-
|
|
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:
|
|
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
|
|
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
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
}
|
|
1886
|
-
|
|
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
|
|
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 {
|
|
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 {
|
|
2
|
-
import { t as projectRuntimeToolInputSchema } from "./tool-schema-json-projection-
|
|
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
|
-
|
|
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;
|
package/dist/providers.d.mts
CHANGED
package/dist/providers.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as AssistantMessageEventStream } from "./event-stream-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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
|
|
18
|
-
|
|
19
|
-
|
|
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(
|
|
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
|
|
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
|
|
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
|
|
379
|
-
const marker = match
|
|
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,
|