@ai-sdk-tool/parser 2.1.4 → 2.1.5

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/README.md CHANGED
@@ -124,7 +124,7 @@ See `examples/parser-core/src/*` for runnable demos (streaming/non‑streaming,
124
124
  - Set `DEBUG_PARSER_MW=parse` to log original matched text and parsed summary.
125
125
  - Optional `DEBUG_PARSER_MW_STYLE=bg|inverse|underline|bold` to change highlight style.
126
126
  - Provider options passthrough: `providerOptions.toolCallMiddleware` fields are merged into protocol options. Internal fields used:
127
- - `toolNames`: internal propagation of custom tool names.
127
+ - `originalTools`: internal propagation of custom tool schemas.
128
128
  - `toolChoice`: internal fast‑path activation for required/specific tool modes.
129
129
  - Transform details: `transformParams` injects a system message built from protocol `formatTools` and clears `tools` since many providers strip/ignore them.
130
130
 
package/dist/index.cjs CHANGED
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
+ var __create = Object.create;
2
3
  var __defProp = Object.defineProperty;
3
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
5
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
8
  var __export = (target, all) => {
7
9
  for (var name in all)
@@ -15,24 +17,30 @@ var __copyProps = (to, from, except, desc) => {
15
17
  }
16
18
  return to;
17
19
  };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
18
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
29
 
20
30
  // src/index.ts
21
31
  var index_exports = {};
22
32
  __export(index_exports, {
23
33
  RJSON: () => robust_json_exports,
24
- coerceBySchema: () => coerceBySchema,
25
- coerceToolCallInput: () => coerceToolCallInput,
26
34
  createDynamicIfThenElseSchema: () => createDynamicIfThenElseSchema,
27
35
  createToolMiddleware: () => createToolMiddleware,
36
+ decodeOriginalTools: () => decodeOriginalTools,
37
+ encodeOriginalTools: () => encodeOriginalTools,
28
38
  escapeRegExp: () => escapeRegExp,
29
39
  extractOnErrorOption: () => extractOnErrorOption,
30
- fixToolCallWithSchema: () => fixToolCallWithSchema,
40
+ extractToolNamesFromOriginalTools: () => extractToolNamesFromOriginalTools,
31
41
  gemmaToolMiddleware: () => gemmaToolMiddleware,
32
42
  getDebugLevel: () => getDebugLevel,
33
- getFunctionTools: () => getFunctionTools,
34
43
  getPotentialStartIndex: () => getPotentialStartIndex,
35
- getSchemaType: () => getSchemaType,
36
44
  hasInputProperty: () => hasInputProperty,
37
45
  hermesToolMiddleware: () => hermesToolMiddleware,
38
46
  isToolCallContent: () => isToolCallContent,
@@ -43,7 +51,7 @@ __export(index_exports, {
43
51
  logParsedSummary: () => logParsedSummary,
44
52
  logRawChunk: () => logRawChunk,
45
53
  morphXmlProtocol: () => morphXmlProtocol,
46
- unwrapJsonSchema: () => unwrapJsonSchema,
54
+ originalToolsSchema: () => originalToolsSchema,
47
55
  xmlToolMiddleware: () => xmlToolMiddleware
48
56
  });
49
57
  module.exports = __toCommonJS(index_exports);
@@ -766,210 +774,6 @@ function stringify(obj) {
766
774
  return "null";
767
775
  }
768
776
 
769
- // src/utils/coercion.ts
770
- function unwrapJsonSchema(schema) {
771
- if (!schema || typeof schema !== "object") return schema;
772
- const s = schema;
773
- if (s.jsonSchema && typeof s.jsonSchema === "object") {
774
- return unwrapJsonSchema(s.jsonSchema);
775
- }
776
- return schema;
777
- }
778
- function getSchemaType(schema) {
779
- const unwrapped = unwrapJsonSchema(schema);
780
- if (!unwrapped || typeof unwrapped !== "object") return void 0;
781
- const t = unwrapped.type;
782
- if (typeof t === "string") return t;
783
- if (Array.isArray(t)) {
784
- const preferred = [
785
- "object",
786
- "array",
787
- "boolean",
788
- "number",
789
- "integer",
790
- "string"
791
- ];
792
- for (const p of preferred) if (t.includes(p)) return p;
793
- }
794
- const s = unwrapped;
795
- if (s && typeof s === "object" && (s.properties || s.additionalProperties)) {
796
- return "object";
797
- }
798
- if (s && typeof s === "object" && (s.items || s.prefixItems)) {
799
- return "array";
800
- }
801
- return void 0;
802
- }
803
- function coerceBySchema(value, schema) {
804
- const unwrapped = unwrapJsonSchema(schema);
805
- if (!unwrapped || typeof unwrapped !== "object") {
806
- if (typeof value === "string") {
807
- const s = value.trim();
808
- const lower = s.toLowerCase();
809
- if (lower === "true") return true;
810
- if (lower === "false") return false;
811
- if (/^-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?$/.test(s)) {
812
- const num = Number(s);
813
- if (Number.isFinite(num)) return num;
814
- }
815
- if (s.startsWith("{") && s.endsWith("}") || s.startsWith("[") && s.endsWith("]")) {
816
- try {
817
- const parsed = JSON.parse(s);
818
- return coerceBySchema(parsed, void 0);
819
- } catch (e) {
820
- }
821
- }
822
- }
823
- return value;
824
- }
825
- const schemaType = getSchemaType(unwrapped);
826
- if (typeof value === "string") {
827
- const s = value.trim();
828
- if (schemaType === "object") {
829
- try {
830
- let normalized = s.replace(/'/g, '"');
831
- normalized = normalized.replace(/^\{\s*\}$/s, "{}");
832
- const obj = JSON.parse(normalized);
833
- if (obj && typeof obj === "object" && !Array.isArray(obj)) {
834
- const props = unwrapped.properties;
835
- const out = {};
836
- for (const [k, v] of Object.entries(obj)) {
837
- const propSchema = props ? props[k] : void 0;
838
- out[k] = typeof propSchema === "boolean" ? v : coerceBySchema(v, propSchema);
839
- }
840
- return out;
841
- }
842
- } catch (e) {
843
- }
844
- }
845
- if (schemaType === "array") {
846
- try {
847
- const normalized = s.replace(/'/g, '"');
848
- const arr = JSON.parse(normalized);
849
- if (Array.isArray(arr)) {
850
- const u = unwrapped;
851
- const prefixItems = Array.isArray(
852
- u.prefixItems
853
- ) ? u.prefixItems : void 0;
854
- const itemsSchema = u.items;
855
- if (prefixItems && arr.length === prefixItems.length) {
856
- return arr.map((v, i) => coerceBySchema(v, prefixItems[i]));
857
- }
858
- return arr.map((v) => coerceBySchema(v, itemsSchema));
859
- }
860
- } catch (e) {
861
- const csv = s.includes("\n") ? s.split(/\n+/) : s.split(/,\s*/);
862
- const trimmed = csv.map((x) => x.trim()).filter((x) => x.length > 0);
863
- const u = unwrapped;
864
- const prefixItems = Array.isArray(
865
- u.prefixItems
866
- ) ? u.prefixItems : void 0;
867
- const itemsSchema = u.items;
868
- if (prefixItems && trimmed.length === prefixItems.length) {
869
- return trimmed.map((x, i) => coerceBySchema(x, prefixItems[i]));
870
- }
871
- return trimmed.map((x) => coerceBySchema(x, itemsSchema));
872
- }
873
- }
874
- }
875
- if (schemaType === "object" && value && typeof value === "object" && !Array.isArray(value)) {
876
- const out = {};
877
- const props = unwrapped.properties;
878
- for (const [k, v] of Object.entries(value)) {
879
- const propSchema = props ? props[k] : void 0;
880
- out[k] = typeof propSchema === "boolean" ? v : coerceBySchema(v, propSchema);
881
- }
882
- return out;
883
- }
884
- if (schemaType === "array") {
885
- const u = unwrapped;
886
- const itemsSchema = u.items;
887
- const prefixItems = Array.isArray(
888
- u.prefixItems
889
- ) ? u.prefixItems : void 0;
890
- if (Array.isArray(value)) {
891
- if (prefixItems && value.length === prefixItems.length) {
892
- return value.map((v, i) => coerceBySchema(v, prefixItems[i]));
893
- }
894
- return value.map((v) => coerceBySchema(v, itemsSchema));
895
- }
896
- if (value && typeof value === "object") {
897
- const maybe = value;
898
- if (Object.prototype.hasOwnProperty.call(maybe, "item")) {
899
- const items = maybe.item;
900
- const arr = Array.isArray(items) ? items : [items];
901
- if (prefixItems && arr.length === prefixItems.length) {
902
- return arr.map((v, i) => coerceBySchema(v, prefixItems[i]));
903
- }
904
- return arr.map((v) => coerceBySchema(v, itemsSchema));
905
- }
906
- const keys = Object.keys(maybe);
907
- if (keys.length === 1) {
908
- const singleKey = keys[0];
909
- const singleValue = maybe[singleKey];
910
- if (Array.isArray(singleValue)) {
911
- const coercedArray = singleValue.map(
912
- (v) => coerceBySchema(v, itemsSchema)
913
- );
914
- return coercedArray;
915
- }
916
- }
917
- if (keys.length > 0 && keys.every((k) => /^\d+$/.test(k))) {
918
- const arr = keys.sort((a, b) => Number(a) - Number(b)).map((k) => maybe[k]);
919
- if (prefixItems && arr.length === prefixItems.length) {
920
- return arr.map((v, i) => coerceBySchema(v, prefixItems[i]));
921
- }
922
- return arr.map((v) => coerceBySchema(v, itemsSchema));
923
- }
924
- }
925
- if (value == null || typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
926
- if (prefixItems && prefixItems.length > 0) {
927
- return [coerceBySchema(value, prefixItems[0])];
928
- }
929
- return [coerceBySchema(value, itemsSchema)];
930
- }
931
- }
932
- if (typeof value === "string") {
933
- const s = value.trim();
934
- if (schemaType === "boolean") {
935
- const lower = s.toLowerCase();
936
- if (lower === "true") return true;
937
- if (lower === "false") return false;
938
- }
939
- if (schemaType === "number" || schemaType === "integer") {
940
- if (/^-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?$/.test(s)) {
941
- const num = Number(s);
942
- if (Number.isFinite(num)) return num;
943
- }
944
- }
945
- }
946
- return value;
947
- }
948
- function fixToolCallWithSchema(part, tools) {
949
- var _a;
950
- if (part.type !== "tool-call") return part;
951
- const tc = part;
952
- let args = {};
953
- if (typeof tc.input === "string") {
954
- try {
955
- args = JSON.parse(tc.input);
956
- } catch (e) {
957
- return part;
958
- }
959
- } else if (tc.input && typeof tc.input === "object") {
960
- args = tc.input;
961
- }
962
- const schema = (_a = tools.find((t) => t.name === tc.toolName)) == null ? void 0 : _a.inputSchema;
963
- const coerced = coerceBySchema(args, schema);
964
- return {
965
- ...part,
966
- input: JSON.stringify(coerced != null ? coerced : {})
967
- };
968
- }
969
- function coerceToolCallInput(part, tools) {
970
- return fixToolCallWithSchema(part, tools);
971
- }
972
-
973
777
  // src/utils/debug.ts
974
778
  function normalizeBooleanString(value) {
975
779
  const normalized = value.trim().toLowerCase();
@@ -1057,33 +861,34 @@ function extractOnErrorOption(providerOptions) {
1057
861
  return void 0;
1058
862
  }
1059
863
 
1060
- // src/utils/tools.ts
864
+ // src/utils/provider-options.ts
865
+ var originalToolsSchema = {
866
+ encode: encodeOriginalTools,
867
+ decode: decodeOriginalTools
868
+ };
869
+ function encodeOriginalTools(tools) {
870
+ return (tools == null ? void 0 : tools.map((t) => ({
871
+ name: t.name,
872
+ inputSchema: JSON.stringify(t.inputSchema)
873
+ }))) || [];
874
+ }
875
+ function decodeOriginalTools(originalTools) {
876
+ const tools = (originalTools == null ? void 0 : originalTools.map(
877
+ (t) => ({
878
+ name: t.name,
879
+ inputSchema: JSON.parse(t.inputSchema)
880
+ })
881
+ )) || [];
882
+ return tools;
883
+ }
884
+ function extractToolNamesFromOriginalTools(originalTools) {
885
+ return (originalTools == null ? void 0 : originalTools.map((t) => t.name)) || [];
886
+ }
1061
887
  function isToolChoiceActive(params) {
1062
888
  var _a, _b, _c;
1063
889
  const toolChoice = (_b = (_a = params.providerOptions) == null ? void 0 : _a.toolCallMiddleware) == null ? void 0 : _b.toolChoice;
1064
890
  return !!(typeof params.providerOptions === "object" && params.providerOptions !== null && typeof ((_c = params.providerOptions) == null ? void 0 : _c.toolCallMiddleware) === "object" && toolChoice && typeof toolChoice === "object" && (toolChoice.type === "tool" || toolChoice.type === "required"));
1065
891
  }
1066
- function getFunctionTools(params) {
1067
- var _a, _b;
1068
- const functionTools = ((_a = params.tools) != null ? _a : []).filter(
1069
- (t) => t.type === "function"
1070
- );
1071
- if (functionTools.length > 0) return functionTools;
1072
- const rawToolNames = params.providerOptions && typeof params.providerOptions === "object" && ((_b = params.providerOptions.toolCallMiddleware) == null ? void 0 : _b.toolNames) || [];
1073
- const toStringArray = (val) => Array.isArray(val) ? val.filter(
1074
- (item) => typeof item === "string"
1075
- ) : [];
1076
- const toolNames = toStringArray(rawToolNames);
1077
- if (toolNames.length > 0) {
1078
- return toolNames.map((name) => ({
1079
- type: "function",
1080
- name,
1081
- description: "",
1082
- inputSchema: { type: "object" }
1083
- }));
1084
- }
1085
- return [];
1086
- }
1087
892
 
1088
893
  // src/utils/type-guards.ts
1089
894
  function isToolCallContent(content) {
@@ -1338,57 +1143,13 @@ var jsonMixProtocol = ({
1338
1143
 
1339
1144
  // src/protocols/morph-xml-protocol.ts
1340
1145
  var import_provider_utils3 = require("@ai-sdk/provider-utils");
1341
- var import_rxml = require("@ai-sdk-tool/rxml");
1342
- function getToolSchema(tools, originalSchemas, toolName) {
1343
- var _a;
1344
- const original = originalSchemas[toolName];
1345
- if (original) return original;
1346
- const fallback = (_a = tools.find((t) => t.name === toolName)) == null ? void 0 : _a.inputSchema;
1347
- return fallback;
1348
- }
1349
- function findToolCalls(text, toolNames) {
1350
- const toolCalls = [];
1351
- for (const toolName of toolNames) {
1352
- let searchIndex = 0;
1353
- while (searchIndex < text.length) {
1354
- const startTag = `<${toolName}>`;
1355
- const tagStart = text.indexOf(startTag, searchIndex);
1356
- if (tagStart === -1) break;
1357
- const remainingText = text.substring(tagStart);
1358
- const range = (0, import_rxml.findFirstTopLevelRange)(remainingText, toolName);
1359
- if (range) {
1360
- const contentStart = tagStart + startTag.length;
1361
- const contentEnd = contentStart + (range.end - range.start);
1362
- let fullTagEnd = contentEnd + `</${toolName}>`.length;
1363
- const closeHead = text.indexOf(`</${toolName}`, contentEnd);
1364
- if (closeHead === contentEnd) {
1365
- let p = closeHead + 2 + toolName.length;
1366
- while (p < text.length && /\s/.test(text[p])) p++;
1367
- if (text[p] === ">") fullTagEnd = p + 1;
1368
- }
1369
- const toolContent = text.substring(contentStart, contentEnd);
1370
- const fullSegment = text.substring(tagStart, fullTagEnd);
1371
- toolCalls.push({
1372
- toolName,
1373
- startIndex: tagStart,
1374
- endIndex: fullTagEnd,
1375
- content: toolContent,
1376
- segment: fullSegment
1377
- });
1378
- searchIndex = fullTagEnd;
1379
- } else {
1380
- searchIndex = tagStart + startTag.length;
1381
- }
1382
- }
1383
- }
1384
- return toolCalls.sort((a, b) => a.startIndex - b.startIndex);
1385
- }
1146
+ var RXML = __toESM(require("@ai-sdk-tool/rxml"), 1);
1386
1147
  var morphXmlProtocol = () => ({
1387
1148
  formatTools({ tools, toolSystemPromptTemplate }) {
1388
1149
  const toolsForPrompt = (tools || []).map((tool) => ({
1389
1150
  name: tool.name,
1390
1151
  description: tool.description,
1391
- parameters: unwrapJsonSchema(tool.inputSchema)
1152
+ parameters: RXML.unwrapJsonSchema(tool.inputSchema)
1392
1153
  }));
1393
1154
  return toolSystemPromptTemplate(JSON.stringify(toolsForPrompt));
1394
1155
  },
@@ -1404,20 +1165,19 @@ var morphXmlProtocol = () => ({
1404
1165
  } else {
1405
1166
  args = inputValue;
1406
1167
  }
1407
- return (0, import_rxml.stringify)(toolCall.toolName, args, {
1168
+ return RXML.stringify(toolCall.toolName, args, {
1408
1169
  suppressEmptyNode: false,
1409
1170
  format: false
1410
1171
  });
1411
1172
  },
1412
1173
  formatToolResponse(toolResult) {
1413
- return (0, import_rxml.stringify)("tool_response", {
1174
+ return RXML.stringify("tool_response", {
1414
1175
  tool_name: toolResult.toolName,
1415
1176
  result: toolResult.output
1416
1177
  });
1417
1178
  },
1418
1179
  parseGeneratedText({ text, tools, options }) {
1419
1180
  var _a;
1420
- const originalSchemas = (options == null ? void 0 : options.originalToolSchemas) || {};
1421
1181
  const toolNames = tools.map((t) => t.name).filter((name) => name != null);
1422
1182
  if (toolNames.length === 0) {
1423
1183
  return [{ type: "text", text }];
@@ -1433,13 +1193,11 @@ var morphXmlProtocol = () => ({
1433
1193
  }
1434
1194
  }
1435
1195
  try {
1436
- const toolSchema = getToolSchema(
1437
- tools,
1438
- originalSchemas,
1439
- toolCall.toolName
1440
- );
1441
- const parsed = (0, import_rxml.parse)(toolCall.content, toolSchema, {
1442
- onError: options == null ? void 0 : options.onError
1196
+ const toolSchema = getToolSchema(tools, toolCall.toolName);
1197
+ const parsed = RXML.parse(toolCall.content, toolSchema, {
1198
+ onError: options == null ? void 0 : options.onError,
1199
+ // Disable HTML self-closing tag behavior to allow base, meta, link etc. as regular tags
1200
+ noChildNodes: []
1443
1201
  });
1444
1202
  processedElements.push({
1445
1203
  type: "tool-call",
@@ -1471,8 +1229,8 @@ var morphXmlProtocol = () => ({
1471
1229
  return processedElements;
1472
1230
  },
1473
1231
  createStreamParser({ tools, options }) {
1474
- const originalSchemas = (options == null ? void 0 : options.originalToolSchemas) || {};
1475
1232
  const toolNames = tools.map((t) => t.name).filter((name) => name != null);
1233
+ const maxStartTagLen = toolNames.length ? Math.max(...toolNames.map((n) => `<${n}>`.length)) : 0;
1476
1234
  let buffer = "";
1477
1235
  let currentToolCall = null;
1478
1236
  let currentTextId = null;
@@ -1514,13 +1272,11 @@ var morphXmlProtocol = () => ({
1514
1272
  const toolContent = buffer.substring(0, endTagIndex);
1515
1273
  buffer = buffer.substring(endTagIndex + endTag.length);
1516
1274
  try {
1517
- const toolSchema = getToolSchema(
1518
- tools,
1519
- originalSchemas,
1520
- currentToolCall.name
1521
- );
1522
- const parsed = (0, import_rxml.parse)(toolContent, toolSchema, {
1523
- onError: options == null ? void 0 : options.onError
1275
+ const toolSchema = getToolSchema(tools, currentToolCall.name);
1276
+ const parsed = RXML.parse(toolContent, toolSchema, {
1277
+ onError: options == null ? void 0 : options.onError,
1278
+ // Disable HTML self-closing tag behavior to allow base, meta, link etc. as regular tags
1279
+ noChildNodes: []
1524
1280
  });
1525
1281
  flushText(controller);
1526
1282
  controller.enqueue({
@@ -1532,11 +1288,11 @@ var morphXmlProtocol = () => ({
1532
1288
  } catch (error) {
1533
1289
  const originalCallText = `<${currentToolCall.name}>${toolContent}${endTag}`;
1534
1290
  let message = "Could not process streaming XML tool call; emitting original text.";
1535
- if (error instanceof import_rxml.RXMLDuplicateStringTagError) {
1291
+ if (error instanceof RXML.RXMLDuplicateStringTagError) {
1536
1292
  message = `Duplicate string tags detected in streaming tool call '${currentToolCall.name}'; emitting original text.`;
1537
- } else if (error instanceof import_rxml.RXMLCoercionError) {
1293
+ } else if (error instanceof RXML.RXMLCoercionError) {
1538
1294
  message = `Failed to coerce arguments for streaming tool call '${currentToolCall.name}'; emitting original text.`;
1539
- } else if (error instanceof import_rxml.RXMLParseError) {
1295
+ } else if (error instanceof RXML.RXMLParseError) {
1540
1296
  message = `Failed to parse XML for streaming tool call '${currentToolCall.name}'; emitting original text.`;
1541
1297
  }
1542
1298
  (_a = options == null ? void 0 : options.onError) == null ? void 0 : _a.call(options, message, {
@@ -1572,6 +1328,14 @@ var morphXmlProtocol = () => ({
1572
1328
  );
1573
1329
  currentToolCall = { name: earliestToolName, content: "" };
1574
1330
  } else {
1331
+ const tail = Math.max(0, maxStartTagLen - 1);
1332
+ const safeLen = Math.max(0, buffer.length - tail);
1333
+ if (safeLen > 0) {
1334
+ const textToFlush = buffer.slice(0, safeLen);
1335
+ flushText(controller, textToFlush);
1336
+ buffer = buffer.slice(safeLen);
1337
+ continue;
1338
+ }
1575
1339
  break;
1576
1340
  }
1577
1341
  }
@@ -1596,6 +1360,48 @@ var morphXmlProtocol = () => ({
1596
1360
  return findToolCalls(text, toolNames).map((tc) => tc.segment);
1597
1361
  }
1598
1362
  });
1363
+ function getToolSchema(tools, toolName) {
1364
+ var _a;
1365
+ return (_a = tools.find((t) => t.name === toolName)) == null ? void 0 : _a.inputSchema;
1366
+ }
1367
+ function findToolCalls(text, toolNames) {
1368
+ var _a;
1369
+ const toolCalls = [];
1370
+ for (const toolName of toolNames) {
1371
+ let searchIndex = 0;
1372
+ while (searchIndex < text.length) {
1373
+ const startTag = `<${toolName}>`;
1374
+ const tagStart = text.indexOf(startTag, searchIndex);
1375
+ if (tagStart === -1) break;
1376
+ const remainingText = text.substring(tagStart);
1377
+ const range = RXML.findFirstTopLevelRange(remainingText, toolName);
1378
+ if (range) {
1379
+ const contentStart = tagStart + startTag.length;
1380
+ const contentEnd = contentStart + (range.end - range.start);
1381
+ let fullTagEnd = contentEnd + `</${toolName}>`.length;
1382
+ const closeHead = text.indexOf(`</${toolName}`, contentEnd);
1383
+ if (closeHead === contentEnd) {
1384
+ let p = closeHead + 2 + toolName.length;
1385
+ while (p < text.length && /\s/.test(text[p])) p++;
1386
+ if (text[p] === ">") fullTagEnd = p + 1;
1387
+ }
1388
+ const segment = text.substring(tagStart, fullTagEnd);
1389
+ const content = (_a = RXML.extractRawInner(segment, toolName)) != null ? _a : text.substring(contentStart, contentEnd);
1390
+ toolCalls.push({
1391
+ toolName,
1392
+ startIndex: tagStart,
1393
+ endIndex: fullTagEnd,
1394
+ content,
1395
+ segment
1396
+ });
1397
+ searchIndex = fullTagEnd;
1398
+ } else {
1399
+ searchIndex = tagStart + startTag.length;
1400
+ }
1401
+ }
1402
+ }
1403
+ return toolCalls.sort((a, b) => a.startIndex - b.startIndex);
1404
+ }
1599
1405
 
1600
1406
  // src/protocols/tool-call-protocol.ts
1601
1407
  function isProtocolFactory(protocol) {
@@ -1604,12 +1410,13 @@ function isProtocolFactory(protocol) {
1604
1410
 
1605
1411
  // src/generate-handler.ts
1606
1412
  var import_provider_utils4 = require("@ai-sdk/provider-utils");
1413
+ var RXML2 = __toESM(require("@ai-sdk-tool/rxml"), 1);
1607
1414
  async function wrapGenerate({
1608
1415
  protocol,
1609
1416
  doGenerate,
1610
1417
  params
1611
1418
  }) {
1612
- var _a, _b;
1419
+ var _a, _b, _c, _d;
1613
1420
  if (isToolChoiceActive(params)) {
1614
1421
  const result2 = await doGenerate();
1615
1422
  let parsed2 = {};
@@ -1650,6 +1457,9 @@ async function wrapGenerate({
1650
1457
  content: [toolCall]
1651
1458
  };
1652
1459
  }
1460
+ const tools = originalToolsSchema.decode(
1461
+ (_d = (_c = params.providerOptions) == null ? void 0 : _c.toolCallMiddleware) == null ? void 0 : _d.originalTools
1462
+ );
1653
1463
  const result = await doGenerate();
1654
1464
  if (result.content.length === 0) {
1655
1465
  return result;
@@ -1665,16 +1475,15 @@ async function wrapGenerate({
1665
1475
  }
1666
1476
  return protocol.parseGeneratedText({
1667
1477
  text: contentItem.text,
1668
- tools: getFunctionTools(params),
1478
+ tools,
1669
1479
  options: {
1670
1480
  ...extractOnErrorOption(params.providerOptions),
1671
1481
  ...(_a2 = params.providerOptions) == null ? void 0 : _a2.toolCallMiddleware
1672
1482
  }
1673
1483
  });
1674
1484
  });
1675
- const tools = getFunctionTools(params);
1676
1485
  const newContent = parsed.map(
1677
- (part) => coerceToolCallInput(part, tools)
1486
+ (part) => fixToolCallWithSchema(part, tools)
1678
1487
  );
1679
1488
  const debugLevel = getDebugLevel();
1680
1489
  if (debugLevel === "stream") {
@@ -1696,6 +1505,27 @@ async function wrapGenerate({
1696
1505
  content: newContent
1697
1506
  };
1698
1507
  }
1508
+ function fixToolCallWithSchema(part, tools) {
1509
+ var _a;
1510
+ if (part.type !== "tool-call") return part;
1511
+ const tc = part;
1512
+ let args = {};
1513
+ if (typeof tc.input === "string") {
1514
+ try {
1515
+ args = JSON.parse(tc.input);
1516
+ } catch (e) {
1517
+ return part;
1518
+ }
1519
+ } else if (tc.input && typeof tc.input === "object") {
1520
+ args = tc.input;
1521
+ }
1522
+ const schema = (_a = tools.find((t) => t.name === tc.toolName)) == null ? void 0 : _a.inputSchema;
1523
+ const coerced = RXML2.coerceBySchema(args, schema);
1524
+ return {
1525
+ ...part,
1526
+ input: JSON.stringify(coerced != null ? coerced : {})
1527
+ };
1528
+ }
1699
1529
 
1700
1530
  // src/stream-handler.ts
1701
1531
  var import_provider_utils5 = require("@ai-sdk/provider-utils");
@@ -1705,7 +1535,7 @@ async function wrapStream({
1705
1535
  doGenerate,
1706
1536
  params
1707
1537
  }) {
1708
- var _a;
1538
+ var _a, _b, _c;
1709
1539
  if (isToolChoiceActive(params)) {
1710
1540
  return toolChoiceStream({
1711
1541
  doGenerate,
@@ -1714,10 +1544,12 @@ async function wrapStream({
1714
1544
  }
1715
1545
  const { stream, ...rest } = await doStream();
1716
1546
  const debugLevel = getDebugLevel();
1717
- const tools = getFunctionTools(params);
1547
+ const tools = originalToolsSchema.decode(
1548
+ (_b = (_a = params.providerOptions) == null ? void 0 : _a.toolCallMiddleware) == null ? void 0 : _b.originalTools
1549
+ );
1718
1550
  const options = {
1719
1551
  ...extractOnErrorOption(params.providerOptions),
1720
- ...(_a = params.providerOptions) == null ? void 0 : _a.toolCallMiddleware
1552
+ ...(_c = params.providerOptions) == null ? void 0 : _c.toolCallMiddleware
1721
1553
  };
1722
1554
  if (debugLevel === "off") {
1723
1555
  return {
@@ -1926,10 +1758,10 @@ async function transformParams({
1926
1758
  ...params.providerOptions || {},
1927
1759
  toolCallMiddleware: {
1928
1760
  ...params.providerOptions && typeof params.providerOptions === "object" && params.providerOptions.toolCallMiddleware || {},
1929
- // INTERNAL: used by the middleware to propagate the names of custom
1930
- // function tools into downstream handlers (stream/generate) when
1931
- // providers strip or ignore `params.tools`. Not a stable public API.
1932
- toolNames: functionTools.map((t) => t.name)
1761
+ // INTERNAL: used by the middleware so downstream parsers can access
1762
+ // the original tool schemas even if providers strip `params.tools`.
1763
+ // Not a stable public API.
1764
+ originalTools: originalToolsSchema.encode(functionTools)
1933
1765
  }
1934
1766
  }
1935
1767
  };
@@ -2210,7 +2042,7 @@ When an argument is an array, write each item inside a single element on one lin
2210
2042
  Examples:
2211
2043
  <get_weather>
2212
2044
  <location>
2213
- San Fransisco
2045
+ San Francisco
2214
2046
  </location>
2215
2047
  </get_weather>`;
2216
2048
  }
@@ -2218,18 +2050,16 @@ San Fransisco
2218
2050
  // Annotate the CommonJS export names for ESM import in node:
2219
2051
  0 && (module.exports = {
2220
2052
  RJSON,
2221
- coerceBySchema,
2222
- coerceToolCallInput,
2223
2053
  createDynamicIfThenElseSchema,
2224
2054
  createToolMiddleware,
2055
+ decodeOriginalTools,
2056
+ encodeOriginalTools,
2225
2057
  escapeRegExp,
2226
2058
  extractOnErrorOption,
2227
- fixToolCallWithSchema,
2059
+ extractToolNamesFromOriginalTools,
2228
2060
  gemmaToolMiddleware,
2229
2061
  getDebugLevel,
2230
- getFunctionTools,
2231
2062
  getPotentialStartIndex,
2232
- getSchemaType,
2233
2063
  hasInputProperty,
2234
2064
  hermesToolMiddleware,
2235
2065
  isToolCallContent,
@@ -2240,7 +2070,7 @@ San Fransisco
2240
2070
  logParsedSummary,
2241
2071
  logRawChunk,
2242
2072
  morphXmlProtocol,
2243
- unwrapJsonSchema,
2073
+ originalToolsSchema,
2244
2074
  xmlToolMiddleware
2245
2075
  });
2246
2076
  //# sourceMappingURL=index.cjs.map