@ai-sdk-tool/parser 2.1.4 → 2.1.6

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/index.js CHANGED
@@ -722,210 +722,6 @@ function stringify(obj) {
722
722
  return "null";
723
723
  }
724
724
 
725
- // src/utils/coercion.ts
726
- function unwrapJsonSchema(schema) {
727
- if (!schema || typeof schema !== "object") return schema;
728
- const s = schema;
729
- if (s.jsonSchema && typeof s.jsonSchema === "object") {
730
- return unwrapJsonSchema(s.jsonSchema);
731
- }
732
- return schema;
733
- }
734
- function getSchemaType(schema) {
735
- const unwrapped = unwrapJsonSchema(schema);
736
- if (!unwrapped || typeof unwrapped !== "object") return void 0;
737
- const t = unwrapped.type;
738
- if (typeof t === "string") return t;
739
- if (Array.isArray(t)) {
740
- const preferred = [
741
- "object",
742
- "array",
743
- "boolean",
744
- "number",
745
- "integer",
746
- "string"
747
- ];
748
- for (const p of preferred) if (t.includes(p)) return p;
749
- }
750
- const s = unwrapped;
751
- if (s && typeof s === "object" && (s.properties || s.additionalProperties)) {
752
- return "object";
753
- }
754
- if (s && typeof s === "object" && (s.items || s.prefixItems)) {
755
- return "array";
756
- }
757
- return void 0;
758
- }
759
- function coerceBySchema(value, schema) {
760
- const unwrapped = unwrapJsonSchema(schema);
761
- if (!unwrapped || typeof unwrapped !== "object") {
762
- if (typeof value === "string") {
763
- const s = value.trim();
764
- const lower = s.toLowerCase();
765
- if (lower === "true") return true;
766
- if (lower === "false") return false;
767
- if (/^-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?$/.test(s)) {
768
- const num = Number(s);
769
- if (Number.isFinite(num)) return num;
770
- }
771
- if (s.startsWith("{") && s.endsWith("}") || s.startsWith("[") && s.endsWith("]")) {
772
- try {
773
- const parsed = JSON.parse(s);
774
- return coerceBySchema(parsed, void 0);
775
- } catch (e) {
776
- }
777
- }
778
- }
779
- return value;
780
- }
781
- const schemaType = getSchemaType(unwrapped);
782
- if (typeof value === "string") {
783
- const s = value.trim();
784
- if (schemaType === "object") {
785
- try {
786
- let normalized = s.replace(/'/g, '"');
787
- normalized = normalized.replace(/^\{\s*\}$/s, "{}");
788
- const obj = JSON.parse(normalized);
789
- if (obj && typeof obj === "object" && !Array.isArray(obj)) {
790
- const props = unwrapped.properties;
791
- const out = {};
792
- for (const [k, v] of Object.entries(obj)) {
793
- const propSchema = props ? props[k] : void 0;
794
- out[k] = typeof propSchema === "boolean" ? v : coerceBySchema(v, propSchema);
795
- }
796
- return out;
797
- }
798
- } catch (e) {
799
- }
800
- }
801
- if (schemaType === "array") {
802
- try {
803
- const normalized = s.replace(/'/g, '"');
804
- const arr = JSON.parse(normalized);
805
- if (Array.isArray(arr)) {
806
- const u = unwrapped;
807
- const prefixItems = Array.isArray(
808
- u.prefixItems
809
- ) ? u.prefixItems : void 0;
810
- const itemsSchema = u.items;
811
- if (prefixItems && arr.length === prefixItems.length) {
812
- return arr.map((v, i) => coerceBySchema(v, prefixItems[i]));
813
- }
814
- return arr.map((v) => coerceBySchema(v, itemsSchema));
815
- }
816
- } catch (e) {
817
- const csv = s.includes("\n") ? s.split(/\n+/) : s.split(/,\s*/);
818
- const trimmed = csv.map((x) => x.trim()).filter((x) => x.length > 0);
819
- const u = unwrapped;
820
- const prefixItems = Array.isArray(
821
- u.prefixItems
822
- ) ? u.prefixItems : void 0;
823
- const itemsSchema = u.items;
824
- if (prefixItems && trimmed.length === prefixItems.length) {
825
- return trimmed.map((x, i) => coerceBySchema(x, prefixItems[i]));
826
- }
827
- return trimmed.map((x) => coerceBySchema(x, itemsSchema));
828
- }
829
- }
830
- }
831
- if (schemaType === "object" && value && typeof value === "object" && !Array.isArray(value)) {
832
- const out = {};
833
- const props = unwrapped.properties;
834
- for (const [k, v] of Object.entries(value)) {
835
- const propSchema = props ? props[k] : void 0;
836
- out[k] = typeof propSchema === "boolean" ? v : coerceBySchema(v, propSchema);
837
- }
838
- return out;
839
- }
840
- if (schemaType === "array") {
841
- const u = unwrapped;
842
- const itemsSchema = u.items;
843
- const prefixItems = Array.isArray(
844
- u.prefixItems
845
- ) ? u.prefixItems : void 0;
846
- if (Array.isArray(value)) {
847
- if (prefixItems && value.length === prefixItems.length) {
848
- return value.map((v, i) => coerceBySchema(v, prefixItems[i]));
849
- }
850
- return value.map((v) => coerceBySchema(v, itemsSchema));
851
- }
852
- if (value && typeof value === "object") {
853
- const maybe = value;
854
- if (Object.prototype.hasOwnProperty.call(maybe, "item")) {
855
- const items = maybe.item;
856
- const arr = Array.isArray(items) ? items : [items];
857
- if (prefixItems && arr.length === prefixItems.length) {
858
- return arr.map((v, i) => coerceBySchema(v, prefixItems[i]));
859
- }
860
- return arr.map((v) => coerceBySchema(v, itemsSchema));
861
- }
862
- const keys = Object.keys(maybe);
863
- if (keys.length === 1) {
864
- const singleKey = keys[0];
865
- const singleValue = maybe[singleKey];
866
- if (Array.isArray(singleValue)) {
867
- const coercedArray = singleValue.map(
868
- (v) => coerceBySchema(v, itemsSchema)
869
- );
870
- return coercedArray;
871
- }
872
- }
873
- if (keys.length > 0 && keys.every((k) => /^\d+$/.test(k))) {
874
- const arr = keys.sort((a, b) => Number(a) - Number(b)).map((k) => maybe[k]);
875
- if (prefixItems && arr.length === prefixItems.length) {
876
- return arr.map((v, i) => coerceBySchema(v, prefixItems[i]));
877
- }
878
- return arr.map((v) => coerceBySchema(v, itemsSchema));
879
- }
880
- }
881
- if (value == null || typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
882
- if (prefixItems && prefixItems.length > 0) {
883
- return [coerceBySchema(value, prefixItems[0])];
884
- }
885
- return [coerceBySchema(value, itemsSchema)];
886
- }
887
- }
888
- if (typeof value === "string") {
889
- const s = value.trim();
890
- if (schemaType === "boolean") {
891
- const lower = s.toLowerCase();
892
- if (lower === "true") return true;
893
- if (lower === "false") return false;
894
- }
895
- if (schemaType === "number" || schemaType === "integer") {
896
- if (/^-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?$/.test(s)) {
897
- const num = Number(s);
898
- if (Number.isFinite(num)) return num;
899
- }
900
- }
901
- }
902
- return value;
903
- }
904
- function fixToolCallWithSchema(part, tools) {
905
- var _a;
906
- if (part.type !== "tool-call") return part;
907
- const tc = part;
908
- let args = {};
909
- if (typeof tc.input === "string") {
910
- try {
911
- args = JSON.parse(tc.input);
912
- } catch (e) {
913
- return part;
914
- }
915
- } else if (tc.input && typeof tc.input === "object") {
916
- args = tc.input;
917
- }
918
- const schema = (_a = tools.find((t) => t.name === tc.toolName)) == null ? void 0 : _a.inputSchema;
919
- const coerced = coerceBySchema(args, schema);
920
- return {
921
- ...part,
922
- input: JSON.stringify(coerced != null ? coerced : {})
923
- };
924
- }
925
- function coerceToolCallInput(part, tools) {
926
- return fixToolCallWithSchema(part, tools);
927
- }
928
-
929
725
  // src/utils/debug.ts
930
726
  function normalizeBooleanString(value) {
931
727
  const normalized = value.trim().toLowerCase();
@@ -1013,33 +809,34 @@ function extractOnErrorOption(providerOptions) {
1013
809
  return void 0;
1014
810
  }
1015
811
 
1016
- // src/utils/tools.ts
812
+ // src/utils/provider-options.ts
813
+ var originalToolsSchema = {
814
+ encode: encodeOriginalTools,
815
+ decode: decodeOriginalTools
816
+ };
817
+ function encodeOriginalTools(tools) {
818
+ return (tools == null ? void 0 : tools.map((t) => ({
819
+ name: t.name,
820
+ inputSchema: JSON.stringify(t.inputSchema)
821
+ }))) || [];
822
+ }
823
+ function decodeOriginalTools(originalTools) {
824
+ const tools = (originalTools == null ? void 0 : originalTools.map(
825
+ (t) => ({
826
+ name: t.name,
827
+ inputSchema: JSON.parse(t.inputSchema)
828
+ })
829
+ )) || [];
830
+ return tools;
831
+ }
832
+ function extractToolNamesFromOriginalTools(originalTools) {
833
+ return (originalTools == null ? void 0 : originalTools.map((t) => t.name)) || [];
834
+ }
1017
835
  function isToolChoiceActive(params) {
1018
836
  var _a, _b, _c;
1019
837
  const toolChoice = (_b = (_a = params.providerOptions) == null ? void 0 : _a.toolCallMiddleware) == null ? void 0 : _b.toolChoice;
1020
838
  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"));
1021
839
  }
1022
- function getFunctionTools(params) {
1023
- var _a, _b;
1024
- const functionTools = ((_a = params.tools) != null ? _a : []).filter(
1025
- (t) => t.type === "function"
1026
- );
1027
- if (functionTools.length > 0) return functionTools;
1028
- const rawToolNames = params.providerOptions && typeof params.providerOptions === "object" && ((_b = params.providerOptions.toolCallMiddleware) == null ? void 0 : _b.toolNames) || [];
1029
- const toStringArray = (val) => Array.isArray(val) ? val.filter(
1030
- (item) => typeof item === "string"
1031
- ) : [];
1032
- const toolNames = toStringArray(rawToolNames);
1033
- if (toolNames.length > 0) {
1034
- return toolNames.map((name) => ({
1035
- type: "function",
1036
- name,
1037
- description: "",
1038
- inputSchema: { type: "object" }
1039
- }));
1040
- }
1041
- return [];
1042
- }
1043
840
 
1044
841
  // src/utils/type-guards.ts
1045
842
  function isToolCallContent(content) {
@@ -1294,64 +1091,13 @@ var jsonMixProtocol = ({
1294
1091
 
1295
1092
  // src/protocols/morph-xml-protocol.ts
1296
1093
  import { generateId as generateId3 } from "@ai-sdk/provider-utils";
1297
- import {
1298
- findFirstTopLevelRange,
1299
- parse as parseXml,
1300
- RXMLCoercionError,
1301
- RXMLDuplicateStringTagError,
1302
- RXMLParseError,
1303
- stringify as stringify2
1304
- } from "@ai-sdk-tool/rxml";
1305
- function getToolSchema(tools, originalSchemas, toolName) {
1306
- var _a;
1307
- const original = originalSchemas[toolName];
1308
- if (original) return original;
1309
- const fallback = (_a = tools.find((t) => t.name === toolName)) == null ? void 0 : _a.inputSchema;
1310
- return fallback;
1311
- }
1312
- function findToolCalls(text, toolNames) {
1313
- const toolCalls = [];
1314
- for (const toolName of toolNames) {
1315
- let searchIndex = 0;
1316
- while (searchIndex < text.length) {
1317
- const startTag = `<${toolName}>`;
1318
- const tagStart = text.indexOf(startTag, searchIndex);
1319
- if (tagStart === -1) break;
1320
- const remainingText = text.substring(tagStart);
1321
- const range = findFirstTopLevelRange(remainingText, toolName);
1322
- if (range) {
1323
- const contentStart = tagStart + startTag.length;
1324
- const contentEnd = contentStart + (range.end - range.start);
1325
- let fullTagEnd = contentEnd + `</${toolName}>`.length;
1326
- const closeHead = text.indexOf(`</${toolName}`, contentEnd);
1327
- if (closeHead === contentEnd) {
1328
- let p = closeHead + 2 + toolName.length;
1329
- while (p < text.length && /\s/.test(text[p])) p++;
1330
- if (text[p] === ">") fullTagEnd = p + 1;
1331
- }
1332
- const toolContent = text.substring(contentStart, contentEnd);
1333
- const fullSegment = text.substring(tagStart, fullTagEnd);
1334
- toolCalls.push({
1335
- toolName,
1336
- startIndex: tagStart,
1337
- endIndex: fullTagEnd,
1338
- content: toolContent,
1339
- segment: fullSegment
1340
- });
1341
- searchIndex = fullTagEnd;
1342
- } else {
1343
- searchIndex = tagStart + startTag.length;
1344
- }
1345
- }
1346
- }
1347
- return toolCalls.sort((a, b) => a.startIndex - b.startIndex);
1348
- }
1094
+ import * as RXML from "@ai-sdk-tool/rxml";
1349
1095
  var morphXmlProtocol = () => ({
1350
1096
  formatTools({ tools, toolSystemPromptTemplate }) {
1351
1097
  const toolsForPrompt = (tools || []).map((tool) => ({
1352
1098
  name: tool.name,
1353
1099
  description: tool.description,
1354
- parameters: unwrapJsonSchema(tool.inputSchema)
1100
+ parameters: RXML.unwrapJsonSchema(tool.inputSchema)
1355
1101
  }));
1356
1102
  return toolSystemPromptTemplate(JSON.stringify(toolsForPrompt));
1357
1103
  },
@@ -1367,20 +1113,19 @@ var morphXmlProtocol = () => ({
1367
1113
  } else {
1368
1114
  args = inputValue;
1369
1115
  }
1370
- return stringify2(toolCall.toolName, args, {
1116
+ return RXML.stringify(toolCall.toolName, args, {
1371
1117
  suppressEmptyNode: false,
1372
1118
  format: false
1373
1119
  });
1374
1120
  },
1375
1121
  formatToolResponse(toolResult) {
1376
- return stringify2("tool_response", {
1122
+ return RXML.stringify("tool_response", {
1377
1123
  tool_name: toolResult.toolName,
1378
1124
  result: toolResult.output
1379
1125
  });
1380
1126
  },
1381
1127
  parseGeneratedText({ text, tools, options }) {
1382
1128
  var _a;
1383
- const originalSchemas = (options == null ? void 0 : options.originalToolSchemas) || {};
1384
1129
  const toolNames = tools.map((t) => t.name).filter((name) => name != null);
1385
1130
  if (toolNames.length === 0) {
1386
1131
  return [{ type: "text", text }];
@@ -1396,13 +1141,11 @@ var morphXmlProtocol = () => ({
1396
1141
  }
1397
1142
  }
1398
1143
  try {
1399
- const toolSchema = getToolSchema(
1400
- tools,
1401
- originalSchemas,
1402
- toolCall.toolName
1403
- );
1404
- const parsed = parseXml(toolCall.content, toolSchema, {
1405
- onError: options == null ? void 0 : options.onError
1144
+ const toolSchema = getToolSchema(tools, toolCall.toolName);
1145
+ const parsed = RXML.parse(toolCall.content, toolSchema, {
1146
+ onError: options == null ? void 0 : options.onError,
1147
+ // Disable HTML self-closing tag behavior to allow base, meta, link etc. as regular tags
1148
+ noChildNodes: []
1406
1149
  });
1407
1150
  processedElements.push({
1408
1151
  type: "tool-call",
@@ -1434,8 +1177,8 @@ var morphXmlProtocol = () => ({
1434
1177
  return processedElements;
1435
1178
  },
1436
1179
  createStreamParser({ tools, options }) {
1437
- const originalSchemas = (options == null ? void 0 : options.originalToolSchemas) || {};
1438
1180
  const toolNames = tools.map((t) => t.name).filter((name) => name != null);
1181
+ const maxStartTagLen = toolNames.length ? Math.max(...toolNames.map((n) => `<${n}>`.length)) : 0;
1439
1182
  let buffer = "";
1440
1183
  let currentToolCall = null;
1441
1184
  let currentTextId = null;
@@ -1477,13 +1220,11 @@ var morphXmlProtocol = () => ({
1477
1220
  const toolContent = buffer.substring(0, endTagIndex);
1478
1221
  buffer = buffer.substring(endTagIndex + endTag.length);
1479
1222
  try {
1480
- const toolSchema = getToolSchema(
1481
- tools,
1482
- originalSchemas,
1483
- currentToolCall.name
1484
- );
1485
- const parsed = parseXml(toolContent, toolSchema, {
1486
- onError: options == null ? void 0 : options.onError
1223
+ const toolSchema = getToolSchema(tools, currentToolCall.name);
1224
+ const parsed = RXML.parse(toolContent, toolSchema, {
1225
+ onError: options == null ? void 0 : options.onError,
1226
+ // Disable HTML self-closing tag behavior to allow base, meta, link etc. as regular tags
1227
+ noChildNodes: []
1487
1228
  });
1488
1229
  flushText(controller);
1489
1230
  controller.enqueue({
@@ -1495,11 +1236,11 @@ var morphXmlProtocol = () => ({
1495
1236
  } catch (error) {
1496
1237
  const originalCallText = `<${currentToolCall.name}>${toolContent}${endTag}`;
1497
1238
  let message = "Could not process streaming XML tool call; emitting original text.";
1498
- if (error instanceof RXMLDuplicateStringTagError) {
1239
+ if (error instanceof RXML.RXMLDuplicateStringTagError) {
1499
1240
  message = `Duplicate string tags detected in streaming tool call '${currentToolCall.name}'; emitting original text.`;
1500
- } else if (error instanceof RXMLCoercionError) {
1241
+ } else if (error instanceof RXML.RXMLCoercionError) {
1501
1242
  message = `Failed to coerce arguments for streaming tool call '${currentToolCall.name}'; emitting original text.`;
1502
- } else if (error instanceof RXMLParseError) {
1243
+ } else if (error instanceof RXML.RXMLParseError) {
1503
1244
  message = `Failed to parse XML for streaming tool call '${currentToolCall.name}'; emitting original text.`;
1504
1245
  }
1505
1246
  (_a = options == null ? void 0 : options.onError) == null ? void 0 : _a.call(options, message, {
@@ -1535,6 +1276,14 @@ var morphXmlProtocol = () => ({
1535
1276
  );
1536
1277
  currentToolCall = { name: earliestToolName, content: "" };
1537
1278
  } else {
1279
+ const tail = Math.max(0, maxStartTagLen - 1);
1280
+ const safeLen = Math.max(0, buffer.length - tail);
1281
+ if (safeLen > 0) {
1282
+ const textToFlush = buffer.slice(0, safeLen);
1283
+ flushText(controller, textToFlush);
1284
+ buffer = buffer.slice(safeLen);
1285
+ continue;
1286
+ }
1538
1287
  break;
1539
1288
  }
1540
1289
  }
@@ -1559,6 +1308,48 @@ var morphXmlProtocol = () => ({
1559
1308
  return findToolCalls(text, toolNames).map((tc) => tc.segment);
1560
1309
  }
1561
1310
  });
1311
+ function getToolSchema(tools, toolName) {
1312
+ var _a;
1313
+ return (_a = tools.find((t) => t.name === toolName)) == null ? void 0 : _a.inputSchema;
1314
+ }
1315
+ function findToolCalls(text, toolNames) {
1316
+ var _a;
1317
+ const toolCalls = [];
1318
+ for (const toolName of toolNames) {
1319
+ let searchIndex = 0;
1320
+ while (searchIndex < text.length) {
1321
+ const startTag = `<${toolName}>`;
1322
+ const tagStart = text.indexOf(startTag, searchIndex);
1323
+ if (tagStart === -1) break;
1324
+ const remainingText = text.substring(tagStart);
1325
+ const range = RXML.findFirstTopLevelRange(remainingText, toolName);
1326
+ if (range) {
1327
+ const contentStart = tagStart + startTag.length;
1328
+ const contentEnd = contentStart + (range.end - range.start);
1329
+ let fullTagEnd = contentEnd + `</${toolName}>`.length;
1330
+ const closeHead = text.indexOf(`</${toolName}`, contentEnd);
1331
+ if (closeHead === contentEnd) {
1332
+ let p = closeHead + 2 + toolName.length;
1333
+ while (p < text.length && /\s/.test(text[p])) p++;
1334
+ if (text[p] === ">") fullTagEnd = p + 1;
1335
+ }
1336
+ const segment = text.substring(tagStart, fullTagEnd);
1337
+ const content = (_a = RXML.extractRawInner(segment, toolName)) != null ? _a : text.substring(contentStart, contentEnd);
1338
+ toolCalls.push({
1339
+ toolName,
1340
+ startIndex: tagStart,
1341
+ endIndex: fullTagEnd,
1342
+ content,
1343
+ segment
1344
+ });
1345
+ searchIndex = fullTagEnd;
1346
+ } else {
1347
+ searchIndex = tagStart + startTag.length;
1348
+ }
1349
+ }
1350
+ }
1351
+ return toolCalls.sort((a, b) => a.startIndex - b.startIndex);
1352
+ }
1562
1353
 
1563
1354
  // src/protocols/tool-call-protocol.ts
1564
1355
  function isProtocolFactory(protocol) {
@@ -1567,12 +1358,13 @@ function isProtocolFactory(protocol) {
1567
1358
 
1568
1359
  // src/generate-handler.ts
1569
1360
  import { generateId as generateId4 } from "@ai-sdk/provider-utils";
1361
+ import * as RXML2 from "@ai-sdk-tool/rxml";
1570
1362
  async function wrapGenerate({
1571
1363
  protocol,
1572
1364
  doGenerate,
1573
1365
  params
1574
1366
  }) {
1575
- var _a, _b;
1367
+ var _a, _b, _c, _d, _e, _f, _g, _h;
1576
1368
  if (isToolChoiceActive(params)) {
1577
1369
  const result2 = await doGenerate();
1578
1370
  let parsed2 = {};
@@ -1605,7 +1397,16 @@ async function wrapGenerate({
1605
1397
  };
1606
1398
  const debugLevelToolChoice = getDebugLevel();
1607
1399
  const originText = first && first.type === "text" ? first.text : "";
1608
- if (debugLevelToolChoice === "parse") {
1400
+ const dbg2 = (_d = (_c = params.providerOptions) == null ? void 0 : _c.toolCallMiddleware) == null ? void 0 : _d.debugSummary;
1401
+ if (dbg2) {
1402
+ dbg2.originalText = originText;
1403
+ try {
1404
+ dbg2.toolCalls = JSON.stringify([
1405
+ { toolName: toolCall.toolName, input: toolCall.input }
1406
+ ]);
1407
+ } catch (e) {
1408
+ }
1409
+ } else if (debugLevelToolChoice === "parse") {
1609
1410
  logParsedSummary({ toolCalls: [toolCall], originalText: originText });
1610
1411
  }
1611
1412
  return {
@@ -1613,6 +1414,9 @@ async function wrapGenerate({
1613
1414
  content: [toolCall]
1614
1415
  };
1615
1416
  }
1417
+ const tools = originalToolsSchema.decode(
1418
+ (_f = (_e = params.providerOptions) == null ? void 0 : _e.toolCallMiddleware) == null ? void 0 : _f.originalTools
1419
+ );
1616
1420
  const result = await doGenerate();
1617
1421
  if (result.content.length === 0) {
1618
1422
  return result;
@@ -1628,30 +1432,41 @@ async function wrapGenerate({
1628
1432
  }
1629
1433
  return protocol.parseGeneratedText({
1630
1434
  text: contentItem.text,
1631
- tools: getFunctionTools(params),
1435
+ tools,
1632
1436
  options: {
1633
1437
  ...extractOnErrorOption(params.providerOptions),
1634
1438
  ...(_a2 = params.providerOptions) == null ? void 0 : _a2.toolCallMiddleware
1635
1439
  }
1636
1440
  });
1637
1441
  });
1638
- const tools = getFunctionTools(params);
1639
1442
  const newContent = parsed.map(
1640
- (part) => coerceToolCallInput(part, tools)
1443
+ (part) => fixToolCallWithSchema(part, tools)
1641
1444
  );
1642
1445
  const debugLevel = getDebugLevel();
1643
1446
  if (debugLevel === "stream") {
1644
1447
  newContent.forEach((part) => logParsedChunk(part));
1645
1448
  }
1646
- if (debugLevel === "parse") {
1647
- const allText = result.content.filter(
1648
- (c) => c.type === "text"
1649
- ).map((c) => c.text).join("\n\n");
1650
- const segments = protocol.extractToolCallSegments ? protocol.extractToolCallSegments({ text: allText, tools }) : [];
1651
- const originalText = segments.join("\n\n");
1652
- const toolCalls = newContent.filter(
1653
- (p) => p.type === "tool-call"
1654
- );
1449
+ const allText = result.content.filter(
1450
+ (c) => c.type === "text"
1451
+ ).map((c) => c.text).join("\n\n");
1452
+ const segments = protocol.extractToolCallSegments ? protocol.extractToolCallSegments({ text: allText, tools }) : [];
1453
+ const originalText = segments.join("\n\n");
1454
+ const toolCalls = newContent.filter(
1455
+ (p) => p.type === "tool-call"
1456
+ );
1457
+ const dbg = (_h = (_g = params.providerOptions) == null ? void 0 : _g.toolCallMiddleware) == null ? void 0 : _h.debugSummary;
1458
+ if (dbg) {
1459
+ dbg.originalText = originalText;
1460
+ try {
1461
+ dbg.toolCalls = JSON.stringify(
1462
+ toolCalls.map((tc) => ({
1463
+ toolName: tc.toolName,
1464
+ input: tc.input
1465
+ }))
1466
+ );
1467
+ } catch (e) {
1468
+ }
1469
+ } else if (debugLevel === "parse") {
1655
1470
  logParsedSummary({ toolCalls, originalText });
1656
1471
  }
1657
1472
  return {
@@ -1659,6 +1474,27 @@ async function wrapGenerate({
1659
1474
  content: newContent
1660
1475
  };
1661
1476
  }
1477
+ function fixToolCallWithSchema(part, tools) {
1478
+ var _a;
1479
+ if (part.type !== "tool-call") return part;
1480
+ const tc = part;
1481
+ let args = {};
1482
+ if (typeof tc.input === "string") {
1483
+ try {
1484
+ args = JSON.parse(tc.input);
1485
+ } catch (e) {
1486
+ return part;
1487
+ }
1488
+ } else if (tc.input && typeof tc.input === "object") {
1489
+ args = tc.input;
1490
+ }
1491
+ const schema = (_a = tools.find((t) => t.name === tc.toolName)) == null ? void 0 : _a.inputSchema;
1492
+ const coerced = RXML2.coerceBySchema(args, schema);
1493
+ return {
1494
+ ...part,
1495
+ input: JSON.stringify(coerced != null ? coerced : {})
1496
+ };
1497
+ }
1662
1498
 
1663
1499
  // src/stream-handler.ts
1664
1500
  import { generateId as generateId5 } from "@ai-sdk/provider-utils";
@@ -1668,7 +1504,7 @@ async function wrapStream({
1668
1504
  doGenerate,
1669
1505
  params
1670
1506
  }) {
1671
- var _a;
1507
+ var _a, _b, _c;
1672
1508
  if (isToolChoiceActive(params)) {
1673
1509
  return toolChoiceStream({
1674
1510
  doGenerate,
@@ -1677,10 +1513,12 @@ async function wrapStream({
1677
1513
  }
1678
1514
  const { stream, ...rest } = await doStream();
1679
1515
  const debugLevel = getDebugLevel();
1680
- const tools = getFunctionTools(params);
1516
+ const tools = originalToolsSchema.decode(
1517
+ (_b = (_a = params.providerOptions) == null ? void 0 : _a.toolCallMiddleware) == null ? void 0 : _b.originalTools
1518
+ );
1681
1519
  const options = {
1682
1520
  ...extractOnErrorOption(params.providerOptions),
1683
- ...(_a = params.providerOptions) == null ? void 0 : _a.toolCallMiddleware
1521
+ ...(_c = params.providerOptions) == null ? void 0 : _c.toolCallMiddleware
1684
1522
  };
1685
1523
  if (debugLevel === "off") {
1686
1524
  return {
@@ -1750,6 +1588,7 @@ async function wrapStream({
1750
1588
  transform: /* @__PURE__ */ (() => {
1751
1589
  const parsedToolCalls = [];
1752
1590
  return (part, controller) => {
1591
+ var _a2, _b2;
1753
1592
  if (part.type === "tool-call") {
1754
1593
  parsedToolCalls.push(part);
1755
1594
  }
@@ -1760,10 +1599,27 @@ async function wrapStream({
1760
1599
  tools
1761
1600
  }) : [];
1762
1601
  const origin = segments.join("\n\n");
1763
- logParsedSummary({
1764
- toolCalls: parsedToolCalls,
1765
- originalText: origin
1766
- });
1602
+ const dbg = (_b2 = (_a2 = params.providerOptions) == null ? void 0 : _a2.toolCallMiddleware) == null ? void 0 : _b2.debugSummary;
1603
+ if (dbg) {
1604
+ dbg.originalText = origin;
1605
+ try {
1606
+ const toolCallParts = parsedToolCalls.filter(
1607
+ (p) => p.type === "tool-call"
1608
+ );
1609
+ dbg.toolCalls = JSON.stringify(
1610
+ toolCallParts.map((tc) => ({
1611
+ toolName: tc.toolName,
1612
+ input: tc.input
1613
+ }))
1614
+ );
1615
+ } catch (e) {
1616
+ }
1617
+ } else {
1618
+ logParsedSummary({
1619
+ toolCalls: parsedToolCalls,
1620
+ originalText: origin
1621
+ });
1622
+ }
1767
1623
  } catch (e) {
1768
1624
  }
1769
1625
  }
@@ -1889,10 +1745,10 @@ async function transformParams({
1889
1745
  ...params.providerOptions || {},
1890
1746
  toolCallMiddleware: {
1891
1747
  ...params.providerOptions && typeof params.providerOptions === "object" && params.providerOptions.toolCallMiddleware || {},
1892
- // INTERNAL: used by the middleware to propagate the names of custom
1893
- // function tools into downstream handlers (stream/generate) when
1894
- // providers strip or ignore `params.tools`. Not a stable public API.
1895
- toolNames: functionTools.map((t) => t.name)
1748
+ // INTERNAL: used by the middleware so downstream parsers can access
1749
+ // the original tool schemas even if providers strip `params.tools`.
1750
+ // Not a stable public API.
1751
+ originalTools: originalToolsSchema.encode(functionTools)
1896
1752
  }
1897
1753
  }
1898
1754
  };
@@ -2173,25 +2029,23 @@ When an argument is an array, write each item inside a single element on one lin
2173
2029
  Examples:
2174
2030
  <get_weather>
2175
2031
  <location>
2176
- San Fransisco
2032
+ San Francisco
2177
2033
  </location>
2178
2034
  </get_weather>`;
2179
2035
  }
2180
2036
  });
2181
2037
  export {
2182
2038
  robust_json_exports as RJSON,
2183
- coerceBySchema,
2184
- coerceToolCallInput,
2185
2039
  createDynamicIfThenElseSchema,
2186
2040
  createToolMiddleware,
2041
+ decodeOriginalTools,
2042
+ encodeOriginalTools,
2187
2043
  escapeRegExp,
2188
2044
  extractOnErrorOption,
2189
- fixToolCallWithSchema,
2045
+ extractToolNamesFromOriginalTools,
2190
2046
  gemmaToolMiddleware,
2191
2047
  getDebugLevel,
2192
- getFunctionTools,
2193
2048
  getPotentialStartIndex,
2194
- getSchemaType,
2195
2049
  hasInputProperty,
2196
2050
  hermesToolMiddleware,
2197
2051
  isToolCallContent,
@@ -2202,7 +2056,7 @@ export {
2202
2056
  logParsedSummary,
2203
2057
  logRawChunk,
2204
2058
  morphXmlProtocol,
2205
- unwrapJsonSchema,
2059
+ originalToolsSchema,
2206
2060
  xmlToolMiddleware
2207
2061
  };
2208
2062
  //# sourceMappingURL=index.js.map