@librechat/agents 2.4.321 → 3.0.0-rc1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/agents/AgentContext.cjs +218 -0
- package/dist/cjs/agents/AgentContext.cjs.map +1 -0
- package/dist/cjs/common/enum.cjs +14 -5
- package/dist/cjs/common/enum.cjs.map +1 -1
- package/dist/cjs/events.cjs +10 -6
- package/dist/cjs/events.cjs.map +1 -1
- package/dist/cjs/graphs/Graph.cjs +309 -212
- package/dist/cjs/graphs/Graph.cjs.map +1 -1
- package/dist/cjs/graphs/MultiAgentGraph.cjs +322 -0
- package/dist/cjs/graphs/MultiAgentGraph.cjs.map +1 -0
- package/dist/cjs/llm/anthropic/index.cjs +54 -9
- package/dist/cjs/llm/anthropic/index.cjs.map +1 -1
- package/dist/cjs/llm/anthropic/types.cjs.map +1 -1
- package/dist/cjs/llm/anthropic/utils/message_inputs.cjs +52 -6
- package/dist/cjs/llm/anthropic/utils/message_inputs.cjs.map +1 -1
- package/dist/cjs/llm/anthropic/utils/message_outputs.cjs +22 -2
- package/dist/cjs/llm/anthropic/utils/message_outputs.cjs.map +1 -1
- package/dist/cjs/llm/anthropic/utils/tools.cjs +29 -0
- package/dist/cjs/llm/anthropic/utils/tools.cjs.map +1 -0
- package/dist/cjs/llm/google/index.cjs +144 -0
- package/dist/cjs/llm/google/index.cjs.map +1 -0
- package/dist/cjs/llm/google/utils/common.cjs +477 -0
- package/dist/cjs/llm/google/utils/common.cjs.map +1 -0
- package/dist/cjs/llm/ollama/index.cjs +67 -0
- package/dist/cjs/llm/ollama/index.cjs.map +1 -0
- package/dist/cjs/llm/ollama/utils.cjs +158 -0
- package/dist/cjs/llm/ollama/utils.cjs.map +1 -0
- package/dist/cjs/llm/openai/index.cjs +389 -3
- package/dist/cjs/llm/openai/index.cjs.map +1 -1
- package/dist/cjs/llm/openai/utils/index.cjs +672 -0
- package/dist/cjs/llm/openai/utils/index.cjs.map +1 -0
- package/dist/cjs/llm/providers.cjs +15 -15
- package/dist/cjs/llm/providers.cjs.map +1 -1
- package/dist/cjs/llm/text.cjs +14 -3
- package/dist/cjs/llm/text.cjs.map +1 -1
- package/dist/cjs/llm/vertexai/index.cjs +330 -0
- package/dist/cjs/llm/vertexai/index.cjs.map +1 -0
- package/dist/cjs/main.cjs +11 -0
- package/dist/cjs/main.cjs.map +1 -1
- package/dist/cjs/run.cjs +120 -81
- package/dist/cjs/run.cjs.map +1 -1
- package/dist/cjs/stream.cjs +85 -51
- package/dist/cjs/stream.cjs.map +1 -1
- package/dist/cjs/tools/ToolNode.cjs +10 -4
- package/dist/cjs/tools/ToolNode.cjs.map +1 -1
- package/dist/cjs/tools/handlers.cjs +119 -13
- package/dist/cjs/tools/handlers.cjs.map +1 -1
- package/dist/cjs/tools/search/anthropic.cjs +40 -0
- package/dist/cjs/tools/search/anthropic.cjs.map +1 -0
- package/dist/cjs/tools/search/firecrawl.cjs +61 -13
- package/dist/cjs/tools/search/firecrawl.cjs.map +1 -1
- package/dist/cjs/tools/search/format.cjs +9 -3
- package/dist/cjs/tools/search/format.cjs.map +1 -1
- package/dist/cjs/tools/search/rerankers.cjs +35 -50
- package/dist/cjs/tools/search/rerankers.cjs.map +1 -1
- package/dist/cjs/tools/search/schema.cjs +70 -0
- package/dist/cjs/tools/search/schema.cjs.map +1 -0
- package/dist/cjs/tools/search/search.cjs +145 -38
- package/dist/cjs/tools/search/search.cjs.map +1 -1
- package/dist/cjs/tools/search/tool.cjs +165 -48
- package/dist/cjs/tools/search/tool.cjs.map +1 -1
- package/dist/cjs/tools/search/utils.cjs +34 -5
- package/dist/cjs/tools/search/utils.cjs.map +1 -1
- package/dist/cjs/utils/events.cjs +31 -0
- package/dist/cjs/utils/events.cjs.map +1 -0
- package/dist/cjs/utils/title.cjs +57 -21
- package/dist/cjs/utils/title.cjs.map +1 -1
- package/dist/cjs/utils/tokens.cjs +54 -7
- package/dist/cjs/utils/tokens.cjs.map +1 -1
- package/dist/esm/agents/AgentContext.mjs +216 -0
- package/dist/esm/agents/AgentContext.mjs.map +1 -0
- package/dist/esm/common/enum.mjs +15 -6
- package/dist/esm/common/enum.mjs.map +1 -1
- package/dist/esm/events.mjs +10 -6
- package/dist/esm/events.mjs.map +1 -1
- package/dist/esm/graphs/Graph.mjs +311 -214
- package/dist/esm/graphs/Graph.mjs.map +1 -1
- package/dist/esm/graphs/MultiAgentGraph.mjs +320 -0
- package/dist/esm/graphs/MultiAgentGraph.mjs.map +1 -0
- package/dist/esm/llm/anthropic/index.mjs +54 -9
- package/dist/esm/llm/anthropic/index.mjs.map +1 -1
- package/dist/esm/llm/anthropic/types.mjs.map +1 -1
- package/dist/esm/llm/anthropic/utils/message_inputs.mjs +52 -6
- package/dist/esm/llm/anthropic/utils/message_inputs.mjs.map +1 -1
- package/dist/esm/llm/anthropic/utils/message_outputs.mjs +22 -2
- package/dist/esm/llm/anthropic/utils/message_outputs.mjs.map +1 -1
- package/dist/esm/llm/anthropic/utils/tools.mjs +27 -0
- package/dist/esm/llm/anthropic/utils/tools.mjs.map +1 -0
- package/dist/esm/llm/google/index.mjs +142 -0
- package/dist/esm/llm/google/index.mjs.map +1 -0
- package/dist/esm/llm/google/utils/common.mjs +471 -0
- package/dist/esm/llm/google/utils/common.mjs.map +1 -0
- package/dist/esm/llm/ollama/index.mjs +65 -0
- package/dist/esm/llm/ollama/index.mjs.map +1 -0
- package/dist/esm/llm/ollama/utils.mjs +155 -0
- package/dist/esm/llm/ollama/utils.mjs.map +1 -0
- package/dist/esm/llm/openai/index.mjs +388 -4
- package/dist/esm/llm/openai/index.mjs.map +1 -1
- package/dist/esm/llm/openai/utils/index.mjs +666 -0
- package/dist/esm/llm/openai/utils/index.mjs.map +1 -0
- package/dist/esm/llm/providers.mjs +5 -5
- package/dist/esm/llm/providers.mjs.map +1 -1
- package/dist/esm/llm/text.mjs +14 -3
- package/dist/esm/llm/text.mjs.map +1 -1
- package/dist/esm/llm/vertexai/index.mjs +328 -0
- package/dist/esm/llm/vertexai/index.mjs.map +1 -0
- package/dist/esm/main.mjs +6 -5
- package/dist/esm/main.mjs.map +1 -1
- package/dist/esm/run.mjs +121 -83
- package/dist/esm/run.mjs.map +1 -1
- package/dist/esm/stream.mjs +87 -54
- package/dist/esm/stream.mjs.map +1 -1
- package/dist/esm/tools/ToolNode.mjs +10 -4
- package/dist/esm/tools/ToolNode.mjs.map +1 -1
- package/dist/esm/tools/handlers.mjs +119 -15
- package/dist/esm/tools/handlers.mjs.map +1 -1
- package/dist/esm/tools/search/anthropic.mjs +37 -0
- package/dist/esm/tools/search/anthropic.mjs.map +1 -0
- package/dist/esm/tools/search/firecrawl.mjs +61 -13
- package/dist/esm/tools/search/firecrawl.mjs.map +1 -1
- package/dist/esm/tools/search/format.mjs +10 -4
- package/dist/esm/tools/search/format.mjs.map +1 -1
- package/dist/esm/tools/search/rerankers.mjs +35 -50
- package/dist/esm/tools/search/rerankers.mjs.map +1 -1
- package/dist/esm/tools/search/schema.mjs +61 -0
- package/dist/esm/tools/search/schema.mjs.map +1 -0
- package/dist/esm/tools/search/search.mjs +146 -39
- package/dist/esm/tools/search/search.mjs.map +1 -1
- package/dist/esm/tools/search/tool.mjs +164 -47
- package/dist/esm/tools/search/tool.mjs.map +1 -1
- package/dist/esm/tools/search/utils.mjs +33 -6
- package/dist/esm/tools/search/utils.mjs.map +1 -1
- package/dist/esm/utils/events.mjs +29 -0
- package/dist/esm/utils/events.mjs.map +1 -0
- package/dist/esm/utils/title.mjs +57 -22
- package/dist/esm/utils/title.mjs.map +1 -1
- package/dist/esm/utils/tokens.mjs +54 -8
- package/dist/esm/utils/tokens.mjs.map +1 -1
- package/dist/types/agents/AgentContext.d.ts +91 -0
- package/dist/types/common/enum.d.ts +15 -6
- package/dist/types/events.d.ts +5 -4
- package/dist/types/graphs/Graph.d.ts +64 -67
- package/dist/types/graphs/MultiAgentGraph.d.ts +37 -0
- package/dist/types/graphs/index.d.ts +1 -0
- package/dist/types/llm/anthropic/index.d.ts +11 -0
- package/dist/types/llm/anthropic/types.d.ts +9 -3
- package/dist/types/llm/anthropic/utils/message_inputs.d.ts +1 -1
- package/dist/types/llm/anthropic/utils/output_parsers.d.ts +4 -4
- package/dist/types/llm/anthropic/utils/tools.d.ts +3 -0
- package/dist/types/llm/google/index.d.ts +13 -0
- package/dist/types/llm/google/types.d.ts +32 -0
- package/dist/types/llm/google/utils/common.d.ts +19 -0
- package/dist/types/llm/google/utils/tools.d.ts +10 -0
- package/dist/types/llm/google/utils/zod_to_genai_parameters.d.ts +14 -0
- package/dist/types/llm/ollama/index.d.ts +7 -0
- package/dist/types/llm/ollama/utils.d.ts +7 -0
- package/dist/types/llm/openai/index.d.ts +72 -3
- package/dist/types/llm/openai/types.d.ts +10 -0
- package/dist/types/llm/openai/utils/index.d.ts +20 -0
- package/dist/types/llm/text.d.ts +1 -1
- package/dist/types/llm/vertexai/index.d.ts +293 -0
- package/dist/types/messages/reducer.d.ts +9 -0
- package/dist/types/run.d.ts +19 -12
- package/dist/types/scripts/ant_web_search.d.ts +1 -0
- package/dist/types/scripts/args.d.ts +2 -1
- package/dist/types/scripts/handoff-test.d.ts +1 -0
- package/dist/types/scripts/multi-agent-conditional.d.ts +1 -0
- package/dist/types/scripts/multi-agent-parallel.d.ts +1 -0
- package/dist/types/scripts/multi-agent-sequence.d.ts +1 -0
- package/dist/types/scripts/multi-agent-test.d.ts +1 -0
- package/dist/types/stream.d.ts +10 -3
- package/dist/types/tools/CodeExecutor.d.ts +2 -2
- package/dist/types/tools/ToolNode.d.ts +1 -1
- package/dist/types/tools/handlers.d.ts +17 -4
- package/dist/types/tools/search/anthropic.d.ts +16 -0
- package/dist/types/tools/search/firecrawl.d.ts +16 -0
- package/dist/types/tools/search/rerankers.d.ts +8 -5
- package/dist/types/tools/search/schema.d.ts +16 -0
- package/dist/types/tools/search/tool.d.ts +13 -0
- package/dist/types/tools/search/types.d.ts +64 -9
- package/dist/types/tools/search/utils.d.ts +9 -2
- package/dist/types/types/graph.d.ts +95 -15
- package/dist/types/types/llm.d.ts +24 -10
- package/dist/types/types/run.d.ts +46 -8
- package/dist/types/types/stream.d.ts +16 -2
- package/dist/types/types/tools.d.ts +1 -1
- package/dist/types/utils/events.d.ts +6 -0
- package/dist/types/utils/title.d.ts +2 -1
- package/dist/types/utils/tokens.d.ts +24 -0
- package/package.json +35 -18
- package/src/agents/AgentContext.ts +315 -0
- package/src/common/enum.ts +14 -5
- package/src/events.ts +24 -13
- package/src/graphs/Graph.ts +495 -312
- package/src/graphs/MultiAgentGraph.ts +381 -0
- package/src/graphs/index.ts +2 -1
- package/src/llm/anthropic/Jacob_Lee_Resume_2023.pdf +0 -0
- package/src/llm/anthropic/index.ts +78 -13
- package/src/llm/anthropic/llm.spec.ts +491 -115
- package/src/llm/anthropic/types.ts +39 -3
- package/src/llm/anthropic/utils/message_inputs.ts +67 -11
- package/src/llm/anthropic/utils/message_outputs.ts +21 -2
- package/src/llm/anthropic/utils/output_parsers.ts +25 -6
- package/src/llm/anthropic/utils/tools.ts +29 -0
- package/src/llm/google/index.ts +218 -0
- package/src/llm/google/types.ts +43 -0
- package/src/llm/google/utils/common.ts +646 -0
- package/src/llm/google/utils/tools.ts +160 -0
- package/src/llm/google/utils/zod_to_genai_parameters.ts +86 -0
- package/src/llm/ollama/index.ts +89 -0
- package/src/llm/ollama/utils.ts +193 -0
- package/src/llm/openai/index.ts +600 -14
- package/src/llm/openai/types.ts +24 -0
- package/src/llm/openai/utils/index.ts +912 -0
- package/src/llm/openai/utils/isReasoningModel.test.ts +90 -0
- package/src/llm/providers.ts +10 -9
- package/src/llm/text.ts +26 -7
- package/src/llm/vertexai/index.ts +360 -0
- package/src/messages/reducer.ts +80 -0
- package/src/run.ts +181 -112
- package/src/scripts/ant_web_search.ts +158 -0
- package/src/scripts/args.ts +12 -8
- package/src/scripts/cli4.ts +29 -21
- package/src/scripts/cli5.ts +29 -21
- package/src/scripts/code_exec.ts +54 -23
- package/src/scripts/code_exec_files.ts +48 -17
- package/src/scripts/code_exec_simple.ts +46 -27
- package/src/scripts/handoff-test.ts +135 -0
- package/src/scripts/image.ts +52 -20
- package/src/scripts/multi-agent-conditional.ts +220 -0
- package/src/scripts/multi-agent-example-output.md +110 -0
- package/src/scripts/multi-agent-parallel.ts +337 -0
- package/src/scripts/multi-agent-sequence.ts +212 -0
- package/src/scripts/multi-agent-test.ts +186 -0
- package/src/scripts/search.ts +4 -12
- package/src/scripts/simple.ts +25 -10
- package/src/scripts/tools.ts +48 -18
- package/src/specs/anthropic.simple.test.ts +150 -34
- package/src/specs/azure.simple.test.ts +325 -0
- package/src/specs/openai.simple.test.ts +140 -33
- package/src/specs/openrouter.simple.test.ts +107 -0
- package/src/specs/prune.test.ts +4 -9
- package/src/specs/reasoning.test.ts +80 -44
- package/src/specs/token-memoization.test.ts +39 -0
- package/src/stream.test.ts +94 -0
- package/src/stream.ts +139 -60
- package/src/tools/ToolNode.ts +21 -7
- package/src/tools/handlers.ts +192 -18
- package/src/tools/search/anthropic.ts +51 -0
- package/src/tools/search/firecrawl.ts +78 -24
- package/src/tools/search/format.ts +10 -5
- package/src/tools/search/rerankers.ts +50 -62
- package/src/tools/search/schema.ts +63 -0
- package/src/tools/search/search.ts +167 -34
- package/src/tools/search/tool.ts +222 -46
- package/src/tools/search/types.ts +65 -10
- package/src/tools/search/utils.ts +37 -5
- package/src/types/graph.ts +272 -103
- package/src/types/llm.ts +25 -12
- package/src/types/run.ts +51 -13
- package/src/types/stream.ts +22 -1
- package/src/types/tools.ts +16 -10
- package/src/utils/events.ts +32 -0
- package/src/utils/llmConfig.ts +20 -8
- package/src/utils/title.ts +104 -30
- package/src/utils/tokens.ts +69 -10
package/src/tools/handlers.ts
CHANGED
|
@@ -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 {
|
|
7
|
+
import type { MultiAgentGraph, StandardGraph } from '@/graphs';
|
|
8
|
+
import type { AgentContext } from '@/agents/AgentContext';
|
|
6
9
|
import type * as t from '@/types';
|
|
7
|
-
import {
|
|
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:
|
|
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?:
|
|
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 = (
|
|
128
|
-
|
|
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
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
/* eslint-disable no-console */
|
|
2
1
|
import axios from 'axios';
|
|
3
2
|
import { processContent } from './content';
|
|
4
3
|
import type * as t from './types';
|
|
4
|
+
import { createDefaultLogger } from './utils';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Firecrawl scraper implementation
|
|
@@ -12,6 +12,22 @@ export class FirecrawlScraper {
|
|
|
12
12
|
private apiUrl: string;
|
|
13
13
|
private defaultFormats: string[];
|
|
14
14
|
private timeout: number;
|
|
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;
|
|
15
31
|
|
|
16
32
|
constructor(config: t.FirecrawlScraperConfig = {}) {
|
|
17
33
|
this.apiKey = config.apiKey ?? process.env.FIRECRAWL_API_KEY ?? '';
|
|
@@ -22,14 +38,34 @@ export class FirecrawlScraper {
|
|
|
22
38
|
'https://api.firecrawl.dev';
|
|
23
39
|
this.apiUrl = `${baseUrl.replace(/\/+$/, '')}/v1/scrape`;
|
|
24
40
|
|
|
25
|
-
this.defaultFormats = config.formats ?? ['markdown', '
|
|
26
|
-
this.timeout = config.timeout ??
|
|
41
|
+
this.defaultFormats = config.formats ?? ['markdown', 'rawHtml'];
|
|
42
|
+
this.timeout = config.timeout ?? 7500;
|
|
43
|
+
|
|
44
|
+
this.logger = config.logger || createDefaultLogger();
|
|
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;
|
|
27
61
|
|
|
28
62
|
if (!this.apiKey) {
|
|
29
|
-
|
|
63
|
+
this.logger.warn('FIRECRAWL_API_KEY is not set. Scraping will not work.');
|
|
30
64
|
}
|
|
31
65
|
|
|
32
|
-
|
|
66
|
+
this.logger.debug(
|
|
67
|
+
`Firecrawl scraper initialized with API URL: ${this.apiUrl}`
|
|
68
|
+
);
|
|
33
69
|
}
|
|
34
70
|
|
|
35
71
|
/**
|
|
@@ -53,25 +89,36 @@ export class FirecrawlScraper {
|
|
|
53
89
|
}
|
|
54
90
|
|
|
55
91
|
try {
|
|
56
|
-
const
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
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}`,
|
|
66
119
|
},
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
'Content-Type': 'application/json',
|
|
70
|
-
Authorization: `Bearer ${this.apiKey}`,
|
|
71
|
-
},
|
|
72
|
-
timeout: this.timeout,
|
|
73
|
-
}
|
|
74
|
-
);
|
|
120
|
+
timeout: this.timeout,
|
|
121
|
+
});
|
|
75
122
|
|
|
76
123
|
return [url, response.data];
|
|
77
124
|
} catch (error) {
|
|
@@ -107,7 +154,7 @@ export class FirecrawlScraper {
|
|
|
107
154
|
);
|
|
108
155
|
return [markdown, rest];
|
|
109
156
|
} catch (error) {
|
|
110
|
-
|
|
157
|
+
this.logger.error('Error processing content:', error);
|
|
111
158
|
return [response.data.markdown, undefined];
|
|
112
159
|
}
|
|
113
160
|
} else if (response.data.markdown != null) {
|
|
@@ -151,3 +198,10 @@ export const createFirecrawlScraper = (
|
|
|
151
198
|
): FirecrawlScraper => {
|
|
152
199
|
return new FirecrawlScraper(config);
|
|
153
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
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type * as t from './types';
|
|
2
|
-
import { getDomainName } from './utils';
|
|
2
|
+
import { getDomainName, fileExtRegex } from './utils';
|
|
3
3
|
|
|
4
4
|
function addHighlightSection(): string[] {
|
|
5
5
|
return ['\n## Highlights', ''];
|
|
@@ -62,6 +62,15 @@ function formatSource(
|
|
|
62
62
|
|
|
63
63
|
for (let j = 0; j < h.references.length; j++) {
|
|
64
64
|
const ref = h.references[j];
|
|
65
|
+
if (ref.reference.originalUrl.includes('mailto:')) {
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
if (ref.type !== 'link') {
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
if (fileExtRegex.test(ref.reference.originalUrl)) {
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
65
74
|
references.push({
|
|
66
75
|
type: ref.type,
|
|
67
76
|
link: ref.reference.originalUrl,
|
|
@@ -72,10 +81,6 @@ function formatSource(
|
|
|
72
81
|
).split('\n')[0],
|
|
73
82
|
});
|
|
74
83
|
|
|
75
|
-
if (ref.type !== 'link') {
|
|
76
|
-
continue;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
84
|
if (!hasHeader) {
|
|
80
85
|
refLines.push('Core References:');
|
|
81
86
|
hasHeader = true;
|