@jaypie/llm 1.3.7 → 1.3.8

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.
@@ -5420,11 +5420,7 @@ class Toolkit {
5420
5420
  return toolCopy;
5421
5421
  });
5422
5422
  }
5423
- async call({ name, arguments: args }) {
5424
- const tool = this._tools.find((t) => t.name === name);
5425
- if (!tool) {
5426
- throw new Error(`Tool '${name}' not found`);
5427
- }
5423
+ parseArgs(args) {
5428
5424
  let parsedArgs;
5429
5425
  try {
5430
5426
  parsedArgs = JSON.parse(args);
@@ -5435,35 +5431,53 @@ class Toolkit {
5435
5431
  catch {
5436
5432
  parsedArgs = args;
5437
5433
  }
5434
+ return parsedArgs;
5435
+ }
5436
+ /**
5437
+ * Resolve a tool's `message` (static string or function of args) without
5438
+ * calling the tool. Returns undefined when the tool is missing or defines
5439
+ * no message. Never throws; resolution errors log at warn.
5440
+ */
5441
+ async resolveMessage({ name, arguments: args, }) {
5442
+ const tool = this._tools.find((t) => t.name === name);
5443
+ if (!tool || !tool.message) {
5444
+ return undefined;
5445
+ }
5446
+ try {
5447
+ if (typeof tool.message === "string") {
5448
+ return tool.message;
5449
+ }
5450
+ const parsedArgs = this.parseArgs(args);
5451
+ if (typeof tool.message === "function") {
5452
+ return await kit.resolveValue(tool.message(parsedArgs, { name }));
5453
+ }
5454
+ log.warn("[Toolkit] Tool provided unknown message type");
5455
+ return String(tool.message);
5456
+ }
5457
+ catch (error) {
5458
+ log.warn("[Toolkit] Caught error resolving tool message");
5459
+ log.var({ error });
5460
+ return undefined;
5461
+ }
5462
+ }
5463
+ async call({ name, arguments: args, message: resolvedMessage, }) {
5464
+ const tool = this._tools.find((t) => t.name === name);
5465
+ if (!tool) {
5466
+ throw new Error(`Tool '${name}' not found`);
5467
+ }
5468
+ const parsedArgs = this.parseArgs(args);
5438
5469
  if (this.log !== false) {
5439
5470
  try {
5440
5471
  const context = {
5441
5472
  name,
5442
5473
  args: parsedArgs,
5443
5474
  };
5444
- let message;
5445
5475
  if (this.explain) {
5446
5476
  context.explanation = parsedArgs.__Explanation;
5447
5477
  }
5448
- if (tool.message) {
5449
- if (typeof tool.message === "string") {
5450
- log.trace("[Toolkit] Tool provided string message");
5451
- message = tool.message;
5452
- }
5453
- else if (typeof tool.message === "function") {
5454
- log.trace("[Toolkit] Tool provided function message");
5455
- log.trace("[Toolkit] Resolving message result");
5456
- message = await kit.resolveValue(tool.message(parsedArgs, { name }));
5457
- }
5458
- else {
5459
- log.warn("[Toolkit] Tool provided unknown message type");
5460
- message = String(tool.message);
5461
- }
5462
- }
5463
- else {
5464
- log.trace("[Toolkit] Log tool call with default message");
5465
- message = `${tool.name}:${JSON.stringify(parsedArgs)}`;
5466
- }
5478
+ const message = resolvedMessage ??
5479
+ (await this.resolveMessage({ arguments: args, name })) ??
5480
+ `${tool.name}:${JSON.stringify(parsedArgs)}`;
5467
5481
  if (typeof this.log === "function") {
5468
5482
  log.trace("[Toolkit] Log tool call with custom logger");
5469
5483
  await kit.resolveValue(this.log(message, context));
@@ -6878,10 +6892,19 @@ class OperateLoop {
6878
6892
  this.appendResponseItemsToRequest(currentProviderRequest, responseItems);
6879
6893
  // Process each tool call
6880
6894
  for (const toolCall of toolCalls) {
6895
+ // Resolved once per call; never throws (undefined when tool has no message)
6896
+ const toolMessage = await state.toolkit.resolveMessage({
6897
+ arguments: toolCall.arguments,
6898
+ name: toolCall.name,
6899
+ });
6881
6900
  try {
6882
6901
  await emitProgress({
6883
6902
  event: {
6884
- tool: { arguments: toolCall.arguments, name: toolCall.name },
6903
+ tool: {
6904
+ arguments: toolCall.arguments,
6905
+ message: toolMessage,
6906
+ name: toolCall.name,
6907
+ },
6885
6908
  turn: state.currentTurn,
6886
6909
  type: exports.LlmProgressEventType.ToolCall,
6887
6910
  },
@@ -6890,6 +6913,7 @@ class OperateLoop {
6890
6913
  // Execute beforeEachTool hook
6891
6914
  await this.hookRunnerInstance.runBeforeTool(context.hooks, {
6892
6915
  args: toolCall.arguments,
6916
+ message: toolMessage,
6893
6917
  toolName: toolCall.name,
6894
6918
  });
6895
6919
  // Call the tool inside a child tool span (no-op when disabled)
@@ -6897,6 +6921,7 @@ class OperateLoop {
6897
6921
  const result = await withLlmObsSpan({ kind: "tool", name: toolCall.name }, async () => {
6898
6922
  const result = await state.toolkit.call({
6899
6923
  arguments: toolCall.arguments,
6924
+ message: toolMessage,
6900
6925
  name: toolCall.name,
6901
6926
  });
6902
6927
  annotateLlmObs({
@@ -6917,6 +6942,7 @@ class OperateLoop {
6917
6942
  // Execute afterEachTool hook
6918
6943
  await this.hookRunnerInstance.runAfterTool(context.hooks, {
6919
6944
  args: toolCall.arguments,
6945
+ message: toolMessage,
6920
6946
  result,
6921
6947
  toolName: toolCall.name,
6922
6948
  });
@@ -6950,6 +6976,7 @@ class OperateLoop {
6950
6976
  await this.hookRunnerInstance.runOnToolError(context.hooks, {
6951
6977
  args: toolCall.arguments,
6952
6978
  error: error,
6979
+ message: toolMessage,
6953
6980
  toolName: toolCall.name,
6954
6981
  });
6955
6982
  // Set error on response
@@ -7460,10 +7487,16 @@ class StreamLoop {
7460
7487
  async *processToolCalls(toolCalls, state, context) {
7461
7488
  const log = getLogger$6();
7462
7489
  for (const toolCall of toolCalls) {
7490
+ // Resolved once per call; never throws (undefined when tool has no message)
7491
+ const toolMessage = await state.toolkit.resolveMessage({
7492
+ arguments: toolCall.arguments,
7493
+ name: toolCall.name,
7494
+ });
7463
7495
  try {
7464
7496
  // Execute beforeEachTool hook
7465
7497
  await this.hookRunnerInstance.runBeforeTool(context.hooks, {
7466
7498
  args: toolCall.arguments,
7499
+ message: toolMessage,
7467
7500
  toolName: toolCall.name,
7468
7501
  });
7469
7502
  // Call the tool inside a child tool span (no-op when disabled)
@@ -7471,6 +7504,7 @@ class StreamLoop {
7471
7504
  const result = await withLlmObsSpan({ kind: "tool", name: toolCall.name }, async () => {
7472
7505
  const result = await state.toolkit.call({
7473
7506
  arguments: toolCall.arguments,
7507
+ message: toolMessage,
7474
7508
  name: toolCall.name,
7475
7509
  });
7476
7510
  annotateLlmObs({
@@ -7483,6 +7517,7 @@ class StreamLoop {
7483
7517
  // Execute afterEachTool hook
7484
7518
  await this.hookRunnerInstance.runAfterTool(context.hooks, {
7485
7519
  args: toolCall.arguments,
7520
+ message: toolMessage,
7486
7521
  result,
7487
7522
  toolName: toolCall.name,
7488
7523
  });
@@ -7510,6 +7545,7 @@ class StreamLoop {
7510
7545
  await this.hookRunnerInstance.runOnToolError(context.hooks, {
7511
7546
  args: toolCall.arguments,
7512
7547
  error: error,
7548
+ message: toolMessage,
7513
7549
  toolName: toolCall.name,
7514
7550
  });
7515
7551
  // Yield error chunk