@librechat/agents 3.1.86 → 3.1.88

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 (160) hide show
  1. package/README.md +69 -0
  2. package/dist/cjs/events.cjs +23 -0
  3. package/dist/cjs/events.cjs.map +1 -1
  4. package/dist/cjs/graphs/Graph.cjs +133 -18
  5. package/dist/cjs/graphs/Graph.cjs.map +1 -1
  6. package/dist/cjs/graphs/MultiAgentGraph.cjs +1 -1
  7. package/dist/cjs/graphs/MultiAgentGraph.cjs.map +1 -1
  8. package/dist/cjs/llm/anthropic/index.cjs +251 -53
  9. package/dist/cjs/llm/anthropic/index.cjs.map +1 -1
  10. package/dist/cjs/llm/init.cjs +1 -5
  11. package/dist/cjs/llm/init.cjs.map +1 -1
  12. package/dist/cjs/llm/openai/index.cjs +113 -24
  13. package/dist/cjs/llm/openai/index.cjs.map +1 -1
  14. package/dist/cjs/llm/openai/utils/index.cjs.map +1 -1
  15. package/dist/cjs/llm/openrouter/index.cjs +3 -1
  16. package/dist/cjs/llm/openrouter/index.cjs.map +1 -1
  17. package/dist/cjs/main.cjs +18 -5
  18. package/dist/cjs/main.cjs.map +1 -1
  19. package/dist/cjs/openai/index.cjs +253 -0
  20. package/dist/cjs/openai/index.cjs.map +1 -0
  21. package/dist/cjs/responses/index.cjs +448 -0
  22. package/dist/cjs/responses/index.cjs.map +1 -0
  23. package/dist/cjs/run.cjs +108 -7
  24. package/dist/cjs/run.cjs.map +1 -1
  25. package/dist/cjs/session/AgentSession.cjs +1057 -0
  26. package/dist/cjs/session/AgentSession.cjs.map +1 -0
  27. package/dist/cjs/session/JsonlSessionStore.cjs +425 -0
  28. package/dist/cjs/session/JsonlSessionStore.cjs.map +1 -0
  29. package/dist/cjs/session/handlers.cjs +221 -0
  30. package/dist/cjs/session/handlers.cjs.map +1 -0
  31. package/dist/cjs/session/ids.cjs +22 -0
  32. package/dist/cjs/session/ids.cjs.map +1 -0
  33. package/dist/cjs/session/messageSerialization.cjs +179 -0
  34. package/dist/cjs/session/messageSerialization.cjs.map +1 -0
  35. package/dist/cjs/stream.cjs +475 -11
  36. package/dist/cjs/stream.cjs.map +1 -1
  37. package/dist/cjs/summarization/node.cjs +1 -1
  38. package/dist/cjs/summarization/node.cjs.map +1 -1
  39. package/dist/cjs/tools/ToolNode.cjs +177 -59
  40. package/dist/cjs/tools/ToolNode.cjs.map +1 -1
  41. package/dist/cjs/tools/eagerEventExecution.cjs +113 -0
  42. package/dist/cjs/tools/eagerEventExecution.cjs.map +1 -0
  43. package/dist/cjs/tools/handlers.cjs +1 -1
  44. package/dist/cjs/tools/handlers.cjs.map +1 -1
  45. package/dist/cjs/tools/streamedToolCallSeals.cjs +42 -0
  46. package/dist/cjs/tools/streamedToolCallSeals.cjs.map +1 -0
  47. package/dist/esm/events.mjs +23 -1
  48. package/dist/esm/events.mjs.map +1 -1
  49. package/dist/esm/graphs/Graph.mjs +133 -18
  50. package/dist/esm/graphs/Graph.mjs.map +1 -1
  51. package/dist/esm/graphs/MultiAgentGraph.mjs +1 -1
  52. package/dist/esm/graphs/MultiAgentGraph.mjs.map +1 -1
  53. package/dist/esm/llm/anthropic/index.mjs +251 -53
  54. package/dist/esm/llm/anthropic/index.mjs.map +1 -1
  55. package/dist/esm/llm/init.mjs +1 -5
  56. package/dist/esm/llm/init.mjs.map +1 -1
  57. package/dist/esm/llm/openai/index.mjs +113 -25
  58. package/dist/esm/llm/openai/index.mjs.map +1 -1
  59. package/dist/esm/llm/openai/utils/index.mjs.map +1 -1
  60. package/dist/esm/llm/openrouter/index.mjs +4 -2
  61. package/dist/esm/llm/openrouter/index.mjs.map +1 -1
  62. package/dist/esm/main.mjs +5 -1
  63. package/dist/esm/main.mjs.map +1 -1
  64. package/dist/esm/openai/index.mjs +246 -0
  65. package/dist/esm/openai/index.mjs.map +1 -0
  66. package/dist/esm/responses/index.mjs +440 -0
  67. package/dist/esm/responses/index.mjs.map +1 -0
  68. package/dist/esm/run.mjs +108 -7
  69. package/dist/esm/run.mjs.map +1 -1
  70. package/dist/esm/session/AgentSession.mjs +1054 -0
  71. package/dist/esm/session/AgentSession.mjs.map +1 -0
  72. package/dist/esm/session/JsonlSessionStore.mjs +422 -0
  73. package/dist/esm/session/JsonlSessionStore.mjs.map +1 -0
  74. package/dist/esm/session/handlers.mjs +219 -0
  75. package/dist/esm/session/handlers.mjs.map +1 -0
  76. package/dist/esm/session/ids.mjs +17 -0
  77. package/dist/esm/session/ids.mjs.map +1 -0
  78. package/dist/esm/session/messageSerialization.mjs +173 -0
  79. package/dist/esm/session/messageSerialization.mjs.map +1 -0
  80. package/dist/esm/stream.mjs +476 -12
  81. package/dist/esm/stream.mjs.map +1 -1
  82. package/dist/esm/summarization/node.mjs +1 -1
  83. package/dist/esm/summarization/node.mjs.map +1 -1
  84. package/dist/esm/tools/ToolNode.mjs +177 -59
  85. package/dist/esm/tools/ToolNode.mjs.map +1 -1
  86. package/dist/esm/tools/eagerEventExecution.mjs +107 -0
  87. package/dist/esm/tools/eagerEventExecution.mjs.map +1 -0
  88. package/dist/esm/tools/handlers.mjs +1 -1
  89. package/dist/esm/tools/handlers.mjs.map +1 -1
  90. package/dist/esm/tools/streamedToolCallSeals.mjs +36 -0
  91. package/dist/esm/tools/streamedToolCallSeals.mjs.map +1 -0
  92. package/dist/types/events.d.ts +1 -0
  93. package/dist/types/graphs/Graph.d.ts +24 -9
  94. package/dist/types/index.d.ts +1 -0
  95. package/dist/types/llm/openai/index.d.ts +1 -0
  96. package/dist/types/openai/index.d.ts +75 -0
  97. package/dist/types/responses/index.d.ts +97 -0
  98. package/dist/types/run.d.ts +2 -0
  99. package/dist/types/session/AgentSession.d.ts +32 -0
  100. package/dist/types/session/JsonlSessionStore.d.ts +67 -0
  101. package/dist/types/session/handlers.d.ts +8 -0
  102. package/dist/types/session/ids.d.ts +4 -0
  103. package/dist/types/session/index.d.ts +5 -0
  104. package/dist/types/session/messageSerialization.d.ts +7 -0
  105. package/dist/types/session/types.d.ts +191 -0
  106. package/dist/types/tools/ToolNode.d.ts +12 -1
  107. package/dist/types/tools/eagerEventExecution.d.ts +23 -0
  108. package/dist/types/tools/streamedToolCallSeals.d.ts +13 -0
  109. package/dist/types/types/hitl.d.ts +4 -0
  110. package/dist/types/types/run.d.ts +11 -1
  111. package/dist/types/types/tools.d.ts +36 -0
  112. package/package.json +19 -2
  113. package/src/__tests__/stream.eagerEventExecution.test.ts +2571 -0
  114. package/src/events.ts +29 -0
  115. package/src/graphs/Graph.ts +224 -50
  116. package/src/graphs/MultiAgentGraph.ts +1 -1
  117. package/src/graphs/__tests__/composition.smoke.test.ts +30 -0
  118. package/src/index.ts +3 -0
  119. package/src/llm/anthropic/index.ts +356 -84
  120. package/src/llm/anthropic/llm.spec.ts +64 -0
  121. package/src/llm/custom-chat-models.smoke.test.ts +175 -4
  122. package/src/llm/openai/contentBlocks.test.ts +35 -0
  123. package/src/llm/openai/deepseek.test.ts +201 -2
  124. package/src/llm/openai/index.ts +171 -26
  125. package/src/llm/openai/utils/index.ts +22 -0
  126. package/src/llm/openrouter/index.ts +4 -2
  127. package/src/openai/__tests__/openai.test.ts +337 -0
  128. package/src/openai/index.ts +404 -0
  129. package/src/responses/__tests__/responses.test.ts +652 -0
  130. package/src/responses/index.ts +677 -0
  131. package/src/run.ts +158 -8
  132. package/src/scripts/compare_pi_vs_ours.ts +592 -173
  133. package/src/scripts/session_live.ts +548 -0
  134. package/src/session/AgentSession.ts +1432 -0
  135. package/src/session/JsonlSessionStore.ts +572 -0
  136. package/src/session/__tests__/JsonlSessionStore.test.ts +1410 -0
  137. package/src/session/__tests__/handlers.test.ts +161 -0
  138. package/src/session/handlers.ts +272 -0
  139. package/src/session/ids.ts +17 -0
  140. package/src/session/index.ts +44 -0
  141. package/src/session/messageSerialization.ts +207 -0
  142. package/src/session/types.ts +275 -0
  143. package/src/specs/custom-event-await.test.ts +89 -0
  144. package/src/specs/summarization.test.ts +1 -1
  145. package/src/stream.ts +756 -48
  146. package/src/summarization/node.ts +1 -1
  147. package/src/tools/ToolNode.ts +299 -126
  148. package/src/tools/__tests__/ToolNode.eagerEventExecution.test.ts +373 -0
  149. package/src/tools/__tests__/handlers.test.ts +2 -1
  150. package/src/tools/__tests__/hitl.test.ts +206 -110
  151. package/src/tools/eagerEventExecution.ts +153 -0
  152. package/src/tools/handlers.ts +8 -4
  153. package/src/tools/streamedToolCallSeals.ts +57 -0
  154. package/src/types/hitl.ts +4 -0
  155. package/src/types/run.ts +11 -0
  156. package/src/types/tools.ts +36 -0
  157. package/dist/cjs/llm/text.cjs +0 -69
  158. package/dist/cjs/llm/text.cjs.map +0 -1
  159. package/dist/esm/llm/text.mjs +0 -67
  160. package/dist/esm/llm/text.mjs.map +0 -1
@@ -0,0 +1,107 @@
1
+ function coerceRecordArgs(args) {
2
+ if (typeof args === 'string') {
3
+ try {
4
+ const parsed = JSON.parse(args);
5
+ return coerceRecordArgs(parsed);
6
+ }
7
+ catch {
8
+ return undefined;
9
+ }
10
+ }
11
+ if (args === null || typeof args !== 'object' || Array.isArray(args)) {
12
+ return undefined;
13
+ }
14
+ return args;
15
+ }
16
+ function stableStringify(value) {
17
+ if (Array.isArray(value)) {
18
+ return `[${value.map((item) => stableStringify(item)).join(',')}]`;
19
+ }
20
+ if (value !== null && typeof value === 'object') {
21
+ const record = value;
22
+ const keys = Object.keys(record).sort();
23
+ return `{${keys
24
+ .map((key) => `${JSON.stringify(key)}:${stableStringify(record[key])}`)
25
+ .join(',')}}`;
26
+ }
27
+ return JSON.stringify(value);
28
+ }
29
+ function recordArgsEqual(left, right) {
30
+ return stableStringify(left) === stableStringify(right);
31
+ }
32
+ function normalizeError(error) {
33
+ return error instanceof Error ? error : new Error(String(error));
34
+ }
35
+ function buildToolExecutionRequestPlan(args) {
36
+ const invalidArgsBehavior = args.invalidArgsBehavior ?? 'abort';
37
+ const prepared = [];
38
+ for (const toolCall of args.toolCalls) {
39
+ if (toolCall.id == null ||
40
+ toolCall.id === '' ||
41
+ toolCall.name === '') {
42
+ return undefined;
43
+ }
44
+ const coercedArgs = coerceRecordArgs(toolCall.args);
45
+ if (coercedArgs == null) {
46
+ if (invalidArgsBehavior === 'abort') {
47
+ return undefined;
48
+ }
49
+ prepared.push({
50
+ id: toolCall.id,
51
+ name: toolCall.name,
52
+ args: {},
53
+ stepId: toolCall.stepId,
54
+ codeSessionContext: toolCall.codeSessionContext,
55
+ rejectedErrorMessage: 'Invalid tool call arguments: expected a JSON object.',
56
+ });
57
+ continue;
58
+ }
59
+ prepared.push({
60
+ id: toolCall.id,
61
+ name: toolCall.name,
62
+ args: coercedArgs,
63
+ stepId: toolCall.stepId,
64
+ codeSessionContext: toolCall.codeSessionContext,
65
+ });
66
+ }
67
+ const nextUsageCount = new Map(args.usageCount);
68
+ const allRequests = prepared.map((toolCall) => {
69
+ const turn = nextUsageCount.get(toolCall.name) ?? 0;
70
+ nextUsageCount.set(toolCall.name, turn + 1);
71
+ const request = {
72
+ id: toolCall.id,
73
+ name: toolCall.name,
74
+ args: toolCall.args,
75
+ stepId: toolCall.stepId,
76
+ turn,
77
+ };
78
+ if (toolCall.codeSessionContext != null) {
79
+ request.codeSessionContext = toolCall.codeSessionContext;
80
+ }
81
+ return request;
82
+ });
83
+ const requests = allRequests.filter((_, index) => prepared[index].rejectedErrorMessage == null);
84
+ const rejectedResults = prepared.flatMap((toolCall) => {
85
+ if (toolCall.rejectedErrorMessage == null) {
86
+ return [];
87
+ }
88
+ return [
89
+ {
90
+ toolCallId: toolCall.id,
91
+ status: 'error',
92
+ content: '',
93
+ errorMessage: toolCall.rejectedErrorMessage,
94
+ },
95
+ ];
96
+ });
97
+ for (const [toolName, count] of nextUsageCount) {
98
+ args.usageCount.set(toolName, count);
99
+ }
100
+ for (const request of allRequests) {
101
+ args.recordTurn?.(request.name, request.turn ?? 0, request.id);
102
+ }
103
+ return { allRequests, requests, rejectedResults };
104
+ }
105
+
106
+ export { buildToolExecutionRequestPlan, coerceRecordArgs, normalizeError, recordArgsEqual, stableStringify };
107
+ //# sourceMappingURL=eagerEventExecution.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eagerEventExecution.mjs","sources":["../../../src/tools/eagerEventExecution.ts"],"sourcesContent":["import type * as t from '@/types';\n\nexport function coerceRecordArgs(\n args: unknown\n): Record<string, unknown> | undefined {\n if (typeof args === 'string') {\n try {\n const parsed = JSON.parse(args) as unknown;\n return coerceRecordArgs(parsed);\n } catch {\n return undefined;\n }\n }\n\n if (args === null || typeof args !== 'object' || Array.isArray(args)) {\n return undefined;\n }\n\n return args as Record<string, unknown>;\n}\n\nexport function stableStringify(value: unknown): string {\n if (Array.isArray(value)) {\n return `[${value.map((item) => stableStringify(item)).join(',')}]`;\n }\n\n if (value !== null && typeof value === 'object') {\n const record = value as Record<string, unknown>;\n const keys = Object.keys(record).sort();\n return `{${keys\n .map((key) => `${JSON.stringify(key)}:${stableStringify(record[key])}`)\n .join(',')}}`;\n }\n\n return JSON.stringify(value);\n}\n\nexport function recordArgsEqual(\n left: Record<string, unknown>,\n right: Record<string, unknown>\n): boolean {\n return stableStringify(left) === stableStringify(right);\n}\n\nexport function normalizeError(error: unknown): Error {\n return error instanceof Error ? error : new Error(String(error));\n}\n\nexport type ToolExecutionPlanCall = {\n id?: string;\n name: string;\n args: unknown;\n stepId?: string;\n codeSessionContext?: t.ToolCallRequest['codeSessionContext'];\n};\n\nexport type ToolExecutionRequestPlan = {\n allRequests: t.ToolCallRequest[];\n requests: t.ToolCallRequest[];\n rejectedResults: t.ToolExecuteResult[];\n};\n\nexport function buildToolExecutionRequestPlan(args: {\n toolCalls: ToolExecutionPlanCall[];\n usageCount: Map<string, number>;\n invalidArgsBehavior?: 'abort' | 'error-result';\n recordTurn?: (toolName: string, turn: number, callId: string) => void;\n}): ToolExecutionRequestPlan | undefined {\n const invalidArgsBehavior = args.invalidArgsBehavior ?? 'abort';\n const prepared: Array<{\n id: string;\n name: string;\n args: Record<string, unknown>;\n stepId?: string;\n codeSessionContext?: t.ToolCallRequest['codeSessionContext'];\n rejectedErrorMessage?: string;\n }> = [];\n\n for (const toolCall of args.toolCalls) {\n if (\n toolCall.id == null ||\n toolCall.id === '' ||\n toolCall.name === ''\n ) {\n return undefined;\n }\n const coercedArgs = coerceRecordArgs(toolCall.args);\n if (coercedArgs == null) {\n if (invalidArgsBehavior === 'abort') {\n return undefined;\n }\n prepared.push({\n id: toolCall.id,\n name: toolCall.name,\n args: {},\n stepId: toolCall.stepId,\n codeSessionContext: toolCall.codeSessionContext,\n rejectedErrorMessage:\n 'Invalid tool call arguments: expected a JSON object.',\n });\n continue;\n }\n prepared.push({\n id: toolCall.id,\n name: toolCall.name,\n args: coercedArgs,\n stepId: toolCall.stepId,\n codeSessionContext: toolCall.codeSessionContext,\n });\n }\n\n const nextUsageCount = new Map(args.usageCount);\n const allRequests = prepared.map((toolCall): t.ToolCallRequest => {\n const turn = nextUsageCount.get(toolCall.name) ?? 0;\n nextUsageCount.set(toolCall.name, turn + 1);\n const request: t.ToolCallRequest = {\n id: toolCall.id,\n name: toolCall.name,\n args: toolCall.args,\n stepId: toolCall.stepId,\n turn,\n };\n if (toolCall.codeSessionContext != null) {\n request.codeSessionContext = toolCall.codeSessionContext;\n }\n return request;\n });\n const requests = allRequests.filter(\n (_, index) => prepared[index].rejectedErrorMessage == null\n );\n const rejectedResults = prepared.flatMap((toolCall) => {\n if (toolCall.rejectedErrorMessage == null) {\n return [];\n }\n return [\n {\n toolCallId: toolCall.id,\n status: 'error' as const,\n content: '',\n errorMessage: toolCall.rejectedErrorMessage,\n },\n ];\n });\n\n for (const [toolName, count] of nextUsageCount) {\n args.usageCount.set(toolName, count);\n }\n for (const request of allRequests) {\n args.recordTurn?.(request.name, request.turn ?? 0, request.id);\n }\n\n return { allRequests, requests, rejectedResults };\n}\n"],"names":[],"mappings":"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"}
@@ -83,7 +83,7 @@ async function handleToolCallChunks({ graph, stepKey, toolCallChunks, metadata,
83
83
  await graph.dispatchRunStepDelta(stepId, {
84
84
  type: StepTypes.TOOL_CALLS,
85
85
  tool_calls: toolCallChunks,
86
- });
86
+ }, metadata);
87
87
  }
88
88
  const handleToolCalls = async (toolCalls, metadata, graph) => {
89
89
  if (!graph || !metadata) {
@@ -1 +1 @@
1
- {"version":3,"file":"handlers.mjs","sources":["../../../src/tools/handlers.ts"],"sourcesContent":["/* eslint-disable no-console */\n// src/tools/handlers.ts\nimport { nanoid } from 'nanoid';\nimport { ToolMessage } from '@langchain/core/messages';\nimport type { AnthropicWebSearchResultBlockParam } from '@/llm/anthropic/types';\nimport type { ToolCall, ToolCallChunk } from '@langchain/core/messages/tool';\nimport type { Graph, MultiAgentGraph, StandardGraph } from '@/graphs';\nimport type { AgentContext } from '@/agents/AgentContext';\nimport type * as t from '@/types';\nimport {\n ToolCallTypes,\n GraphEvents,\n StepTypes,\n Providers,\n Constants,\n} from '@/common';\nimport {\n coerceAnthropicSearchResults,\n isAnthropicWebSearchResult,\n} from '@/tools/search/anthropic';\nimport { formatResultsForLLM } from '@/tools/search/format';\nimport { getMessageId } from '@/messages';\n\nexport async function handleToolCallChunks({\n graph,\n stepKey,\n toolCallChunks,\n metadata,\n}: {\n graph: StandardGraph | MultiAgentGraph;\n stepKey: string;\n toolCallChunks: ToolCallChunk[];\n metadata?: Record<string, unknown>;\n}): Promise<void> {\n let prevStepId: string;\n let prevRunStep: t.RunStep | undefined;\n try {\n prevStepId = graph.getStepIdByKey(stepKey);\n prevRunStep = graph.getRunStep(prevStepId);\n } catch {\n /** Edge Case: If no previous step exists, create a new message creation step */\n const message_id = getMessageId(stepKey, graph, true) ?? '';\n prevStepId = await graph.dispatchRunStep(\n stepKey,\n {\n type: StepTypes.MESSAGE_CREATION,\n message_creation: {\n message_id,\n },\n },\n metadata\n );\n prevRunStep = graph.getRunStep(prevStepId);\n }\n\n const _stepId = graph.getStepIdByKey(stepKey);\n\n /** Edge Case: Tool Call Run Step or `tool_call_ids` never dispatched */\n const tool_calls: ToolCall[] | undefined =\n prevStepId && prevRunStep && prevRunStep.type === StepTypes.MESSAGE_CREATION\n ? []\n : undefined;\n\n /** Edge Case: `id` and `name` fields cannot be empty strings */\n for (const toolCallChunk of toolCallChunks) {\n if (toolCallChunk.name === '') {\n toolCallChunk.name = undefined;\n }\n if (toolCallChunk.id === '') {\n toolCallChunk.id = undefined;\n } else if (\n tool_calls != null &&\n toolCallChunk.id != null &&\n toolCallChunk.name != null\n ) {\n tool_calls.push({\n args: {},\n id: toolCallChunk.id,\n name: toolCallChunk.name,\n type: ToolCallTypes.TOOL_CALL,\n });\n }\n }\n\n let stepId: string = _stepId;\n const alreadyDispatched =\n prevRunStep?.type === StepTypes.MESSAGE_CREATION &&\n graph.messageStepHasToolCalls.has(prevStepId);\n\n if (prevRunStep?.type === StepTypes.TOOL_CALLS) {\n /**\n * If previous step is already a tool_calls step, use that step ID\n * This ensures tool call deltas are dispatched to the correct step\n */\n stepId = prevStepId;\n } else if (\n !alreadyDispatched &&\n prevRunStep?.type === StepTypes.MESSAGE_CREATION\n ) {\n /**\n * Create tool_calls step as soon as we receive the first tool call chunk\n * This ensures deltas are always associated with the correct step\n *\n * NOTE: We do NOT dispatch an empty text block here because:\n * - Empty text blocks cause providers (Anthropic, Bedrock) to reject messages\n * - The tool_calls themselves are sufficient for the step\n * - Empty content with tool_call_ids gets stored in conversation history\n * and causes \"messages must have non-empty content\" errors on replay\n */\n graph.messageStepHasToolCalls.set(prevStepId, true);\n stepId = await graph.dispatchRunStep(\n stepKey,\n {\n type: StepTypes.TOOL_CALLS,\n tool_calls: tool_calls ?? [],\n },\n metadata\n );\n }\n\n await graph.dispatchRunStepDelta(stepId, {\n type: StepTypes.TOOL_CALLS,\n tool_calls: toolCallChunks,\n });\n}\n\nexport const handleToolCalls = async (\n toolCalls?: ToolCall[],\n metadata?: Record<string, unknown>,\n graph?: Graph | StandardGraph | MultiAgentGraph\n): Promise<void> => {\n if (!graph || !metadata) {\n console.warn('Graph or metadata not found in `handleToolCalls`');\n return;\n }\n\n if (!toolCalls) {\n return;\n }\n\n if (toolCalls.length === 0) {\n return;\n }\n\n const stepKey = graph.getStepKey(metadata);\n\n /**\n * Track whether we've already reused an empty TOOL_CALLS step created by\n * handleToolCallChunks during streaming. Only reuse it once (for the first\n * tool call); subsequent parallel tool calls must create their own steps.\n */\n let reusedChunkStepId: string | undefined;\n\n for (const tool_call of toolCalls) {\n const toolCallId = tool_call.id ?? `toolu_${nanoid()}`;\n tool_call.id = toolCallId;\n if (!toolCallId || graph.toolCallStepIds.has(toolCallId)) {\n continue;\n }\n\n let prevStepId = '';\n let prevRunStep: t.RunStep | undefined;\n try {\n prevStepId = graph.getStepIdByKey(stepKey);\n prevRunStep = graph.getRunStep(prevStepId);\n } catch {\n // no previous step\n }\n\n /**\n * If the previous step is TOOL_CALLS (from handleToolCallChunks or a prior\n * iteration), either reuse it (if empty) or dispatch a new TOOL_CALLS step\n * directly — skip the intermediate MESSAGE_CREATION to avoid orphaned gaps.\n */\n if (prevRunStep?.type === StepTypes.TOOL_CALLS) {\n const details = prevRunStep.stepDetails as t.ToolCallsDetails;\n const isEmpty = !details.tool_calls || details.tool_calls.length === 0;\n if (isEmpty && prevStepId !== reusedChunkStepId) {\n graph.toolCallStepIds.set(toolCallId, prevStepId);\n reusedChunkStepId = prevStepId;\n continue;\n }\n await graph.dispatchRunStep(\n stepKey,\n { type: StepTypes.TOOL_CALLS, tool_calls: [tool_call] },\n metadata\n );\n continue;\n }\n\n /**\n * NOTE: We do NOT dispatch empty text blocks with tool_call_ids because:\n * - Empty text blocks cause providers (Anthropic, Bedrock) to reject messages\n * - They get stored in conversation history and cause errors on replay:\n * \"messages must have non-empty content\" (Anthropic)\n * \"The content field in the Message object is empty\" (Bedrock)\n * - The tool_calls themselves are sufficient\n */\n if (prevStepId && prevRunStep) {\n graph.messageStepHasToolCalls.set(prevStepId, true);\n } else if (!prevRunStep) {\n const messageId = getMessageId(stepKey, graph, true) ?? '';\n const stepId = await graph.dispatchRunStep(\n stepKey,\n {\n type: StepTypes.MESSAGE_CREATION,\n message_creation: {\n message_id: messageId,\n },\n },\n metadata\n );\n graph.messageStepHasToolCalls.set(stepId, true);\n }\n\n await graph.dispatchRunStep(\n stepKey,\n {\n type: StepTypes.TOOL_CALLS,\n tool_calls: [tool_call],\n },\n metadata\n );\n }\n};\n\nexport const toolResultTypes = new Set([\n // 'tool_use',\n // 'server_tool_use',\n // 'input_json_delta',\n 'tool_result',\n 'web_search_result',\n 'web_search_tool_result',\n]);\n\n/**\n * Handles the result of a server tool call; in other words, a provider's built-in tool.\n * As of 2025-07-06, only Anthropic handles server tool calls with this pattern.\n */\nexport async function handleServerToolResult({\n graph,\n content,\n metadata,\n agentContext,\n}: {\n graph: StandardGraph | MultiAgentGraph;\n content?: string | t.MessageContentComplex[];\n metadata?: Record<string, unknown>;\n agentContext?: AgentContext;\n}): Promise<boolean> {\n let skipHandling = false;\n if (agentContext?.provider !== Providers.ANTHROPIC) {\n return skipHandling;\n }\n if (\n typeof content === 'string' ||\n content == null ||\n content.length === 0 ||\n (content.length === 1 &&\n (content[0] as t.ToolResultContent).tool_use_id == null)\n ) {\n return skipHandling;\n }\n\n for (const contentPart of content) {\n const toolUseId = (contentPart as t.ToolResultContent).tool_use_id;\n if (toolUseId == null || toolUseId === '') {\n continue;\n }\n const stepId = graph.toolCallStepIds.get(toolUseId);\n if (stepId == null || stepId === '') {\n console.warn(\n `Tool use ID ${toolUseId} not found in graph, cannot dispatch tool result.`\n );\n continue;\n }\n const runStep = graph.getRunStep(stepId);\n if (!runStep) {\n console.warn(\n `Run step for ${stepId} does not exist, cannot dispatch tool result.`\n );\n continue;\n } else if (runStep.type !== StepTypes.TOOL_CALLS) {\n console.warn(\n `Run step for ${stepId} is not a tool call step, cannot dispatch tool result.`\n );\n continue;\n }\n\n const toolCall =\n runStep.stepDetails.type === StepTypes.TOOL_CALLS\n ? (runStep.stepDetails.tool_calls?.find(\n (toolCall) => toolCall.id === toolUseId\n ) as ToolCall)\n : undefined;\n\n if (!toolCall) {\n continue;\n }\n\n if (\n contentPart.type === 'web_search_result' ||\n contentPart.type === 'web_search_tool_result'\n ) {\n await handleAnthropicSearchResults({\n contentPart: contentPart as t.ToolResultContent,\n toolCall,\n metadata,\n graph,\n });\n }\n\n if (!skipHandling) {\n skipHandling = true;\n }\n }\n\n return skipHandling;\n}\n\nasync function handleAnthropicSearchResults({\n contentPart,\n toolCall,\n metadata,\n graph,\n}: {\n contentPart: t.ToolResultContent;\n toolCall: Partial<ToolCall>;\n metadata?: Record<string, unknown>;\n graph: StandardGraph | MultiAgentGraph;\n}): Promise<void> {\n if (!Array.isArray(contentPart.content)) {\n console.warn(\n `Expected content to be an array, got ${typeof contentPart.content}`\n );\n return;\n }\n\n if (!isAnthropicWebSearchResult(contentPart.content[0])) {\n console.warn(\n `Expected content to be an Anthropic web search result, got ${JSON.stringify(\n contentPart.content\n )}`\n );\n return;\n }\n\n const turn = graph.invokedToolIds?.size ?? 0;\n const searchResultData = coerceAnthropicSearchResults({\n turn,\n results: contentPart.content as AnthropicWebSearchResultBlockParam[],\n });\n\n const name = toolCall.name;\n const input = toolCall.args ?? {};\n const artifact = {\n [Constants.WEB_SEARCH]: searchResultData,\n };\n const { output: formattedOutput } = formatResultsForLLM(\n turn,\n searchResultData\n );\n const output = new ToolMessage({\n name,\n artifact,\n content: formattedOutput,\n tool_call_id: toolCall.id!,\n });\n const toolEndData: t.ToolEndData = {\n input,\n output,\n };\n await graph.handlerRegistry\n ?.getHandler(GraphEvents.TOOL_END)\n ?.handle(GraphEvents.TOOL_END, toolEndData, metadata, graph);\n\n if (graph.invokedToolIds == null) {\n graph.invokedToolIds = new Set<string>();\n }\n\n graph.invokedToolIds.add(toolCall.id!);\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"handlers.mjs","sources":["../../../src/tools/handlers.ts"],"sourcesContent":["/* eslint-disable no-console */\n// src/tools/handlers.ts\nimport { nanoid } from 'nanoid';\nimport { ToolMessage } from '@langchain/core/messages';\nimport type { AnthropicWebSearchResultBlockParam } from '@/llm/anthropic/types';\nimport type { ToolCall, ToolCallChunk } from '@langchain/core/messages/tool';\nimport type { Graph, MultiAgentGraph, StandardGraph } from '@/graphs';\nimport type { AgentContext } from '@/agents/AgentContext';\nimport type * as t from '@/types';\nimport {\n ToolCallTypes,\n GraphEvents,\n StepTypes,\n Providers,\n Constants,\n} from '@/common';\nimport {\n coerceAnthropicSearchResults,\n isAnthropicWebSearchResult,\n} from '@/tools/search/anthropic';\nimport { formatResultsForLLM } from '@/tools/search/format';\nimport { getMessageId } from '@/messages';\n\nexport async function handleToolCallChunks({\n graph,\n stepKey,\n toolCallChunks,\n metadata,\n}: {\n graph: StandardGraph | MultiAgentGraph;\n stepKey: string;\n toolCallChunks: ToolCallChunk[];\n metadata?: Record<string, unknown>;\n}): Promise<void> {\n let prevStepId: string;\n let prevRunStep: t.RunStep | undefined;\n try {\n prevStepId = graph.getStepIdByKey(stepKey);\n prevRunStep = graph.getRunStep(prevStepId);\n } catch {\n /** Edge Case: If no previous step exists, create a new message creation step */\n const message_id = getMessageId(stepKey, graph, true) ?? '';\n prevStepId = await graph.dispatchRunStep(\n stepKey,\n {\n type: StepTypes.MESSAGE_CREATION,\n message_creation: {\n message_id,\n },\n },\n metadata\n );\n prevRunStep = graph.getRunStep(prevStepId);\n }\n\n const _stepId = graph.getStepIdByKey(stepKey);\n\n /** Edge Case: Tool Call Run Step or `tool_call_ids` never dispatched */\n const tool_calls: ToolCall[] | undefined =\n prevStepId && prevRunStep && prevRunStep.type === StepTypes.MESSAGE_CREATION\n ? []\n : undefined;\n\n /** Edge Case: `id` and `name` fields cannot be empty strings */\n for (const toolCallChunk of toolCallChunks) {\n if (toolCallChunk.name === '') {\n toolCallChunk.name = undefined;\n }\n if (toolCallChunk.id === '') {\n toolCallChunk.id = undefined;\n } else if (\n tool_calls != null &&\n toolCallChunk.id != null &&\n toolCallChunk.name != null\n ) {\n tool_calls.push({\n args: {},\n id: toolCallChunk.id,\n name: toolCallChunk.name,\n type: ToolCallTypes.TOOL_CALL,\n });\n }\n }\n\n let stepId: string = _stepId;\n const alreadyDispatched =\n prevRunStep?.type === StepTypes.MESSAGE_CREATION &&\n graph.messageStepHasToolCalls.has(prevStepId);\n\n if (prevRunStep?.type === StepTypes.TOOL_CALLS) {\n /**\n * If previous step is already a tool_calls step, use that step ID\n * This ensures tool call deltas are dispatched to the correct step\n */\n stepId = prevStepId;\n } else if (\n !alreadyDispatched &&\n prevRunStep?.type === StepTypes.MESSAGE_CREATION\n ) {\n /**\n * Create tool_calls step as soon as we receive the first tool call chunk\n * This ensures deltas are always associated with the correct step\n *\n * NOTE: We do NOT dispatch an empty text block here because:\n * - Empty text blocks cause providers (Anthropic, Bedrock) to reject messages\n * - The tool_calls themselves are sufficient for the step\n * - Empty content with tool_call_ids gets stored in conversation history\n * and causes \"messages must have non-empty content\" errors on replay\n */\n graph.messageStepHasToolCalls.set(prevStepId, true);\n stepId = await graph.dispatchRunStep(\n stepKey,\n {\n type: StepTypes.TOOL_CALLS,\n tool_calls: tool_calls ?? [],\n },\n metadata\n );\n }\n\n await graph.dispatchRunStepDelta(\n stepId,\n {\n type: StepTypes.TOOL_CALLS,\n tool_calls: toolCallChunks,\n },\n metadata\n );\n}\n\nexport const handleToolCalls = async (\n toolCalls?: ToolCall[],\n metadata?: Record<string, unknown>,\n graph?: Graph | StandardGraph | MultiAgentGraph\n): Promise<void> => {\n if (!graph || !metadata) {\n console.warn('Graph or metadata not found in `handleToolCalls`');\n return;\n }\n\n if (!toolCalls) {\n return;\n }\n\n if (toolCalls.length === 0) {\n return;\n }\n\n const stepKey = graph.getStepKey(metadata);\n\n /**\n * Track whether we've already reused an empty TOOL_CALLS step created by\n * handleToolCallChunks during streaming. Only reuse it once (for the first\n * tool call); subsequent parallel tool calls must create their own steps.\n */\n let reusedChunkStepId: string | undefined;\n\n for (const tool_call of toolCalls) {\n const toolCallId = tool_call.id ?? `toolu_${nanoid()}`;\n tool_call.id = toolCallId;\n if (!toolCallId || graph.toolCallStepIds.has(toolCallId)) {\n continue;\n }\n\n let prevStepId = '';\n let prevRunStep: t.RunStep | undefined;\n try {\n prevStepId = graph.getStepIdByKey(stepKey);\n prevRunStep = graph.getRunStep(prevStepId);\n } catch {\n // no previous step\n }\n\n /**\n * If the previous step is TOOL_CALLS (from handleToolCallChunks or a prior\n * iteration), either reuse it (if empty) or dispatch a new TOOL_CALLS step\n * directly — skip the intermediate MESSAGE_CREATION to avoid orphaned gaps.\n */\n if (prevRunStep?.type === StepTypes.TOOL_CALLS) {\n const details = prevRunStep.stepDetails as t.ToolCallsDetails;\n const isEmpty = !details.tool_calls || details.tool_calls.length === 0;\n if (isEmpty && prevStepId !== reusedChunkStepId) {\n graph.toolCallStepIds.set(toolCallId, prevStepId);\n reusedChunkStepId = prevStepId;\n continue;\n }\n await graph.dispatchRunStep(\n stepKey,\n { type: StepTypes.TOOL_CALLS, tool_calls: [tool_call] },\n metadata\n );\n continue;\n }\n\n /**\n * NOTE: We do NOT dispatch empty text blocks with tool_call_ids because:\n * - Empty text blocks cause providers (Anthropic, Bedrock) to reject messages\n * - They get stored in conversation history and cause errors on replay:\n * \"messages must have non-empty content\" (Anthropic)\n * \"The content field in the Message object is empty\" (Bedrock)\n * - The tool_calls themselves are sufficient\n */\n if (prevStepId && prevRunStep) {\n graph.messageStepHasToolCalls.set(prevStepId, true);\n } else if (!prevRunStep) {\n const messageId = getMessageId(stepKey, graph, true) ?? '';\n const stepId = await graph.dispatchRunStep(\n stepKey,\n {\n type: StepTypes.MESSAGE_CREATION,\n message_creation: {\n message_id: messageId,\n },\n },\n metadata\n );\n graph.messageStepHasToolCalls.set(stepId, true);\n }\n\n await graph.dispatchRunStep(\n stepKey,\n {\n type: StepTypes.TOOL_CALLS,\n tool_calls: [tool_call],\n },\n metadata\n );\n }\n};\n\nexport const toolResultTypes = new Set([\n // 'tool_use',\n // 'server_tool_use',\n // 'input_json_delta',\n 'tool_result',\n 'web_search_result',\n 'web_search_tool_result',\n]);\n\n/**\n * Handles the result of a server tool call; in other words, a provider's built-in tool.\n * As of 2025-07-06, only Anthropic handles server tool calls with this pattern.\n */\nexport async function handleServerToolResult({\n graph,\n content,\n metadata,\n agentContext,\n}: {\n graph: StandardGraph | MultiAgentGraph;\n content?: string | t.MessageContentComplex[];\n metadata?: Record<string, unknown>;\n agentContext?: AgentContext;\n}): Promise<boolean> {\n let skipHandling = false;\n if (agentContext?.provider !== Providers.ANTHROPIC) {\n return skipHandling;\n }\n if (\n typeof content === 'string' ||\n content == null ||\n content.length === 0 ||\n (content.length === 1 &&\n (content[0] as t.ToolResultContent).tool_use_id == null)\n ) {\n return skipHandling;\n }\n\n for (const contentPart of content) {\n const toolUseId = (contentPart as t.ToolResultContent).tool_use_id;\n if (toolUseId == null || toolUseId === '') {\n continue;\n }\n const stepId = graph.toolCallStepIds.get(toolUseId);\n if (stepId == null || stepId === '') {\n console.warn(\n `Tool use ID ${toolUseId} not found in graph, cannot dispatch tool result.`\n );\n continue;\n }\n const runStep = graph.getRunStep(stepId);\n if (!runStep) {\n console.warn(\n `Run step for ${stepId} does not exist, cannot dispatch tool result.`\n );\n continue;\n } else if (runStep.type !== StepTypes.TOOL_CALLS) {\n console.warn(\n `Run step for ${stepId} is not a tool call step, cannot dispatch tool result.`\n );\n continue;\n }\n\n const toolCall =\n runStep.stepDetails.type === StepTypes.TOOL_CALLS\n ? (runStep.stepDetails.tool_calls?.find(\n (toolCall) => toolCall.id === toolUseId\n ) as ToolCall)\n : undefined;\n\n if (!toolCall) {\n continue;\n }\n\n if (\n contentPart.type === 'web_search_result' ||\n contentPart.type === 'web_search_tool_result'\n ) {\n await handleAnthropicSearchResults({\n contentPart: contentPart as t.ToolResultContent,\n toolCall,\n metadata,\n graph,\n });\n }\n\n if (!skipHandling) {\n skipHandling = true;\n }\n }\n\n return skipHandling;\n}\n\nasync function handleAnthropicSearchResults({\n contentPart,\n toolCall,\n metadata,\n graph,\n}: {\n contentPart: t.ToolResultContent;\n toolCall: Partial<ToolCall>;\n metadata?: Record<string, unknown>;\n graph: StandardGraph | MultiAgentGraph;\n}): Promise<void> {\n if (!Array.isArray(contentPart.content)) {\n console.warn(\n `Expected content to be an array, got ${typeof contentPart.content}`\n );\n return;\n }\n\n if (!isAnthropicWebSearchResult(contentPart.content[0])) {\n console.warn(\n `Expected content to be an Anthropic web search result, got ${JSON.stringify(\n contentPart.content\n )}`\n );\n return;\n }\n\n const turn = graph.invokedToolIds?.size ?? 0;\n const searchResultData = coerceAnthropicSearchResults({\n turn,\n results: contentPart.content as AnthropicWebSearchResultBlockParam[],\n });\n\n const name = toolCall.name;\n const input = toolCall.args ?? {};\n const artifact = {\n [Constants.WEB_SEARCH]: searchResultData,\n };\n const { output: formattedOutput } = formatResultsForLLM(\n turn,\n searchResultData\n );\n const output = new ToolMessage({\n name,\n artifact,\n content: formattedOutput,\n tool_call_id: toolCall.id!,\n });\n const toolEndData: t.ToolEndData = {\n input,\n output,\n };\n await graph.handlerRegistry\n ?.getHandler(GraphEvents.TOOL_END)\n ?.handle(GraphEvents.TOOL_END, toolEndData, metadata, graph);\n\n if (graph.invokedToolIds == null) {\n graph.invokedToolIds = new Set<string>();\n }\n\n graph.invokedToolIds.add(toolCall.id!);\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ const STREAMED_TOOL_CALL_ADAPTER_METADATA_KEY = 'lc_streamed_tool_call_adapter';
2
+ const STREAMED_TOOL_CALL_SEAL_METADATA_KEY = 'lc_streamed_tool_call_seal';
3
+ const OPENAI_RESPONSES_STREAMED_TOOL_CALL_ADAPTER = 'openai_responses';
4
+ function getStreamedToolCallAdapter(metadata) {
5
+ if (metadata?.[STREAMED_TOOL_CALL_ADAPTER_METADATA_KEY] ===
6
+ OPENAI_RESPONSES_STREAMED_TOOL_CALL_ADAPTER) {
7
+ return OPENAI_RESPONSES_STREAMED_TOOL_CALL_ADAPTER;
8
+ }
9
+ return undefined;
10
+ }
11
+ function getStreamedToolCallSeal(metadata) {
12
+ const seal = metadata?.[STREAMED_TOOL_CALL_SEAL_METADATA_KEY];
13
+ if (seal == null || typeof seal !== 'object') {
14
+ return undefined;
15
+ }
16
+ if (!('kind' in seal)) {
17
+ return undefined;
18
+ }
19
+ if (seal.kind === 'all') {
20
+ return { kind: 'all' };
21
+ }
22
+ if (seal.kind !== 'single') {
23
+ return undefined;
24
+ }
25
+ const id = 'id' in seal && typeof seal.id === 'string' ? seal.id : undefined;
26
+ const index = 'index' in seal && typeof seal.index === 'number'
27
+ ? seal.index
28
+ : undefined;
29
+ if (id == null && index == null) {
30
+ return undefined;
31
+ }
32
+ return { kind: 'single', id, index };
33
+ }
34
+
35
+ export { OPENAI_RESPONSES_STREAMED_TOOL_CALL_ADAPTER, STREAMED_TOOL_CALL_ADAPTER_METADATA_KEY, STREAMED_TOOL_CALL_SEAL_METADATA_KEY, getStreamedToolCallAdapter, getStreamedToolCallSeal };
36
+ //# sourceMappingURL=streamedToolCallSeals.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"streamedToolCallSeals.mjs","sources":["../../../src/tools/streamedToolCallSeals.ts"],"sourcesContent":["export const STREAMED_TOOL_CALL_ADAPTER_METADATA_KEY =\n 'lc_streamed_tool_call_adapter';\nexport const STREAMED_TOOL_CALL_SEAL_METADATA_KEY =\n 'lc_streamed_tool_call_seal';\nexport const OPENAI_RESPONSES_STREAMED_TOOL_CALL_ADAPTER = 'openai_responses';\n\nexport type StreamedToolCallAdapter =\n typeof OPENAI_RESPONSES_STREAMED_TOOL_CALL_ADAPTER;\n\nexport type StreamedToolCallSeal =\n | {\n kind: 'single';\n id?: string;\n index?: number;\n }\n | {\n kind: 'all';\n };\n\nexport function getStreamedToolCallAdapter(\n metadata: Record<string, unknown> | undefined\n): StreamedToolCallAdapter | undefined {\n if (\n metadata?.[STREAMED_TOOL_CALL_ADAPTER_METADATA_KEY] ===\n OPENAI_RESPONSES_STREAMED_TOOL_CALL_ADAPTER\n ) {\n return OPENAI_RESPONSES_STREAMED_TOOL_CALL_ADAPTER;\n }\n return undefined;\n}\n\nexport function getStreamedToolCallSeal(\n metadata: Record<string, unknown> | undefined\n): StreamedToolCallSeal | undefined {\n const seal = metadata?.[STREAMED_TOOL_CALL_SEAL_METADATA_KEY];\n if (seal == null || typeof seal !== 'object') {\n return undefined;\n }\n if (!('kind' in seal)) {\n return undefined;\n }\n if (seal.kind === 'all') {\n return { kind: 'all' };\n }\n if (seal.kind !== 'single') {\n return undefined;\n }\n const id = 'id' in seal && typeof seal.id === 'string' ? seal.id : undefined;\n const index =\n 'index' in seal && typeof seal.index === 'number'\n ? seal.index\n : undefined;\n if (id == null && index == null) {\n return undefined;\n }\n return { kind: 'single', id, index };\n}\n"],"names":[],"mappings":"AAAO,MAAM,uCAAuC,GAClD;AACK,MAAM,oCAAoC,GAC/C;AACK,MAAM,2CAA2C,GAAG;AAerD,SAAU,0BAA0B,CACxC,QAA6C,EAAA;AAE7C,IAAA,IACE,QAAQ,GAAG,uCAAuC,CAAC;AACnD,QAAA,2CAA2C,EAC3C;AACA,QAAA,OAAO,2CAA2C;IACpD;AACA,IAAA,OAAO,SAAS;AAClB;AAEM,SAAU,uBAAuB,CACrC,QAA6C,EAAA;AAE7C,IAAA,MAAM,IAAI,GAAG,QAAQ,GAAG,oCAAoC,CAAC;IAC7D,IAAI,IAAI,IAAI,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE;AAC5C,QAAA,OAAO,SAAS;IAClB;AACA,IAAA,IAAI,EAAE,MAAM,IAAI,IAAI,CAAC,EAAE;AACrB,QAAA,OAAO,SAAS;IAClB;AACA,IAAA,IAAI,IAAI,CAAC,IAAI,KAAK,KAAK,EAAE;AACvB,QAAA,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE;IACxB;AACA,IAAA,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ,EAAE;AAC1B,QAAA,OAAO,SAAS;IAClB;IACA,MAAM,EAAE,GAAG,IAAI,IAAI,IAAI,IAAI,OAAO,IAAI,CAAC,EAAE,KAAK,QAAQ,GAAG,IAAI,CAAC,EAAE,GAAG,SAAS;IAC5E,MAAM,KAAK,GACT,OAAO,IAAI,IAAI,IAAI,OAAO,IAAI,CAAC,KAAK,KAAK;UACrC,IAAI,CAAC;UACL,SAAS;IACf,IAAI,EAAE,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,EAAE;AAC/B,QAAA,OAAO,SAAS;IAClB;IACA,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,KAAK,EAAE;AACtC;;;;"}
@@ -7,6 +7,7 @@ export declare class HandlerRegistry {
7
7
  register(eventType: string, handler: t.EventHandler): void;
8
8
  getHandler(eventType: string): t.EventHandler | undefined;
9
9
  }
10
+ export declare function composeEventHandlers(...handlerSets: Array<Record<string, t.EventHandler> | undefined>): Record<string, t.EventHandler>;
10
11
  export declare class ModelEndHandler implements t.EventHandler {
11
12
  collectedUsage?: UsageMetadata[];
12
13
  constructor(collectedUsage?: UsageMetadata[]);
@@ -23,9 +23,9 @@ export declare abstract class Graph<T extends t.BaseGraphState = t.BaseGraphStat
23
23
  abstract getStepIdByKey(stepKey: string, index?: number): string;
24
24
  abstract getRunStep(stepId: string): t.RunStep | undefined;
25
25
  abstract dispatchRunStep(stepKey: string, stepDetails: t.StepDetails, metadata?: Record<string, unknown>): Promise<string>;
26
- abstract dispatchRunStepDelta(id: string, delta: t.ToolCallDelta): Promise<void>;
27
- abstract dispatchMessageDelta(id: string, delta: t.MessageDelta): Promise<void>;
28
- abstract dispatchReasoningDelta(stepId: string, delta: t.ReasoningDelta): Promise<void>;
26
+ abstract dispatchRunStepDelta(id: string, delta: t.ToolCallDelta, metadata?: Record<string, unknown>): Promise<void>;
27
+ abstract dispatchMessageDelta(id: string, delta: t.MessageDelta, metadata?: Record<string, unknown>): Promise<void>;
28
+ abstract dispatchReasoningDelta(stepId: string, delta: t.ReasoningDelta, metadata?: Record<string, unknown>): Promise<void>;
29
29
  abstract createCallModel(agentId?: string, currentModel?: t.ChatModel): (state: t.AgentSubgraphState, config?: RunnableConfig) => Promise<Partial<t.AgentSubgraphState>>;
30
30
  messageStepHasToolCalls: Map<string, boolean>;
31
31
  messageIdsByStepKey: Map<string, string>;
@@ -36,11 +36,12 @@ export declare abstract class Graph<T extends t.BaseGraphState = t.BaseGraphStat
36
36
  contentIndexMap: Map<string, number>;
37
37
  toolCallStepIds: Map<string, string>;
38
38
  /**
39
- * Step IDs that have been dispatched via handler registry directly
40
- * (in dispatchRunStep). Used by the custom event callback to skip
41
- * duplicate dispatch through the LangGraph callback chain.
39
+ * Step IDs dispatched through the handler registry during this run.
40
+ * Event echo suppression is tracked separately so repeated deltas for
41
+ * the same step are scoped to the active custom event dispatch.
42
42
  */
43
43
  handlerDispatchedStepIds: Set<string>;
44
+ protected handlerDispatchedEventCounts: Map<string, number>;
44
45
  signal?: AbortSignal;
45
46
  /** Set of invoked tool call IDs from non-message run steps completed mid-run, if any */
46
47
  invokedToolIds?: Set<string>;
@@ -59,6 +60,16 @@ export declare abstract class Graph<T extends t.BaseGraphState = t.BaseGraphStat
59
60
  * graph compiles.
60
61
  */
61
62
  toolOutputReferences: t.ToolOutputReferencesConfig | undefined;
63
+ /**
64
+ * Run-scoped opt-in for eager event-driven tool execution. The stream
65
+ * handler may prestart eligible event-driven tools; ToolNode later
66
+ * consumes the settled promises while preserving final ToolMessage order.
67
+ */
68
+ eagerEventToolExecution: t.EagerEventToolExecutionConfig | undefined;
69
+ eagerEventToolExecutions: Map<string, t.EagerEventToolExecution>;
70
+ eagerEventToolUsageCount: Map<string, number>;
71
+ private eagerEventToolUsageCountsByAgentId;
72
+ eagerEventToolCallChunks: Map<string, t.EagerEventToolCallChunkState>;
62
73
  /**
63
74
  * Run-scoped execution backend for built-in code tools. Defaults to the
64
75
  * remote Code API sandbox when unset.
@@ -83,6 +94,10 @@ export declare abstract class Graph<T extends t.BaseGraphState = t.BaseGraphStat
83
94
  * Call after a run completes and content has been extracted.
84
95
  */
85
96
  clearHeavyState(): void;
97
+ getEagerEventToolUsageCount(agentId?: string): Map<string, number>;
98
+ protected clearEagerEventToolUsageCounts(): void;
99
+ markHandlerDispatchedEvent(eventName: string, stepId: string): () => void;
100
+ hasHandlerDispatchedEvent(eventName: string, stepId: string): boolean;
86
101
  /**
87
102
  * Subclass hook to register a freshly compiled ToolNode so
88
103
  * `clearHeavyState` can flush its per-Run direct-path turn cache
@@ -219,7 +234,7 @@ export declare class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode>
219
234
  * Kept for backward compatibility
220
235
  */
221
236
  handleToolCallError(data: t.ToolErrorData, metadata?: Record<string, unknown>): Promise<void>;
222
- dispatchRunStepDelta(id: string, delta: t.ToolCallDelta): Promise<void>;
223
- dispatchMessageDelta(id: string, delta: t.MessageDelta): Promise<void>;
224
- dispatchReasoningDelta: (stepId: string, delta: t.ReasoningDelta) => Promise<void>;
237
+ dispatchRunStepDelta(id: string, delta: t.ToolCallDelta, metadata?: Record<string, unknown>): Promise<void>;
238
+ dispatchMessageDelta(id: string, delta: t.MessageDelta, metadata?: Record<string, unknown>): Promise<void>;
239
+ dispatchReasoningDelta: (stepId: string, delta: t.ReasoningDelta, metadata?: Record<string, unknown>) => Promise<void>;
225
240
  }
@@ -24,6 +24,7 @@ export * from './tools/search';
24
24
  export * from './common';
25
25
  export * from './utils';
26
26
  export * from './hooks';
27
+ export * from './session';
27
28
  export * from './hitl';
28
29
  export type * from './types';
29
30
  export * from './langchain';
@@ -24,6 +24,7 @@ type LibreChatOpenAIFields = t.ChatOpenAIFields & {
24
24
  type LibreChatAzureOpenAIFields = t.AzureOpenAIInput & {
25
25
  _lc_stream_delay?: number;
26
26
  };
27
+ export declare function emitStreamChunkCallback(chunk: ChatGenerationChunk, runManager?: CallbackManagerForLLMRun): Promise<void>;
27
28
  /**
28
29
  * Formats a tool in either OpenAI format, or LangChain structured tool format
29
30
  * into an OpenAI tool format. If the tool is already in OpenAI format, return without
@@ -0,0 +1,75 @@
1
+ import type * as t from '@/types';
2
+ export interface OpenAICompatibleWriter {
3
+ write(data: string): void | Promise<void>;
4
+ }
5
+ export interface OpenAIResponseContext {
6
+ requestId: string;
7
+ model: string;
8
+ created: number;
9
+ }
10
+ export interface OpenAICompletionUsage {
11
+ prompt_tokens: number;
12
+ completion_tokens: number;
13
+ total_tokens: number;
14
+ completion_tokens_details?: {
15
+ reasoning_tokens?: number;
16
+ };
17
+ }
18
+ export interface OpenAIToolCall {
19
+ id: string;
20
+ type: 'function';
21
+ function: {
22
+ name: string;
23
+ arguments: string;
24
+ };
25
+ }
26
+ export interface OpenAIChatCompletionChunkChoice {
27
+ index: number;
28
+ delta: {
29
+ role?: 'assistant';
30
+ content?: string | null;
31
+ reasoning?: string | null;
32
+ tool_calls?: Array<{
33
+ index: number;
34
+ id?: string;
35
+ type?: 'function';
36
+ function?: {
37
+ name?: string;
38
+ arguments?: string;
39
+ };
40
+ }>;
41
+ };
42
+ finish_reason: 'stop' | 'length' | 'tool_calls' | 'content_filter' | null;
43
+ }
44
+ export interface OpenAIChatCompletionChunk {
45
+ id: string;
46
+ object: 'chat.completion.chunk';
47
+ created: number;
48
+ model: string;
49
+ choices: OpenAIChatCompletionChunkChoice[];
50
+ usage?: OpenAICompletionUsage;
51
+ }
52
+ export interface OpenAIStreamTracker {
53
+ hasRole: boolean;
54
+ hasText: boolean;
55
+ hasReasoning: boolean;
56
+ lastChunkKind?: 'text' | 'reasoning' | 'tool_call';
57
+ toolCalls: Map<number, OpenAIToolCall>;
58
+ toolCallsByStep?: Map<string, Map<number, OpenAIToolCall>>;
59
+ usage: {
60
+ promptTokens: number;
61
+ completionTokens: number;
62
+ reasoningTokens: number;
63
+ };
64
+ }
65
+ export interface OpenAIHandlerConfig {
66
+ writer: OpenAICompatibleWriter;
67
+ context: OpenAIResponseContext;
68
+ tracker: OpenAIStreamTracker;
69
+ }
70
+ export declare function createOpenAIStreamTracker(): OpenAIStreamTracker;
71
+ export declare function createChatCompletionChunk(context: OpenAIResponseContext, delta: OpenAIChatCompletionChunkChoice['delta'], finishReason?: OpenAIChatCompletionChunkChoice['finish_reason'], usage?: OpenAICompletionUsage): OpenAIChatCompletionChunk;
72
+ export declare function createChatCompletionUsageChunk(context: OpenAIResponseContext, usage: OpenAICompletionUsage): OpenAIChatCompletionChunk;
73
+ export declare function writeOpenAISSE(writer: OpenAICompatibleWriter, data: OpenAIChatCompletionChunk | '[DONE]'): Promise<void>;
74
+ export declare function createOpenAIHandlers(config: OpenAIHandlerConfig): Record<string, t.EventHandler>;
75
+ export declare function sendOpenAIFinalChunk(config: OpenAIHandlerConfig, finishReason?: OpenAIChatCompletionChunkChoice['finish_reason']): Promise<void>;
@@ -0,0 +1,97 @@
1
+ import type * as t from '@/types';
2
+ export interface ResponsesCompatibleWriter {
3
+ write(data: string): void | Promise<void>;
4
+ }
5
+ export type ResponseStatus = 'in_progress' | 'completed' | 'failed' | 'incomplete';
6
+ export type ItemStatus = 'in_progress' | 'incomplete' | 'completed';
7
+ export interface ResponseContext {
8
+ responseId: string;
9
+ model: string;
10
+ createdAt: number;
11
+ previousResponseId?: string;
12
+ instructions?: string;
13
+ }
14
+ export interface ResponseOutputTextContent {
15
+ type: 'output_text';
16
+ text: string;
17
+ annotations: [];
18
+ logprobs: [];
19
+ }
20
+ export interface ResponseMessageItem {
21
+ type: 'message';
22
+ id: string;
23
+ role: 'assistant';
24
+ status: ItemStatus;
25
+ content: ResponseOutputTextContent[];
26
+ }
27
+ export interface ResponseFunctionCallItem {
28
+ type: 'function_call';
29
+ id: string;
30
+ call_id: string;
31
+ name: string;
32
+ arguments: string;
33
+ status: ItemStatus;
34
+ }
35
+ export interface ResponseReasoningItem {
36
+ type: 'reasoning';
37
+ id: string;
38
+ status: ItemStatus;
39
+ content: Array<{
40
+ type: 'reasoning_text';
41
+ text: string;
42
+ }>;
43
+ summary: [];
44
+ }
45
+ export type ResponseOutputItem = ResponseMessageItem | ResponseFunctionCallItem | ResponseReasoningItem;
46
+ export interface ResponseObject {
47
+ id: string;
48
+ object: 'response';
49
+ created_at: number;
50
+ completed_at: number | null;
51
+ status: ResponseStatus;
52
+ model: string;
53
+ previous_response_id: string | null;
54
+ instructions: string | null;
55
+ output: ResponseOutputItem[];
56
+ error: {
57
+ type: string;
58
+ message: string;
59
+ code?: string;
60
+ } | null;
61
+ usage: {
62
+ input_tokens: number;
63
+ output_tokens: number;
64
+ total_tokens: number;
65
+ } | null;
66
+ }
67
+ export interface ResponseEvent {
68
+ type: string;
69
+ sequence_number: number;
70
+ [key: string]: unknown;
71
+ }
72
+ export interface ResponseTracker {
73
+ sequenceNumber: number;
74
+ items: ResponseOutputItem[];
75
+ message: ResponseMessageItem | undefined;
76
+ reasoning: ResponseReasoningItem | undefined;
77
+ functionCalls: Map<string, ResponseFunctionCallItem>;
78
+ functionCallsByStep: Map<string, Array<ResponseFunctionCallItem | undefined>>;
79
+ responseCreated: boolean;
80
+ usage: {
81
+ inputTokens: number;
82
+ outputTokens: number;
83
+ };
84
+ nextSequence(): number;
85
+ }
86
+ export interface ResponsesHandlerConfig {
87
+ writer: ResponsesCompatibleWriter;
88
+ context: ResponseContext;
89
+ tracker: ResponseTracker;
90
+ }
91
+ export declare function createResponseTracker(): ResponseTracker;
92
+ export declare function buildResponse(context: ResponseContext, tracker: ResponseTracker, status?: ResponseStatus): ResponseObject;
93
+ export declare function writeResponseEvent(writer: ResponsesCompatibleWriter, event: ResponseEvent): Promise<void>;
94
+ export declare function writeResponsesDone(writer: ResponsesCompatibleWriter): Promise<void>;
95
+ export declare function ensureResponseCreated(config: ResponsesHandlerConfig): Promise<void>;
96
+ export declare function createResponsesEventHandlers(config: ResponsesHandlerConfig): Record<string, t.EventHandler>;
97
+ export declare function emitResponseCompleted(config: ResponsesHandlerConfig): Promise<void>;
@@ -13,6 +13,7 @@ export declare class Run<_T extends t.BaseGraphState> {
13
13
  private hookRegistry?;
14
14
  private humanInTheLoop?;
15
15
  private toolOutputReferences?;
16
+ private eagerEventToolExecution?;
16
17
  private toolExecution?;
17
18
  private indexTokenCountMap?;
18
19
  calibrationRatio: number;
@@ -178,6 +179,7 @@ export declare class Run<_T extends t.BaseGraphState> {
178
179
  version: 'v1' | 'v2';
179
180
  run_id?: string;
180
181
  }, streamOptions?: t.EventStreamOptions): Promise<MessageContentComplex[] | undefined>;
182
+ private resolveInterruptResumeConfig;
181
183
  private createSystemCallback;
182
184
  getCallbacks(clientCallbacks: t.ClientCallbacks): t.SystemCallbacks;
183
185
  generateTitle({ provider, inputText, contentParts, titlePrompt, clientOptions, chainOptions, skipLanguage, titleMethod, titlePromptTemplate, }: t.RunTitleOptions): Promise<{
@@ -0,0 +1,32 @@
1
+ import type { BaseCheckpointSaver } from '@langchain/langgraph';
2
+ import type { AgentSessionConfig, AgentSessionCheckpointLookupOptions, AgentSessionCheckpointReference, AgentSessionInput, AgentSessionRunOptions, AgentSessionRunResult, AgentSessionStream, SessionBranchOptions, SessionCompactOptions, SessionForkOptions } from './types';
3
+ import { JsonlSessionStore } from './JsonlSessionStore';
4
+ export declare class AgentSession {
5
+ private runConfig;
6
+ private store;
7
+ private calibrationRatio;
8
+ private checkpointing;
9
+ cwd: string;
10
+ threadId: string;
11
+ private constructor();
12
+ static create(config: AgentSessionConfig): Promise<AgentSession>;
13
+ get sessionPath(): string | undefined;
14
+ getSessionStore(): JsonlSessionStore | undefined;
15
+ getCheckpointer(): BaseCheckpointSaver | undefined;
16
+ getLatestCheckpoint(options?: AgentSessionCheckpointLookupOptions): Promise<AgentSessionCheckpointReference | undefined>;
17
+ private hasCheckpointState;
18
+ private recordCheckpoint;
19
+ private getCheckpointThreadIds;
20
+ private resetCheckpointThreads;
21
+ private runInternal;
22
+ run(input: AgentSessionInput, options?: AgentSessionRunOptions): Promise<AgentSessionRunResult>;
23
+ stream(input: AgentSessionInput, options?: AgentSessionRunOptions): AgentSessionStream;
24
+ resumeSession(pathOrId?: string): Promise<AgentSession>;
25
+ clone(options?: SessionForkOptions): Promise<AgentSession>;
26
+ fork(entryId: string, options?: SessionForkOptions): Promise<AgentSession>;
27
+ branch(entryId: string, options?: SessionBranchOptions): Promise<void>;
28
+ compact(options?: SessionCompactOptions): Promise<void>;
29
+ private compactActivePath;
30
+ resumeInterrupt<TResume>(resumeValue: TResume, options?: AgentSessionRunOptions): Promise<AgentSessionRunResult>;
31
+ }
32
+ export declare function createAgentSession(config: AgentSessionConfig): Promise<AgentSession>;