@librechat/agents 3.9.7 → 4.0.0

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.
Files changed (74) hide show
  1. package/dist/cjs/common/enum.cjs +1 -0
  2. package/dist/cjs/common/enum.cjs.map +1 -1
  3. package/dist/cjs/graphs/Graph.cjs +4 -3
  4. package/dist/cjs/graphs/Graph.cjs.map +1 -1
  5. package/dist/cjs/instrumentation.cjs +3 -3
  6. package/dist/cjs/langfuse.cjs +3 -3
  7. package/dist/cjs/langfuseRuntimeScope.cjs +1 -1
  8. package/dist/cjs/langfuseToolOutputTracing.cjs +2 -2
  9. package/dist/cjs/llm/bedrock/index.cjs +1 -1
  10. package/dist/cjs/llm/bedrock/index.cjs.map +1 -1
  11. package/dist/cjs/llm/bedrock/utils/message_inputs.cjs +20 -9
  12. package/dist/cjs/llm/bedrock/utils/message_inputs.cjs.map +1 -1
  13. package/dist/cjs/llm/invoke.cjs +1 -1
  14. package/dist/cjs/run.cjs +4 -3
  15. package/dist/cjs/run.cjs.map +1 -1
  16. package/dist/cjs/stream.cjs +7 -4
  17. package/dist/cjs/stream.cjs.map +1 -1
  18. package/dist/cjs/tools/ProgrammaticToolCalling.cjs +1 -1
  19. package/dist/cjs/tools/ToolNode.cjs +20 -6
  20. package/dist/cjs/tools/ToolNode.cjs.map +1 -1
  21. package/dist/cjs/tools/handlers.cjs +2 -2
  22. package/dist/cjs/tools/handlers.cjs.map +1 -1
  23. package/dist/cjs/tools/subagent/SubagentExecutor.cjs +22 -0
  24. package/dist/cjs/tools/subagent/SubagentExecutor.cjs.map +1 -1
  25. package/dist/cjs/utils/events.cjs +20 -2
  26. package/dist/cjs/utils/events.cjs.map +1 -1
  27. package/dist/esm/common/enum.mjs +1 -0
  28. package/dist/esm/common/enum.mjs.map +1 -1
  29. package/dist/esm/graphs/Graph.mjs +4 -3
  30. package/dist/esm/graphs/Graph.mjs.map +1 -1
  31. package/dist/esm/instrumentation.mjs +3 -3
  32. package/dist/esm/langfuse.mjs +3 -3
  33. package/dist/esm/langfuseRuntimeScope.mjs +1 -1
  34. package/dist/esm/langfuseToolOutputTracing.mjs +2 -2
  35. package/dist/esm/llm/bedrock/index.mjs +1 -1
  36. package/dist/esm/llm/bedrock/index.mjs.map +1 -1
  37. package/dist/esm/llm/bedrock/utils/message_inputs.mjs +20 -9
  38. package/dist/esm/llm/bedrock/utils/message_inputs.mjs.map +1 -1
  39. package/dist/esm/llm/invoke.mjs +1 -1
  40. package/dist/esm/run.mjs +4 -3
  41. package/dist/esm/run.mjs.map +1 -1
  42. package/dist/esm/stream.mjs +11 -7
  43. package/dist/esm/stream.mjs.map +1 -1
  44. package/dist/esm/tools/ProgrammaticToolCalling.mjs +1 -1
  45. package/dist/esm/tools/ToolNode.mjs +24 -9
  46. package/dist/esm/tools/ToolNode.mjs.map +1 -1
  47. package/dist/esm/tools/handlers.mjs +2 -2
  48. package/dist/esm/tools/handlers.mjs.map +1 -1
  49. package/dist/esm/tools/subagent/SubagentExecutor.mjs +22 -0
  50. package/dist/esm/tools/subagent/SubagentExecutor.mjs.map +1 -1
  51. package/dist/esm/utils/events.mjs +20 -3
  52. package/dist/esm/utils/events.mjs.map +1 -1
  53. package/dist/types/common/enum.d.ts +2 -0
  54. package/dist/types/graphs/Graph.d.ts +2 -2
  55. package/dist/types/llm/bedrock/utils/message_inputs.d.ts +13 -1
  56. package/dist/types/tools/handlers.d.ts +2 -1
  57. package/dist/types/types/graph.d.ts +3 -3
  58. package/dist/types/types/stream.d.ts +24 -0
  59. package/dist/types/types/tools.d.ts +2 -0
  60. package/dist/types/utils/events.d.ts +4 -0
  61. package/package.json +1 -1
  62. package/src/common/enum.ts +2 -0
  63. package/src/graphs/Graph.ts +5 -2
  64. package/src/llm/bedrock/index.ts +4 -2
  65. package/src/llm/bedrock/utils/message_inputs.ts +62 -15
  66. package/src/run.ts +9 -7
  67. package/src/stream.ts +12 -3
  68. package/src/tools/ToolNode.ts +32 -6
  69. package/src/tools/handlers.ts +4 -1
  70. package/src/tools/subagent/SubagentExecutor.ts +24 -0
  71. package/src/types/graph.ts +3 -0
  72. package/src/types/stream.ts +21 -0
  73. package/src/types/tools.ts +2 -0
  74. package/src/utils/events.ts +21 -2
@@ -3463,6 +3463,10 @@ export class SubagentExecutor {
3463
3463
  scheduleWrap(eventName, 'run_step', data, memberAgentId);
3464
3464
  return;
3465
3465
  }
3466
+ if (eventName === GraphEvents.ON_TOOL_CALLS_DISPATCHED) {
3467
+ scheduleWrap(eventName, 'tool_calls_dispatched', data, memberAgentId);
3468
+ return;
3469
+ }
3466
3470
  if (eventName === GraphEvents.ON_RUN_STEP_DELTA) {
3467
3471
  scheduleWrap(eventName, 'run_step_delta', data, memberAgentId);
3468
3472
  return;
@@ -3816,6 +3820,26 @@ export function sanitizeForwardedSubagentUpdateData(
3816
3820
  if (eventName === GraphEvents.ON_RUN_STEP_DELTA) {
3817
3821
  return sanitizeRunStepDeltaUpdateData(data);
3818
3822
  }
3823
+ if (eventName === GraphEvents.ON_TOOL_CALLS_DISPATCHED) {
3824
+ if (!isObjectLike(data)) return undefined;
3825
+ const event = data as { dispatched_at?: number; toolCalls?: unknown };
3826
+ if (!Array.isArray(event.toolCalls) || typeof event.dispatched_at !== 'number') {
3827
+ return undefined;
3828
+ }
3829
+ return {
3830
+ dispatched_at: event.dispatched_at,
3831
+ toolCalls: (event.toolCalls as unknown[]).flatMap((call) => {
3832
+ if (!isObjectLike(call)) return [];
3833
+ const entry = call as Record<string, unknown>;
3834
+ if (typeof entry.id !== 'string' || typeof entry.name !== 'string') return [];
3835
+ return [{
3836
+ id: entry.id,
3837
+ name: entry.name,
3838
+ ...(typeof entry.stepId === 'string' ? { stepId: entry.stepId } : {}),
3839
+ }];
3840
+ }),
3841
+ };
3842
+ }
3819
3843
  if (eventName === GraphEvents.ON_RUN_STEP_COMPLETED) {
3820
3844
  return sanitizeRunStepCompletedUpdateData(data);
3821
3845
  }
@@ -17,6 +17,7 @@ import type {
17
17
  RunStepDeltaEvent,
18
18
  RunStepResumeState,
19
19
  RunStepClosedEvent,
20
+ ToolCallsDispatchedEvent,
20
21
  MessageDeltaEvent,
21
22
  ReasoningDeltaEvent,
22
23
  } from '@/types/stream';
@@ -209,6 +210,7 @@ export interface EventHandler {
209
210
  | RunStep
210
211
  | RunStepDeltaEvent
211
212
  | RunStepClosedEvent
213
+ | ToolCallsDispatchedEvent
212
214
  | MessageDeltaEvent
213
215
  | ReasoningDeltaEvent
214
216
  | SummarizeStartEvent
@@ -694,6 +696,7 @@ export type SubagentUpdatePhase =
694
696
  | 'start'
695
697
  | 'run_step'
696
698
  | 'run_step_delta'
699
+ | 'tool_calls_dispatched'
697
700
  | 'run_step_completed'
698
701
  | 'run_step_closed'
699
702
  | 'message_delta'
@@ -158,6 +158,8 @@ export interface RunStepDeltaEvent {
158
158
  * The delta containing the fields that have changed on the run step.
159
159
  */
160
160
  delta: ToolCallDelta;
161
+ /** Epoch ms when the SDK received this tool-call fragment, before step dispatch. */
162
+ observed_at?: number;
161
163
  }
162
164
 
163
165
  /**
@@ -264,6 +266,25 @@ export type ToolCallCompleted = {
264
266
  tool_call: ProcessedToolCall;
265
267
  };
266
268
 
269
+ /**
270
+ * A tool call has crossed from model-authored argument preparation into SDK
271
+ * execution. Emitted immediately before host dispatch or direct invocation;
272
+ * it does not claim the host has begun its own work. Paired with the tool
273
+ * completion `completed_at`, the stamp measures SDK handoff-to-result time,
274
+ * not MCP or database execution time. The earliest `observed_at` tool-call
275
+ * delta for a call bounds its argument preparation time; consumers correlate
276
+ * deltas by step/index until an ID is known. For a call without streamed
277
+ * fragments, the preparation start is unknown. Never infer a missing start.
278
+ * An eager call may dispatch before it has a step ID, and this observational
279
+ * event may arrive after completion: correlate by tool call ID and timestamps,
280
+ * not arrival order.
281
+ */
282
+ export type ToolCallsDispatchedEvent = {
283
+ dispatched_at: number;
284
+ runId?: string;
285
+ toolCalls: Array<{ id: string; name: string; stepId?: string }>;
286
+ };
287
+
267
288
  export type ToolCompleteEvent = ToolCallCompleted & {
268
289
  /** The Step Id of the Tool Call */
269
290
  id: string;
@@ -700,6 +700,8 @@ export type OutcomePatch = {
700
700
  export type ToolExecuteResult = {
701
701
  /** Matches ToolCallRequest.id */
702
702
  toolCallId: string;
703
+ /** SDK-stamped result receipt time; never host-supplied or inferred from handler cleanup. */
704
+ received_at?: number;
703
705
  /** Tool output content */
704
706
  content: string | unknown[];
705
707
  /** Optional artifact (for content_and_artifact format) */
@@ -2,6 +2,7 @@
2
2
  // src/utils/events.ts
3
3
  import { dispatchCustomEvent } from '@langchain/core/callbacks/dispatch';
4
4
  import type { RunnableConfig } from '@langchain/core/runnables';
5
+ import type { ToolCallsDispatchedEvent } from '@/types/stream';
5
6
  import type { ToolExecuteBatchRequest } from '@/types/tools';
6
7
  import type { AgentLogEvent } from '@/types/graph';
7
8
  import { traceHostToolResults } from '@/langfuse';
@@ -24,11 +25,13 @@ export async function safeDispatchCustomEvent(
24
25
  resolve: (
25
26
  results: Parameters<ToolExecuteBatchRequest['resolve']>[0]
26
27
  ): void => {
28
+ const receivedAt = Date.now();
29
+ const stamped = results.map((result) => ({ ...result, received_at: receivedAt }));
27
30
  void traceHostToolResults(request, results, config).then(
28
- () => request.resolve(results),
31
+ () => request.resolve(stamped),
29
32
  () => {
30
33
  console.warn('Failed to record host tool execution metadata');
31
- request.resolve(results);
34
+ request.resolve(stamped);
32
35
  }
33
36
  );
34
37
  },
@@ -54,6 +57,22 @@ export async function safeDispatchCustomEvent(
54
57
  }
55
58
  }
56
59
 
60
+ /** Builds an argument-free snapshot once per handoff, not once per result. */
61
+ export function createToolCallsDispatchedEvent(
62
+ config: RunnableConfig,
63
+ calls: readonly Pick<
64
+ ToolExecuteBatchRequest['toolCalls'][number],
65
+ 'id' | 'name' | 'stepId'
66
+ >[]
67
+ ): ToolCallsDispatchedEvent {
68
+ const runId = config.configurable?.run_id;
69
+ return {
70
+ dispatched_at: Date.now(),
71
+ ...(typeof runId === 'string' ? { runId } : {}),
72
+ toolCalls: calls.map(({ id, name, stepId }) => ({ id, name, stepId })),
73
+ };
74
+ }
75
+
57
76
  /**
58
77
  * Fire-and-forget diagnostic log event.
59
78
  * Debug-level logs are gated behind AGENT_DEBUG_LOGGING=true to avoid