@librechat/agents 3.0.0-rc1 → 3.0.0-rc11

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 (187) 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 +7 -2
  4. package/dist/cjs/graphs/Graph.cjs.map +1 -1
  5. package/dist/cjs/graphs/MultiAgentGraph.cjs +229 -44
  6. package/dist/cjs/graphs/MultiAgentGraph.cjs.map +1 -1
  7. package/dist/cjs/llm/anthropic/index.cjs +21 -2
  8. package/dist/cjs/llm/anthropic/index.cjs.map +1 -1
  9. package/dist/cjs/llm/google/index.cjs +3 -0
  10. package/dist/cjs/llm/google/index.cjs.map +1 -1
  11. package/dist/cjs/llm/google/utils/common.cjs +13 -0
  12. package/dist/cjs/llm/google/utils/common.cjs.map +1 -1
  13. package/dist/cjs/llm/ollama/index.cjs +3 -0
  14. package/dist/cjs/llm/ollama/index.cjs.map +1 -1
  15. package/dist/cjs/llm/openai/index.cjs +53 -1
  16. package/dist/cjs/llm/openai/index.cjs.map +1 -1
  17. package/dist/cjs/llm/openai/utils/index.cjs +6 -1
  18. package/dist/cjs/llm/openai/utils/index.cjs.map +1 -1
  19. package/dist/cjs/llm/openrouter/index.cjs +5 -1
  20. package/dist/cjs/llm/openrouter/index.cjs.map +1 -1
  21. package/dist/cjs/llm/vertexai/index.cjs +1 -1
  22. package/dist/cjs/llm/vertexai/index.cjs.map +1 -1
  23. package/dist/cjs/main.cjs +3 -1
  24. package/dist/cjs/main.cjs.map +1 -1
  25. package/dist/cjs/messages/core.cjs +5 -1
  26. package/dist/cjs/messages/core.cjs.map +1 -1
  27. package/dist/cjs/messages/format.cjs +52 -34
  28. package/dist/cjs/messages/format.cjs.map +1 -1
  29. package/dist/cjs/messages/prune.cjs +28 -0
  30. package/dist/cjs/messages/prune.cjs.map +1 -1
  31. package/dist/cjs/run.cjs +28 -15
  32. package/dist/cjs/run.cjs.map +1 -1
  33. package/dist/cjs/stream.cjs +1 -1
  34. package/dist/cjs/stream.cjs.map +1 -1
  35. package/dist/cjs/tools/ToolNode.cjs +2 -0
  36. package/dist/cjs/tools/ToolNode.cjs.map +1 -1
  37. package/dist/cjs/tools/search/firecrawl.cjs +3 -1
  38. package/dist/cjs/tools/search/firecrawl.cjs.map +1 -1
  39. package/dist/cjs/tools/search/rerankers.cjs +8 -6
  40. package/dist/cjs/tools/search/rerankers.cjs.map +1 -1
  41. package/dist/cjs/tools/search/search.cjs +5 -5
  42. package/dist/cjs/tools/search/search.cjs.map +1 -1
  43. package/dist/cjs/tools/search/serper-scraper.cjs +132 -0
  44. package/dist/cjs/tools/search/serper-scraper.cjs.map +1 -0
  45. package/dist/cjs/tools/search/tool.cjs +46 -9
  46. package/dist/cjs/tools/search/tool.cjs.map +1 -1
  47. package/dist/cjs/utils/handlers.cjs +70 -0
  48. package/dist/cjs/utils/handlers.cjs.map +1 -0
  49. package/dist/esm/common/enum.mjs +1 -0
  50. package/dist/esm/common/enum.mjs.map +1 -1
  51. package/dist/esm/graphs/Graph.mjs +7 -2
  52. package/dist/esm/graphs/Graph.mjs.map +1 -1
  53. package/dist/esm/graphs/MultiAgentGraph.mjs +230 -45
  54. package/dist/esm/graphs/MultiAgentGraph.mjs.map +1 -1
  55. package/dist/esm/llm/anthropic/index.mjs +21 -2
  56. package/dist/esm/llm/anthropic/index.mjs.map +1 -1
  57. package/dist/esm/llm/google/index.mjs +3 -0
  58. package/dist/esm/llm/google/index.mjs.map +1 -1
  59. package/dist/esm/llm/google/utils/common.mjs +13 -0
  60. package/dist/esm/llm/google/utils/common.mjs.map +1 -1
  61. package/dist/esm/llm/ollama/index.mjs +3 -0
  62. package/dist/esm/llm/ollama/index.mjs.map +1 -1
  63. package/dist/esm/llm/openai/index.mjs +53 -1
  64. package/dist/esm/llm/openai/index.mjs.map +1 -1
  65. package/dist/esm/llm/openai/utils/index.mjs +6 -1
  66. package/dist/esm/llm/openai/utils/index.mjs.map +1 -1
  67. package/dist/esm/llm/openrouter/index.mjs +5 -1
  68. package/dist/esm/llm/openrouter/index.mjs.map +1 -1
  69. package/dist/esm/llm/vertexai/index.mjs +1 -1
  70. package/dist/esm/llm/vertexai/index.mjs.map +1 -1
  71. package/dist/esm/main.mjs +2 -1
  72. package/dist/esm/main.mjs.map +1 -1
  73. package/dist/esm/messages/core.mjs +5 -1
  74. package/dist/esm/messages/core.mjs.map +1 -1
  75. package/dist/esm/messages/format.mjs +52 -34
  76. package/dist/esm/messages/format.mjs.map +1 -1
  77. package/dist/esm/messages/prune.mjs +28 -0
  78. package/dist/esm/messages/prune.mjs.map +1 -1
  79. package/dist/esm/run.mjs +28 -15
  80. package/dist/esm/run.mjs.map +1 -1
  81. package/dist/esm/stream.mjs +1 -1
  82. package/dist/esm/stream.mjs.map +1 -1
  83. package/dist/esm/tools/ToolNode.mjs +2 -0
  84. package/dist/esm/tools/ToolNode.mjs.map +1 -1
  85. package/dist/esm/tools/search/firecrawl.mjs +3 -1
  86. package/dist/esm/tools/search/firecrawl.mjs.map +1 -1
  87. package/dist/esm/tools/search/rerankers.mjs +8 -6
  88. package/dist/esm/tools/search/rerankers.mjs.map +1 -1
  89. package/dist/esm/tools/search/search.mjs +5 -5
  90. package/dist/esm/tools/search/search.mjs.map +1 -1
  91. package/dist/esm/tools/search/serper-scraper.mjs +129 -0
  92. package/dist/esm/tools/search/serper-scraper.mjs.map +1 -0
  93. package/dist/esm/tools/search/tool.mjs +46 -9
  94. package/dist/esm/tools/search/tool.mjs.map +1 -1
  95. package/dist/esm/utils/handlers.mjs +68 -0
  96. package/dist/esm/utils/handlers.mjs.map +1 -0
  97. package/dist/types/common/enum.d.ts +2 -1
  98. package/dist/types/graphs/MultiAgentGraph.d.ts +12 -2
  99. package/dist/types/llm/anthropic/index.d.ts +3 -0
  100. package/dist/types/llm/google/index.d.ts +1 -0
  101. package/dist/types/llm/ollama/index.d.ts +1 -0
  102. package/dist/types/llm/openai/index.d.ts +14 -0
  103. package/dist/types/llm/openrouter/index.d.ts +4 -2
  104. package/dist/types/llm/vertexai/index.d.ts +1 -1
  105. package/dist/types/messages/format.d.ts +23 -20
  106. package/dist/types/run.d.ts +1 -1
  107. package/dist/types/tools/search/firecrawl.d.ts +2 -1
  108. package/dist/types/tools/search/rerankers.d.ts +4 -1
  109. package/dist/types/tools/search/search.d.ts +1 -2
  110. package/dist/types/tools/search/serper-scraper.d.ts +59 -0
  111. package/dist/types/tools/search/tool.d.ts +25 -4
  112. package/dist/types/tools/search/types.d.ts +31 -1
  113. package/dist/types/types/graph.d.ts +38 -4
  114. package/dist/types/types/llm.d.ts +1 -0
  115. package/dist/types/types/run.d.ts +5 -1
  116. package/dist/types/utils/handlers.d.ts +34 -0
  117. package/dist/types/utils/index.d.ts +1 -0
  118. package/package.json +11 -3
  119. package/src/common/enum.ts +1 -0
  120. package/src/graphs/Graph.ts +8 -2
  121. package/src/graphs/MultiAgentGraph.ts +267 -50
  122. package/src/llm/anthropic/index.ts +23 -2
  123. package/src/llm/google/index.ts +4 -0
  124. package/src/llm/google/utils/common.ts +14 -0
  125. package/src/llm/ollama/index.ts +3 -0
  126. package/src/llm/openai/index.ts +60 -1
  127. package/src/llm/openai/utils/index.ts +7 -1
  128. package/src/llm/openrouter/index.ts +15 -6
  129. package/src/llm/vertexai/index.ts +2 -2
  130. package/src/messages/core.ts +5 -2
  131. package/src/messages/format.ts +67 -39
  132. package/src/messages/formatMessage.test.ts +418 -2
  133. package/src/messages/prune.ts +51 -0
  134. package/src/run.ts +38 -27
  135. package/src/scripts/multi-agent-chain.ts +278 -0
  136. package/src/scripts/multi-agent-document-review-chain.ts +197 -0
  137. package/src/scripts/multi-agent-hybrid-flow.ts +310 -0
  138. package/src/scripts/multi-agent-parallel.ts +27 -23
  139. package/src/scripts/multi-agent-supervisor.ts +362 -0
  140. package/src/scripts/search.ts +5 -1
  141. package/src/scripts/test-custom-prompt-key.ts +145 -0
  142. package/src/scripts/test-handoff-input.ts +170 -0
  143. package/src/scripts/test-multi-agent-list-handoff.ts +261 -0
  144. package/src/scripts/test-tools-before-handoff.ts +233 -0
  145. package/src/scripts/tools.ts +4 -1
  146. package/src/stream.ts +4 -1
  147. package/src/tools/search/firecrawl.ts +5 -2
  148. package/src/tools/search/jina-reranker.test.ts +126 -0
  149. package/src/tools/search/rerankers.ts +11 -5
  150. package/src/tools/search/search.ts +6 -8
  151. package/src/tools/search/serper-scraper.ts +155 -0
  152. package/src/tools/search/tool.ts +49 -8
  153. package/src/tools/search/types.ts +46 -0
  154. package/src/types/graph.ts +51 -5
  155. package/src/types/llm.ts +1 -0
  156. package/src/types/run.ts +6 -1
  157. package/src/utils/handlers.ts +107 -0
  158. package/src/utils/index.ts +2 -1
  159. package/src/utils/llmConfig.ts +35 -1
  160. package/dist/types/scripts/abort.d.ts +0 -1
  161. package/dist/types/scripts/ant_web_search.d.ts +0 -1
  162. package/dist/types/scripts/args.d.ts +0 -7
  163. package/dist/types/scripts/caching.d.ts +0 -1
  164. package/dist/types/scripts/cli.d.ts +0 -1
  165. package/dist/types/scripts/cli2.d.ts +0 -1
  166. package/dist/types/scripts/cli3.d.ts +0 -1
  167. package/dist/types/scripts/cli4.d.ts +0 -1
  168. package/dist/types/scripts/cli5.d.ts +0 -1
  169. package/dist/types/scripts/code_exec.d.ts +0 -1
  170. package/dist/types/scripts/code_exec_files.d.ts +0 -1
  171. package/dist/types/scripts/code_exec_simple.d.ts +0 -1
  172. package/dist/types/scripts/content.d.ts +0 -1
  173. package/dist/types/scripts/empty_input.d.ts +0 -1
  174. package/dist/types/scripts/handoff-test.d.ts +0 -1
  175. package/dist/types/scripts/image.d.ts +0 -1
  176. package/dist/types/scripts/memory.d.ts +0 -1
  177. package/dist/types/scripts/multi-agent-conditional.d.ts +0 -1
  178. package/dist/types/scripts/multi-agent-parallel.d.ts +0 -1
  179. package/dist/types/scripts/multi-agent-sequence.d.ts +0 -1
  180. package/dist/types/scripts/multi-agent-test.d.ts +0 -1
  181. package/dist/types/scripts/search.d.ts +0 -1
  182. package/dist/types/scripts/simple.d.ts +0 -1
  183. package/dist/types/scripts/stream.d.ts +0 -1
  184. package/dist/types/scripts/thinking.d.ts +0 -1
  185. package/dist/types/scripts/tools.d.ts +0 -1
  186. package/dist/types/specs/spec.utils.d.ts +0 -1
  187. package/src/scripts/multi-agent-example-output.md +0 -110
@@ -2,13 +2,25 @@
2
2
 
3
3
  var zod = require('zod');
4
4
  var tools = require('@langchain/core/tools');
5
+ var prompts = require('@langchain/core/prompts');
5
6
  var messages = require('@langchain/core/messages');
6
7
  var langgraph = require('@langchain/langgraph');
7
8
  var Graph = require('./Graph.cjs');
9
+ var _enum = require('../common/enum.cjs');
8
10
 
9
11
  /**
10
12
  * MultiAgentGraph extends StandardGraph to support dynamic multi-agent workflows
11
- * with handoffs, fan-in/fan-out, and other composable patterns
13
+ * with handoffs, fan-in/fan-out, and other composable patterns.
14
+ *
15
+ * Key behavior:
16
+ * - Agents with ONLY handoff edges: Can dynamically route to any handoff destination
17
+ * - Agents with ONLY direct edges: Always follow their direct edges
18
+ * - Agents with BOTH: Use Command for exclusive routing (handoff OR direct, not both)
19
+ * - If handoff occurs: Only the handoff destination executes
20
+ * - If no handoff: Direct edges execute (potentially in parallel)
21
+ *
22
+ * This enables the common pattern where an agent either delegates (handoff)
23
+ * OR continues its workflow (direct edges), but not both simultaneously.
12
24
  */
13
25
  class MultiAgentGraph extends Graph.StandardGraph {
14
26
  edges;
@@ -102,13 +114,6 @@ class MultiAgentGraph extends Graph.StandardGraph {
102
114
  agentContext.tools = [];
103
115
  }
104
116
  agentContext.tools.push(...handoffTools);
105
- // Update tool map
106
- for (const tool of handoffTools) {
107
- if (!agentContext.toolMap) {
108
- agentContext.toolMap = new Map();
109
- }
110
- agentContext.toolMap.set(tool.name, tool);
111
- }
112
117
  }
113
118
  }
114
119
  /**
@@ -117,19 +122,23 @@ class MultiAgentGraph extends Graph.StandardGraph {
117
122
  createHandoffToolsForEdge(edge) {
118
123
  const tools$1 = [];
119
124
  const destinations = Array.isArray(edge.to) ? edge.to : [edge.to];
120
- // If there's a condition, create a single conditional handoff tool
125
+ /** If there's a condition, create a single conditional handoff tool */
121
126
  if (edge.condition != null) {
122
127
  const toolName = 'conditional_transfer';
123
128
  const toolDescription = edge.description ?? 'Conditionally transfer control based on state';
124
- tools$1.push(tools.tool(async (_, config) => {
129
+ /** Check if we have a prompt for handoff input */
130
+ const hasHandoffInput = edge.prompt != null && typeof edge.prompt === 'string';
131
+ const handoffInputDescription = hasHandoffInput ? edge.prompt : undefined;
132
+ const promptKey = edge.promptKey ?? 'instructions';
133
+ tools$1.push(tools.tool(async (input, config) => {
125
134
  const state = langgraph.getCurrentTaskInput();
126
135
  const toolCallId = config?.toolCall?.id ??
127
136
  'unknown';
128
- // Evaluate condition
137
+ /** Evaluated condition */
129
138
  const result = edge.condition(state);
130
139
  let destination;
131
140
  if (typeof result === 'boolean') {
132
- // If true, use first destination; if false, don't transfer
141
+ /** If true, use first destination; if false, don't transfer */
133
142
  if (!result)
134
143
  return null;
135
144
  destination = destinations[0];
@@ -138,11 +147,17 @@ class MultiAgentGraph extends Graph.StandardGraph {
138
147
  destination = result;
139
148
  }
140
149
  else {
141
- // Array of destinations - for now, use the first
150
+ /** Array of destinations - for now, use the first */
142
151
  destination = Array.isArray(result) ? result[0] : destinations[0];
143
152
  }
153
+ let content = `Conditionally transferred to ${destination}`;
154
+ if (hasHandoffInput &&
155
+ promptKey in input &&
156
+ input[promptKey] != null) {
157
+ content += `\n\n${promptKey.charAt(0).toUpperCase() + promptKey.slice(1)}: ${input[promptKey]}`;
158
+ }
144
159
  const toolMessage = new messages.ToolMessage({
145
- content: `Conditionally transferred to ${destination}`,
160
+ content,
146
161
  name: toolName,
147
162
  tool_call_id: toolCallId,
148
163
  });
@@ -153,20 +168,39 @@ class MultiAgentGraph extends Graph.StandardGraph {
153
168
  });
154
169
  }, {
155
170
  name: toolName,
156
- schema: zod.z.object({}),
171
+ schema: hasHandoffInput
172
+ ? zod.z.object({
173
+ [promptKey]: zod.z
174
+ .string()
175
+ .optional()
176
+ .describe(handoffInputDescription),
177
+ })
178
+ : zod.z.object({}),
157
179
  description: toolDescription,
158
180
  }));
159
181
  }
160
182
  else {
161
- // Create individual tools for each destination
183
+ /** Create individual tools for each destination */
162
184
  for (const destination of destinations) {
163
- const toolName = `transfer_to_${destination}`;
185
+ const toolName = `${_enum.Constants.LC_TRANSFER_TO_}${destination}`;
164
186
  const toolDescription = edge.description ?? `Transfer control to agent '${destination}'`;
165
- tools$1.push(tools.tool(async (_, config) => {
187
+ /** Check if we have a prompt for handoff input */
188
+ const hasHandoffInput = edge.prompt != null && typeof edge.prompt === 'string';
189
+ const handoffInputDescription = hasHandoffInput
190
+ ? edge.prompt
191
+ : undefined;
192
+ const promptKey = edge.promptKey ?? 'instructions';
193
+ tools$1.push(tools.tool(async (input, config) => {
166
194
  const toolCallId = config?.toolCall?.id ??
167
195
  'unknown';
196
+ let content = `Successfully transferred to ${destination}`;
197
+ if (hasHandoffInput &&
198
+ promptKey in input &&
199
+ input[promptKey] != null) {
200
+ content += `\n\n${promptKey.charAt(0).toUpperCase() + promptKey.slice(1)}: ${input[promptKey]}`;
201
+ }
168
202
  const toolMessage = new messages.ToolMessage({
169
- content: `Successfully transferred to ${destination}`,
203
+ content,
170
204
  name: toolName,
171
205
  tool_call_id: toolCallId,
172
206
  });
@@ -178,7 +212,14 @@ class MultiAgentGraph extends Graph.StandardGraph {
178
212
  });
179
213
  }, {
180
214
  name: toolName,
181
- schema: zod.z.object({}),
215
+ schema: hasHandoffInput
216
+ ? zod.z.object({
217
+ [promptKey]: zod.z
218
+ .string()
219
+ .optional()
220
+ .describe(handoffInputDescription),
221
+ })
222
+ : zod.z.object({}),
182
223
  description: toolDescription,
183
224
  }));
184
225
  }
@@ -189,7 +230,7 @@ class MultiAgentGraph extends Graph.StandardGraph {
189
230
  * Create a complete agent subgraph (similar to createReactAgent)
190
231
  */
191
232
  createAgentSubgraph(agentId) {
192
- // This is essentially the same as createAgentNode from StandardGraph
233
+ /** This is essentially the same as `createAgentNode` from `StandardGraph` */
193
234
  return this.createAgentNode(agentId);
194
235
  }
195
236
  /**
@@ -208,6 +249,12 @@ class MultiAgentGraph extends Graph.StandardGraph {
208
249
  },
209
250
  default: () => [],
210
251
  }),
252
+ /** Channel for passing filtered messages to agents when excludeResults is true */
253
+ agentMessages: langgraph.Annotation({
254
+ /** Replaces state entirely */
255
+ reducer: (a, b) => b,
256
+ default: () => [],
257
+ }),
211
258
  });
212
259
  const builder = new langgraph.StateGraph(StateAnnotation);
213
260
  // Add all agents as complete subgraphs
@@ -231,17 +278,105 @@ class MultiAgentGraph extends Graph.StandardGraph {
231
278
  dests.forEach((dest) => directDestinations.add(dest));
232
279
  }
233
280
  }
234
- // If agent has handoff destinations, add END to possible ends
235
- // If agent only has direct destinations, it naturally ends without explicit END
236
- const destinations = new Set([...handoffDestinations]);
281
+ /** Check if this agent has BOTH handoff and direct edges */
282
+ const hasHandoffEdges = handoffDestinations.size > 0;
283
+ const hasDirectEdges = directDestinations.size > 0;
284
+ const needsCommandRouting = hasHandoffEdges && hasDirectEdges;
285
+ /** Collect all possible destinations for this agent */
286
+ const allDestinations = new Set([
287
+ ...handoffDestinations,
288
+ ...directDestinations,
289
+ ]);
237
290
  if (handoffDestinations.size > 0 || directDestinations.size === 0) {
238
- destinations.add(langgraph.END);
291
+ allDestinations.add(langgraph.END);
239
292
  }
240
- // Create the agent subgraph (includes agent + tools)
293
+ /** Agent subgraph (includes agent + tools) */
241
294
  const agentSubgraph = this.createAgentSubgraph(agentId);
242
- // Add the agent as a node with its possible destinations
243
- builder.addNode(agentId, agentSubgraph, {
244
- ends: Array.from(destinations),
295
+ /** Wrapper function that handles agentMessages channel and conditional routing */
296
+ const agentWrapper = async (state) => {
297
+ let result;
298
+ if (state.agentMessages != null && state.agentMessages.length > 0) {
299
+ /**
300
+ * When using agentMessages (excludeResults=true), we need to update
301
+ * the token map to account for the new prompt message
302
+ */
303
+ const agentContext = this.agentContexts.get(agentId);
304
+ if (agentContext && agentContext.tokenCounter) {
305
+ // The agentMessages contains:
306
+ // 1. Filtered messages (0 to startIndex) - already have token counts
307
+ // 2. New prompt message - needs token counting
308
+ const freshTokenMap = {};
309
+ // Copy existing token counts for filtered messages (0 to startIndex)
310
+ for (let i = 0; i < this.startIndex; i++) {
311
+ const tokenCount = agentContext.indexTokenCountMap[i];
312
+ if (tokenCount !== undefined) {
313
+ freshTokenMap[i] = tokenCount;
314
+ }
315
+ }
316
+ // Calculate tokens only for the new prompt message (last message)
317
+ const promptMessageIndex = state.agentMessages.length - 1;
318
+ if (promptMessageIndex >= this.startIndex) {
319
+ const promptMessage = state.agentMessages[promptMessageIndex];
320
+ freshTokenMap[promptMessageIndex] =
321
+ agentContext.tokenCounter(promptMessage);
322
+ }
323
+ // Update the agent's token map with instructions added
324
+ agentContext.updateTokenMapWithInstructions(freshTokenMap);
325
+ }
326
+ /** Temporary state with messages replaced by `agentMessages` */
327
+ const transformedState = {
328
+ ...state,
329
+ messages: state.agentMessages,
330
+ };
331
+ result = await agentSubgraph.invoke(transformedState);
332
+ result = {
333
+ ...result,
334
+ /** Clear agentMessages for next agent */
335
+ agentMessages: [],
336
+ };
337
+ }
338
+ else {
339
+ result = await agentSubgraph.invoke(state);
340
+ }
341
+ /** If agent has both handoff and direct edges, use Command for exclusive routing */
342
+ if (needsCommandRouting) {
343
+ /** Check if a handoff occurred */
344
+ const lastMessage = result.messages[result.messages.length - 1];
345
+ if (lastMessage != null &&
346
+ lastMessage.getType() === 'tool' &&
347
+ typeof lastMessage.name === 'string' &&
348
+ lastMessage.name.startsWith(_enum.Constants.LC_TRANSFER_TO_)) {
349
+ /** Handoff occurred - extract destination and navigate there exclusively */
350
+ const handoffDest = lastMessage.name.replace(_enum.Constants.LC_TRANSFER_TO_, '');
351
+ return new langgraph.Command({
352
+ update: result,
353
+ goto: handoffDest,
354
+ });
355
+ }
356
+ else {
357
+ /** No handoff - proceed with direct edges */
358
+ const directDests = Array.from(directDestinations);
359
+ if (directDests.length === 1) {
360
+ return new langgraph.Command({
361
+ update: result,
362
+ goto: directDests[0],
363
+ });
364
+ }
365
+ else if (directDests.length > 1) {
366
+ /** Multiple direct destinations - they'll run in parallel */
367
+ return new langgraph.Command({
368
+ update: result,
369
+ goto: directDests,
370
+ });
371
+ }
372
+ }
373
+ }
374
+ /** No special routing needed - return state normally */
375
+ return result;
376
+ };
377
+ /** Wrapped agent as a node with its possible destinations */
378
+ builder.addNode(agentId, agentWrapper, {
379
+ ends: Array.from(allDestinations),
245
380
  });
246
381
  }
247
382
  // Add starting edges for all starting nodes
@@ -250,7 +385,8 @@ class MultiAgentGraph extends Graph.StandardGraph {
250
385
  /** @ts-ignore */
251
386
  builder.addEdge(langgraph.START, startNode);
252
387
  }
253
- /** Add direct edges for automatic transitions
388
+ /**
389
+ * Add direct edges for automatic transitions
254
390
  * Group edges by destination to handle fan-in scenarios
255
391
  */
256
392
  const edgesByDestination = new Map();
@@ -265,30 +401,66 @@ class MultiAgentGraph extends Graph.StandardGraph {
265
401
  }
266
402
  for (const [destination, edges] of edgesByDestination) {
267
403
  /** Checks if this is a fan-in scenario with prompt instructions */
268
- const edgesWithPrompt = edges.filter((edge) => edge.promptInstructions != null && edge.promptInstructions !== '');
404
+ const edgesWithPrompt = edges.filter((edge) => edge.prompt != null && edge.prompt !== '');
269
405
  if (edgesWithPrompt.length > 0) {
270
- // Fan-in with prompt: create a single wrapper node for this destination
406
+ /**
407
+ * Single wrapper node for destination (Fan-in with prompt)
408
+ */
271
409
  const wrapperNodeId = `fan_in_${destination}_prompt`;
272
- // Use the first edge's prompt instructions (they should all be the same for fan-in)
273
- const promptInstructions = edgesWithPrompt[0].promptInstructions;
410
+ /**
411
+ * First edge's `prompt`
412
+ * (they should all be the same for fan-in)
413
+ */
414
+ const prompt = edgesWithPrompt[0].prompt;
415
+ /**
416
+ * First edge's `excludeResults` flag
417
+ * (they should all be the same for fan-in)
418
+ */
419
+ const excludeResults = edgesWithPrompt[0].excludeResults;
274
420
  builder.addNode(wrapperNodeId, async (state) => {
275
421
  let promptText;
276
- if (typeof promptInstructions === 'function') {
277
- promptText = promptInstructions(state.messages);
422
+ let effectiveExcludeResults = excludeResults;
423
+ if (typeof prompt === 'function') {
424
+ promptText = await prompt(state.messages, this.startIndex);
278
425
  }
279
- else {
280
- promptText = promptInstructions;
426
+ else if (prompt != null) {
427
+ if (prompt.includes('{results}')) {
428
+ const resultsMessages = state.messages.slice(this.startIndex);
429
+ const resultsString = messages.getBufferString(resultsMessages);
430
+ const promptTemplate = prompts.PromptTemplate.fromTemplate(prompt);
431
+ const result = await promptTemplate.invoke({
432
+ results: resultsString,
433
+ });
434
+ promptText = result.value;
435
+ effectiveExcludeResults =
436
+ excludeResults !== false && promptText !== '';
437
+ }
438
+ else {
439
+ promptText = prompt;
440
+ }
281
441
  }
282
442
  if (promptText != null && promptText !== '') {
283
- // Return state with the prompt message added
443
+ if (effectiveExcludeResults == null ||
444
+ effectiveExcludeResults === false) {
445
+ return {
446
+ messages: [new messages.HumanMessage(promptText)],
447
+ };
448
+ }
449
+ /** When `excludeResults` is true, use agentMessages channel
450
+ * to pass filtered messages + prompt to the destination agent
451
+ */
452
+ const filteredMessages = state.messages.slice(0, this.startIndex);
284
453
  return {
285
- messages: [...state.messages, new messages.HumanMessage(promptText)],
454
+ messages: [new messages.HumanMessage(promptText)],
455
+ agentMessages: langgraph.messagesStateReducer(filteredMessages, [
456
+ new messages.HumanMessage(promptText),
457
+ ]),
286
458
  };
287
459
  }
288
- // No prompt needed, return empty update
460
+ /** No prompt needed, return empty update */
289
461
  return {};
290
462
  });
291
- // Add edges from all sources to the wrapper, then wrapper to destination
463
+ /** Add edges from all sources to the wrapper, then wrapper to destination */
292
464
  for (const edge of edges) {
293
465
  const sources = Array.isArray(edge.from) ? edge.from : [edge.from];
294
466
  for (const source of sources) {
@@ -297,16 +469,29 @@ class MultiAgentGraph extends Graph.StandardGraph {
297
469
  builder.addEdge(source, wrapperNodeId);
298
470
  }
299
471
  }
300
- // Single edge from wrapper to destination
472
+ /** Single edge from wrapper to destination */
301
473
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
302
474
  /** @ts-ignore */
303
475
  builder.addEdge(wrapperNodeId, destination);
304
476
  }
305
477
  else {
306
- // No prompt instructions, add direct edges
478
+ /** No prompt instructions, add direct edges (skip if source uses Command routing) */
307
479
  for (const edge of edges) {
308
480
  const sources = Array.isArray(edge.from) ? edge.from : [edge.from];
309
481
  for (const source of sources) {
482
+ /** Check if this source node has both handoff and direct edges */
483
+ const sourceHandoffEdges = this.handoffEdges.filter((e) => {
484
+ const eSources = Array.isArray(e.from) ? e.from : [e.from];
485
+ return eSources.includes(source);
486
+ });
487
+ const sourceDirectEdges = this.directEdges.filter((e) => {
488
+ const eSources = Array.isArray(e.from) ? e.from : [e.from];
489
+ return eSources.includes(source);
490
+ });
491
+ /** Skip adding edge if source uses Command routing (has both types) */
492
+ if (sourceHandoffEdges.length > 0 && sourceDirectEdges.length > 0) {
493
+ continue;
494
+ }
310
495
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
311
496
  /** @ts-ignore */
312
497
  builder.addEdge(source, destination);
@@ -1 +1 @@
1
- {"version":3,"file":"MultiAgentGraph.cjs","sources":["../../../src/graphs/MultiAgentGraph.ts"],"sourcesContent":["import { z } from 'zod';\nimport { tool } from '@langchain/core/tools';\nimport { ToolMessage, HumanMessage } from '@langchain/core/messages';\nimport {\n END,\n START,\n Command,\n StateGraph,\n Annotation,\n getCurrentTaskInput,\n messagesStateReducer,\n} from '@langchain/langgraph';\nimport type { ToolRunnableConfig } from '@langchain/core/tools';\nimport type { BaseMessage } from '@langchain/core/messages';\nimport type * as t from '@/types';\nimport { StandardGraph } from './Graph';\n\n/**\n * MultiAgentGraph extends StandardGraph to support dynamic multi-agent workflows\n * with handoffs, fan-in/fan-out, and other composable patterns\n */\nexport class MultiAgentGraph extends StandardGraph {\n private edges: t.GraphEdge[];\n private startingNodes: Set<string> = new Set();\n private directEdges: t.GraphEdge[] = [];\n private handoffEdges: t.GraphEdge[] = [];\n\n constructor(input: t.MultiAgentGraphInput) {\n super(input);\n this.edges = input.edges;\n this.categorizeEdges();\n this.analyzeGraph();\n this.createHandoffTools();\n }\n\n /**\n * Categorize edges into handoff and direct types\n */\n private categorizeEdges(): void {\n for (const edge of this.edges) {\n // Default behavior: edges with conditions or explicit 'handoff' type are handoff edges\n // Edges with explicit 'direct' type or multi-destination without conditions are direct edges\n if (edge.edgeType === 'direct') {\n this.directEdges.push(edge);\n } else if (edge.edgeType === 'handoff' || edge.condition != null) {\n this.handoffEdges.push(edge);\n } else {\n // Default: single-to-single edges are handoff, single-to-multiple are direct\n const destinations = Array.isArray(edge.to) ? edge.to : [edge.to];\n const sources = Array.isArray(edge.from) ? edge.from : [edge.from];\n\n if (sources.length === 1 && destinations.length > 1) {\n // Fan-out pattern defaults to direct\n this.directEdges.push(edge);\n } else {\n // Everything else defaults to handoff\n this.handoffEdges.push(edge);\n }\n }\n }\n }\n\n /**\n * Analyze graph structure to determine starting nodes and connections\n */\n private analyzeGraph(): void {\n const hasIncomingEdge = new Set<string>();\n\n // Track all nodes that have incoming edges\n for (const edge of this.edges) {\n const destinations = Array.isArray(edge.to) ? edge.to : [edge.to];\n destinations.forEach((dest) => hasIncomingEdge.add(dest));\n }\n\n // Starting nodes are those without incoming edges\n for (const agentId of this.agentContexts.keys()) {\n if (!hasIncomingEdge.has(agentId)) {\n this.startingNodes.add(agentId);\n }\n }\n\n // If no starting nodes found, use the first agent\n if (this.startingNodes.size === 0 && this.agentContexts.size > 0) {\n this.startingNodes.add(this.agentContexts.keys().next().value!);\n }\n }\n\n /**\n * Create handoff tools for agents based on handoff edges only\n */\n private createHandoffTools(): void {\n // Group handoff edges by source agent(s)\n const handoffsByAgent = new Map<string, t.GraphEdge[]>();\n\n // Only process handoff edges for tool creation\n for (const edge of this.handoffEdges) {\n const sources = Array.isArray(edge.from) ? edge.from : [edge.from];\n sources.forEach((source) => {\n if (!handoffsByAgent.has(source)) {\n handoffsByAgent.set(source, []);\n }\n handoffsByAgent.get(source)!.push(edge);\n });\n }\n\n // Create handoff tools for each agent\n for (const [agentId, edges] of handoffsByAgent) {\n const agentContext = this.agentContexts.get(agentId);\n if (!agentContext) continue;\n\n // Create handoff tools for this agent's outgoing edges\n const handoffTools: t.GenericTool[] = [];\n for (const edge of edges) {\n handoffTools.push(...this.createHandoffToolsForEdge(edge));\n }\n\n // Add handoff tools to the agent's existing tools\n if (!agentContext.tools) {\n agentContext.tools = [];\n }\n agentContext.tools.push(...handoffTools);\n\n // Update tool map\n for (const tool of handoffTools) {\n if (!agentContext.toolMap) {\n agentContext.toolMap = new Map();\n }\n agentContext.toolMap.set(tool.name, tool);\n }\n }\n }\n\n /**\n * Create handoff tools for an edge (handles multiple destinations)\n */\n private createHandoffToolsForEdge(edge: t.GraphEdge): t.GenericTool[] {\n const tools: t.GenericTool[] = [];\n const destinations = Array.isArray(edge.to) ? edge.to : [edge.to];\n\n // If there's a condition, create a single conditional handoff tool\n if (edge.condition != null) {\n const toolName = 'conditional_transfer';\n const toolDescription =\n edge.description ?? 'Conditionally transfer control based on state';\n\n tools.push(\n tool(\n async (_, config) => {\n const state = getCurrentTaskInput() as t.BaseGraphState;\n const toolCallId =\n (config as ToolRunnableConfig | undefined)?.toolCall?.id ??\n 'unknown';\n\n // Evaluate condition\n const result = edge.condition!(state);\n let destination: string;\n\n if (typeof result === 'boolean') {\n // If true, use first destination; if false, don't transfer\n if (!result) return null;\n destination = destinations[0];\n } else if (typeof result === 'string') {\n destination = result;\n } else {\n // Array of destinations - for now, use the first\n destination = Array.isArray(result) ? result[0] : destinations[0];\n }\n\n const toolMessage = new ToolMessage({\n content: `Conditionally transferred to ${destination}`,\n name: toolName,\n tool_call_id: toolCallId,\n });\n\n return new Command({\n goto: destination,\n update: { messages: state.messages.concat(toolMessage) },\n graph: Command.PARENT,\n });\n },\n {\n name: toolName,\n schema: z.object({}),\n description: toolDescription,\n }\n )\n );\n } else {\n // Create individual tools for each destination\n for (const destination of destinations) {\n const toolName = `transfer_to_${destination}`;\n const toolDescription =\n edge.description ?? `Transfer control to agent '${destination}'`;\n\n tools.push(\n tool(\n async (_, config) => {\n const toolCallId =\n (config as ToolRunnableConfig | undefined)?.toolCall?.id ??\n 'unknown';\n const toolMessage = new ToolMessage({\n content: `Successfully transferred to ${destination}`,\n name: toolName,\n tool_call_id: toolCallId,\n });\n\n const state = getCurrentTaskInput() as t.BaseGraphState;\n\n return new Command({\n goto: destination,\n update: { messages: state.messages.concat(toolMessage) },\n graph: Command.PARENT,\n });\n },\n {\n name: toolName,\n schema: z.object({}),\n description: toolDescription,\n }\n )\n );\n }\n }\n\n return tools;\n }\n\n /**\n * Create a complete agent subgraph (similar to createReactAgent)\n */\n private createAgentSubgraph(agentId: string): t.CompiledAgentWorfklow {\n // This is essentially the same as createAgentNode from StandardGraph\n return this.createAgentNode(agentId);\n }\n\n /**\n * Create the multi-agent workflow with dynamic handoffs\n */\n override createWorkflow(): t.CompiledStateWorkflow {\n const StateAnnotation = Annotation.Root({\n messages: Annotation<BaseMessage[]>({\n reducer: (a, b) => {\n if (!a.length) {\n this.startIndex = a.length + b.length;\n }\n const result = messagesStateReducer(a, b);\n this.messages = result;\n return result;\n },\n default: () => [],\n }),\n });\n\n const builder = new StateGraph(StateAnnotation);\n\n // Add all agents as complete subgraphs\n for (const [agentId] of this.agentContexts) {\n // Get all possible destinations for this agent\n const handoffDestinations = new Set<string>();\n const directDestinations = new Set<string>();\n\n // Check handoff edges for destinations\n for (const edge of this.handoffEdges) {\n const sources = Array.isArray(edge.from) ? edge.from : [edge.from];\n if (sources.includes(agentId) === true) {\n const dests = Array.isArray(edge.to) ? edge.to : [edge.to];\n dests.forEach((dest) => handoffDestinations.add(dest));\n }\n }\n\n // Check direct edges for destinations\n for (const edge of this.directEdges) {\n const sources = Array.isArray(edge.from) ? edge.from : [edge.from];\n if (sources.includes(agentId) === true) {\n const dests = Array.isArray(edge.to) ? edge.to : [edge.to];\n dests.forEach((dest) => directDestinations.add(dest));\n }\n }\n\n // If agent has handoff destinations, add END to possible ends\n // If agent only has direct destinations, it naturally ends without explicit END\n const destinations = new Set([...handoffDestinations]);\n if (handoffDestinations.size > 0 || directDestinations.size === 0) {\n destinations.add(END);\n }\n\n // Create the agent subgraph (includes agent + tools)\n const agentSubgraph = this.createAgentSubgraph(agentId);\n\n // Add the agent as a node with its possible destinations\n builder.addNode(agentId, agentSubgraph, {\n ends: Array.from(destinations),\n });\n }\n\n // Add starting edges for all starting nodes\n for (const startNode of this.startingNodes) {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n /** @ts-ignore */\n builder.addEdge(START, startNode);\n }\n\n /** Add direct edges for automatic transitions\n * Group edges by destination to handle fan-in scenarios\n */\n const edgesByDestination = new Map<string, t.GraphEdge[]>();\n\n for (const edge of this.directEdges) {\n const destinations = Array.isArray(edge.to) ? edge.to : [edge.to];\n for (const destination of destinations) {\n if (!edgesByDestination.has(destination)) {\n edgesByDestination.set(destination, []);\n }\n edgesByDestination.get(destination)!.push(edge);\n }\n }\n\n for (const [destination, edges] of edgesByDestination) {\n /** Checks if this is a fan-in scenario with prompt instructions */\n const edgesWithPrompt = edges.filter(\n (edge) =>\n edge.promptInstructions != null && edge.promptInstructions !== ''\n );\n\n if (edgesWithPrompt.length > 0) {\n // Fan-in with prompt: create a single wrapper node for this destination\n const wrapperNodeId = `fan_in_${destination}_prompt`;\n\n // Use the first edge's prompt instructions (they should all be the same for fan-in)\n const promptInstructions = edgesWithPrompt[0].promptInstructions;\n\n builder.addNode(wrapperNodeId, async (state: t.BaseGraphState) => {\n let promptText: string | undefined;\n\n if (typeof promptInstructions === 'function') {\n promptText = promptInstructions(state.messages);\n } else {\n promptText = promptInstructions;\n }\n\n if (promptText != null && promptText !== '') {\n // Return state with the prompt message added\n return {\n messages: [...state.messages, new HumanMessage(promptText)],\n };\n }\n\n // No prompt needed, return empty update\n return {};\n });\n\n // Add edges from all sources to the wrapper, then wrapper to destination\n for (const edge of edges) {\n const sources = Array.isArray(edge.from) ? edge.from : [edge.from];\n for (const source of sources) {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n /** @ts-ignore */\n builder.addEdge(source, wrapperNodeId);\n }\n }\n\n // Single edge from wrapper to destination\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n /** @ts-ignore */\n builder.addEdge(wrapperNodeId, destination);\n } else {\n // No prompt instructions, add direct edges\n for (const edge of edges) {\n const sources = Array.isArray(edge.from) ? edge.from : [edge.from];\n for (const source of sources) {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n /** @ts-ignore */\n builder.addEdge(source, destination);\n }\n }\n }\n }\n\n return builder.compile(this.compileOptions as unknown as never);\n }\n}\n"],"names":["StandardGraph","tools","tool","getCurrentTaskInput","ToolMessage","Command","z","Annotation","messagesStateReducer","StateGraph","END","START","HumanMessage"],"mappings":"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"}
1
+ {"version":3,"file":"MultiAgentGraph.cjs","sources":["../../../src/graphs/MultiAgentGraph.ts"],"sourcesContent":["import { z } from 'zod';\nimport { tool } from '@langchain/core/tools';\nimport { PromptTemplate } from '@langchain/core/prompts';\nimport {\n ToolMessage,\n HumanMessage,\n getBufferString,\n} from '@langchain/core/messages';\nimport {\n END,\n START,\n Command,\n StateGraph,\n Annotation,\n getCurrentTaskInput,\n messagesStateReducer,\n} from '@langchain/langgraph';\nimport type { ToolRunnableConfig } from '@langchain/core/tools';\nimport type { BaseMessage } from '@langchain/core/messages';\nimport type * as t from '@/types';\nimport { StandardGraph } from './Graph';\nimport { Constants } from '@/common';\n\n/**\n * MultiAgentGraph extends StandardGraph to support dynamic multi-agent workflows\n * with handoffs, fan-in/fan-out, and other composable patterns.\n *\n * Key behavior:\n * - Agents with ONLY handoff edges: Can dynamically route to any handoff destination\n * - Agents with ONLY direct edges: Always follow their direct edges\n * - Agents with BOTH: Use Command for exclusive routing (handoff OR direct, not both)\n * - If handoff occurs: Only the handoff destination executes\n * - If no handoff: Direct edges execute (potentially in parallel)\n *\n * This enables the common pattern where an agent either delegates (handoff)\n * OR continues its workflow (direct edges), but not both simultaneously.\n */\nexport class MultiAgentGraph extends StandardGraph {\n private edges: t.GraphEdge[];\n private startingNodes: Set<string> = new Set();\n private directEdges: t.GraphEdge[] = [];\n private handoffEdges: t.GraphEdge[] = [];\n\n constructor(input: t.MultiAgentGraphInput) {\n super(input);\n this.edges = input.edges;\n this.categorizeEdges();\n this.analyzeGraph();\n this.createHandoffTools();\n }\n\n /**\n * Categorize edges into handoff and direct types\n */\n private categorizeEdges(): void {\n for (const edge of this.edges) {\n // Default behavior: edges with conditions or explicit 'handoff' type are handoff edges\n // Edges with explicit 'direct' type or multi-destination without conditions are direct edges\n if (edge.edgeType === 'direct') {\n this.directEdges.push(edge);\n } else if (edge.edgeType === 'handoff' || edge.condition != null) {\n this.handoffEdges.push(edge);\n } else {\n // Default: single-to-single edges are handoff, single-to-multiple are direct\n const destinations = Array.isArray(edge.to) ? edge.to : [edge.to];\n const sources = Array.isArray(edge.from) ? edge.from : [edge.from];\n\n if (sources.length === 1 && destinations.length > 1) {\n // Fan-out pattern defaults to direct\n this.directEdges.push(edge);\n } else {\n // Everything else defaults to handoff\n this.handoffEdges.push(edge);\n }\n }\n }\n }\n\n /**\n * Analyze graph structure to determine starting nodes and connections\n */\n private analyzeGraph(): void {\n const hasIncomingEdge = new Set<string>();\n\n // Track all nodes that have incoming edges\n for (const edge of this.edges) {\n const destinations = Array.isArray(edge.to) ? edge.to : [edge.to];\n destinations.forEach((dest) => hasIncomingEdge.add(dest));\n }\n\n // Starting nodes are those without incoming edges\n for (const agentId of this.agentContexts.keys()) {\n if (!hasIncomingEdge.has(agentId)) {\n this.startingNodes.add(agentId);\n }\n }\n\n // If no starting nodes found, use the first agent\n if (this.startingNodes.size === 0 && this.agentContexts.size > 0) {\n this.startingNodes.add(this.agentContexts.keys().next().value!);\n }\n }\n\n /**\n * Create handoff tools for agents based on handoff edges only\n */\n private createHandoffTools(): void {\n // Group handoff edges by source agent(s)\n const handoffsByAgent = new Map<string, t.GraphEdge[]>();\n\n // Only process handoff edges for tool creation\n for (const edge of this.handoffEdges) {\n const sources = Array.isArray(edge.from) ? edge.from : [edge.from];\n sources.forEach((source) => {\n if (!handoffsByAgent.has(source)) {\n handoffsByAgent.set(source, []);\n }\n handoffsByAgent.get(source)!.push(edge);\n });\n }\n\n // Create handoff tools for each agent\n for (const [agentId, edges] of handoffsByAgent) {\n const agentContext = this.agentContexts.get(agentId);\n if (!agentContext) continue;\n\n // Create handoff tools for this agent's outgoing edges\n const handoffTools: t.GenericTool[] = [];\n for (const edge of edges) {\n handoffTools.push(...this.createHandoffToolsForEdge(edge));\n }\n\n // Add handoff tools to the agent's existing tools\n if (!agentContext.tools) {\n agentContext.tools = [];\n }\n agentContext.tools.push(...handoffTools);\n }\n }\n\n /**\n * Create handoff tools for an edge (handles multiple destinations)\n */\n private createHandoffToolsForEdge(edge: t.GraphEdge): t.GenericTool[] {\n const tools: t.GenericTool[] = [];\n const destinations = Array.isArray(edge.to) ? edge.to : [edge.to];\n\n /** If there's a condition, create a single conditional handoff tool */\n if (edge.condition != null) {\n const toolName = 'conditional_transfer';\n const toolDescription =\n edge.description ?? 'Conditionally transfer control based on state';\n\n /** Check if we have a prompt for handoff input */\n const hasHandoffInput =\n edge.prompt != null && typeof edge.prompt === 'string';\n const handoffInputDescription = hasHandoffInput ? edge.prompt : undefined;\n const promptKey = edge.promptKey ?? 'instructions';\n\n tools.push(\n tool(\n async (input: Record<string, unknown>, config) => {\n const state = getCurrentTaskInput() as t.BaseGraphState;\n const toolCallId =\n (config as ToolRunnableConfig | undefined)?.toolCall?.id ??\n 'unknown';\n\n /** Evaluated condition */\n const result = edge.condition!(state);\n let destination: string;\n\n if (typeof result === 'boolean') {\n /** If true, use first destination; if false, don't transfer */\n if (!result) return null;\n destination = destinations[0];\n } else if (typeof result === 'string') {\n destination = result;\n } else {\n /** Array of destinations - for now, use the first */\n destination = Array.isArray(result) ? result[0] : destinations[0];\n }\n\n let content = `Conditionally transferred to ${destination}`;\n if (\n hasHandoffInput &&\n promptKey in input &&\n input[promptKey] != null\n ) {\n content += `\\n\\n${promptKey.charAt(0).toUpperCase() + promptKey.slice(1)}: ${input[promptKey]}`;\n }\n\n const toolMessage = new ToolMessage({\n content,\n name: toolName,\n tool_call_id: toolCallId,\n });\n\n return new Command({\n goto: destination,\n update: { messages: state.messages.concat(toolMessage) },\n graph: Command.PARENT,\n });\n },\n {\n name: toolName,\n schema: hasHandoffInput\n ? z.object({\n [promptKey]: z\n .string()\n .optional()\n .describe(handoffInputDescription as string),\n })\n : z.object({}),\n description: toolDescription,\n }\n )\n );\n } else {\n /** Create individual tools for each destination */\n for (const destination of destinations) {\n const toolName = `${Constants.LC_TRANSFER_TO_}${destination}`;\n const toolDescription =\n edge.description ?? `Transfer control to agent '${destination}'`;\n\n /** Check if we have a prompt for handoff input */\n const hasHandoffInput =\n edge.prompt != null && typeof edge.prompt === 'string';\n const handoffInputDescription = hasHandoffInput\n ? edge.prompt\n : undefined;\n const promptKey = edge.promptKey ?? 'instructions';\n\n tools.push(\n tool(\n async (input: Record<string, unknown>, config) => {\n const toolCallId =\n (config as ToolRunnableConfig | undefined)?.toolCall?.id ??\n 'unknown';\n\n let content = `Successfully transferred to ${destination}`;\n if (\n hasHandoffInput &&\n promptKey in input &&\n input[promptKey] != null\n ) {\n content += `\\n\\n${promptKey.charAt(0).toUpperCase() + promptKey.slice(1)}: ${input[promptKey]}`;\n }\n\n const toolMessage = new ToolMessage({\n content,\n name: toolName,\n tool_call_id: toolCallId,\n });\n\n const state = getCurrentTaskInput() as t.BaseGraphState;\n\n return new Command({\n goto: destination,\n update: { messages: state.messages.concat(toolMessage) },\n graph: Command.PARENT,\n });\n },\n {\n name: toolName,\n schema: hasHandoffInput\n ? z.object({\n [promptKey]: z\n .string()\n .optional()\n .describe(handoffInputDescription as string),\n })\n : z.object({}),\n description: toolDescription,\n }\n )\n );\n }\n }\n\n return tools;\n }\n\n /**\n * Create a complete agent subgraph (similar to createReactAgent)\n */\n private createAgentSubgraph(agentId: string): t.CompiledAgentWorfklow {\n /** This is essentially the same as `createAgentNode` from `StandardGraph` */\n return this.createAgentNode(agentId);\n }\n\n /**\n * Create the multi-agent workflow with dynamic handoffs\n */\n override createWorkflow(): t.CompiledMultiAgentWorkflow {\n const StateAnnotation = Annotation.Root({\n messages: Annotation<BaseMessage[]>({\n reducer: (a, b) => {\n if (!a.length) {\n this.startIndex = a.length + b.length;\n }\n const result = messagesStateReducer(a, b);\n this.messages = result;\n return result;\n },\n default: () => [],\n }),\n /** Channel for passing filtered messages to agents when excludeResults is true */\n agentMessages: Annotation<BaseMessage[]>({\n /** Replaces state entirely */\n reducer: (a, b) => b,\n default: () => [],\n }),\n });\n\n const builder = new StateGraph(StateAnnotation);\n\n // Add all agents as complete subgraphs\n for (const [agentId] of this.agentContexts) {\n // Get all possible destinations for this agent\n const handoffDestinations = new Set<string>();\n const directDestinations = new Set<string>();\n\n // Check handoff edges for destinations\n for (const edge of this.handoffEdges) {\n const sources = Array.isArray(edge.from) ? edge.from : [edge.from];\n if (sources.includes(agentId) === true) {\n const dests = Array.isArray(edge.to) ? edge.to : [edge.to];\n dests.forEach((dest) => handoffDestinations.add(dest));\n }\n }\n\n // Check direct edges for destinations\n for (const edge of this.directEdges) {\n const sources = Array.isArray(edge.from) ? edge.from : [edge.from];\n if (sources.includes(agentId) === true) {\n const dests = Array.isArray(edge.to) ? edge.to : [edge.to];\n dests.forEach((dest) => directDestinations.add(dest));\n }\n }\n\n /** Check if this agent has BOTH handoff and direct edges */\n const hasHandoffEdges = handoffDestinations.size > 0;\n const hasDirectEdges = directDestinations.size > 0;\n const needsCommandRouting = hasHandoffEdges && hasDirectEdges;\n\n /** Collect all possible destinations for this agent */\n const allDestinations = new Set([\n ...handoffDestinations,\n ...directDestinations,\n ]);\n if (handoffDestinations.size > 0 || directDestinations.size === 0) {\n allDestinations.add(END);\n }\n\n /** Agent subgraph (includes agent + tools) */\n const agentSubgraph = this.createAgentSubgraph(agentId);\n\n /** Wrapper function that handles agentMessages channel and conditional routing */\n const agentWrapper = async (\n state: t.MultiAgentGraphState\n ): Promise<t.MultiAgentGraphState | Command> => {\n let result: t.MultiAgentGraphState;\n\n if (state.agentMessages != null && state.agentMessages.length > 0) {\n /**\n * When using agentMessages (excludeResults=true), we need to update\n * the token map to account for the new prompt message\n */\n const agentContext = this.agentContexts.get(agentId);\n if (agentContext && agentContext.tokenCounter) {\n // The agentMessages contains:\n // 1. Filtered messages (0 to startIndex) - already have token counts\n // 2. New prompt message - needs token counting\n\n const freshTokenMap: Record<string, number> = {};\n\n // Copy existing token counts for filtered messages (0 to startIndex)\n for (let i = 0; i < this.startIndex; i++) {\n const tokenCount = agentContext.indexTokenCountMap[i];\n if (tokenCount !== undefined) {\n freshTokenMap[i] = tokenCount;\n }\n }\n\n // Calculate tokens only for the new prompt message (last message)\n const promptMessageIndex = state.agentMessages.length - 1;\n if (promptMessageIndex >= this.startIndex) {\n const promptMessage = state.agentMessages[promptMessageIndex];\n freshTokenMap[promptMessageIndex] =\n agentContext.tokenCounter(promptMessage);\n }\n\n // Update the agent's token map with instructions added\n agentContext.updateTokenMapWithInstructions(freshTokenMap);\n }\n\n /** Temporary state with messages replaced by `agentMessages` */\n const transformedState: t.MultiAgentGraphState = {\n ...state,\n messages: state.agentMessages,\n };\n result = await agentSubgraph.invoke(transformedState);\n result = {\n ...result,\n /** Clear agentMessages for next agent */\n agentMessages: [],\n };\n } else {\n result = await agentSubgraph.invoke(state);\n }\n\n /** If agent has both handoff and direct edges, use Command for exclusive routing */\n if (needsCommandRouting) {\n /** Check if a handoff occurred */\n const lastMessage = result.messages[\n result.messages.length - 1\n ] as BaseMessage | null;\n if (\n lastMessage != null &&\n lastMessage.getType() === 'tool' &&\n typeof lastMessage.name === 'string' &&\n lastMessage.name.startsWith(Constants.LC_TRANSFER_TO_)\n ) {\n /** Handoff occurred - extract destination and navigate there exclusively */\n const handoffDest = lastMessage.name.replace(\n Constants.LC_TRANSFER_TO_,\n ''\n );\n return new Command({\n update: result,\n goto: handoffDest,\n });\n } else {\n /** No handoff - proceed with direct edges */\n const directDests = Array.from(directDestinations);\n if (directDests.length === 1) {\n return new Command({\n update: result,\n goto: directDests[0],\n });\n } else if (directDests.length > 1) {\n /** Multiple direct destinations - they'll run in parallel */\n return new Command({\n update: result,\n goto: directDests,\n });\n }\n }\n }\n\n /** No special routing needed - return state normally */\n return result;\n };\n\n /** Wrapped agent as a node with its possible destinations */\n builder.addNode(agentId, agentWrapper, {\n ends: Array.from(allDestinations),\n });\n }\n\n // Add starting edges for all starting nodes\n for (const startNode of this.startingNodes) {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n /** @ts-ignore */\n builder.addEdge(START, startNode);\n }\n\n /**\n * Add direct edges for automatic transitions\n * Group edges by destination to handle fan-in scenarios\n */\n const edgesByDestination = new Map<string, t.GraphEdge[]>();\n\n for (const edge of this.directEdges) {\n const destinations = Array.isArray(edge.to) ? edge.to : [edge.to];\n for (const destination of destinations) {\n if (!edgesByDestination.has(destination)) {\n edgesByDestination.set(destination, []);\n }\n edgesByDestination.get(destination)!.push(edge);\n }\n }\n\n for (const [destination, edges] of edgesByDestination) {\n /** Checks if this is a fan-in scenario with prompt instructions */\n const edgesWithPrompt = edges.filter(\n (edge) => edge.prompt != null && edge.prompt !== ''\n );\n\n if (edgesWithPrompt.length > 0) {\n /**\n * Single wrapper node for destination (Fan-in with prompt)\n */\n const wrapperNodeId = `fan_in_${destination}_prompt`;\n /**\n * First edge's `prompt`\n * (they should all be the same for fan-in)\n */\n const prompt = edgesWithPrompt[0].prompt;\n /**\n * First edge's `excludeResults` flag\n * (they should all be the same for fan-in)\n */\n const excludeResults = edgesWithPrompt[0].excludeResults;\n\n builder.addNode(wrapperNodeId, async (state: t.BaseGraphState) => {\n let promptText: string | undefined;\n let effectiveExcludeResults = excludeResults;\n\n if (typeof prompt === 'function') {\n promptText = await prompt(state.messages, this.startIndex);\n } else if (prompt != null) {\n if (prompt.includes('{results}')) {\n const resultsMessages = state.messages.slice(this.startIndex);\n const resultsString = getBufferString(resultsMessages);\n const promptTemplate = PromptTemplate.fromTemplate(prompt);\n const result = await promptTemplate.invoke({\n results: resultsString,\n });\n promptText = result.value;\n effectiveExcludeResults =\n excludeResults !== false && promptText !== '';\n } else {\n promptText = prompt;\n }\n }\n\n if (promptText != null && promptText !== '') {\n if (\n effectiveExcludeResults == null ||\n effectiveExcludeResults === false\n ) {\n return {\n messages: [new HumanMessage(promptText)],\n };\n }\n\n /** When `excludeResults` is true, use agentMessages channel\n * to pass filtered messages + prompt to the destination agent\n */\n const filteredMessages = state.messages.slice(0, this.startIndex);\n return {\n messages: [new HumanMessage(promptText)],\n agentMessages: messagesStateReducer(filteredMessages, [\n new HumanMessage(promptText),\n ]),\n };\n }\n\n /** No prompt needed, return empty update */\n return {};\n });\n\n /** Add edges from all sources to the wrapper, then wrapper to destination */\n for (const edge of edges) {\n const sources = Array.isArray(edge.from) ? edge.from : [edge.from];\n for (const source of sources) {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n /** @ts-ignore */\n builder.addEdge(source, wrapperNodeId);\n }\n }\n\n /** Single edge from wrapper to destination */\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n /** @ts-ignore */\n builder.addEdge(wrapperNodeId, destination);\n } else {\n /** No prompt instructions, add direct edges (skip if source uses Command routing) */\n for (const edge of edges) {\n const sources = Array.isArray(edge.from) ? edge.from : [edge.from];\n for (const source of sources) {\n /** Check if this source node has both handoff and direct edges */\n const sourceHandoffEdges = this.handoffEdges.filter((e) => {\n const eSources = Array.isArray(e.from) ? e.from : [e.from];\n return eSources.includes(source);\n });\n const sourceDirectEdges = this.directEdges.filter((e) => {\n const eSources = Array.isArray(e.from) ? e.from : [e.from];\n return eSources.includes(source);\n });\n\n /** Skip adding edge if source uses Command routing (has both types) */\n if (sourceHandoffEdges.length > 0 && sourceDirectEdges.length > 0) {\n continue;\n }\n\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n /** @ts-ignore */\n builder.addEdge(source, destination);\n }\n }\n }\n }\n\n return builder.compile(this.compileOptions as unknown as never);\n }\n}\n"],"names":["StandardGraph","tools","tool","getCurrentTaskInput","ToolMessage","Command","z","Constants","Annotation","messagesStateReducer","StateGraph","END","START","getBufferString","PromptTemplate","HumanMessage"],"mappings":"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"}
@@ -85,18 +85,23 @@ class CustomAnthropic extends anthropic.ChatAnthropicMessages {
85
85
  message_delta;
86
86
  tools_in_params;
87
87
  emitted_usage;
88
+ top_k;
88
89
  constructor(fields) {
89
90
  super(fields);
90
91
  this.resetTokenEvents();
92
+ this.setDirectFields(fields);
91
93
  this._lc_stream_delay = fields?._lc_stream_delay ?? 25;
92
94
  }
95
+ static lc_name() {
96
+ return 'LibreChatAnthropic';
97
+ }
93
98
  /**
94
99
  * Get the parameters used to invoke the model
95
100
  */
96
101
  invocationParams(options) {
97
102
  const tool_choice = tools.handleToolChoice(options?.tool_choice);
98
103
  if (this.thinking.type === 'enabled') {
99
- if (this.topK !== -1 && this.topK != null) {
104
+ if (this.top_k !== -1 && this.top_k != null) {
100
105
  throw new Error('topK is not supported when thinking is enabled');
101
106
  }
102
107
  if (this.topP !== -1 && this.topP != null) {
@@ -120,7 +125,7 @@ class CustomAnthropic extends anthropic.ChatAnthropicMessages {
120
125
  return {
121
126
  model: this.model,
122
127
  temperature: this.temperature,
123
- top_k: this.topK,
128
+ top_k: this.top_k,
124
129
  top_p: this.topP,
125
130
  stop_sequences: options?.stop ?? this.stopSequences,
126
131
  stream: this.streaming,
@@ -165,6 +170,20 @@ class CustomAnthropic extends anthropic.ChatAnthropicMessages {
165
170
  this.emitted_usage = undefined;
166
171
  this.tools_in_params = undefined;
167
172
  }
173
+ setDirectFields(fields) {
174
+ this.temperature = fields?.temperature ?? undefined;
175
+ this.topP = fields?.topP ?? undefined;
176
+ this.top_k = fields?.topK;
177
+ if (this.temperature === -1 || this.temperature === 1) {
178
+ this.temperature = undefined;
179
+ }
180
+ if (this.topP === -1) {
181
+ this.topP = undefined;
182
+ }
183
+ if (this.top_k === -1) {
184
+ this.top_k = undefined;
185
+ }
186
+ }
168
187
  createGenerationChunk({ token, chunk, usageMetadata, shouldStreamUsage, }) {
169
188
  const usage_metadata = shouldStreamUsage
170
189
  ? (usageMetadata ?? chunk.usage_metadata)