@librechat/agents 2.4.322 → 3.0.0-rc10

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 (279) hide show
  1. package/dist/cjs/agents/AgentContext.cjs +218 -0
  2. package/dist/cjs/agents/AgentContext.cjs.map +1 -0
  3. package/dist/cjs/common/enum.cjs +15 -5
  4. package/dist/cjs/common/enum.cjs.map +1 -1
  5. package/dist/cjs/events.cjs +10 -6
  6. package/dist/cjs/events.cjs.map +1 -1
  7. package/dist/cjs/graphs/Graph.cjs +309 -213
  8. package/dist/cjs/graphs/Graph.cjs.map +1 -1
  9. package/dist/cjs/graphs/MultiAgentGraph.cjs +507 -0
  10. package/dist/cjs/graphs/MultiAgentGraph.cjs.map +1 -0
  11. package/dist/cjs/llm/anthropic/index.cjs +54 -9
  12. package/dist/cjs/llm/anthropic/index.cjs.map +1 -1
  13. package/dist/cjs/llm/anthropic/types.cjs.map +1 -1
  14. package/dist/cjs/llm/anthropic/utils/message_inputs.cjs +52 -6
  15. package/dist/cjs/llm/anthropic/utils/message_inputs.cjs.map +1 -1
  16. package/dist/cjs/llm/anthropic/utils/message_outputs.cjs +22 -2
  17. package/dist/cjs/llm/anthropic/utils/message_outputs.cjs.map +1 -1
  18. package/dist/cjs/llm/anthropic/utils/tools.cjs +29 -0
  19. package/dist/cjs/llm/anthropic/utils/tools.cjs.map +1 -0
  20. package/dist/cjs/llm/google/index.cjs +144 -0
  21. package/dist/cjs/llm/google/index.cjs.map +1 -0
  22. package/dist/cjs/llm/google/utils/common.cjs +477 -0
  23. package/dist/cjs/llm/google/utils/common.cjs.map +1 -0
  24. package/dist/cjs/llm/ollama/index.cjs +67 -0
  25. package/dist/cjs/llm/ollama/index.cjs.map +1 -0
  26. package/dist/cjs/llm/ollama/utils.cjs +158 -0
  27. package/dist/cjs/llm/ollama/utils.cjs.map +1 -0
  28. package/dist/cjs/llm/openai/index.cjs +422 -3
  29. package/dist/cjs/llm/openai/index.cjs.map +1 -1
  30. package/dist/cjs/llm/openai/utils/index.cjs +672 -0
  31. package/dist/cjs/llm/openai/utils/index.cjs.map +1 -0
  32. package/dist/cjs/llm/providers.cjs +15 -15
  33. package/dist/cjs/llm/providers.cjs.map +1 -1
  34. package/dist/cjs/llm/text.cjs +14 -3
  35. package/dist/cjs/llm/text.cjs.map +1 -1
  36. package/dist/cjs/llm/vertexai/index.cjs +330 -0
  37. package/dist/cjs/llm/vertexai/index.cjs.map +1 -0
  38. package/dist/cjs/main.cjs +11 -0
  39. package/dist/cjs/main.cjs.map +1 -1
  40. package/dist/cjs/run.cjs +137 -85
  41. package/dist/cjs/run.cjs.map +1 -1
  42. package/dist/cjs/stream.cjs +86 -52
  43. package/dist/cjs/stream.cjs.map +1 -1
  44. package/dist/cjs/tools/ToolNode.cjs +10 -4
  45. package/dist/cjs/tools/ToolNode.cjs.map +1 -1
  46. package/dist/cjs/tools/handlers.cjs +119 -13
  47. package/dist/cjs/tools/handlers.cjs.map +1 -1
  48. package/dist/cjs/tools/search/anthropic.cjs +40 -0
  49. package/dist/cjs/tools/search/anthropic.cjs.map +1 -0
  50. package/dist/cjs/tools/search/firecrawl.cjs +55 -9
  51. package/dist/cjs/tools/search/firecrawl.cjs.map +1 -1
  52. package/dist/cjs/tools/search/format.cjs +6 -6
  53. package/dist/cjs/tools/search/format.cjs.map +1 -1
  54. package/dist/cjs/tools/search/rerankers.cjs +7 -29
  55. package/dist/cjs/tools/search/rerankers.cjs.map +1 -1
  56. package/dist/cjs/tools/search/search.cjs +86 -16
  57. package/dist/cjs/tools/search/search.cjs.map +1 -1
  58. package/dist/cjs/tools/search/tool.cjs +4 -2
  59. package/dist/cjs/tools/search/tool.cjs.map +1 -1
  60. package/dist/cjs/tools/search/utils.cjs +1 -1
  61. package/dist/cjs/tools/search/utils.cjs.map +1 -1
  62. package/dist/cjs/utils/events.cjs +31 -0
  63. package/dist/cjs/utils/events.cjs.map +1 -0
  64. package/dist/cjs/utils/title.cjs +57 -21
  65. package/dist/cjs/utils/title.cjs.map +1 -1
  66. package/dist/cjs/utils/tokens.cjs +54 -7
  67. package/dist/cjs/utils/tokens.cjs.map +1 -1
  68. package/dist/esm/agents/AgentContext.mjs +216 -0
  69. package/dist/esm/agents/AgentContext.mjs.map +1 -0
  70. package/dist/esm/common/enum.mjs +16 -6
  71. package/dist/esm/common/enum.mjs.map +1 -1
  72. package/dist/esm/events.mjs +10 -6
  73. package/dist/esm/events.mjs.map +1 -1
  74. package/dist/esm/graphs/Graph.mjs +311 -215
  75. package/dist/esm/graphs/Graph.mjs.map +1 -1
  76. package/dist/esm/graphs/MultiAgentGraph.mjs +505 -0
  77. package/dist/esm/graphs/MultiAgentGraph.mjs.map +1 -0
  78. package/dist/esm/llm/anthropic/index.mjs +54 -9
  79. package/dist/esm/llm/anthropic/index.mjs.map +1 -1
  80. package/dist/esm/llm/anthropic/types.mjs.map +1 -1
  81. package/dist/esm/llm/anthropic/utils/message_inputs.mjs +52 -6
  82. package/dist/esm/llm/anthropic/utils/message_inputs.mjs.map +1 -1
  83. package/dist/esm/llm/anthropic/utils/message_outputs.mjs +22 -2
  84. package/dist/esm/llm/anthropic/utils/message_outputs.mjs.map +1 -1
  85. package/dist/esm/llm/anthropic/utils/tools.mjs +27 -0
  86. package/dist/esm/llm/anthropic/utils/tools.mjs.map +1 -0
  87. package/dist/esm/llm/google/index.mjs +142 -0
  88. package/dist/esm/llm/google/index.mjs.map +1 -0
  89. package/dist/esm/llm/google/utils/common.mjs +471 -0
  90. package/dist/esm/llm/google/utils/common.mjs.map +1 -0
  91. package/dist/esm/llm/ollama/index.mjs +65 -0
  92. package/dist/esm/llm/ollama/index.mjs.map +1 -0
  93. package/dist/esm/llm/ollama/utils.mjs +155 -0
  94. package/dist/esm/llm/ollama/utils.mjs.map +1 -0
  95. package/dist/esm/llm/openai/index.mjs +421 -4
  96. package/dist/esm/llm/openai/index.mjs.map +1 -1
  97. package/dist/esm/llm/openai/utils/index.mjs +666 -0
  98. package/dist/esm/llm/openai/utils/index.mjs.map +1 -0
  99. package/dist/esm/llm/providers.mjs +5 -5
  100. package/dist/esm/llm/providers.mjs.map +1 -1
  101. package/dist/esm/llm/text.mjs +14 -3
  102. package/dist/esm/llm/text.mjs.map +1 -1
  103. package/dist/esm/llm/vertexai/index.mjs +328 -0
  104. package/dist/esm/llm/vertexai/index.mjs.map +1 -0
  105. package/dist/esm/main.mjs +6 -5
  106. package/dist/esm/main.mjs.map +1 -1
  107. package/dist/esm/run.mjs +138 -87
  108. package/dist/esm/run.mjs.map +1 -1
  109. package/dist/esm/stream.mjs +88 -55
  110. package/dist/esm/stream.mjs.map +1 -1
  111. package/dist/esm/tools/ToolNode.mjs +10 -4
  112. package/dist/esm/tools/ToolNode.mjs.map +1 -1
  113. package/dist/esm/tools/handlers.mjs +119 -15
  114. package/dist/esm/tools/handlers.mjs.map +1 -1
  115. package/dist/esm/tools/search/anthropic.mjs +37 -0
  116. package/dist/esm/tools/search/anthropic.mjs.map +1 -0
  117. package/dist/esm/tools/search/firecrawl.mjs +55 -9
  118. package/dist/esm/tools/search/firecrawl.mjs.map +1 -1
  119. package/dist/esm/tools/search/format.mjs +7 -7
  120. package/dist/esm/tools/search/format.mjs.map +1 -1
  121. package/dist/esm/tools/search/rerankers.mjs +7 -29
  122. package/dist/esm/tools/search/rerankers.mjs.map +1 -1
  123. package/dist/esm/tools/search/search.mjs +86 -16
  124. package/dist/esm/tools/search/search.mjs.map +1 -1
  125. package/dist/esm/tools/search/tool.mjs +4 -2
  126. package/dist/esm/tools/search/tool.mjs.map +1 -1
  127. package/dist/esm/tools/search/utils.mjs +1 -1
  128. package/dist/esm/tools/search/utils.mjs.map +1 -1
  129. package/dist/esm/utils/events.mjs +29 -0
  130. package/dist/esm/utils/events.mjs.map +1 -0
  131. package/dist/esm/utils/title.mjs +57 -22
  132. package/dist/esm/utils/title.mjs.map +1 -1
  133. package/dist/esm/utils/tokens.mjs +54 -8
  134. package/dist/esm/utils/tokens.mjs.map +1 -1
  135. package/dist/types/agents/AgentContext.d.ts +91 -0
  136. package/dist/types/common/enum.d.ts +17 -7
  137. package/dist/types/events.d.ts +5 -4
  138. package/dist/types/graphs/Graph.d.ts +64 -67
  139. package/dist/types/graphs/MultiAgentGraph.d.ts +47 -0
  140. package/dist/types/graphs/index.d.ts +1 -0
  141. package/dist/types/llm/anthropic/index.d.ts +11 -0
  142. package/dist/types/llm/anthropic/types.d.ts +9 -3
  143. package/dist/types/llm/anthropic/utils/message_inputs.d.ts +1 -1
  144. package/dist/types/llm/anthropic/utils/output_parsers.d.ts +4 -4
  145. package/dist/types/llm/anthropic/utils/tools.d.ts +3 -0
  146. package/dist/types/llm/google/index.d.ts +13 -0
  147. package/dist/types/llm/google/types.d.ts +32 -0
  148. package/dist/types/llm/google/utils/common.d.ts +19 -0
  149. package/dist/types/llm/google/utils/tools.d.ts +10 -0
  150. package/dist/types/llm/google/utils/zod_to_genai_parameters.d.ts +14 -0
  151. package/dist/types/llm/ollama/index.d.ts +7 -0
  152. package/dist/types/llm/ollama/utils.d.ts +7 -0
  153. package/dist/types/llm/openai/index.d.ts +82 -3
  154. package/dist/types/llm/openai/types.d.ts +10 -0
  155. package/dist/types/llm/openai/utils/index.d.ts +20 -0
  156. package/dist/types/llm/text.d.ts +1 -1
  157. package/dist/types/llm/vertexai/index.d.ts +293 -0
  158. package/dist/types/messages/reducer.d.ts +9 -0
  159. package/dist/types/run.d.ts +19 -12
  160. package/dist/types/stream.d.ts +10 -3
  161. package/dist/types/tools/CodeExecutor.d.ts +2 -2
  162. package/dist/types/tools/ToolNode.d.ts +1 -1
  163. package/dist/types/tools/handlers.d.ts +17 -4
  164. package/dist/types/tools/search/anthropic.d.ts +16 -0
  165. package/dist/types/tools/search/firecrawl.d.ts +15 -0
  166. package/dist/types/tools/search/rerankers.d.ts +0 -1
  167. package/dist/types/tools/search/types.d.ts +30 -9
  168. package/dist/types/types/graph.d.ts +129 -15
  169. package/dist/types/types/llm.d.ts +25 -10
  170. package/dist/types/types/run.d.ts +50 -8
  171. package/dist/types/types/stream.d.ts +16 -2
  172. package/dist/types/types/tools.d.ts +1 -1
  173. package/dist/types/utils/events.d.ts +6 -0
  174. package/dist/types/utils/title.d.ts +2 -1
  175. package/dist/types/utils/tokens.d.ts +24 -0
  176. package/package.json +41 -17
  177. package/src/agents/AgentContext.ts +315 -0
  178. package/src/common/enum.ts +15 -5
  179. package/src/events.ts +24 -13
  180. package/src/graphs/Graph.ts +495 -313
  181. package/src/graphs/MultiAgentGraph.ts +598 -0
  182. package/src/graphs/index.ts +2 -1
  183. package/src/llm/anthropic/Jacob_Lee_Resume_2023.pdf +0 -0
  184. package/src/llm/anthropic/index.ts +78 -13
  185. package/src/llm/anthropic/llm.spec.ts +491 -115
  186. package/src/llm/anthropic/types.ts +39 -3
  187. package/src/llm/anthropic/utils/message_inputs.ts +67 -11
  188. package/src/llm/anthropic/utils/message_outputs.ts +21 -2
  189. package/src/llm/anthropic/utils/output_parsers.ts +25 -6
  190. package/src/llm/anthropic/utils/tools.ts +29 -0
  191. package/src/llm/google/index.ts +218 -0
  192. package/src/llm/google/types.ts +43 -0
  193. package/src/llm/google/utils/common.ts +646 -0
  194. package/src/llm/google/utils/tools.ts +160 -0
  195. package/src/llm/google/utils/zod_to_genai_parameters.ts +86 -0
  196. package/src/llm/ollama/index.ts +89 -0
  197. package/src/llm/ollama/utils.ts +193 -0
  198. package/src/llm/openai/index.ts +641 -14
  199. package/src/llm/openai/types.ts +24 -0
  200. package/src/llm/openai/utils/index.ts +912 -0
  201. package/src/llm/openai/utils/isReasoningModel.test.ts +90 -0
  202. package/src/llm/providers.ts +10 -9
  203. package/src/llm/text.ts +26 -7
  204. package/src/llm/vertexai/index.ts +360 -0
  205. package/src/messages/reducer.ts +80 -0
  206. package/src/run.ts +196 -116
  207. package/src/scripts/ant_web_search.ts +158 -0
  208. package/src/scripts/args.ts +12 -8
  209. package/src/scripts/cli4.ts +29 -21
  210. package/src/scripts/cli5.ts +29 -21
  211. package/src/scripts/code_exec.ts +54 -23
  212. package/src/scripts/code_exec_files.ts +48 -17
  213. package/src/scripts/code_exec_simple.ts +46 -27
  214. package/src/scripts/handoff-test.ts +135 -0
  215. package/src/scripts/image.ts +52 -20
  216. package/src/scripts/multi-agent-chain.ts +278 -0
  217. package/src/scripts/multi-agent-conditional.ts +220 -0
  218. package/src/scripts/multi-agent-document-review-chain.ts +197 -0
  219. package/src/scripts/multi-agent-hybrid-flow.ts +310 -0
  220. package/src/scripts/multi-agent-parallel.ts +341 -0
  221. package/src/scripts/multi-agent-sequence.ts +212 -0
  222. package/src/scripts/multi-agent-supervisor.ts +362 -0
  223. package/src/scripts/multi-agent-test.ts +186 -0
  224. package/src/scripts/search.ts +1 -9
  225. package/src/scripts/simple.ts +25 -10
  226. package/src/scripts/test-custom-prompt-key.ts +145 -0
  227. package/src/scripts/test-handoff-input.ts +170 -0
  228. package/src/scripts/test-multi-agent-list-handoff.ts +261 -0
  229. package/src/scripts/test-tools-before-handoff.ts +233 -0
  230. package/src/scripts/tools.ts +48 -18
  231. package/src/specs/anthropic.simple.test.ts +150 -34
  232. package/src/specs/azure.simple.test.ts +325 -0
  233. package/src/specs/openai.simple.test.ts +140 -33
  234. package/src/specs/openrouter.simple.test.ts +107 -0
  235. package/src/specs/prune.test.ts +4 -9
  236. package/src/specs/reasoning.test.ts +80 -44
  237. package/src/specs/token-memoization.test.ts +39 -0
  238. package/src/stream.test.ts +94 -0
  239. package/src/stream.ts +143 -61
  240. package/src/tools/ToolNode.ts +21 -7
  241. package/src/tools/handlers.ts +192 -18
  242. package/src/tools/search/anthropic.ts +51 -0
  243. package/src/tools/search/firecrawl.ts +69 -20
  244. package/src/tools/search/format.ts +6 -8
  245. package/src/tools/search/rerankers.ts +7 -40
  246. package/src/tools/search/search.ts +97 -16
  247. package/src/tools/search/tool.ts +5 -2
  248. package/src/tools/search/types.ts +30 -10
  249. package/src/tools/search/utils.ts +1 -1
  250. package/src/types/graph.ts +318 -103
  251. package/src/types/llm.ts +26 -12
  252. package/src/types/run.ts +56 -13
  253. package/src/types/stream.ts +22 -1
  254. package/src/types/tools.ts +16 -10
  255. package/src/utils/events.ts +32 -0
  256. package/src/utils/llmConfig.ts +19 -7
  257. package/src/utils/title.ts +104 -30
  258. package/src/utils/tokens.ts +69 -10
  259. package/dist/types/scripts/abort.d.ts +0 -1
  260. package/dist/types/scripts/args.d.ts +0 -6
  261. package/dist/types/scripts/caching.d.ts +0 -1
  262. package/dist/types/scripts/cli.d.ts +0 -1
  263. package/dist/types/scripts/cli2.d.ts +0 -1
  264. package/dist/types/scripts/cli3.d.ts +0 -1
  265. package/dist/types/scripts/cli4.d.ts +0 -1
  266. package/dist/types/scripts/cli5.d.ts +0 -1
  267. package/dist/types/scripts/code_exec.d.ts +0 -1
  268. package/dist/types/scripts/code_exec_files.d.ts +0 -1
  269. package/dist/types/scripts/code_exec_simple.d.ts +0 -1
  270. package/dist/types/scripts/content.d.ts +0 -1
  271. package/dist/types/scripts/empty_input.d.ts +0 -1
  272. package/dist/types/scripts/image.d.ts +0 -1
  273. package/dist/types/scripts/memory.d.ts +0 -1
  274. package/dist/types/scripts/search.d.ts +0 -1
  275. package/dist/types/scripts/simple.d.ts +0 -1
  276. package/dist/types/scripts/stream.d.ts +0 -1
  277. package/dist/types/scripts/thinking.d.ts +0 -1
  278. package/dist/types/scripts/tools.d.ts +0 -1
  279. package/dist/types/specs/spec.utils.d.ts +0 -1
@@ -1,21 +1,36 @@
1
1
  /* eslint-disable no-console */
2
2
  // src/tools/handlers.ts
3
3
  import { nanoid } from 'nanoid';
4
+ import { ToolMessage } from '@langchain/core/messages';
5
+ import type { AnthropicWebSearchResultBlockParam } from '@/llm/anthropic/types';
4
6
  import type { ToolCall, ToolCallChunk } from '@langchain/core/messages/tool';
5
- import type { Graph } from '@/graphs';
7
+ import type { MultiAgentGraph, StandardGraph } from '@/graphs';
8
+ import type { AgentContext } from '@/agents/AgentContext';
6
9
  import type * as t from '@/types';
7
- import { StepTypes, ContentTypes, ToolCallTypes } from '@/common';
10
+ import {
11
+ ToolCallTypes,
12
+ ContentTypes,
13
+ GraphEvents,
14
+ StepTypes,
15
+ Providers,
16
+ Constants,
17
+ } from '@/common';
18
+ import {
19
+ coerceAnthropicSearchResults,
20
+ isAnthropicWebSearchResult,
21
+ } from '@/tools/search/anthropic';
22
+ import { formatResultsForLLM } from '@/tools/search/format';
8
23
  import { getMessageId } from '@/messages';
9
24
 
10
- export function handleToolCallChunks({
25
+ export async function handleToolCallChunks({
11
26
  graph,
12
27
  stepKey,
13
28
  toolCallChunks,
14
29
  }: {
15
- graph: Graph;
30
+ graph: StandardGraph | MultiAgentGraph;
16
31
  stepKey: string;
17
32
  toolCallChunks: ToolCallChunk[];
18
- }): void {
33
+ }): Promise<void> {
19
34
  let prevStepId: string;
20
35
  let prevRunStep: t.RunStep | undefined;
21
36
  try {
@@ -24,7 +39,7 @@ export function handleToolCallChunks({
24
39
  } catch {
25
40
  /** Edge Case: If no previous step exists, create a new message creation step */
26
41
  const message_id = getMessageId(stepKey, graph, true) ?? '';
27
- prevStepId = graph.dispatchRunStep(stepKey, {
42
+ prevStepId = await graph.dispatchRunStep(stepKey, {
28
43
  type: StepTypes.MESSAGE_CREATION,
29
44
  message_creation: {
30
45
  message_id,
@@ -67,7 +82,7 @@ export function handleToolCallChunks({
67
82
  prevRunStep?.type === StepTypes.MESSAGE_CREATION &&
68
83
  graph.messageStepHasToolCalls.has(prevStepId);
69
84
  if (!alreadyDispatched && tool_calls?.length === toolCallChunks.length) {
70
- graph.dispatchMessageDelta(prevStepId, {
85
+ await graph.dispatchMessageDelta(prevStepId, {
71
86
  content: [
72
87
  {
73
88
  type: ContentTypes.TEXT,
@@ -77,22 +92,22 @@ export function handleToolCallChunks({
77
92
  ],
78
93
  });
79
94
  graph.messageStepHasToolCalls.set(prevStepId, true);
80
- stepId = graph.dispatchRunStep(stepKey, {
95
+ stepId = await graph.dispatchRunStep(stepKey, {
81
96
  type: StepTypes.TOOL_CALLS,
82
97
  tool_calls,
83
98
  });
84
99
  }
85
- graph.dispatchRunStepDelta(stepId, {
100
+ await graph.dispatchRunStepDelta(stepId, {
86
101
  type: StepTypes.TOOL_CALLS,
87
102
  tool_calls: toolCallChunks,
88
103
  });
89
104
  }
90
105
 
91
- export const handleToolCalls = (
106
+ export const handleToolCalls = async (
92
107
  toolCalls?: ToolCall[],
93
108
  metadata?: Record<string, unknown>,
94
- graph?: Graph
95
- ): void => {
109
+ graph?: StandardGraph | MultiAgentGraph
110
+ ): Promise<void> => {
96
111
  if (!graph || !metadata) {
97
112
  console.warn(`Graph or metadata not found in ${event} event`);
98
113
  return;
@@ -124,8 +139,10 @@ export const handleToolCalls = (
124
139
  // no previous step
125
140
  }
126
141
 
127
- const dispatchToolCallIds = (lastMessageStepId: string): void => {
128
- graph.dispatchMessageDelta(lastMessageStepId, {
142
+ const dispatchToolCallIds = async (
143
+ lastMessageStepId: string
144
+ ): Promise<void> => {
145
+ await graph.dispatchMessageDelta(lastMessageStepId, {
129
146
  content: [
130
147
  {
131
148
  type: 'text',
@@ -141,7 +158,7 @@ export const handleToolCalls = (
141
158
  prevRunStep &&
142
159
  prevRunStep.type === StepTypes.MESSAGE_CREATION
143
160
  ) {
144
- dispatchToolCallIds(prevStepId);
161
+ await dispatchToolCallIds(prevStepId);
145
162
  graph.messageStepHasToolCalls.set(prevStepId, true);
146
163
  /* If the previous step doesn't exist or is not a message creation */
147
164
  } else if (
@@ -149,19 +166,176 @@ export const handleToolCalls = (
149
166
  prevRunStep.type !== StepTypes.MESSAGE_CREATION
150
167
  ) {
151
168
  const messageId = getMessageId(stepKey, graph, true) ?? '';
152
- const stepId = graph.dispatchRunStep(stepKey, {
169
+ const stepId = await graph.dispatchRunStep(stepKey, {
153
170
  type: StepTypes.MESSAGE_CREATION,
154
171
  message_creation: {
155
172
  message_id: messageId,
156
173
  },
157
174
  });
158
- dispatchToolCallIds(stepId);
175
+ await dispatchToolCallIds(stepId);
159
176
  graph.messageStepHasToolCalls.set(prevStepId, true);
160
177
  }
161
178
 
162
- graph.dispatchRunStep(stepKey, {
179
+ await graph.dispatchRunStep(stepKey, {
163
180
  type: StepTypes.TOOL_CALLS,
164
181
  tool_calls: [tool_call],
165
182
  });
166
183
  }
167
184
  };
185
+
186
+ export const toolResultTypes = new Set([
187
+ // 'tool_use',
188
+ // 'server_tool_use',
189
+ // 'input_json_delta',
190
+ 'tool_result',
191
+ 'web_search_result',
192
+ 'web_search_tool_result',
193
+ ]);
194
+
195
+ /**
196
+ * Handles the result of a server tool call; in other words, a provider's built-in tool.
197
+ * As of 2025-07-06, only Anthropic handles server tool calls with this pattern.
198
+ */
199
+ export async function handleServerToolResult({
200
+ graph,
201
+ content,
202
+ metadata,
203
+ agentContext,
204
+ }: {
205
+ graph: StandardGraph | MultiAgentGraph;
206
+ content?: string | t.MessageContentComplex[];
207
+ metadata?: Record<string, unknown>;
208
+ agentContext?: AgentContext;
209
+ }): Promise<boolean> {
210
+ let skipHandling = false;
211
+ if (agentContext?.provider !== Providers.ANTHROPIC) {
212
+ return skipHandling;
213
+ }
214
+ if (
215
+ typeof content === 'string' ||
216
+ content == null ||
217
+ content.length === 0 ||
218
+ (content.length === 1 &&
219
+ (content[0] as t.ToolResultContent).tool_use_id == null)
220
+ ) {
221
+ return skipHandling;
222
+ }
223
+
224
+ for (const contentPart of content) {
225
+ const toolUseId = (contentPart as t.ToolResultContent).tool_use_id;
226
+ if (toolUseId == null || toolUseId === '') {
227
+ continue;
228
+ }
229
+ const stepId = graph.toolCallStepIds.get(toolUseId);
230
+ if (stepId == null || stepId === '') {
231
+ console.warn(
232
+ `Tool use ID ${toolUseId} not found in graph, cannot dispatch tool result.`
233
+ );
234
+ continue;
235
+ }
236
+ const runStep = graph.getRunStep(stepId);
237
+ if (!runStep) {
238
+ console.warn(
239
+ `Run step for ${stepId} does not exist, cannot dispatch tool result.`
240
+ );
241
+ continue;
242
+ } else if (runStep.type !== StepTypes.TOOL_CALLS) {
243
+ console.warn(
244
+ `Run step for ${stepId} is not a tool call step, cannot dispatch tool result.`
245
+ );
246
+ continue;
247
+ }
248
+
249
+ const toolCall =
250
+ runStep.stepDetails.type === StepTypes.TOOL_CALLS
251
+ ? (runStep.stepDetails.tool_calls?.find(
252
+ (toolCall) => toolCall.id === toolUseId
253
+ ) as ToolCall)
254
+ : undefined;
255
+
256
+ if (!toolCall) {
257
+ continue;
258
+ }
259
+
260
+ if (
261
+ contentPart.type === 'web_search_result' ||
262
+ contentPart.type === 'web_search_tool_result'
263
+ ) {
264
+ await handleAnthropicSearchResults({
265
+ contentPart: contentPart as t.ToolResultContent,
266
+ toolCall,
267
+ metadata,
268
+ graph,
269
+ });
270
+ }
271
+
272
+ if (!skipHandling) {
273
+ skipHandling = true;
274
+ }
275
+ }
276
+
277
+ return skipHandling;
278
+ }
279
+
280
+ async function handleAnthropicSearchResults({
281
+ contentPart,
282
+ toolCall,
283
+ metadata,
284
+ graph,
285
+ }: {
286
+ contentPart: t.ToolResultContent;
287
+ toolCall: Partial<ToolCall>;
288
+ metadata?: Record<string, unknown>;
289
+ graph: StandardGraph | MultiAgentGraph;
290
+ }): Promise<void> {
291
+ if (!Array.isArray(contentPart.content)) {
292
+ console.warn(
293
+ `Expected content to be an array, got ${typeof contentPart.content}`
294
+ );
295
+ return;
296
+ }
297
+
298
+ if (!isAnthropicWebSearchResult(contentPart.content[0])) {
299
+ console.warn(
300
+ `Expected content to be an Anthropic web search result, got ${JSON.stringify(
301
+ contentPart.content
302
+ )}`
303
+ );
304
+ return;
305
+ }
306
+
307
+ const turn = graph.invokedToolIds?.size ?? 0;
308
+ const searchResultData = coerceAnthropicSearchResults({
309
+ turn,
310
+ results: contentPart.content as AnthropicWebSearchResultBlockParam[],
311
+ });
312
+
313
+ const name = toolCall.name;
314
+ const input = toolCall.args ?? {};
315
+ const artifact = {
316
+ [Constants.WEB_SEARCH]: searchResultData,
317
+ };
318
+ const { output: formattedOutput } = formatResultsForLLM(
319
+ turn,
320
+ searchResultData
321
+ );
322
+ const output = new ToolMessage({
323
+ name,
324
+ artifact,
325
+ content: formattedOutput,
326
+ tool_call_id: toolCall.id!,
327
+ });
328
+ const toolEndData: t.ToolEndData = {
329
+ input,
330
+ output,
331
+ };
332
+ await graph.handlerRegistry
333
+ ?.getHandler(GraphEvents.TOOL_END)
334
+ ?.handle(GraphEvents.TOOL_END, toolEndData, metadata, graph);
335
+
336
+ if (graph.invokedToolIds == null) {
337
+ graph.invokedToolIds = new Set<string>();
338
+ }
339
+
340
+ graph.invokedToolIds.add(toolCall.id!);
341
+ }
@@ -0,0 +1,51 @@
1
+ import type {
2
+ AnthropicTextBlockParam,
3
+ AnthropicWebSearchResultBlockParam,
4
+ } from '@/llm/anthropic/types';
5
+ import type { SearchResultData, ProcessedOrganic } from './types';
6
+ import { getAttribution } from './utils';
7
+
8
+ /**
9
+ * Coerces Anthropic web search results to the SearchResultData format
10
+ * @param results - Array of Anthropic web search results
11
+ * @param turn - The turn number to associate with these results
12
+ * @returns SearchResultData with minimal ProcessedOrganic items
13
+ */
14
+ export function coerceAnthropicSearchResults({
15
+ results,
16
+ turn = 0,
17
+ }: {
18
+ results: (AnthropicTextBlockParam | AnthropicWebSearchResultBlockParam)[];
19
+ turn?: number;
20
+ }): SearchResultData {
21
+ const organic: ProcessedOrganic[] = results
22
+ .filter((result) => result.type === 'web_search_result')
23
+ .map((result, index) => ({
24
+ link: result.url,
25
+ position: index + 1,
26
+ title: result.title,
27
+ date: result.page_age ?? undefined,
28
+ attribution: getAttribution(result.url),
29
+ }));
30
+
31
+ return {
32
+ turn,
33
+ organic,
34
+ };
35
+ }
36
+
37
+ /**
38
+ * Helper function to check if an object is an Anthropic web search result
39
+ */
40
+ export function isAnthropicWebSearchResult(
41
+ obj: unknown
42
+ ): obj is AnthropicWebSearchResultBlockParam {
43
+ return (
44
+ typeof obj === 'object' &&
45
+ obj !== null &&
46
+ 'type' in obj &&
47
+ obj.type === 'web_search_result' &&
48
+ 'url' in obj &&
49
+ typeof (obj as Record<string, unknown>).url === 'string'
50
+ );
51
+ }
@@ -13,6 +13,21 @@ export class FirecrawlScraper {
13
13
  private defaultFormats: string[];
14
14
  private timeout: number;
15
15
  private logger: t.Logger;
16
+ private includeTags?: string[];
17
+ private excludeTags?: string[];
18
+ private waitFor?: number;
19
+ private maxAge?: number;
20
+ private mobile?: boolean;
21
+ private skipTlsVerification?: boolean;
22
+ private blockAds?: boolean;
23
+ private removeBase64Images?: boolean;
24
+ private parsePDF?: boolean;
25
+ private storeInCache?: boolean;
26
+ private zeroDataRetention?: boolean;
27
+ private headers?: Record<string, string>;
28
+ private location?: { country?: string; languages?: string[] };
29
+ private onlyMainContent?: boolean;
30
+ private changeTrackingOptions?: object;
16
31
 
17
32
  constructor(config: t.FirecrawlScraperConfig = {}) {
18
33
  this.apiKey = config.apiKey ?? process.env.FIRECRAWL_API_KEY ?? '';
@@ -23,11 +38,27 @@ export class FirecrawlScraper {
23
38
  'https://api.firecrawl.dev';
24
39
  this.apiUrl = `${baseUrl.replace(/\/+$/, '')}/v1/scrape`;
25
40
 
26
- this.defaultFormats = config.formats ?? ['markdown', 'html'];
27
- this.timeout = config.timeout ?? 15000;
41
+ this.defaultFormats = config.formats ?? ['markdown', 'rawHtml'];
42
+ this.timeout = config.timeout ?? 7500;
28
43
 
29
44
  this.logger = config.logger || createDefaultLogger();
30
45
 
46
+ this.includeTags = config.includeTags;
47
+ this.excludeTags = config.excludeTags;
48
+ this.waitFor = config.waitFor;
49
+ this.maxAge = config.maxAge;
50
+ this.mobile = config.mobile;
51
+ this.skipTlsVerification = config.skipTlsVerification;
52
+ this.blockAds = config.blockAds;
53
+ this.removeBase64Images = config.removeBase64Images;
54
+ this.parsePDF = config.parsePDF;
55
+ this.storeInCache = config.storeInCache;
56
+ this.zeroDataRetention = config.zeroDataRetention;
57
+ this.headers = config.headers;
58
+ this.location = config.location;
59
+ this.onlyMainContent = config.onlyMainContent;
60
+ this.changeTrackingOptions = config.changeTrackingOptions;
61
+
31
62
  if (!this.apiKey) {
32
63
  this.logger.warn('FIRECRAWL_API_KEY is not set. Scraping will not work.');
33
64
  }
@@ -58,25 +89,36 @@ export class FirecrawlScraper {
58
89
  }
59
90
 
60
91
  try {
61
- const response = await axios.post(
62
- this.apiUrl,
63
- {
64
- url,
65
- formats: options.formats || this.defaultFormats,
66
- includeTags: options.includeTags,
67
- excludeTags: options.excludeTags,
68
- headers: options.headers,
69
- waitFor: options.waitFor,
70
- timeout: options.timeout ?? this.timeout,
92
+ const payload = omitUndefined({
93
+ url,
94
+ formats: options.formats ?? this.defaultFormats,
95
+ includeTags: options.includeTags ?? this.includeTags,
96
+ excludeTags: options.excludeTags ?? this.excludeTags,
97
+ headers: options.headers ?? this.headers,
98
+ waitFor: options.waitFor ?? this.waitFor,
99
+ timeout: options.timeout ?? this.timeout,
100
+ onlyMainContent: options.onlyMainContent ?? this.onlyMainContent,
101
+ maxAge: options.maxAge ?? this.maxAge,
102
+ mobile: options.mobile ?? this.mobile,
103
+ skipTlsVerification:
104
+ options.skipTlsVerification ?? this.skipTlsVerification,
105
+ parsePDF: options.parsePDF ?? this.parsePDF,
106
+ location: options.location ?? this.location,
107
+ removeBase64Images:
108
+ options.removeBase64Images ?? this.removeBase64Images,
109
+ blockAds: options.blockAds ?? this.blockAds,
110
+ storeInCache: options.storeInCache ?? this.storeInCache,
111
+ zeroDataRetention: options.zeroDataRetention ?? this.zeroDataRetention,
112
+ changeTrackingOptions:
113
+ options.changeTrackingOptions ?? this.changeTrackingOptions,
114
+ });
115
+ const response = await axios.post(this.apiUrl, payload, {
116
+ headers: {
117
+ 'Content-Type': 'application/json',
118
+ Authorization: `Bearer ${this.apiKey}`,
71
119
  },
72
- {
73
- headers: {
74
- 'Content-Type': 'application/json',
75
- Authorization: `Bearer ${this.apiKey}`,
76
- },
77
- timeout: this.timeout,
78
- }
79
- );
120
+ timeout: this.timeout,
121
+ });
80
122
 
81
123
  return [url, response.data];
82
124
  } catch (error) {
@@ -156,3 +198,10 @@ export const createFirecrawlScraper = (
156
198
  ): FirecrawlScraper => {
157
199
  return new FirecrawlScraper(config);
158
200
  };
201
+
202
+ // Helper function to clean up payload for firecrawl
203
+ function omitUndefined<T extends object>(obj: T): Partial<T> {
204
+ return Object.fromEntries(
205
+ Object.entries(obj).filter(([, v]) => v !== undefined)
206
+ ) as Partial<T>;
207
+ }
@@ -65,6 +65,12 @@ function formatSource(
65
65
  if (ref.reference.originalUrl.includes('mailto:')) {
66
66
  continue;
67
67
  }
68
+ if (ref.type !== 'link') {
69
+ continue;
70
+ }
71
+ if (fileExtRegex.test(ref.reference.originalUrl)) {
72
+ continue;
73
+ }
68
74
  references.push({
69
75
  type: ref.type,
70
76
  link: ref.reference.originalUrl,
@@ -75,14 +81,6 @@ function formatSource(
75
81
  ).split('\n')[0],
76
82
  });
77
83
 
78
- if (ref.type !== 'link') {
79
- continue;
80
- }
81
-
82
- if (fileExtRegex.test(ref.reference.originalUrl)) {
83
- continue;
84
- }
85
-
86
84
  if (!hasHeader) {
87
85
  refLines.push('Core References:');
88
86
  hasHeader = true;
@@ -25,13 +25,6 @@ export abstract class BaseReranker {
25
25
  .slice(0, Math.min(topK, documents.length))
26
26
  .map((doc) => ({ text: doc, score: 0 }));
27
27
  }
28
-
29
- protected logDocumentSamples(documents: string[]): void {
30
- this.logger.debug('Sample documents being sent to API:');
31
- for (let i = 0; i < Math.min(3, documents.length); i++) {
32
- this.logger.debug(`Document ${i}: ${documents[i].substring(0, 100)}...`);
33
- }
34
- }
35
28
  }
36
29
 
37
30
  export class JinaReranker extends BaseReranker {
@@ -51,7 +44,7 @@ export class JinaReranker extends BaseReranker {
51
44
  documents: string[],
52
45
  topK: number = 5
53
46
  ): Promise<t.Highlight[]> {
54
- this.logger.debug(`Reranking ${documents.length} documents with Jina`);
47
+ this.logger.debug(`Reranking ${documents.length} chunks with Jina`);
55
48
 
56
49
  try {
57
50
  if (this.apiKey == null || this.apiKey === '') {
@@ -59,8 +52,6 @@ export class JinaReranker extends BaseReranker {
59
52
  return this.getDefaultRanking(documents, topK);
60
53
  }
61
54
 
62
- this.logDocumentSamples(documents);
63
-
64
55
  const requestData = {
65
56
  model: 'jina-reranker-v2-base-multilingual',
66
57
  query: query,
@@ -80,19 +71,8 @@ export class JinaReranker extends BaseReranker {
80
71
  }
81
72
  );
82
73
 
83
- // Log the response data structure
84
- this.logger.debug('Jina API response structure:');
85
- this.logger.debug('Model:', response.data?.model);
86
- this.logger.debug('Usage:', response.data?.usage);
87
- this.logger.debug('Results count:', response.data?.results.length);
88
-
89
- // Log a sample of the results
90
- if ((response.data?.results.length ?? 0) > 0) {
91
- this.logger.debug(
92
- 'Sample result:',
93
- JSON.stringify(response.data?.results[0], null, 2)
94
- );
95
- }
74
+ this.logger.debug('Jina API Model:', response.data?.model);
75
+ this.logger.debug('Jina API Usage:', response.data?.usage);
96
76
 
97
77
  if (response.data && response.data.results.length) {
98
78
  return response.data.results.map((result) => {
@@ -146,7 +126,7 @@ export class CohereReranker extends BaseReranker {
146
126
  documents: string[],
147
127
  topK: number = 5
148
128
  ): Promise<t.Highlight[]> {
149
- this.logger.debug(`Reranking ${documents.length} documents with Cohere`);
129
+ this.logger.debug(`Reranking ${documents.length} chunks with Cohere`);
150
130
 
151
131
  try {
152
132
  if (this.apiKey == null || this.apiKey === '') {
@@ -154,8 +134,6 @@ export class CohereReranker extends BaseReranker {
154
134
  return this.getDefaultRanking(documents, topK);
155
135
  }
156
136
 
157
- this.logDocumentSamples(documents);
158
-
159
137
  const requestData = {
160
138
  model: 'rerank-v3.5',
161
139
  query: query,
@@ -174,19 +152,8 @@ export class CohereReranker extends BaseReranker {
174
152
  }
175
153
  );
176
154
 
177
- // Log the response data structure
178
- this.logger.debug('Cohere API response structure:');
179
- this.logger.debug('ID:', response.data?.id);
180
- this.logger.debug('Meta:', response.data?.meta);
181
- this.logger.debug('Results count:', response.data?.results.length);
182
-
183
- // Log a sample of the results
184
- if ((response.data?.results.length ?? 0) > 0) {
185
- this.logger.debug(
186
- 'Sample result:',
187
- JSON.stringify(response.data?.results[0], null, 2)
188
- );
189
- }
155
+ this.logger.debug('Cohere API ID:', response.data?.id);
156
+ this.logger.debug('Cohere API Meta:', response.data?.meta);
190
157
 
191
158
  if (response.data && response.data.results.length) {
192
159
  return response.data.results.map((result) => {
@@ -221,7 +188,7 @@ export class InfinityReranker extends BaseReranker {
221
188
  topK: number = 5
222
189
  ): Promise<t.Highlight[]> {
223
190
  this.logger.debug(
224
- `Reranking ${documents.length} documents with Infinity (placeholder)`
191
+ `Reranking ${documents.length} chunks with Infinity (placeholder)`
225
192
  );
226
193
  // This would be replaced with actual Infinity reranker implementation
227
194
  return this.getDefaultRanking(documents, topK);