@librechat/agents 2.4.322 → 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 +55 -9
- package/dist/cjs/tools/search/firecrawl.cjs.map +1 -1
- package/dist/cjs/tools/search/format.cjs +6 -6
- package/dist/cjs/tools/search/format.cjs.map +1 -1
- package/dist/cjs/tools/search/rerankers.cjs +7 -29
- package/dist/cjs/tools/search/rerankers.cjs.map +1 -1
- package/dist/cjs/tools/search/search.cjs +86 -16
- package/dist/cjs/tools/search/search.cjs.map +1 -1
- package/dist/cjs/tools/search/tool.cjs +4 -2
- package/dist/cjs/tools/search/tool.cjs.map +1 -1
- package/dist/cjs/tools/search/utils.cjs +1 -1
- 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 +55 -9
- package/dist/esm/tools/search/firecrawl.mjs.map +1 -1
- package/dist/esm/tools/search/format.mjs +7 -7
- package/dist/esm/tools/search/format.mjs.map +1 -1
- package/dist/esm/tools/search/rerankers.mjs +7 -29
- package/dist/esm/tools/search/rerankers.mjs.map +1 -1
- package/dist/esm/tools/search/search.mjs +86 -16
- package/dist/esm/tools/search/search.mjs.map +1 -1
- package/dist/esm/tools/search/tool.mjs +4 -2
- package/dist/esm/tools/search/tool.mjs.map +1 -1
- package/dist/esm/tools/search/utils.mjs +1 -1
- 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 +15 -0
- package/dist/types/tools/search/rerankers.d.ts +0 -1
- package/dist/types/tools/search/types.d.ts +30 -9
- 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 +33 -17
- 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 +1 -9
- 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 +69 -20
- package/src/tools/search/format.ts +6 -8
- package/src/tools/search/rerankers.ts +7 -40
- package/src/tools/search/search.ts +97 -16
- package/src/tools/search/tool.ts +5 -2
- package/src/tools/search/types.ts +30 -10
- package/src/tools/search/utils.ts +1 -1
- 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 +19 -7
- 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
|
+
}
|
|
@@ -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', '
|
|
27
|
-
this.timeout = config.timeout ??
|
|
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
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
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
|
-
|
|
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}
|
|
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
|
-
|
|
84
|
-
this.logger.debug('Jina API
|
|
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}
|
|
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
|
-
|
|
178
|
-
this.logger.debug('Cohere API
|
|
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}
|
|
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);
|