@librechat/agents 2.4.322 → 3.0.0-rc2
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 +422 -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 +420 -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-supervisor.d.ts +1 -0
- package/dist/types/scripts/multi-agent-test.d.ts +1 -0
- package/dist/types/scripts/test-custom-prompt-key.d.ts +2 -0
- package/dist/types/scripts/test-handoff-input.d.ts +2 -0
- package/dist/types/scripts/test-multi-agent-list-handoff.d.ts +2 -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 +129 -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 +37 -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 +498 -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 +341 -0
- package/src/scripts/multi-agent-sequence.ts +212 -0
- package/src/scripts/multi-agent-supervisor.ts +361 -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/test-custom-prompt-key.ts +145 -0
- package/src/scripts/test-handoff-input.ts +110 -0
- package/src/scripts/test-multi-agent-list-handoff.ts +258 -0
- 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 +315 -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
|
@@ -1,10 +1,16 @@
|
|
|
1
|
+
/* eslint-disable no-process-env */
|
|
2
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
3
|
+
import { config } from 'dotenv';
|
|
4
|
+
config();
|
|
1
5
|
import { expect, test } from '@jest/globals';
|
|
2
6
|
import * as fs from 'fs/promises';
|
|
3
7
|
import {
|
|
8
|
+
AIMessage,
|
|
4
9
|
AIMessageChunk,
|
|
5
10
|
BaseMessage,
|
|
6
11
|
HumanMessage,
|
|
7
12
|
SystemMessage,
|
|
13
|
+
ToolMessage,
|
|
8
14
|
} from '@langchain/core/messages';
|
|
9
15
|
import { ChatPromptValue } from '@langchain/core/prompt_values';
|
|
10
16
|
import {
|
|
@@ -16,13 +22,53 @@ import {
|
|
|
16
22
|
} from '@langchain/core/prompts';
|
|
17
23
|
import { CallbackManager } from '@langchain/core/callbacks/manager';
|
|
18
24
|
import { concat } from '@langchain/core/utils/stream';
|
|
25
|
+
import { AnthropicVertex } from '@anthropic-ai/vertex-sdk';
|
|
26
|
+
import { BaseLanguageModelInput } from '@langchain/core/language_models/base';
|
|
27
|
+
import { tool } from '@langchain/core/tools';
|
|
28
|
+
import { z } from 'zod';
|
|
19
29
|
import { CustomAnthropic as ChatAnthropic } from './index';
|
|
20
|
-
import { AnthropicMessageResponse } from './types';
|
|
30
|
+
import { AnthropicMessageResponse, ChatAnthropicContentBlock } from './types';
|
|
21
31
|
jest.setTimeout(120000);
|
|
22
32
|
|
|
33
|
+
async function invoke(
|
|
34
|
+
chat: ChatAnthropic,
|
|
35
|
+
invocationType: string,
|
|
36
|
+
input: BaseLanguageModelInput
|
|
37
|
+
): Promise<AIMessageChunk | AIMessage> {
|
|
38
|
+
if (invocationType === 'stream') {
|
|
39
|
+
let output: AIMessageChunk | undefined;
|
|
40
|
+
|
|
41
|
+
const stream = await chat.stream(input);
|
|
42
|
+
|
|
43
|
+
for await (const chunk of stream) {
|
|
44
|
+
if (!output) {
|
|
45
|
+
output = chunk;
|
|
46
|
+
} else {
|
|
47
|
+
output = output.concat(chunk);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return output!;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return chat.invoke(input);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// use this for tests involving "extended thinking"
|
|
58
|
+
const extendedThinkingModelName = 'claude-3-7-sonnet-20250219';
|
|
59
|
+
|
|
60
|
+
// use this for tests involving citations
|
|
61
|
+
const citationsModelName = 'claude-3-5-sonnet-20241022';
|
|
62
|
+
|
|
63
|
+
// use this for tests involving PDF documents
|
|
64
|
+
const pdfModelName = 'claude-3-5-haiku-20241022';
|
|
65
|
+
|
|
66
|
+
// Use this model for all other tests
|
|
67
|
+
const modelName = 'claude-3-haiku-20240307';
|
|
68
|
+
|
|
23
69
|
test('Test ChatAnthropic', async () => {
|
|
24
70
|
const chat = new ChatAnthropic({
|
|
25
|
-
modelName
|
|
71
|
+
modelName,
|
|
26
72
|
maxRetries: 0,
|
|
27
73
|
});
|
|
28
74
|
const message = new HumanMessage('Hello!');
|
|
@@ -32,7 +78,7 @@ test('Test ChatAnthropic', async () => {
|
|
|
32
78
|
|
|
33
79
|
test('Test ChatAnthropic with a bad API key throws appropriate error', async () => {
|
|
34
80
|
const chat = new ChatAnthropic({
|
|
35
|
-
modelName
|
|
81
|
+
modelName,
|
|
36
82
|
maxRetries: 0,
|
|
37
83
|
apiKey: 'bad',
|
|
38
84
|
});
|
|
@@ -65,7 +111,7 @@ test('Test ChatAnthropic with unknown model throws appropriate error', async ()
|
|
|
65
111
|
|
|
66
112
|
test('Test ChatAnthropic Generate', async () => {
|
|
67
113
|
const chat = new ChatAnthropic({
|
|
68
|
-
modelName
|
|
114
|
+
modelName,
|
|
69
115
|
maxRetries: 0,
|
|
70
116
|
});
|
|
71
117
|
const message = new HumanMessage('Hello!');
|
|
@@ -73,7 +119,6 @@ test('Test ChatAnthropic Generate', async () => {
|
|
|
73
119
|
expect(res.generations.length).toBe(2);
|
|
74
120
|
for (const generation of res.generations) {
|
|
75
121
|
expect(generation.length).toBe(1);
|
|
76
|
-
// @eslint-disable-next-line/@typescript-eslint/ban-ts-comment
|
|
77
122
|
for (const message of generation) {
|
|
78
123
|
// console.log(message.text);
|
|
79
124
|
}
|
|
@@ -83,7 +128,7 @@ test('Test ChatAnthropic Generate', async () => {
|
|
|
83
128
|
|
|
84
129
|
test.skip('Test ChatAnthropic Generate w/ ClientOptions', async () => {
|
|
85
130
|
const chat = new ChatAnthropic({
|
|
86
|
-
modelName
|
|
131
|
+
modelName,
|
|
87
132
|
maxRetries: 0,
|
|
88
133
|
clientOptions: {
|
|
89
134
|
defaultHeaders: {
|
|
@@ -96,7 +141,6 @@ test.skip('Test ChatAnthropic Generate w/ ClientOptions', async () => {
|
|
|
96
141
|
expect(res.generations.length).toBe(2);
|
|
97
142
|
for (const generation of res.generations) {
|
|
98
143
|
expect(generation.length).toBe(1);
|
|
99
|
-
// @eslint-disable-next-line/@typescript-eslint/ban-ts-comment
|
|
100
144
|
for (const message of generation) {
|
|
101
145
|
// console.log(message.text);
|
|
102
146
|
}
|
|
@@ -106,7 +150,7 @@ test.skip('Test ChatAnthropic Generate w/ ClientOptions', async () => {
|
|
|
106
150
|
|
|
107
151
|
test('Test ChatAnthropic Generate with a signal in call options', async () => {
|
|
108
152
|
const chat = new ChatAnthropic({
|
|
109
|
-
modelName
|
|
153
|
+
modelName,
|
|
110
154
|
maxRetries: 0,
|
|
111
155
|
});
|
|
112
156
|
const controller = new AbortController();
|
|
@@ -128,9 +172,8 @@ test('Test ChatAnthropic tokenUsage with a batch', async () => {
|
|
|
128
172
|
const model = new ChatAnthropic({
|
|
129
173
|
temperature: 0,
|
|
130
174
|
maxRetries: 0,
|
|
131
|
-
modelName
|
|
175
|
+
modelName,
|
|
132
176
|
});
|
|
133
|
-
// @eslint-disable-next-line/@typescript-eslint/ban-ts-comment
|
|
134
177
|
const res = await model.generate([
|
|
135
178
|
[new HumanMessage(`Hello!`)],
|
|
136
179
|
[new HumanMessage(`Hi!`)],
|
|
@@ -143,7 +186,7 @@ test('Test ChatAnthropic in streaming mode', async () => {
|
|
|
143
186
|
let streamedCompletion = '';
|
|
144
187
|
|
|
145
188
|
const model = new ChatAnthropic({
|
|
146
|
-
modelName
|
|
189
|
+
modelName,
|
|
147
190
|
maxRetries: 0,
|
|
148
191
|
streaming: true,
|
|
149
192
|
callbacks: CallbackManager.fromHandlers({
|
|
@@ -166,7 +209,7 @@ test('Test ChatAnthropic in streaming mode with a signal', async () => {
|
|
|
166
209
|
let streamedCompletion = '';
|
|
167
210
|
|
|
168
211
|
const model = new ChatAnthropic({
|
|
169
|
-
modelName
|
|
212
|
+
modelName,
|
|
170
213
|
maxRetries: 0,
|
|
171
214
|
streaming: true,
|
|
172
215
|
callbacks: CallbackManager.fromHandlers({
|
|
@@ -195,14 +238,13 @@ test('Test ChatAnthropic in streaming mode with a signal', async () => {
|
|
|
195
238
|
|
|
196
239
|
test.skip('Test ChatAnthropic prompt value', async () => {
|
|
197
240
|
const chat = new ChatAnthropic({
|
|
198
|
-
modelName
|
|
241
|
+
modelName,
|
|
199
242
|
maxRetries: 0,
|
|
200
243
|
});
|
|
201
244
|
const message = new HumanMessage('Hello!');
|
|
202
245
|
const res = await chat.generatePrompt([new ChatPromptValue([message])]);
|
|
203
246
|
expect(res.generations.length).toBe(1);
|
|
204
247
|
for (const generation of res.generations) {
|
|
205
|
-
// @eslint-disable-next-line/@typescript-eslint/ban-ts-comment
|
|
206
248
|
for (const g of generation) {
|
|
207
249
|
// console.log(g.text);
|
|
208
250
|
}
|
|
@@ -212,7 +254,7 @@ test.skip('Test ChatAnthropic prompt value', async () => {
|
|
|
212
254
|
|
|
213
255
|
test.skip('ChatAnthropic, docs, prompt templates', async () => {
|
|
214
256
|
const chat = new ChatAnthropic({
|
|
215
|
-
modelName
|
|
257
|
+
modelName,
|
|
216
258
|
maxRetries: 0,
|
|
217
259
|
temperature: 0,
|
|
218
260
|
});
|
|
@@ -226,7 +268,6 @@ test.skip('ChatAnthropic, docs, prompt templates', async () => {
|
|
|
226
268
|
HumanMessagePromptTemplate.fromTemplate('{text}'),
|
|
227
269
|
]);
|
|
228
270
|
|
|
229
|
-
// @eslint-disable-next-line/@typescript-eslint/ban-ts-comment
|
|
230
271
|
const responseA = await chat.generatePrompt([
|
|
231
272
|
await chatPrompt.formatPromptValue({
|
|
232
273
|
input_language: 'English',
|
|
@@ -240,7 +281,7 @@ test.skip('ChatAnthropic, docs, prompt templates', async () => {
|
|
|
240
281
|
|
|
241
282
|
test.skip('ChatAnthropic, longer chain of messages', async () => {
|
|
242
283
|
const chat = new ChatAnthropic({
|
|
243
|
-
modelName
|
|
284
|
+
modelName,
|
|
244
285
|
maxRetries: 0,
|
|
245
286
|
temperature: 0,
|
|
246
287
|
});
|
|
@@ -251,7 +292,6 @@ test.skip('ChatAnthropic, longer chain of messages', async () => {
|
|
|
251
292
|
HumanMessagePromptTemplate.fromTemplate('{text}'),
|
|
252
293
|
]);
|
|
253
294
|
|
|
254
|
-
// @eslint-disable-next-line/@typescript-eslint/ban-ts-comment
|
|
255
295
|
const responseA = await chat.generatePrompt([
|
|
256
296
|
await chatPrompt.formatPromptValue({
|
|
257
297
|
text: 'What did I just say my name was?',
|
|
@@ -265,12 +305,11 @@ test.skip('ChatAnthropic, Anthropic apiUrl set manually via constructor', async
|
|
|
265
305
|
// Pass the default URL through (should use this, and work as normal)
|
|
266
306
|
const anthropicApiUrl = 'https://api.anthropic.com';
|
|
267
307
|
const chat = new ChatAnthropic({
|
|
268
|
-
modelName
|
|
308
|
+
modelName,
|
|
269
309
|
maxRetries: 0,
|
|
270
310
|
anthropicApiUrl,
|
|
271
311
|
});
|
|
272
312
|
const message = new HumanMessage('Hello!');
|
|
273
|
-
// @eslint-disable-next-line/@typescript-eslint/ban-ts-comment
|
|
274
313
|
const res = await chat.call([message]);
|
|
275
314
|
// console.log({ res });
|
|
276
315
|
});
|
|
@@ -279,10 +318,10 @@ test('Test ChatAnthropic stream method', async () => {
|
|
|
279
318
|
const model = new ChatAnthropic({
|
|
280
319
|
maxTokens: 50,
|
|
281
320
|
maxRetries: 0,
|
|
282
|
-
modelName
|
|
321
|
+
modelName,
|
|
283
322
|
});
|
|
284
323
|
const stream = await model.stream('Print hello world.');
|
|
285
|
-
const chunks:
|
|
324
|
+
const chunks: AIMessageChunk[] = [];
|
|
286
325
|
for await (const chunk of stream) {
|
|
287
326
|
chunks.push(chunk);
|
|
288
327
|
}
|
|
@@ -294,7 +333,7 @@ test('Test ChatAnthropic stream method with abort', async () => {
|
|
|
294
333
|
const model = new ChatAnthropic({
|
|
295
334
|
maxTokens: 500,
|
|
296
335
|
maxRetries: 0,
|
|
297
|
-
modelName
|
|
336
|
+
modelName,
|
|
298
337
|
});
|
|
299
338
|
const stream = await model.stream(
|
|
300
339
|
'How is your day going? Be extremely verbose.',
|
|
@@ -302,7 +341,6 @@ test('Test ChatAnthropic stream method with abort', async () => {
|
|
|
302
341
|
signal: AbortSignal.timeout(1000),
|
|
303
342
|
}
|
|
304
343
|
);
|
|
305
|
-
// @eslint-disable-next-line/@typescript-eslint/ban-ts-comment
|
|
306
344
|
for await (const chunk of stream) {
|
|
307
345
|
// console.log(chunk);
|
|
308
346
|
}
|
|
@@ -313,13 +351,12 @@ test('Test ChatAnthropic stream method with early break', async () => {
|
|
|
313
351
|
const model = new ChatAnthropic({
|
|
314
352
|
maxTokens: 50,
|
|
315
353
|
maxRetries: 0,
|
|
316
|
-
modelName
|
|
354
|
+
modelName,
|
|
317
355
|
});
|
|
318
356
|
const stream = await model.stream(
|
|
319
357
|
'How is your day going? Be extremely verbose.'
|
|
320
358
|
);
|
|
321
359
|
let i = 0;
|
|
322
|
-
// @eslint-disable-next-line/@typescript-eslint/ban-ts-comment
|
|
323
360
|
for await (const chunk of stream) {
|
|
324
361
|
// console.log(chunk);
|
|
325
362
|
i += 1;
|
|
@@ -331,7 +368,7 @@ test('Test ChatAnthropic stream method with early break', async () => {
|
|
|
331
368
|
|
|
332
369
|
test('Test ChatAnthropic headers passed through', async () => {
|
|
333
370
|
const chat = new ChatAnthropic({
|
|
334
|
-
modelName
|
|
371
|
+
modelName,
|
|
335
372
|
maxRetries: 0,
|
|
336
373
|
apiKey: 'NOT_REAL',
|
|
337
374
|
clientOptions: {
|
|
@@ -341,36 +378,142 @@ test('Test ChatAnthropic headers passed through', async () => {
|
|
|
341
378
|
},
|
|
342
379
|
});
|
|
343
380
|
const message = new HumanMessage('Hello!');
|
|
344
|
-
// @eslint-disable-next-line/@typescript-eslint/ban-ts-comment
|
|
345
381
|
const res = await chat.invoke([message]);
|
|
346
382
|
// console.log({ res });
|
|
347
383
|
});
|
|
348
384
|
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
385
|
+
describe('ChatAnthropic image inputs', () => {
|
|
386
|
+
test.each(['invoke', 'stream'])(
|
|
387
|
+
'Test ChatAnthropic image_url, %s',
|
|
388
|
+
async (invocationType: string) => {
|
|
389
|
+
const chat = new ChatAnthropic({
|
|
390
|
+
modelName,
|
|
391
|
+
maxRetries: 0,
|
|
392
|
+
});
|
|
393
|
+
|
|
394
|
+
const dataUrlRes = invoke(chat, invocationType, [
|
|
395
|
+
new HumanMessage({
|
|
396
|
+
content: [
|
|
397
|
+
{
|
|
398
|
+
type: 'image_url',
|
|
399
|
+
image_url: {
|
|
400
|
+
url: 'data:image/jpeg;base64,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',
|
|
401
|
+
},
|
|
402
|
+
},
|
|
403
|
+
{ type: 'text', text: 'Describe this image.' },
|
|
404
|
+
],
|
|
405
|
+
}),
|
|
406
|
+
]);
|
|
407
|
+
|
|
408
|
+
await expect(dataUrlRes).resolves.toBeDefined();
|
|
409
|
+
|
|
410
|
+
const urlRes = invoke(chat, invocationType, [
|
|
411
|
+
new HumanMessage({
|
|
412
|
+
content: [
|
|
413
|
+
{
|
|
414
|
+
type: 'image_url',
|
|
415
|
+
image_url:
|
|
416
|
+
'https://upload.wikimedia.org/wikipedia/commons/thumb/3/30/RedDisc.svg/24px-RedDisc.svg.png',
|
|
417
|
+
},
|
|
418
|
+
{ type: 'text', text: 'Describe this image.' },
|
|
419
|
+
],
|
|
420
|
+
}),
|
|
421
|
+
]);
|
|
422
|
+
|
|
423
|
+
await expect(urlRes).resolves.toBeDefined();
|
|
424
|
+
|
|
425
|
+
const invalidSchemeRes = invoke(chat, invocationType, [
|
|
426
|
+
new HumanMessage({
|
|
427
|
+
content: [
|
|
428
|
+
{
|
|
429
|
+
type: 'image_url',
|
|
430
|
+
image_url: 'file:///path/to/image.png',
|
|
431
|
+
},
|
|
432
|
+
{ type: 'text', text: 'Describe this image.' },
|
|
433
|
+
],
|
|
434
|
+
}),
|
|
435
|
+
]);
|
|
436
|
+
|
|
437
|
+
await expect(invalidSchemeRes).rejects.toThrow(
|
|
438
|
+
[
|
|
439
|
+
'Invalid image URL protocol: "file:". Anthropic only supports images as http, https, or base64-encoded data URLs on \'image_url\' content blocks.',
|
|
440
|
+
'Example: data:image/png;base64,/9j/4AAQSk...',
|
|
441
|
+
'Example: https://example.com/image.jpg',
|
|
442
|
+
].join('\n\n')
|
|
443
|
+
);
|
|
444
|
+
|
|
445
|
+
const invalidUrlRes = invoke(chat, invocationType, [
|
|
446
|
+
new HumanMessage({
|
|
447
|
+
content: [
|
|
448
|
+
{
|
|
449
|
+
type: 'image_url',
|
|
450
|
+
image_url: "this isn't a valid URL",
|
|
451
|
+
},
|
|
452
|
+
{ type: 'text', text: 'Describe this image.' },
|
|
453
|
+
],
|
|
454
|
+
}),
|
|
455
|
+
]);
|
|
456
|
+
|
|
457
|
+
await expect(invalidUrlRes).rejects.toThrow(
|
|
458
|
+
[
|
|
459
|
+
`Malformed image URL: "this isn't a valid URL". Content blocks of type 'image_url' must be a valid http, https, or base64-encoded data URL.`,
|
|
460
|
+
'Example: data:image/png;base64,/9j/4AAQSk...',
|
|
461
|
+
'Example: https://example.com/image.jpg',
|
|
462
|
+
].join('\n\n')
|
|
463
|
+
);
|
|
464
|
+
}
|
|
465
|
+
);
|
|
466
|
+
|
|
467
|
+
test.each(['invoke', 'stream'])(
|
|
468
|
+
'Test ChatAnthropic Anthropic Image Block, %s',
|
|
469
|
+
async (invocationType: string) => {
|
|
470
|
+
const chat = new ChatAnthropic({
|
|
471
|
+
modelName,
|
|
472
|
+
maxRetries: 0,
|
|
473
|
+
});
|
|
474
|
+
const base64Res = invoke(chat, invocationType, [
|
|
475
|
+
new HumanMessage({
|
|
476
|
+
content: [
|
|
477
|
+
{
|
|
478
|
+
type: 'image',
|
|
479
|
+
source: {
|
|
480
|
+
type: 'base64',
|
|
481
|
+
media_type: 'image/jpeg',
|
|
482
|
+
data: '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',
|
|
483
|
+
},
|
|
484
|
+
},
|
|
485
|
+
{
|
|
486
|
+
type: 'text',
|
|
487
|
+
text: 'Describe this image',
|
|
488
|
+
},
|
|
489
|
+
],
|
|
490
|
+
}),
|
|
491
|
+
]);
|
|
492
|
+
|
|
493
|
+
await expect(base64Res).resolves.toBeDefined();
|
|
494
|
+
|
|
495
|
+
const urlRes = chat.invoke([
|
|
496
|
+
new HumanMessage({
|
|
497
|
+
content: [
|
|
498
|
+
{
|
|
499
|
+
type: 'image',
|
|
500
|
+
source: {
|
|
501
|
+
type: 'url',
|
|
502
|
+
url: 'https://upload.wikimedia.org/wikipedia/commons/thumb/3/30/RedDisc.svg/24px-RedDisc.svg.png',
|
|
503
|
+
},
|
|
504
|
+
},
|
|
505
|
+
],
|
|
506
|
+
}),
|
|
507
|
+
]);
|
|
508
|
+
|
|
509
|
+
await expect(urlRes).resolves.toBeDefined();
|
|
510
|
+
}
|
|
511
|
+
);
|
|
369
512
|
});
|
|
370
513
|
|
|
371
514
|
test('Stream tokens', async () => {
|
|
372
515
|
const model = new ChatAnthropic({
|
|
373
|
-
|
|
516
|
+
modelName,
|
|
374
517
|
temperature: 0,
|
|
375
518
|
maxTokens: 10,
|
|
376
519
|
});
|
|
@@ -397,14 +540,14 @@ test('Stream tokens', async () => {
|
|
|
397
540
|
});
|
|
398
541
|
|
|
399
542
|
test('id is supplied when invoking', async () => {
|
|
400
|
-
const model = new ChatAnthropic();
|
|
543
|
+
const model = new ChatAnthropic({ modelName });
|
|
401
544
|
const result = await model.invoke('Hello');
|
|
402
545
|
expect(result.id).toBeDefined();
|
|
403
546
|
expect(result.id).not.toEqual('');
|
|
404
547
|
});
|
|
405
548
|
|
|
406
549
|
test('id is supplied when streaming', async () => {
|
|
407
|
-
const model = new ChatAnthropic();
|
|
550
|
+
const model = new ChatAnthropic({ modelName });
|
|
408
551
|
let finalChunk: AIMessageChunk | undefined;
|
|
409
552
|
for await (const chunk of await model.stream('Hello')) {
|
|
410
553
|
finalChunk = !finalChunk ? chunk : concat(finalChunk, chunk);
|
|
@@ -678,7 +821,7 @@ The current date is ${new Date().toISOString()}`;
|
|
|
678
821
|
|
|
679
822
|
test('system prompt caching', async () => {
|
|
680
823
|
const model = new ChatAnthropic({
|
|
681
|
-
|
|
824
|
+
modelName,
|
|
682
825
|
clientOptions: {
|
|
683
826
|
defaultHeaders: {
|
|
684
827
|
'anthropic-beta': 'prompt-caching-2024-07-31',
|
|
@@ -724,7 +867,7 @@ test('system prompt caching', async () => {
|
|
|
724
867
|
// TODO: Add proper test with long tool content
|
|
725
868
|
test.skip('tool caching', async () => {
|
|
726
869
|
const model = new ChatAnthropic({
|
|
727
|
-
|
|
870
|
+
modelName,
|
|
728
871
|
clientOptions: {
|
|
729
872
|
defaultHeaders: {
|
|
730
873
|
'anthropic-beta': 'prompt-caching-2024-07-31',
|
|
@@ -769,14 +912,22 @@ test.skip('tool caching', async () => {
|
|
|
769
912
|
);
|
|
770
913
|
});
|
|
771
914
|
|
|
915
|
+
test.skip('Test ChatAnthropic with custom client', async () => {
|
|
916
|
+
const client = new AnthropicVertex();
|
|
917
|
+
const chat = new ChatAnthropic({
|
|
918
|
+
modelName,
|
|
919
|
+
maxRetries: 0,
|
|
920
|
+
createClient: () => client,
|
|
921
|
+
});
|
|
922
|
+
const message = new HumanMessage('Hello!');
|
|
923
|
+
const res = await chat.invoke([message]);
|
|
924
|
+
// console.log({ res });
|
|
925
|
+
expect(res.usage_metadata?.input_token_details).toBeDefined();
|
|
926
|
+
});
|
|
927
|
+
|
|
772
928
|
test('human message caching', async () => {
|
|
773
929
|
const model = new ChatAnthropic({
|
|
774
|
-
|
|
775
|
-
clientOptions: {
|
|
776
|
-
defaultHeaders: {
|
|
777
|
-
'anthropic-beta': 'prompt-caching-2024-07-31',
|
|
778
|
-
},
|
|
779
|
-
},
|
|
930
|
+
modelName,
|
|
780
931
|
});
|
|
781
932
|
|
|
782
933
|
const messages = [
|
|
@@ -784,7 +935,7 @@ test('human message caching', async () => {
|
|
|
784
935
|
content: [
|
|
785
936
|
{
|
|
786
937
|
type: 'text',
|
|
787
|
-
text: `You are a
|
|
938
|
+
text: `You are a scotsman. Always respond in scotsman dialect.\nUse the following as context when answering questions: ${CACHED_TEXT}`,
|
|
788
939
|
},
|
|
789
940
|
],
|
|
790
941
|
}),
|
|
@@ -813,11 +964,10 @@ test('human message caching', async () => {
|
|
|
813
964
|
|
|
814
965
|
test('Can accept PDF documents', async () => {
|
|
815
966
|
const model = new ChatAnthropic({
|
|
816
|
-
|
|
967
|
+
modelName: pdfModelName,
|
|
817
968
|
});
|
|
818
969
|
|
|
819
|
-
const pdfPath =
|
|
820
|
-
'../langchain-community/src/document_loaders/tests/example_data/Jacob_Lee_Resume_2023.pdf';
|
|
970
|
+
const pdfPath = './src/llm/anthropic/Jacob_Lee_Resume_2023.pdf';
|
|
821
971
|
const pdfBase64 = await fs.readFile(pdfPath, 'base64');
|
|
822
972
|
|
|
823
973
|
const response = await model.invoke([
|
|
@@ -844,70 +994,253 @@ test('Can accept PDF documents', async () => {
|
|
|
844
994
|
expect(response.content.length).toBeGreaterThan(10);
|
|
845
995
|
});
|
|
846
996
|
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
997
|
+
describe('Citations', () => {
|
|
998
|
+
test('document blocks', async () => {
|
|
999
|
+
const citationsModel = new ChatAnthropic({
|
|
1000
|
+
model: citationsModelName,
|
|
1001
|
+
});
|
|
1002
|
+
const messages = [
|
|
1003
|
+
{
|
|
1004
|
+
role: 'user',
|
|
1005
|
+
content: [
|
|
1006
|
+
{
|
|
1007
|
+
type: 'document',
|
|
1008
|
+
source: {
|
|
1009
|
+
type: 'text',
|
|
1010
|
+
media_type: 'text/plain',
|
|
1011
|
+
data: "The grass the user is asking about is bluegrass. The sky is orange because it's night.",
|
|
1012
|
+
},
|
|
1013
|
+
title: 'My Document',
|
|
1014
|
+
context: 'This is a trustworthy document.',
|
|
1015
|
+
citations: {
|
|
1016
|
+
enabled: true,
|
|
1017
|
+
},
|
|
1018
|
+
},
|
|
1019
|
+
{
|
|
1020
|
+
type: 'text',
|
|
1021
|
+
text: 'What color is the grass and sky?',
|
|
1022
|
+
},
|
|
1023
|
+
],
|
|
1024
|
+
},
|
|
1025
|
+
];
|
|
1026
|
+
|
|
1027
|
+
const response = await citationsModel.invoke(messages);
|
|
1028
|
+
|
|
1029
|
+
expect(response.content.length).toBeGreaterThan(2);
|
|
1030
|
+
expect(Array.isArray(response.content)).toBe(true);
|
|
1031
|
+
const blocksWithCitations = (response.content as any[]).filter(
|
|
1032
|
+
(block) => block.citations !== undefined
|
|
1033
|
+
);
|
|
1034
|
+
expect(blocksWithCitations.length).toEqual(2);
|
|
1035
|
+
expect(typeof blocksWithCitations[0].citations[0]).toEqual('object');
|
|
1036
|
+
|
|
1037
|
+
const stream = await citationsModel.stream(messages);
|
|
1038
|
+
let aggregated;
|
|
1039
|
+
let chunkHasCitation = false;
|
|
1040
|
+
for await (const chunk of stream) {
|
|
1041
|
+
aggregated = aggregated === undefined ? chunk : concat(aggregated, chunk);
|
|
1042
|
+
if (
|
|
1043
|
+
!chunkHasCitation &&
|
|
1044
|
+
Array.isArray(chunk.content) &&
|
|
1045
|
+
chunk.content.some((c: any) => c.citations !== undefined)
|
|
1046
|
+
) {
|
|
1047
|
+
chunkHasCitation = true;
|
|
1048
|
+
}
|
|
1049
|
+
}
|
|
1050
|
+
expect(chunkHasCitation).toBe(true);
|
|
1051
|
+
expect(Array.isArray(aggregated?.content)).toBe(true);
|
|
1052
|
+
expect(aggregated?.content.length).toBeGreaterThan(2);
|
|
1053
|
+
expect(
|
|
1054
|
+
(aggregated?.content as any[]).some((c) => c.citations !== undefined)
|
|
1055
|
+
).toBe(true);
|
|
850
1056
|
});
|
|
1057
|
+
describe('search result blocks', () => {
|
|
1058
|
+
const citationsModel = new ChatAnthropic({
|
|
1059
|
+
model: citationsModelName,
|
|
1060
|
+
clientOptions: {
|
|
1061
|
+
defaultHeaders: {
|
|
1062
|
+
'anthropic-beta': 'search-results-2025-06-09',
|
|
1063
|
+
},
|
|
1064
|
+
},
|
|
1065
|
+
});
|
|
851
1066
|
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
1067
|
+
const messages = [
|
|
1068
|
+
{
|
|
1069
|
+
role: 'user',
|
|
1070
|
+
content: [
|
|
1071
|
+
{
|
|
1072
|
+
type: 'search_result',
|
|
1073
|
+
title: 'History of France',
|
|
1074
|
+
source: 'https://example.com/france-history',
|
|
1075
|
+
citations: { enabled: true },
|
|
1076
|
+
content: [
|
|
1077
|
+
{
|
|
1078
|
+
type: 'text',
|
|
1079
|
+
text: 'The capital of France is Paris.',
|
|
1080
|
+
},
|
|
1081
|
+
{
|
|
1082
|
+
type: 'text',
|
|
1083
|
+
text: 'The old capital of France was Lyon.',
|
|
1084
|
+
},
|
|
1085
|
+
],
|
|
1086
|
+
},
|
|
1087
|
+
{
|
|
1088
|
+
type: 'search_result',
|
|
1089
|
+
title: 'Geography of France',
|
|
1090
|
+
source: 'https://example.com/france-geography',
|
|
1091
|
+
citations: { enabled: true },
|
|
1092
|
+
content: [
|
|
1093
|
+
{
|
|
1094
|
+
type: 'text',
|
|
1095
|
+
text: 'France is a country in Europe.',
|
|
1096
|
+
},
|
|
1097
|
+
{
|
|
1098
|
+
type: 'text',
|
|
1099
|
+
text: 'France borders Spain to the south.',
|
|
1100
|
+
},
|
|
1101
|
+
],
|
|
862
1102
|
},
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
enabled: true,
|
|
1103
|
+
{
|
|
1104
|
+
type: 'text',
|
|
1105
|
+
text: 'What is the capital of France and where is it located? You must cite your sources.',
|
|
867
1106
|
},
|
|
1107
|
+
],
|
|
1108
|
+
},
|
|
1109
|
+
];
|
|
1110
|
+
|
|
1111
|
+
test('without streaming', async () => {
|
|
1112
|
+
const response = await citationsModel.invoke(messages);
|
|
1113
|
+
|
|
1114
|
+
expect(Array.isArray(response.content)).toBe(true);
|
|
1115
|
+
expect(response.content.length).toBeGreaterThan(0);
|
|
1116
|
+
|
|
1117
|
+
// Check that we have cited content
|
|
1118
|
+
const blocksWithCitations = (response.content as any[]).filter(
|
|
1119
|
+
(block) => block.citations !== undefined
|
|
1120
|
+
);
|
|
1121
|
+
expect(blocksWithCitations.length).toBeGreaterThan(0);
|
|
1122
|
+
|
|
1123
|
+
// Verify citation structure
|
|
1124
|
+
const citation = blocksWithCitations[0].citations[0];
|
|
1125
|
+
expect(typeof citation).toBe('object');
|
|
1126
|
+
expect(citation.type).toBe('search_result_location');
|
|
1127
|
+
expect(citation.source).toBeDefined();
|
|
1128
|
+
});
|
|
1129
|
+
test('with streaming', async () => {
|
|
1130
|
+
// Test streaming
|
|
1131
|
+
const stream = await citationsModel.stream(messages);
|
|
1132
|
+
let aggregated;
|
|
1133
|
+
let chunkHasCitation = false;
|
|
1134
|
+
for await (const chunk of stream) {
|
|
1135
|
+
aggregated =
|
|
1136
|
+
aggregated === undefined ? chunk : concat(aggregated, chunk);
|
|
1137
|
+
if (
|
|
1138
|
+
!chunkHasCitation &&
|
|
1139
|
+
Array.isArray(chunk.content) &&
|
|
1140
|
+
chunk.content.some((c: any) => c.citations !== undefined)
|
|
1141
|
+
) {
|
|
1142
|
+
chunkHasCitation = true;
|
|
1143
|
+
}
|
|
1144
|
+
}
|
|
1145
|
+
expect(chunkHasCitation).toBe(true);
|
|
1146
|
+
expect(Array.isArray(aggregated?.content)).toBe(true);
|
|
1147
|
+
expect(
|
|
1148
|
+
(aggregated?.content as any[]).some((c) => c.citations !== undefined)
|
|
1149
|
+
).toBe(true);
|
|
1150
|
+
});
|
|
1151
|
+
});
|
|
1152
|
+
|
|
1153
|
+
test('search result blocks from tool', async () => {
|
|
1154
|
+
const ragTool = tool(
|
|
1155
|
+
(): ChatAnthropicContentBlock[] => [
|
|
1156
|
+
{
|
|
1157
|
+
type: 'search_result',
|
|
1158
|
+
title: 'History of France',
|
|
1159
|
+
source: 'https://example.com/france-history',
|
|
1160
|
+
citations: { enabled: true },
|
|
1161
|
+
content: [
|
|
1162
|
+
{
|
|
1163
|
+
type: 'text',
|
|
1164
|
+
text: 'The capital of France is Paris.',
|
|
1165
|
+
},
|
|
1166
|
+
{
|
|
1167
|
+
type: 'text',
|
|
1168
|
+
text: 'France was established as a republic in 1792.',
|
|
1169
|
+
},
|
|
1170
|
+
],
|
|
868
1171
|
},
|
|
869
1172
|
{
|
|
870
|
-
type: '
|
|
871
|
-
|
|
1173
|
+
type: 'search_result',
|
|
1174
|
+
title: 'Geography of France',
|
|
1175
|
+
source: 'https://example.com/france-geography',
|
|
1176
|
+
citations: { enabled: true },
|
|
1177
|
+
content: [
|
|
1178
|
+
{
|
|
1179
|
+
type: 'text',
|
|
1180
|
+
text: 'France is located in Western Europe.',
|
|
1181
|
+
},
|
|
1182
|
+
{
|
|
1183
|
+
type: 'text',
|
|
1184
|
+
text: 'France has a population of approximately 67 million people.',
|
|
1185
|
+
},
|
|
1186
|
+
],
|
|
872
1187
|
},
|
|
873
1188
|
],
|
|
874
|
-
|
|
875
|
-
|
|
1189
|
+
{
|
|
1190
|
+
name: 'search_knowledge_base',
|
|
1191
|
+
description: 'Search the knowledge base for information about France',
|
|
1192
|
+
schema: z.object({
|
|
1193
|
+
query: z.string().describe('The search query'),
|
|
1194
|
+
}),
|
|
1195
|
+
}
|
|
1196
|
+
);
|
|
876
1197
|
|
|
877
|
-
|
|
1198
|
+
const citationsModel = new ChatAnthropic({
|
|
1199
|
+
model: citationsModelName,
|
|
1200
|
+
clientOptions: {
|
|
1201
|
+
defaultHeaders: {
|
|
1202
|
+
'anthropic-beta': 'search-results-2025-06-09',
|
|
1203
|
+
},
|
|
1204
|
+
},
|
|
1205
|
+
}).bindTools([ragTool]);
|
|
878
1206
|
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
expect(blocksWithCitations.length).toEqual(2);
|
|
885
|
-
expect(typeof blocksWithCitations[0].citations[0]).toEqual('object');
|
|
1207
|
+
const messages = [
|
|
1208
|
+
new HumanMessage(
|
|
1209
|
+
'Search for information about France and tell me what you find with proper citations.'
|
|
1210
|
+
),
|
|
1211
|
+
];
|
|
886
1212
|
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
1213
|
+
const response = await citationsModel.invoke(messages);
|
|
1214
|
+
messages.push(response);
|
|
1215
|
+
|
|
1216
|
+
expect(Array.isArray(response.content)).toBe(true);
|
|
1217
|
+
expect(response.content.length).toBeGreaterThan(0);
|
|
1218
|
+
|
|
1219
|
+
// Check that the model called the tool
|
|
1220
|
+
expect(response.tool_calls?.length).toBeGreaterThan(0);
|
|
1221
|
+
expect(response.tool_calls?.[0].name).toBe('search_knowledge_base');
|
|
1222
|
+
|
|
1223
|
+
const toolResponse = await ragTool.invoke(response.tool_calls![0]);
|
|
1224
|
+
messages.push(toolResponse);
|
|
1225
|
+
|
|
1226
|
+
const response2 = await citationsModel.invoke(messages);
|
|
1227
|
+
|
|
1228
|
+
expect(Array.isArray(response2.content)).toBe(true);
|
|
1229
|
+
expect(response2.content.length).toBeGreaterThan(0);
|
|
1230
|
+
// Make sure that a citation exists somewhere in the content list
|
|
1231
|
+
const citationBlock = (response2.content as any[]).find(
|
|
1232
|
+
(block: any) =>
|
|
1233
|
+
Array.isArray(block.citations) && block.citations.length > 0
|
|
1234
|
+
);
|
|
1235
|
+
expect(citationBlock).toBeDefined();
|
|
1236
|
+
expect(citationBlock.citations[0].type).toBe('search_result_location');
|
|
1237
|
+
expect(citationBlock.citations[0].source).toBeDefined();
|
|
1238
|
+
});
|
|
906
1239
|
});
|
|
907
1240
|
|
|
908
1241
|
test('Test thinking blocks multiturn invoke', async () => {
|
|
909
1242
|
const model = new ChatAnthropic({
|
|
910
|
-
model:
|
|
1243
|
+
model: extendedThinkingModelName,
|
|
911
1244
|
maxTokens: 5000,
|
|
912
1245
|
thinking: { type: 'enabled', budget_tokens: 2000 },
|
|
913
1246
|
});
|
|
@@ -945,7 +1278,7 @@ test('Test thinking blocks multiturn invoke', async () => {
|
|
|
945
1278
|
|
|
946
1279
|
test('Test thinking blocks multiturn streaming', async () => {
|
|
947
1280
|
const model = new ChatAnthropic({
|
|
948
|
-
model:
|
|
1281
|
+
model: extendedThinkingModelName,
|
|
949
1282
|
maxTokens: 5000,
|
|
950
1283
|
thinking: { type: 'enabled', budget_tokens: 2000 },
|
|
951
1284
|
});
|
|
@@ -986,7 +1319,7 @@ test('Test thinking blocks multiturn streaming', async () => {
|
|
|
986
1319
|
|
|
987
1320
|
test('Test redacted thinking blocks multiturn invoke', async () => {
|
|
988
1321
|
const model = new ChatAnthropic({
|
|
989
|
-
model:
|
|
1322
|
+
model: extendedThinkingModelName,
|
|
990
1323
|
maxTokens: 5000,
|
|
991
1324
|
thinking: { type: 'enabled', budget_tokens: 2000 },
|
|
992
1325
|
});
|
|
@@ -1023,7 +1356,7 @@ test('Test redacted thinking blocks multiturn invoke', async () => {
|
|
|
1023
1356
|
|
|
1024
1357
|
test('Test redacted thinking blocks multiturn streaming', async () => {
|
|
1025
1358
|
const model = new ChatAnthropic({
|
|
1026
|
-
model:
|
|
1359
|
+
model: extendedThinkingModelName,
|
|
1027
1360
|
maxTokens: 5000,
|
|
1028
1361
|
thinking: { type: 'enabled', budget_tokens: 2000 },
|
|
1029
1362
|
});
|
|
@@ -1064,3 +1397,46 @@ test('Test redacted thinking blocks multiturn streaming', async () => {
|
|
|
1064
1397
|
// test a second time to make sure that we've got input translation working correctly
|
|
1065
1398
|
await doStreaming(streamingMessages);
|
|
1066
1399
|
});
|
|
1400
|
+
|
|
1401
|
+
test('Can handle google function calling blocks in content', async () => {
|
|
1402
|
+
const chat = new ChatAnthropic({
|
|
1403
|
+
modelName: 'claude-3-7-sonnet-latest',
|
|
1404
|
+
maxRetries: 0,
|
|
1405
|
+
});
|
|
1406
|
+
const toolCallId = 'tool_call_id';
|
|
1407
|
+
const messages = [
|
|
1408
|
+
new SystemMessage("You're a helpful assistant"),
|
|
1409
|
+
new HumanMessage('What is the weather like in San Francisco?'),
|
|
1410
|
+
new AIMessage({
|
|
1411
|
+
content: [
|
|
1412
|
+
{
|
|
1413
|
+
// Pass a content block with the `functionCall` object that Google returns.
|
|
1414
|
+
functionCall: {
|
|
1415
|
+
args: {
|
|
1416
|
+
location: 'san francisco',
|
|
1417
|
+
},
|
|
1418
|
+
name: 'get_weather',
|
|
1419
|
+
},
|
|
1420
|
+
},
|
|
1421
|
+
],
|
|
1422
|
+
tool_calls: [
|
|
1423
|
+
{
|
|
1424
|
+
id: toolCallId,
|
|
1425
|
+
name: 'get_weather',
|
|
1426
|
+
args: {
|
|
1427
|
+
location: 'san francisco',
|
|
1428
|
+
},
|
|
1429
|
+
},
|
|
1430
|
+
],
|
|
1431
|
+
}),
|
|
1432
|
+
new ToolMessage({
|
|
1433
|
+
tool_call_id: toolCallId,
|
|
1434
|
+
content: 'The weather is sunny',
|
|
1435
|
+
}),
|
|
1436
|
+
new HumanMessage(
|
|
1437
|
+
'Give me a one sentence description of what the sky looks like.'
|
|
1438
|
+
),
|
|
1439
|
+
];
|
|
1440
|
+
const res = await chat.invoke(messages);
|
|
1441
|
+
expect(res.content.length).toBeGreaterThan(1);
|
|
1442
|
+
});
|