@voltagent/core 0.1.66 → 0.1.68

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.d.ts CHANGED
@@ -130,7 +130,7 @@ declare class ToolManager {
130
130
  /**
131
131
  * Prepare tools for text generation (includes tools from toolkits).
132
132
  */
133
- prepareToolsForGeneration(dynamicTools?: BaseTool[]): BaseTool[];
133
+ prepareToolsForGeneration(dynamicTools?: (BaseTool | Toolkit)[]): BaseTool[];
134
134
  /**
135
135
  * Get agent's tools (including those in toolkits) for API exposure.
136
136
  */
@@ -884,6 +884,11 @@ type MessageFilterOptions = {
884
884
  * Only retrieve messages with this role
885
885
  */
886
886
  role?: BaseMessage["role"];
887
+ /**
888
+ * Only retrieve messages with these types
889
+ * If not specified, all message types are returned
890
+ */
891
+ types?: Array<"text" | "tool-call" | "tool-result">;
887
892
  };
888
893
  /**
889
894
  * Conversation type
@@ -4600,6 +4605,10 @@ declare class Agent<TProvider extends {
4600
4605
  * Add step to history immediately and to conversation steps
4601
4606
  */
4602
4607
  private addStepToHistory;
4608
+ /**
4609
+ * Handle tool execution errors by creating appropriate events and steps
4610
+ */
4611
+ private handleToolError;
4603
4612
  /**
4604
4613
  * Update history entry
4605
4614
  */
package/dist/index.js CHANGED
@@ -5026,7 +5026,15 @@ var LibSQLStorage = class {
5026
5026
  async getMessages(options = {}) {
5027
5027
  await this.initialized;
5028
5028
  await debugDelay();
5029
- const { userId = "default", conversationId = "default", limit, before, after, role } = options;
5029
+ const {
5030
+ userId = "default",
5031
+ conversationId = "default",
5032
+ limit,
5033
+ before,
5034
+ after,
5035
+ role,
5036
+ types
5037
+ } = options;
5030
5038
  const messagesTableName = `${this.options.tablePrefix}_messages`;
5031
5039
  const conversationsTableName = `${this.options.tablePrefix}_conversations`;
5032
5040
  try {
@@ -5057,25 +5065,35 @@ var LibSQLStorage = class {
5057
5065
  conditions.push("m.role = ?");
5058
5066
  args.push(role);
5059
5067
  }
5068
+ if (types) {
5069
+ const placeholders = types.map(() => "?").join(", ");
5070
+ conditions.push(`m.type IN (${placeholders})`);
5071
+ args.push(...types);
5072
+ }
5060
5073
  if (conditions.length > 0) {
5061
5074
  sql += ` WHERE ${conditions.join(" AND ")}`;
5062
5075
  }
5063
- sql += " ORDER BY m.created_at ASC";
5064
5076
  if (limit && limit > 0) {
5065
- sql += " LIMIT ?";
5077
+ sql += " ORDER BY m.created_at DESC LIMIT ?";
5066
5078
  args.push(limit);
5079
+ } else {
5080
+ sql += " ORDER BY m.created_at ASC";
5067
5081
  }
5068
5082
  const result = await this.client.execute({
5069
5083
  sql,
5070
5084
  args
5071
5085
  });
5072
- return result.rows.map((row) => ({
5086
+ const messages = result.rows.map((row) => ({
5073
5087
  id: row.message_id,
5074
5088
  role: row.role,
5075
5089
  content: row.content,
5076
5090
  type: row.type,
5077
5091
  createdAt: row.created_at
5078
5092
  }));
5093
+ if (limit && limit > 0) {
5094
+ return messages.reverse();
5095
+ }
5096
+ return messages;
5079
5097
  } catch (error) {
5080
5098
  this.debug("Error getting messages:", error);
5081
5099
  throw new Error("Failed to get messages from LibSQL database");
@@ -7955,7 +7973,8 @@ var InMemoryStorage = class {
7955
7973
  limit = this.options.storageLimit,
7956
7974
  before,
7957
7975
  after,
7958
- role
7976
+ role,
7977
+ types
7959
7978
  } = options;
7960
7979
  this.debug(
7961
7980
  `Getting messages for user ${userId} and conversation ${conversationId} with options`,
@@ -7967,6 +7986,9 @@ var InMemoryStorage = class {
7967
7986
  if (role) {
7968
7987
  filteredMessages = filteredMessages.filter((m) => m.role === role);
7969
7988
  }
7989
+ if (types) {
7990
+ filteredMessages = filteredMessages.filter((m) => types.includes(m.type));
7991
+ }
7970
7992
  if (before) {
7971
7993
  filteredMessages = filteredMessages.filter(
7972
7994
  (m) => new Date(m.createdAt).getTime() < new Date(before).getTime()
@@ -7978,7 +8000,7 @@ var InMemoryStorage = class {
7978
8000
  );
7979
8001
  }
7980
8002
  filteredMessages.sort((a, b) => {
7981
- return new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime();
8003
+ return new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime();
7982
8004
  });
7983
8005
  if (limit && limit > 0 && filteredMessages.length > limit) {
7984
8006
  filteredMessages = filteredMessages.slice(-limit);
@@ -8889,7 +8911,9 @@ var MemoryManager = class {
8889
8911
  const memoryMessages = await this.conversationMemory.getMessages({
8890
8912
  userId,
8891
8913
  conversationId,
8892
- limit: contextLimit
8914
+ limit: contextLimit,
8915
+ types: ["text"]
8916
+ // Only retrieve text messages for conversation context
8893
8917
  });
8894
8918
  messages = memoryMessages.map((m) => ({
8895
8919
  role: m.role,
@@ -9459,16 +9483,10 @@ var ToolManager = class {
9459
9483
  prepareToolsForGeneration(dynamicTools) {
9460
9484
  let toolsToUse = this.getTools();
9461
9485
  if (dynamicTools?.length) {
9462
- const validDynamicTools = dynamicTools.filter(
9463
- (dt) => dt?.name && dt?.parameters && typeof dt?.execute === "function"
9464
- // Apply optional chaining
9465
- );
9466
- if (validDynamicTools.length !== dynamicTools.length) {
9467
- this.logger.warn(
9468
- "[ToolManager] Some dynamic tools provided to prepareToolsForGeneration were invalid and ignored."
9469
- );
9470
- }
9471
- toolsToUse = [...toolsToUse, ...validDynamicTools];
9486
+ const tempManager = new ToolManager([], this.logger);
9487
+ tempManager.addItems(dynamicTools);
9488
+ const dynamicToolsList = tempManager.getTools();
9489
+ toolsToUse = [...toolsToUse, ...dynamicToolsList];
9472
9490
  }
9473
9491
  return toolsToUse;
9474
9492
  }
@@ -12160,6 +12178,25 @@ ${retrieverContext}`;
12160
12178
  const baseTools = this.toolManager.prepareToolsForGeneration(
12161
12179
  allTools.length > 0 ? allTools : void 0
12162
12180
  );
12181
+ if (this.dynamicTools && resolvedTools.length > 0) {
12182
+ const allToolsForUpdate = baseTools.map((tool2) => ({
12183
+ name: tool2.name,
12184
+ description: tool2.description,
12185
+ parameters: tool2.parameters ? zodSchemaToJsonUI(tool2.parameters) : void 0
12186
+ }));
12187
+ if (historyEntryId && this.historyManager) {
12188
+ const updatedAgentSnapshot = this.getFullState();
12189
+ this.historyManager.updateEntry(historyEntryId, {
12190
+ metadata: {
12191
+ agentSnapshot: {
12192
+ ...updatedAgentSnapshot,
12193
+ tools: allToolsForUpdate
12194
+ // Include resolved tools in the snapshot
12195
+ }
12196
+ }
12197
+ });
12198
+ }
12199
+ }
12163
12200
  if (!operationContext) {
12164
12201
  this.logger.warn(
12165
12202
  "Missing operationContext in prepareTextOptions. Tool execution context might be incomplete.",
@@ -12415,6 +12452,107 @@ ${retrieverContext}`;
12415
12452
  };
12416
12453
  context.conversationSteps.push(finalStep);
12417
12454
  }
12455
+ /**
12456
+ * Handle tool execution errors by creating appropriate events and steps
12457
+ */
12458
+ async handleToolError(error, operationContext, options) {
12459
+ if (!error.toolError) {
12460
+ return;
12461
+ }
12462
+ const { userId, conversationId, internalOptions } = options;
12463
+ const { toolCallId, toolName } = error.toolError;
12464
+ try {
12465
+ const toolStartInfo = operationContext.userContext.get(`tool_${toolCallId}`) || { eventId: void 0, startTime: (/* @__PURE__ */ new Date()).toISOString() };
12466
+ const toolErrorEvent = {
12467
+ id: crypto.randomUUID(),
12468
+ name: "tool:error",
12469
+ type: "tool",
12470
+ startTime: toolStartInfo.startTime,
12471
+ endTime: (/* @__PURE__ */ new Date()).toISOString(),
12472
+ status: "error",
12473
+ level: "ERROR",
12474
+ input: null,
12475
+ output: null,
12476
+ statusMessage: {
12477
+ message: error.message,
12478
+ code: error.code,
12479
+ ...error.toolError && { toolError: error.toolError }
12480
+ },
12481
+ metadata: {
12482
+ displayName: toolName,
12483
+ id: toolName,
12484
+ agentId: this.id
12485
+ },
12486
+ traceId: operationContext.historyEntry.id,
12487
+ parentEventId: toolStartInfo.eventId
12488
+ };
12489
+ this.publishTimelineEvent(operationContext, toolErrorEvent);
12490
+ const toolErrorStep = {
12491
+ id: toolCallId,
12492
+ type: "tool_result",
12493
+ name: toolName,
12494
+ result: {
12495
+ error
12496
+ },
12497
+ content: JSON.stringify([
12498
+ {
12499
+ type: "tool-result",
12500
+ toolCallId,
12501
+ toolName,
12502
+ result: {
12503
+ error: {
12504
+ message: error.message,
12505
+ code: error.code
12506
+ }
12507
+ }
12508
+ }
12509
+ ]),
12510
+ role: "assistant"
12511
+ };
12512
+ this.addStepToHistory(toolErrorStep, operationContext);
12513
+ if (userId) {
12514
+ const onStepFinish = this.memoryManager.createStepFinishHandler(
12515
+ operationContext,
12516
+ userId,
12517
+ conversationId
12518
+ );
12519
+ await onStepFinish(toolErrorStep);
12520
+ }
12521
+ const tool2 = this.toolManager.getToolByName(toolName);
12522
+ if (tool2 && internalOptions) {
12523
+ await this.getMergedHooks(internalOptions).onToolEnd?.({
12524
+ agent: this,
12525
+ tool: tool2,
12526
+ output: void 0,
12527
+ error,
12528
+ context: operationContext
12529
+ });
12530
+ }
12531
+ const methodLogger = operationContext.logger || this.logger;
12532
+ methodLogger.error(
12533
+ buildAgentLogMessage(this.name, "toolCall" /* TOOL_CALL */, `Tool ${toolName} failed`),
12534
+ {
12535
+ event: LogEvents.TOOL_EXECUTION_FAILED,
12536
+ toolName,
12537
+ toolCallId,
12538
+ error: {
12539
+ message: error.message,
12540
+ code: error.code
12541
+ }
12542
+ }
12543
+ );
12544
+ } catch (updateError) {
12545
+ const methodLogger = operationContext.logger || this.logger;
12546
+ methodLogger.error(
12547
+ `Failed to update tool event to error status for ${toolName} (${toolCallId})`,
12548
+ {
12549
+ toolName,
12550
+ toolCallId,
12551
+ error: updateError
12552
+ }
12553
+ );
12554
+ }
12555
+ }
12418
12556
  /**
12419
12557
  * Update history entry
12420
12558
  */
@@ -13022,6 +13160,13 @@ ${retrieverContext}`;
13022
13160
  return extendedResponse;
13023
13161
  } catch (error) {
13024
13162
  const voltagentError = error;
13163
+ if (voltagentError.toolError) {
13164
+ await this.handleToolError(voltagentError, operationContext, {
13165
+ userId,
13166
+ conversationId: finalConversationId,
13167
+ internalOptions
13168
+ });
13169
+ }
13025
13170
  const agentErrorStartInfo = {
13026
13171
  startTime: operationContext.userContext.get("agent_start_time") || (/* @__PURE__ */ new Date()).toISOString(),
13027
13172
  eventId: operationContext.userContext.get("agent_start_event_id")
@@ -13527,53 +13672,11 @@ ${retrieverContext}`;
13527
13672
  },
13528
13673
  onError: async (error) => {
13529
13674
  if (error.toolError) {
13530
- const { toolCallId, toolName } = error.toolError;
13531
- try {
13532
- const toolStartInfo = operationContext.userContext.get(`tool_${toolCallId}`) || { eventId: void 0, startTime: (/* @__PURE__ */ new Date()).toISOString() };
13533
- const toolErrorEvent = {
13534
- id: crypto.randomUUID(),
13535
- name: "tool:error",
13536
- type: "tool",
13537
- startTime: toolStartInfo.startTime,
13538
- endTime: (/* @__PURE__ */ new Date()).toISOString(),
13539
- status: "error",
13540
- level: "ERROR",
13541
- input: null,
13542
- output: null,
13543
- statusMessage: {
13544
- message: error.message,
13545
- code: error.code,
13546
- ...error.toolError && { toolError: error.toolError }
13547
- },
13548
- metadata: {
13549
- displayName: toolName,
13550
- id: toolName,
13551
- agentId: this.id
13552
- },
13553
- traceId: operationContext.historyEntry.id,
13554
- parentEventId: toolStartInfo.eventId
13555
- };
13556
- this.publishTimelineEvent(operationContext, toolErrorEvent);
13557
- } catch (updateError) {
13558
- methodLogger.error(
13559
- `Failed to update tool event to error status for ${toolName} (${toolCallId})`,
13560
- {
13561
- toolName,
13562
- toolCallId,
13563
- error: updateError
13564
- }
13565
- );
13566
- }
13567
- const tool2 = this.toolManager.getToolByName(toolName);
13568
- if (tool2) {
13569
- await this.getMergedHooks(internalOptions).onToolEnd?.({
13570
- agent: this,
13571
- tool: tool2,
13572
- output: void 0,
13573
- error,
13574
- context: operationContext
13575
- });
13576
- }
13675
+ await this.handleToolError(error, operationContext, {
13676
+ userId,
13677
+ conversationId: finalConversationId,
13678
+ internalOptions
13679
+ });
13577
13680
  }
13578
13681
  const agentErrorStartInfo = {
13579
13682
  startTime: operationContext.userContext.get("agent_start_time") || (/* @__PURE__ */ new Date()).toISOString(),
@@ -14183,19 +14286,6 @@ ${retrieverContext}`;
14183
14286
  }
14184
14287
  },
14185
14288
  onError: async (error) => {
14186
- if (error.toolError) {
14187
- const { toolName } = error.toolError;
14188
- const tool2 = this.toolManager.getToolByName(toolName);
14189
- if (tool2) {
14190
- await this.getMergedHooks(internalOptions).onToolEnd?.({
14191
- agent: this,
14192
- tool: tool2,
14193
- output: void 0,
14194
- error,
14195
- context: operationContext
14196
- });
14197
- }
14198
- }
14199
14289
  const agentErrorStartInfo = {
14200
14290
  startTime: operationContext.userContext.get("agent_start_time") || (/* @__PURE__ */ new Date()).toISOString(),
14201
14291
  eventId: operationContext.userContext.get("agent_start_event_id")