@voltagent/core 2.6.1 → 2.6.3

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.mts CHANGED
@@ -9330,6 +9330,9 @@ declare class Agent {
9330
9330
  private getConversationBuffer;
9331
9331
  private getMemoryPersistQueue;
9332
9332
  private ensureStreamingResponseMessageId;
9333
+ private getOrCreateStepResponseMessageId;
9334
+ private getStepResponseMessageFingerprints;
9335
+ private normalizeStepResponseMessages;
9333
9336
  private flushPendingMessagesOnError;
9334
9337
  /**
9335
9338
  * Get contextual logger with parent tracking
@@ -15908,6 +15911,7 @@ declare class VoltAgent {
15908
15911
  private readonly ensureEnvironmentBinding;
15909
15912
  private readonly triggerRegistry;
15910
15913
  private readonly agentRefs;
15914
+ private lastServerlessRemoteConfig?;
15911
15915
  readonly ready: Promise<void>;
15912
15916
  initError?: unknown;
15913
15917
  degraded: boolean;
@@ -15916,6 +15920,8 @@ declare class VoltAgent {
15916
15920
  private ensureEnvironment;
15917
15921
  private autoConfigureVoltOpsClientFromEnv;
15918
15922
  private syncServerlessObservabilityRemote;
15923
+ private isSameServerlessRemoteConfig;
15924
+ private areHeaderRecordsEqual;
15919
15925
  /**
15920
15926
  * Setup graceful shutdown handlers
15921
15927
  */
package/dist/index.d.ts CHANGED
@@ -9330,6 +9330,9 @@ declare class Agent {
9330
9330
  private getConversationBuffer;
9331
9331
  private getMemoryPersistQueue;
9332
9332
  private ensureStreamingResponseMessageId;
9333
+ private getOrCreateStepResponseMessageId;
9334
+ private getStepResponseMessageFingerprints;
9335
+ private normalizeStepResponseMessages;
9333
9336
  private flushPendingMessagesOnError;
9334
9337
  /**
9335
9338
  * Get contextual logger with parent tracking
@@ -15908,6 +15911,7 @@ declare class VoltAgent {
15908
15911
  private readonly ensureEnvironmentBinding;
15909
15912
  private readonly triggerRegistry;
15910
15913
  private readonly agentRefs;
15914
+ private lastServerlessRemoteConfig?;
15911
15915
  readonly ready: Promise<void>;
15912
15916
  initError?: unknown;
15913
15917
  degraded: boolean;
@@ -15916,6 +15920,8 @@ declare class VoltAgent {
15916
15920
  private ensureEnvironment;
15917
15921
  private autoConfigureVoltOpsClientFromEnv;
15918
15922
  private syncServerlessObservabilityRemote;
15923
+ private isSameServerlessRemoteConfig;
15924
+ private areHeaderRecordsEqual;
15919
15925
  /**
15920
15926
  * Setup graceful shutdown handlers
15921
15927
  */
package/dist/index.js CHANGED
@@ -29966,6 +29966,7 @@ var STEP_PERSIST_COUNT_KEY = Symbol("persistedStepCount");
29966
29966
  var ABORT_LISTENER_ATTACHED_KEY = Symbol("abortListenerAttached");
29967
29967
  var MIDDLEWARE_RETRY_FEEDBACK_KEY = Symbol("middlewareRetryFeedback");
29968
29968
  var STREAM_RESPONSE_MESSAGE_ID_KEY = Symbol("streamResponseMessageId");
29969
+ var STEP_RESPONSE_MESSAGE_FINGERPRINTS_KEY = Symbol("stepResponseMessageFingerprints");
29969
29970
  var DEFAULT_FEEDBACK_KEY = "satisfaction";
29970
29971
  var DEFAULT_CONVERSATION_TITLE_PROMPT = [
29971
29972
  "You generate concise titles for new conversations.",
@@ -32416,6 +32417,7 @@ Metadata: ${(0, import_utils33.safeStringify)(metadata)}`;
32416
32417
  oc.systemContext.delete("conversationSteps");
32417
32418
  oc.systemContext.delete("bailedResult");
32418
32419
  oc.systemContext.delete(STREAM_RESPONSE_MESSAGE_ID_KEY);
32420
+ oc.systemContext.delete(STEP_RESPONSE_MESSAGE_FINGERPRINTS_KEY);
32419
32421
  oc.conversationSteps = [];
32420
32422
  oc.output = void 0;
32421
32423
  }
@@ -32440,20 +32442,56 @@ Metadata: ${(0, import_utils33.safeStringify)(metadata)}`;
32440
32442
  return queue;
32441
32443
  }
32442
32444
  async ensureStreamingResponseMessageId(oc, buffer) {
32443
- const existing = oc.systemContext.get(STREAM_RESPONSE_MESSAGE_ID_KEY);
32444
- if (typeof existing === "string" && existing.trim().length > 0) {
32445
- return existing;
32446
- }
32447
- const messageId = (0, import_ai7.generateId)();
32445
+ const messageId = this.getOrCreateStepResponseMessageId(oc);
32448
32446
  const placeholder = {
32449
32447
  id: messageId,
32450
32448
  role: "assistant",
32451
32449
  parts: []
32452
32450
  };
32453
32451
  buffer.ingestUIMessages([placeholder], false);
32452
+ return messageId;
32453
+ }
32454
+ getOrCreateStepResponseMessageId(oc) {
32455
+ const existing = oc.systemContext.get(STREAM_RESPONSE_MESSAGE_ID_KEY);
32456
+ if (typeof existing === "string" && existing.trim().length > 0) {
32457
+ return existing;
32458
+ }
32459
+ const messageId = (0, import_ai7.generateId)();
32454
32460
  oc.systemContext.set(STREAM_RESPONSE_MESSAGE_ID_KEY, messageId);
32455
32461
  return messageId;
32456
32462
  }
32463
+ getStepResponseMessageFingerprints(oc) {
32464
+ const existing = oc.systemContext.get(STEP_RESPONSE_MESSAGE_FINGERPRINTS_KEY);
32465
+ if (existing instanceof Set) {
32466
+ return existing;
32467
+ }
32468
+ const fingerprints = /* @__PURE__ */ new Set();
32469
+ oc.systemContext.set(STEP_RESPONSE_MESSAGE_FINGERPRINTS_KEY, fingerprints);
32470
+ return fingerprints;
32471
+ }
32472
+ normalizeStepResponseMessages(oc, responseMessages) {
32473
+ if (!responseMessages?.length) {
32474
+ return void 0;
32475
+ }
32476
+ const fallbackAssistantMessageId = this.getOrCreateStepResponseMessageId(oc);
32477
+ const fingerprints = this.getStepResponseMessageFingerprints(oc);
32478
+ const normalized = [];
32479
+ for (const responseMessage of responseMessages) {
32480
+ const normalizedMessage = responseMessage.role === "assistant" ? { ...responseMessage, id: fallbackAssistantMessageId } : responseMessage;
32481
+ const fingerprintMessageId = normalizedMessage.role === "assistant" ? fallbackAssistantMessageId : normalizedMessage.id ?? null;
32482
+ const fingerprint = (0, import_utils33.safeStringify)({
32483
+ role: normalizedMessage.role,
32484
+ id: fingerprintMessageId,
32485
+ content: normalizedMessage.content
32486
+ });
32487
+ if (fingerprints.has(fingerprint)) {
32488
+ continue;
32489
+ }
32490
+ fingerprints.add(fingerprint);
32491
+ normalized.push(normalizedMessage);
32492
+ }
32493
+ return normalized.length > 0 ? normalized : void 0;
32494
+ }
32457
32495
  async flushPendingMessagesOnError(oc) {
32458
32496
  const buffer = this.getConversationBuffer(oc);
32459
32497
  const queue = this.getMemoryPersistQueue(oc);
@@ -33802,18 +33840,18 @@ ${retrieverContext}`;
33802
33840
  const toolRouting = this.resolveToolRouting(options);
33803
33841
  oc.systemContext.set(TOOL_ROUTING_CONTEXT_KEY, toolRouting);
33804
33842
  if (toolRouting === false) {
33805
- const supportNames = this.getToolRoutingSupportToolNames();
33806
- const allNames = /* @__PURE__ */ new Set([
33807
- ...Object.keys(preparedStaticTools),
33808
- ...Object.keys(preparedDynamicTools)
33809
- ]);
33810
- const conflicts = [...allNames].filter((name) => supportNames.has(name));
33811
- if (conflicts.length > 0) {
33843
+ const conflicts = /* @__PURE__ */ new Set();
33844
+ for (const tool2 of [...this.toolManager.getAllTools(), ...tempManager.getAllTools()]) {
33845
+ if (this.isToolRoutingSupportTool(tool2)) {
33846
+ conflicts.add(tool2.name);
33847
+ }
33848
+ }
33849
+ if (conflicts.size > 0) {
33812
33850
  throw new Error(
33813
33851
  [
33814
- "toolRouting is disabled but reserved routing tool names are in use:",
33815
- conflicts.join(", "),
33816
- "Rename these tools or enable toolRouting to use the built-in names."
33852
+ "toolRouting is disabled but internal routing support tools are in use:",
33853
+ Array.from(conflicts).join(", "),
33854
+ "Enable toolRouting or remove internal routing tools before disabling it for this request."
33817
33855
  ].join(" ")
33818
33856
  );
33819
33857
  }
@@ -34086,10 +34124,7 @@ ${retrieverContext}`;
34086
34124
  if (!tool2 || typeof tool2 !== "object") {
34087
34125
  return false;
34088
34126
  }
34089
- if (TOOL_ROUTING_INTERNAL_TOOL_SYMBOL in tool2) {
34090
- return true;
34091
- }
34092
- return tool2.name === TOOL_ROUTING_SEARCH_TOOL_NAME || tool2.name === TOOL_ROUTING_CALL_TOOL_NAME;
34127
+ return Object.prototype.hasOwnProperty.call(tool2, TOOL_ROUTING_INTERNAL_TOOL_SYMBOL);
34093
34128
  }
34094
34129
  isToolExecutableForRouting(tool2) {
34095
34130
  if (isProviderTool(tool2)) {
@@ -34621,7 +34656,10 @@ ${retrieverContext}`;
34621
34656
  const conversationPersistence = this.getConversationPersistenceOptionsForContext(oc);
34622
34657
  return async (event) => {
34623
34658
  const { shouldFlushForToolCompletion, bailedResult } = this.processStepContent(oc, event);
34624
- const responseMessages = filterResponseMessages(event.response?.messages);
34659
+ const responseMessages = this.normalizeStepResponseMessages(
34660
+ oc,
34661
+ filterResponseMessages(event.response?.messages)
34662
+ );
34625
34663
  const hasResponseMessages = Boolean(responseMessages && responseMessages.length > 0);
34626
34664
  if (hasResponseMessages && responseMessages) {
34627
34665
  buffer.addModelMessages(responseMessages, "response");
@@ -35165,12 +35203,12 @@ ${retrieverContext}`;
35165
35203
  const memoryInstance = activeMemory || void 0;
35166
35204
  const toolRoutingConfig = this.toolRouting && typeof this.toolRouting === "object" ? this.toolRouting : void 0;
35167
35205
  const toolRoutingState = toolRoutingConfig ? (() => {
35168
- const supportNames = this.getToolRoutingSupportToolNames();
35169
35206
  const searchTool = this.toolManager.getToolByName(TOOL_ROUTING_SEARCH_TOOL_NAME);
35170
35207
  const callTool = this.toolManager.getToolByName(TOOL_ROUTING_CALL_TOOL_NAME);
35171
35208
  const searchApiTool = searchTool && this.isToolRoutingSupportTool(searchTool) ? new ToolManager([searchTool], this.logger).getToolsForApi()[0] : void 0;
35172
35209
  const callApiTool = callTool && this.isToolRoutingSupportTool(callTool) ? new ToolManager([callTool], this.logger).getToolsForApi()[0] : void 0;
35173
- const poolApiTools = this.toolPoolManager.getToolsForApi().filter((tool2) => !supportNames.has(tool2.name));
35210
+ const poolTools = this.toolPoolManager.getAllTools().filter((tool2) => !this.isToolRoutingSupportTool(tool2));
35211
+ const poolApiTools = poolTools.length > 0 ? new ToolManager(poolTools, this.logger).getToolsForApi() : [];
35174
35212
  const exposeApiTools = toolRoutingConfig.expose && toolRoutingConfig.expose.length > 0 ? new ToolManager(toolRoutingConfig.expose, this.logger).getToolsForApi() : [];
35175
35213
  return {
35176
35214
  search: searchApiTool,
@@ -35476,9 +35514,10 @@ ${retrieverContext}`;
35476
35514
  upsertToolRoutingSupportTool(tool2) {
35477
35515
  const existing = this.toolManager.getToolByName(tool2.name);
35478
35516
  if (existing && !this.isToolRoutingSupportTool(existing)) {
35479
- throw new Error(
35480
- `Tool routing requires reserved tool name "${tool2.name}". Rename the conflicting tool to enable tool routing.`
35517
+ this.logger.debug(
35518
+ `Tool routing support tool "${tool2.name}" not added because a user-defined tool with the same name exists.`
35481
35519
  );
35520
+ return;
35482
35521
  }
35483
35522
  if (existing && this.isToolRoutingSupportTool(existing)) {
35484
35523
  this.toolManager.removeTool(tool2.name);
@@ -41150,6 +41189,7 @@ var VoltAgent = class {
41150
41189
  ensureEnvironmentBinding;
41151
41190
  triggerRegistry;
41152
41191
  agentRefs;
41192
+ lastServerlessRemoteConfig;
41153
41193
  ready;
41154
41194
  initError;
41155
41195
  degraded = false;
@@ -41368,17 +41408,53 @@ var VoltAgent = class {
41368
41408
  }
41369
41409
  const baseUrl = voltOpsClient.getApiUrl().replace(/\/$/, "");
41370
41410
  const headers = voltOpsClient.getAuthHeaders();
41411
+ const nextConfig = {
41412
+ tracesUrl: `${baseUrl}/api/public/otel/v1/traces`,
41413
+ logsUrl: `${baseUrl}/api/public/otel/v1/logs`,
41414
+ headers
41415
+ };
41416
+ if (this.isSameServerlessRemoteConfig(nextConfig)) {
41417
+ return;
41418
+ }
41419
+ this.lastServerlessRemoteConfig = {
41420
+ tracesUrl: nextConfig.tracesUrl,
41421
+ logsUrl: nextConfig.logsUrl,
41422
+ headers: { ...nextConfig.headers }
41423
+ };
41371
41424
  this.observability.updateServerlessRemote({
41372
41425
  traces: {
41373
- url: `${baseUrl}/api/public/otel/v1/traces`,
41374
- headers
41426
+ url: nextConfig.tracesUrl,
41427
+ headers: nextConfig.headers
41375
41428
  },
41376
41429
  logs: {
41377
- url: `${baseUrl}/api/public/otel/v1/logs`,
41378
- headers
41430
+ url: nextConfig.logsUrl,
41431
+ headers: nextConfig.headers
41379
41432
  }
41380
41433
  });
41381
41434
  }
41435
+ isSameServerlessRemoteConfig(nextConfig) {
41436
+ const previous = this.lastServerlessRemoteConfig;
41437
+ if (!previous) {
41438
+ return false;
41439
+ }
41440
+ if (previous.tracesUrl !== nextConfig.tracesUrl || previous.logsUrl !== nextConfig.logsUrl) {
41441
+ return false;
41442
+ }
41443
+ return this.areHeaderRecordsEqual(previous.headers, nextConfig.headers);
41444
+ }
41445
+ areHeaderRecordsEqual(left, right) {
41446
+ const leftKeys = Object.keys(left);
41447
+ const rightKeys = Object.keys(right);
41448
+ if (leftKeys.length !== rightKeys.length) {
41449
+ return false;
41450
+ }
41451
+ for (const key of leftKeys) {
41452
+ if (left[key] !== right[key]) {
41453
+ return false;
41454
+ }
41455
+ }
41456
+ return true;
41457
+ }
41382
41458
  /**
41383
41459
  * Setup graceful shutdown handlers
41384
41460
  */