@ai-sdk-tool/parser 2.0.11 → 2.0.13

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
@@ -1,33 +1,11 @@
1
- "use strict";
2
1
  var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
2
  var __export = (target, all) => {
7
3
  for (var name in all)
8
4
  __defProp(target, name, { get: all[name], enumerable: true });
9
5
  };
10
- var __copyProps = (to, from, except, desc) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
12
- for (let key of __getOwnPropNames(from))
13
- if (!__hasOwnProp.call(to, key) && key !== except)
14
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
- }
16
- return to;
17
- };
18
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
-
20
- // src/index.ts
21
- var index_exports = {};
22
- __export(index_exports, {
23
- createToolMiddleware: () => createToolMiddleware,
24
- gemmaToolMiddleware: () => gemmaToolMiddleware,
25
- hermesToolMiddleware: () => hermesToolMiddleware
26
- });
27
- module.exports = __toCommonJS(index_exports);
28
6
 
29
7
  // src/tool-call-middleware.ts
30
- var import_provider_utils2 = require("@ai-sdk/provider-utils");
8
+ import { generateId as generateId2 } from "@ai-sdk/provider-utils";
31
9
 
32
10
  // src/utils/conv-tool-prompt.ts
33
11
  function convertToolPrompt({
@@ -356,15 +334,15 @@ function makeTokenSpecs(relaxed) {
356
334
  { re: /^(?:true|false|null)/, f: fKeyword },
357
335
  // Keywords
358
336
  // Number: optional sign, digits, optional decimal part, optional exponent
359
- { re: /^\-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?/, f: fNumber },
337
+ { re: /^-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?/, f: fNumber },
360
338
  // String: double-quoted, handles escapes
361
- { re: /^"(?:[^"\\]|\\["bnrtf\\\/]|\\u[0-9a-fA-F]{4})*"/, f: fStringDouble }
339
+ { re: /^"(?:[^"\\]|\\["bnrtf\\/]|\\u[0-9a-fA-F]{4})*"/, f: fStringDouble }
362
340
  ];
363
341
  if (relaxed) {
364
342
  tokenSpecs = tokenSpecs.concat([
365
343
  // Single-quoted strings
366
344
  {
367
- re: /^'((?:[^'\\]|\\['bnrtf\\\/]|\\u[0-9a-fA-F]{4})*)'/,
345
+ re: /^'((?:[^'\\]|\\['bnrtf\\/]|\\u[0-9a-fA-F]{4})*)'/,
368
346
  f: fStringSingle
369
347
  },
370
348
  // Single-line comments (// ...)
@@ -373,7 +351,7 @@ function makeTokenSpecs(relaxed) {
373
351
  { re: /^\/\*[\s\S]*?\*\//, f: fComment },
374
352
  // Unquoted identifiers (treated as strings)
375
353
  // Allows letters, numbers, _, -, +, ., *, ?, !, |, &, %, ^, /, #, \
376
- { re: /^[$a-zA-Z0-9_\-+\.\*\?!\|&%\^\/#\\]+/, f: fIdentifier }
354
+ { re: /^[$a-zA-Z0-9_\-+.*?!|&%^/#\\]+/, f: fIdentifier }
377
355
  // Note: The order matters here. Identifiers are checked after keywords/numbers.
378
356
  ]);
379
357
  }
@@ -636,7 +614,7 @@ function parseMany(tokens, state, result, opts) {
636
614
  switch (token.type) {
637
615
  case opts.endSymbol:
638
616
  return result;
639
- case ",":
617
+ case ",": {
640
618
  const nextToken = tokens[state.pos];
641
619
  if (state.tolerant && nextToken && nextToken.type === opts.endSymbol) {
642
620
  raiseError(state, token, `Trailing comma before '${opts.endSymbol}'`);
@@ -645,6 +623,7 @@ function parseMany(tokens, state, result, opts) {
645
623
  }
646
624
  opts.elementParser(tokens, state, result);
647
625
  break;
626
+ }
648
627
  // Default case is only reachable in tolerant mode recovery above
649
628
  default:
650
629
  opts.elementParser(tokens, state, result);
@@ -713,6 +692,7 @@ function parseAny(tokens, state, end = false) {
713
692
  return ret;
714
693
  }
715
694
  function parse(text, optsOrReviver) {
695
+ var _a;
716
696
  let options = {};
717
697
  if (typeof optsOrReviver === "function") {
718
698
  options.reviver = optsOrReviver;
@@ -734,7 +714,7 @@ function parse(text, optsOrReviver) {
734
714
  }
735
715
  options.tolerant = options.tolerant || options.warnings || false;
736
716
  options.warnings = options.warnings || false;
737
- options.duplicate = options.duplicate || false;
717
+ options.duplicate = (_a = options.duplicate) != null ? _a : false;
738
718
  if (!options.relaxed && !options.warnings && !options.tolerant) {
739
719
  if (!options.duplicate) {
740
720
  } else {
@@ -752,8 +732,8 @@ function parse(text, optsOrReviver) {
752
732
  pos: 0,
753
733
  reviver: options.reviver,
754
734
  tolerant: options.tolerant,
755
- duplicate: !options.duplicate,
756
- // Internal state: true means *check* for duplicates
735
+ duplicate: options.duplicate,
736
+ // true = allow duplicate keys, false = reject duplicates
757
737
  warnings: []
758
738
  };
759
739
  return parseAny(tokens, state, true);
@@ -774,8 +754,8 @@ function parse(text, optsOrReviver) {
774
754
  reviver: options.reviver,
775
755
  tolerant: options.tolerant || false,
776
756
  // Ensure boolean
777
- duplicate: !options.duplicate,
778
- // true = check duplicates
757
+ duplicate: options.duplicate,
758
+ // true = allow duplicate keys, false = reject duplicates
779
759
  warnings: []
780
760
  };
781
761
  return parseAny(tokens, state, true);
@@ -812,12 +792,13 @@ function stringify(obj) {
812
792
  }
813
793
 
814
794
  // src/stream-handler.ts
815
- var import_provider_utils = require("@ai-sdk/provider-utils");
795
+ import { generateId } from "@ai-sdk/provider-utils";
816
796
  async function normalToolStream({
817
797
  doStream,
818
798
  toolCallTag,
819
799
  toolCallEndTag
820
800
  }) {
801
+ var _a;
821
802
  const { stream, ...rest } = await doStream();
822
803
  let isFirstToolCall = true;
823
804
  let isFirstText = true;
@@ -831,6 +812,25 @@ async function normalToolStream({
831
812
  const transformStream = new TransformStream({
832
813
  transform(chunk, controller) {
833
814
  if (chunk.type === "finish") {
815
+ if (isToolCall && (buffer.length > 0 || toolCallIndex >= 0 && toolCallBuffer[toolCallIndex])) {
816
+ if (!currentTextId) {
817
+ currentTextId = generateId();
818
+ controller.enqueue({
819
+ type: "text-start",
820
+ id: currentTextId
821
+ });
822
+ hasEmittedTextStart = true;
823
+ }
824
+ const incompleteContent = (toolCallBuffer[toolCallIndex] || "") + buffer;
825
+ controller.enqueue({
826
+ type: "text-delta",
827
+ id: currentTextId,
828
+ delta: toolCallTag + incompleteContent
829
+ });
830
+ if (toolCallIndex >= 0) {
831
+ toolCallBuffer = toolCallBuffer.slice(0, toolCallIndex);
832
+ }
833
+ }
834
834
  if (currentTextId && hasEmittedTextStart) {
835
835
  controller.enqueue({
836
836
  type: "text-end",
@@ -845,13 +845,13 @@ async function normalToolStream({
845
845
  const parsedToolCall = relaxed_json_exports.parse(toolCall);
846
846
  controller.enqueue({
847
847
  type: "tool-call",
848
- toolCallId: (0, import_provider_utils.generateId)(),
848
+ toolCallId: generateId(),
849
849
  toolName: parsedToolCall.name,
850
850
  input: JSON.stringify(parsedToolCall.arguments)
851
851
  });
852
852
  } catch (e) {
853
853
  console.error(`Error parsing tool call: ${toolCall}`, e);
854
- const errorId = (0, import_provider_utils.generateId)();
854
+ const errorId = generateId();
855
855
  controller.enqueue({
856
856
  type: "text-start",
857
857
  id: errorId
@@ -859,7 +859,7 @@ async function normalToolStream({
859
859
  controller.enqueue({
860
860
  type: "text-delta",
861
861
  id: errorId,
862
- delta: `Failed to parse tool call: ${e}`
862
+ delta: `${toolCallTag}${toolCall}${toolCallEndTag}`
863
863
  });
864
864
  controller.enqueue({
865
865
  type: "text-end",
@@ -876,7 +876,7 @@ async function normalToolStream({
876
876
  }
877
877
  buffer += chunk.delta;
878
878
  function publish(text) {
879
- if (text.length > 0) {
879
+ if (text.length > 0 || isToolCall) {
880
880
  const prefix = afterSwitch && (isToolCall ? !isFirstToolCall : !isFirstText) ? "\n" : "";
881
881
  if (isToolCall) {
882
882
  if (currentTextId && hasEmittedTextStart) {
@@ -891,9 +891,9 @@ async function normalToolStream({
891
891
  toolCallBuffer[toolCallIndex] = "";
892
892
  }
893
893
  toolCallBuffer[toolCallIndex] += text;
894
- } else {
894
+ } else if (text.length > 0) {
895
895
  if (!currentTextId) {
896
- currentTextId = (0, import_provider_utils.generateId)();
896
+ currentTextId = generateId();
897
897
  controller.enqueue({
898
898
  type: "text-start",
899
899
  id: currentTextId
@@ -922,39 +922,44 @@ async function normalToolStream({
922
922
  buffer = "";
923
923
  break;
924
924
  }
925
- publish(buffer.slice(0, startIndex));
926
925
  const foundFullMatch = startIndex + nextTag.length <= buffer.length;
927
926
  if (foundFullMatch) {
927
+ publish(buffer.slice(0, startIndex));
928
928
  buffer = buffer.slice(startIndex + nextTag.length);
929
929
  toolCallIndex++;
930
930
  isToolCall = !isToolCall;
931
931
  afterSwitch = true;
932
932
  } else {
933
- buffer = buffer.slice(startIndex);
934
933
  break;
935
934
  }
936
935
  } while (true);
937
936
  }
938
937
  });
939
938
  return {
940
- stream: stream.pipeThrough(transformStream),
939
+ stream: (_a = stream == null ? void 0 : stream.pipeThrough(transformStream)) != null ? _a : new ReadableStream(),
941
940
  ...rest
942
941
  };
943
942
  }
944
943
  async function toolChoiceStream({
945
944
  doGenerate
946
945
  }) {
946
+ var _a;
947
947
  const result = await doGenerate();
948
- const toolJson = result.content[0].type === "text" ? JSON.parse(result.content[0].text) : {};
948
+ const toolJson = (result == null ? void 0 : result.content) && result.content.length > 0 && ((_a = result.content[0]) == null ? void 0 : _a.type) === "text" ? JSON.parse(result.content[0].text) : {};
949
949
  const toolCallChunk = {
950
950
  type: "tool-call",
951
- toolCallId: (0, import_provider_utils.generateId)(),
952
- toolName: toolJson.name,
951
+ toolCallId: generateId(),
952
+ toolName: toolJson.name || "unknown",
953
953
  input: JSON.stringify(toolJson.arguments || {})
954
954
  };
955
955
  const finishChunk = {
956
956
  type: "finish",
957
- usage: result.usage,
957
+ usage: (result == null ? void 0 : result.usage) || // TODO: If possible, try to return a certain amount of LLM usage.
958
+ {
959
+ inputTokens: 0,
960
+ outputTokens: 0,
961
+ totalTokens: 0
962
+ },
958
963
  finishReason: "tool-calls"
959
964
  };
960
965
  const stream = new ReadableStream({
@@ -965,8 +970,8 @@ async function toolChoiceStream({
965
970
  }
966
971
  });
967
972
  return {
968
- request: result.request,
969
- response: result.response,
973
+ request: (result == null ? void 0 : result.request) || {},
974
+ response: (result == null ? void 0 : result.response) || {},
970
975
  stream
971
976
  };
972
977
  }
@@ -1012,8 +1017,8 @@ function createToolMiddleware({
1012
1017
  {
1013
1018
  type: "tool-call",
1014
1019
  toolCallType: "function",
1015
- toolCallId: (0, import_provider_utils2.generateId)(),
1016
- toolName: toolJson.name,
1020
+ toolCallId: generateId2(),
1021
+ toolName: toolJson.name || "unknown",
1017
1022
  input: JSON.stringify(toolJson.arguments || {})
1018
1023
  }
1019
1024
  ]
@@ -1044,7 +1049,7 @@ function createToolMiddleware({
1044
1049
  }
1045
1050
  return {
1046
1051
  type: "tool-call",
1047
- toolCallId: (0, import_provider_utils2.generateId)(),
1052
+ toolCallId: generateId2(),
1048
1053
  toolName: parsedToolCall.name,
1049
1054
  // Ensure args is always a JSON string
1050
1055
  input: typeof parsedToolCall.arguments === "string" ? parsedToolCall.arguments : JSON.stringify(parsedToolCall.arguments)
@@ -1122,7 +1127,7 @@ function createToolMiddleware({
1122
1127
  if (((_b = params.toolChoice) == null ? void 0 : _b.type) === "tool") {
1123
1128
  const selectedToolName = params.toolChoice.toolName;
1124
1129
  const selectedTool = (_c = params.tools) == null ? void 0 : _c.find(
1125
- (tool) => tool.name === selectedToolName
1130
+ (tool) => tool.type === "function" ? tool.name === selectedToolName : tool.id === selectedToolName
1126
1131
  );
1127
1132
  if (!selectedTool) {
1128
1133
  throw new Error(
@@ -1186,7 +1191,7 @@ function createToolMiddleware({
1186
1191
  var gemmaToolMiddleware = createToolMiddleware({
1187
1192
  toolSystemPromptTemplate(tools) {
1188
1193
  return `You have access to functions. If you decide to invoke any of the function(s),
1189
- you MUST put it in the format of
1194
+ you MUST put it in the format of markdown code fence block with the language name of tool_call , e.g.
1190
1195
  \`\`\`tool_call
1191
1196
  {'name': <function-name>, 'arguments': <args-dict>}
1192
1197
  \`\`\`
@@ -1194,7 +1199,8 @@ You SHOULD NOT include any other text in the response if you call a function
1194
1199
  ${tools}`;
1195
1200
  },
1196
1201
  toolCallTag: "```tool_call\n",
1197
- toolCallEndTag: "```",
1202
+ toolCallEndTag: "\n``",
1203
+ // two backticks are more common in gemma output
1198
1204
  toolResponseTag: "```tool_response\n",
1199
1205
  toolResponseEndTag: "\n```"
1200
1206
  });
@@ -1216,10 +1222,9 @@ For each function call return a json object with function name and arguments wit
1216
1222
  toolResponseTag: "<tool_response>",
1217
1223
  toolResponseEndTag: "</tool_response>"
1218
1224
  });
1219
- // Annotate the CommonJS export names for ESM import in node:
1220
- 0 && (module.exports = {
1225
+ export {
1221
1226
  createToolMiddleware,
1222
1227
  gemmaToolMiddleware,
1223
1228
  hermesToolMiddleware
1224
- });
1229
+ };
1225
1230
  //# sourceMappingURL=index.js.map