@librechat/agents 2.4.322 → 3.0.0-rc10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/agents/AgentContext.cjs +218 -0
- package/dist/cjs/agents/AgentContext.cjs.map +1 -0
- package/dist/cjs/common/enum.cjs +15 -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 -213
- package/dist/cjs/graphs/Graph.cjs.map +1 -1
- package/dist/cjs/graphs/MultiAgentGraph.cjs +507 -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 +422 -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 +137 -85
- package/dist/cjs/run.cjs.map +1 -1
- package/dist/cjs/stream.cjs +86 -52
- 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 +16 -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 -215
- package/dist/esm/graphs/Graph.mjs.map +1 -1
- package/dist/esm/graphs/MultiAgentGraph.mjs +505 -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 +421 -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 +138 -87
- package/dist/esm/run.mjs.map +1 -1
- package/dist/esm/stream.mjs +88 -55
- 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 +17 -7
- package/dist/types/events.d.ts +5 -4
- package/dist/types/graphs/Graph.d.ts +64 -67
- package/dist/types/graphs/MultiAgentGraph.d.ts +47 -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 +82 -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/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 +25 -10
- package/dist/types/types/run.d.ts +50 -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 +41 -17
- package/src/agents/AgentContext.ts +315 -0
- package/src/common/enum.ts +15 -5
- package/src/events.ts +24 -13
- package/src/graphs/Graph.ts +495 -313
- package/src/graphs/MultiAgentGraph.ts +598 -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 +641 -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 +196 -116
- 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-chain.ts +278 -0
- package/src/scripts/multi-agent-conditional.ts +220 -0
- package/src/scripts/multi-agent-document-review-chain.ts +197 -0
- package/src/scripts/multi-agent-hybrid-flow.ts +310 -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 +362 -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 +170 -0
- package/src/scripts/test-multi-agent-list-handoff.ts +261 -0
- package/src/scripts/test-tools-before-handoff.ts +233 -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 +143 -61
- 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 +318 -103
- package/src/types/llm.ts +26 -12
- package/src/types/run.ts +56 -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/dist/types/scripts/abort.d.ts +0 -1
- package/dist/types/scripts/args.d.ts +0 -6
- package/dist/types/scripts/caching.d.ts +0 -1
- package/dist/types/scripts/cli.d.ts +0 -1
- package/dist/types/scripts/cli2.d.ts +0 -1
- package/dist/types/scripts/cli3.d.ts +0 -1
- package/dist/types/scripts/cli4.d.ts +0 -1
- package/dist/types/scripts/cli5.d.ts +0 -1
- package/dist/types/scripts/code_exec.d.ts +0 -1
- package/dist/types/scripts/code_exec_files.d.ts +0 -1
- package/dist/types/scripts/code_exec_simple.d.ts +0 -1
- package/dist/types/scripts/content.d.ts +0 -1
- package/dist/types/scripts/empty_input.d.ts +0 -1
- package/dist/types/scripts/image.d.ts +0 -1
- package/dist/types/scripts/memory.d.ts +0 -1
- package/dist/types/scripts/search.d.ts +0 -1
- package/dist/types/scripts/simple.d.ts +0 -1
- package/dist/types/scripts/stream.d.ts +0 -1
- package/dist/types/scripts/thinking.d.ts +0 -1
- package/dist/types/scripts/tools.d.ts +0 -1
- package/dist/types/specs/spec.utils.d.ts +0 -1
|
@@ -4,12 +4,19 @@
|
|
|
4
4
|
import { config } from 'dotenv';
|
|
5
5
|
config();
|
|
6
6
|
import { Calculator } from '@langchain/community/tools/calculator';
|
|
7
|
-
import {
|
|
8
|
-
|
|
7
|
+
import {
|
|
8
|
+
HumanMessage,
|
|
9
|
+
BaseMessage,
|
|
10
|
+
UsageMetadata,
|
|
11
|
+
} from '@langchain/core/messages';
|
|
9
12
|
import type * as t from '@/types';
|
|
10
|
-
import {
|
|
13
|
+
import {
|
|
14
|
+
ToolEndHandler,
|
|
15
|
+
ModelEndHandler,
|
|
16
|
+
createMetadataAggregator,
|
|
17
|
+
} from '@/events';
|
|
18
|
+
import { ContentTypes, GraphEvents, Providers, TitleMethod } from '@/common';
|
|
11
19
|
import { ChatModelStreamHandler, createContentAggregator } from '@/stream';
|
|
12
|
-
import { ContentTypes, GraphEvents, Providers } from '@/common';
|
|
13
20
|
import { capitalizeFirstLetter } from './spec.utils';
|
|
14
21
|
import { getLLMConfig } from '@/utils/llmConfig';
|
|
15
22
|
import { getArgs } from '@/scripts/args';
|
|
@@ -17,7 +24,7 @@ import { Run } from '@/run';
|
|
|
17
24
|
|
|
18
25
|
const provider = Providers.ANTHROPIC;
|
|
19
26
|
describe(`${capitalizeFirstLetter(provider)} Streaming Tests`, () => {
|
|
20
|
-
jest.setTimeout(
|
|
27
|
+
jest.setTimeout(60000);
|
|
21
28
|
let run: Run<t.IState>;
|
|
22
29
|
let runningHistory: BaseMessage[];
|
|
23
30
|
let collectedUsage: UsageMetadata[];
|
|
@@ -36,7 +43,8 @@ describe(`${capitalizeFirstLetter(provider)} Streaming Tests`, () => {
|
|
|
36
43
|
beforeEach(async () => {
|
|
37
44
|
conversationHistory = [];
|
|
38
45
|
collectedUsage = [];
|
|
39
|
-
const { contentParts: cp, aggregateContent: ac } =
|
|
46
|
+
const { contentParts: cp, aggregateContent: ac } =
|
|
47
|
+
createContentAggregator();
|
|
40
48
|
contentParts = cp as t.MessageContentComplex[];
|
|
41
49
|
aggregateContent = ac;
|
|
42
50
|
});
|
|
@@ -49,36 +57,62 @@ describe(`${capitalizeFirstLetter(provider)} Streaming Tests`, () => {
|
|
|
49
57
|
onRunStepSpy.mockReset();
|
|
50
58
|
});
|
|
51
59
|
|
|
52
|
-
const setupCustomHandlers = (): Record<
|
|
60
|
+
const setupCustomHandlers = (): Record<
|
|
61
|
+
string | GraphEvents,
|
|
62
|
+
t.EventHandler
|
|
63
|
+
> => ({
|
|
53
64
|
[GraphEvents.TOOL_END]: new ToolEndHandler(),
|
|
54
65
|
[GraphEvents.CHAT_MODEL_END]: new ModelEndHandler(collectedUsage),
|
|
55
66
|
[GraphEvents.CHAT_MODEL_STREAM]: new ChatModelStreamHandler(),
|
|
56
67
|
[GraphEvents.ON_RUN_STEP_COMPLETED]: {
|
|
57
|
-
handle: (
|
|
58
|
-
|
|
59
|
-
|
|
68
|
+
handle: (
|
|
69
|
+
event: GraphEvents.ON_RUN_STEP_COMPLETED,
|
|
70
|
+
data: t.StreamEventData
|
|
71
|
+
): void => {
|
|
72
|
+
aggregateContent({
|
|
73
|
+
event,
|
|
74
|
+
data: data as unknown as { result: t.ToolEndEvent },
|
|
75
|
+
});
|
|
76
|
+
},
|
|
60
77
|
},
|
|
61
78
|
[GraphEvents.ON_RUN_STEP]: {
|
|
62
|
-
handle: (
|
|
79
|
+
handle: (
|
|
80
|
+
event: GraphEvents.ON_RUN_STEP,
|
|
81
|
+
data: t.StreamEventData,
|
|
82
|
+
metadata,
|
|
83
|
+
graph
|
|
84
|
+
): void => {
|
|
63
85
|
onRunStepSpy(event, data, metadata, graph);
|
|
64
86
|
aggregateContent({ event, data: data as t.RunStep });
|
|
65
|
-
}
|
|
87
|
+
},
|
|
66
88
|
},
|
|
67
89
|
[GraphEvents.ON_RUN_STEP_DELTA]: {
|
|
68
|
-
handle: (
|
|
90
|
+
handle: (
|
|
91
|
+
event: GraphEvents.ON_RUN_STEP_DELTA,
|
|
92
|
+
data: t.StreamEventData
|
|
93
|
+
): void => {
|
|
69
94
|
aggregateContent({ event, data: data as t.RunStepDeltaEvent });
|
|
70
|
-
}
|
|
95
|
+
},
|
|
71
96
|
},
|
|
72
97
|
[GraphEvents.ON_MESSAGE_DELTA]: {
|
|
73
|
-
handle: (
|
|
98
|
+
handle: (
|
|
99
|
+
event: GraphEvents.ON_MESSAGE_DELTA,
|
|
100
|
+
data: t.StreamEventData,
|
|
101
|
+
metadata,
|
|
102
|
+
graph
|
|
103
|
+
): void => {
|
|
74
104
|
onMessageDeltaSpy(event, data, metadata, graph);
|
|
75
105
|
aggregateContent({ event, data: data as t.MessageDeltaEvent });
|
|
76
|
-
}
|
|
106
|
+
},
|
|
77
107
|
},
|
|
78
108
|
[GraphEvents.TOOL_START]: {
|
|
79
|
-
handle: (
|
|
109
|
+
handle: (
|
|
110
|
+
_event: string,
|
|
111
|
+
_data: t.StreamEventData,
|
|
112
|
+
_metadata?: Record<string, unknown>
|
|
113
|
+
): void => {
|
|
80
114
|
// Handle tool start
|
|
81
|
-
}
|
|
115
|
+
},
|
|
82
116
|
},
|
|
83
117
|
});
|
|
84
118
|
|
|
@@ -93,7 +127,8 @@ describe(`${capitalizeFirstLetter(provider)} Streaming Tests`, () => {
|
|
|
93
127
|
type: 'standard',
|
|
94
128
|
llmConfig,
|
|
95
129
|
tools: [new Calculator()],
|
|
96
|
-
instructions:
|
|
130
|
+
instructions:
|
|
131
|
+
'You are a friendly AI assistant. Always address the user by their name.',
|
|
97
132
|
additional_instructions: `The user's name is ${userName} and they are located in ${location}.`,
|
|
98
133
|
},
|
|
99
134
|
returnContent: true,
|
|
@@ -109,7 +144,9 @@ describe(`${capitalizeFirstLetter(provider)} Streaming Tests`, () => {
|
|
|
109
144
|
|
|
110
145
|
const finalContentParts = await run.processStream(inputs, config);
|
|
111
146
|
expect(finalContentParts).toBeDefined();
|
|
112
|
-
const allTextParts = finalContentParts?.every(
|
|
147
|
+
const allTextParts = finalContentParts?.every(
|
|
148
|
+
(part) => part.type === ContentTypes.TEXT
|
|
149
|
+
);
|
|
113
150
|
expect(allTextParts).toBe(true);
|
|
114
151
|
expect(collectedUsage.length).toBeGreaterThan(0);
|
|
115
152
|
expect(collectedUsage[0].input_tokens).toBeGreaterThan(0);
|
|
@@ -117,26 +154,34 @@ describe(`${capitalizeFirstLetter(provider)} Streaming Tests`, () => {
|
|
|
117
154
|
|
|
118
155
|
const finalMessages = run.getRunMessages();
|
|
119
156
|
expect(finalMessages).toBeDefined();
|
|
120
|
-
conversationHistory.push(...finalMessages ?? []);
|
|
157
|
+
conversationHistory.push(...(finalMessages ?? []));
|
|
121
158
|
expect(conversationHistory.length).toBeGreaterThan(1);
|
|
122
159
|
runningHistory = conversationHistory.slice();
|
|
123
160
|
|
|
124
161
|
expect(onMessageDeltaSpy).toHaveBeenCalled();
|
|
125
162
|
expect(onMessageDeltaSpy.mock.calls.length).toBeGreaterThan(1);
|
|
126
|
-
expect(
|
|
163
|
+
expect(onMessageDeltaSpy.mock.calls[0][3]).toBeDefined(); // Graph exists
|
|
127
164
|
|
|
128
165
|
expect(onRunStepSpy).toHaveBeenCalled();
|
|
129
166
|
expect(onRunStepSpy.mock.calls.length).toBeGreaterThan(0);
|
|
130
|
-
expect(
|
|
167
|
+
expect(onRunStepSpy.mock.calls[0][3]).toBeDefined(); // Graph exists
|
|
131
168
|
|
|
132
169
|
const { handleLLMEnd, collected } = createMetadataAggregator();
|
|
133
170
|
const titleResult = await run.generateTitle({
|
|
171
|
+
provider,
|
|
134
172
|
inputText: userMessage,
|
|
173
|
+
titleMethod: TitleMethod.STRUCTURED,
|
|
135
174
|
contentParts,
|
|
175
|
+
clientOptions: {
|
|
176
|
+
...llmConfig,
|
|
177
|
+
model: 'claude-3-5-haiku-latest',
|
|
178
|
+
},
|
|
136
179
|
chainOptions: {
|
|
137
|
-
callbacks: [
|
|
138
|
-
|
|
139
|
-
|
|
180
|
+
callbacks: [
|
|
181
|
+
{
|
|
182
|
+
handleLLMEnd,
|
|
183
|
+
},
|
|
184
|
+
],
|
|
140
185
|
},
|
|
141
186
|
});
|
|
142
187
|
|
|
@@ -146,9 +191,71 @@ describe(`${capitalizeFirstLetter(provider)} Streaming Tests`, () => {
|
|
|
146
191
|
expect(collected).toBeDefined();
|
|
147
192
|
});
|
|
148
193
|
|
|
194
|
+
test(`${capitalizeFirstLetter(provider)}: should generate title using completion method`, async () => {
|
|
195
|
+
const { userName, location } = await getArgs();
|
|
196
|
+
const llmConfig = getLLMConfig(provider);
|
|
197
|
+
const customHandlers = setupCustomHandlers();
|
|
198
|
+
|
|
199
|
+
run = await Run.create<t.IState>({
|
|
200
|
+
runId: 'test-run-id-completion',
|
|
201
|
+
graphConfig: {
|
|
202
|
+
type: 'standard',
|
|
203
|
+
llmConfig,
|
|
204
|
+
tools: [new Calculator()],
|
|
205
|
+
instructions:
|
|
206
|
+
'You are a friendly AI assistant. Always address the user by their name.',
|
|
207
|
+
additional_instructions: `The user's name is ${userName} and they are located in ${location}.`,
|
|
208
|
+
},
|
|
209
|
+
returnContent: true,
|
|
210
|
+
customHandlers,
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
const userMessage =
|
|
214
|
+
'Can you help me calculate the area of a circle with radius 5?';
|
|
215
|
+
conversationHistory = [];
|
|
216
|
+
conversationHistory.push(new HumanMessage(userMessage));
|
|
217
|
+
|
|
218
|
+
const inputs = {
|
|
219
|
+
messages: conversationHistory,
|
|
220
|
+
};
|
|
221
|
+
|
|
222
|
+
const finalContentParts = await run.processStream(inputs, config);
|
|
223
|
+
expect(finalContentParts).toBeDefined();
|
|
224
|
+
|
|
225
|
+
const { handleLLMEnd, collected } = createMetadataAggregator();
|
|
226
|
+
const titleResult = await run.generateTitle({
|
|
227
|
+
provider,
|
|
228
|
+
inputText: userMessage,
|
|
229
|
+
titleMethod: TitleMethod.COMPLETION, // Using completion method
|
|
230
|
+
contentParts,
|
|
231
|
+
clientOptions: {
|
|
232
|
+
...llmConfig,
|
|
233
|
+
model: 'claude-3-5-haiku-latest',
|
|
234
|
+
},
|
|
235
|
+
chainOptions: {
|
|
236
|
+
callbacks: [
|
|
237
|
+
{
|
|
238
|
+
handleLLMEnd,
|
|
239
|
+
},
|
|
240
|
+
],
|
|
241
|
+
},
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
expect(titleResult).toBeDefined();
|
|
245
|
+
expect(titleResult.title).toBeDefined();
|
|
246
|
+
expect(titleResult.title).not.toBe('');
|
|
247
|
+
// Completion method doesn't return language
|
|
248
|
+
expect(titleResult.language).toBeUndefined();
|
|
249
|
+
expect(collected).toBeDefined();
|
|
250
|
+
console.log(`Completion method generated title: "${titleResult.title}"`);
|
|
251
|
+
});
|
|
252
|
+
|
|
149
253
|
test(`${capitalizeFirstLetter(provider)}: should follow-up`, async () => {
|
|
150
254
|
console.log('Previous conversation length:', runningHistory.length);
|
|
151
|
-
console.log(
|
|
255
|
+
console.log(
|
|
256
|
+
'Last message:',
|
|
257
|
+
runningHistory[runningHistory.length - 1].content
|
|
258
|
+
);
|
|
152
259
|
const { userName, location } = await getArgs();
|
|
153
260
|
const llmConfig = getLLMConfig(provider);
|
|
154
261
|
const customHandlers = setupCustomHandlers();
|
|
@@ -159,7 +266,8 @@ describe(`${capitalizeFirstLetter(provider)} Streaming Tests`, () => {
|
|
|
159
266
|
type: 'standard',
|
|
160
267
|
llmConfig,
|
|
161
268
|
tools: [new Calculator()],
|
|
162
|
-
instructions:
|
|
269
|
+
instructions:
|
|
270
|
+
'You are a friendly AI assistant. Always address the user by their name.',
|
|
163
271
|
additional_instructions: `The user's name is ${userName} and they are located in ${location}.`,
|
|
164
272
|
},
|
|
165
273
|
returnContent: true,
|
|
@@ -175,7 +283,9 @@ describe(`${capitalizeFirstLetter(provider)} Streaming Tests`, () => {
|
|
|
175
283
|
|
|
176
284
|
const finalContentParts = await run.processStream(inputs, config);
|
|
177
285
|
expect(finalContentParts).toBeDefined();
|
|
178
|
-
const allTextParts = finalContentParts?.every(
|
|
286
|
+
const allTextParts = finalContentParts?.every(
|
|
287
|
+
(part) => part.type === ContentTypes.TEXT
|
|
288
|
+
);
|
|
179
289
|
expect(allTextParts).toBe(true);
|
|
180
290
|
expect(collectedUsage.length).toBeGreaterThan(0);
|
|
181
291
|
expect(collectedUsage[0].input_tokens).toBeGreaterThan(0);
|
|
@@ -184,7 +294,10 @@ describe(`${capitalizeFirstLetter(provider)} Streaming Tests`, () => {
|
|
|
184
294
|
const finalMessages = run.getRunMessages();
|
|
185
295
|
expect(finalMessages).toBeDefined();
|
|
186
296
|
expect(finalMessages?.length).toBeGreaterThan(0);
|
|
187
|
-
console.log(
|
|
297
|
+
console.log(
|
|
298
|
+
`${capitalizeFirstLetter(provider)} follow-up message:`,
|
|
299
|
+
finalMessages?.[finalMessages.length - 1]?.content
|
|
300
|
+
);
|
|
188
301
|
|
|
189
302
|
expect(onMessageDeltaSpy).toHaveBeenCalled();
|
|
190
303
|
expect(onMessageDeltaSpy.mock.calls.length).toBeGreaterThan(1);
|
|
@@ -196,9 +309,12 @@ describe(`${capitalizeFirstLetter(provider)} Streaming Tests`, () => {
|
|
|
196
309
|
test('should handle errors appropriately', async () => {
|
|
197
310
|
// Test error scenarios
|
|
198
311
|
await expect(async () => {
|
|
199
|
-
await run.processStream(
|
|
200
|
-
|
|
201
|
-
|
|
312
|
+
await run.processStream(
|
|
313
|
+
{
|
|
314
|
+
messages: [],
|
|
315
|
+
},
|
|
316
|
+
{} as any
|
|
317
|
+
);
|
|
202
318
|
}).rejects.toThrow();
|
|
203
319
|
});
|
|
204
|
-
});
|
|
320
|
+
});
|
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
/* eslint-disable no-console */
|
|
2
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
3
|
+
// src/scripts/cli.test.ts
|
|
4
|
+
import { config } from 'dotenv';
|
|
5
|
+
config();
|
|
6
|
+
import { Calculator } from '@langchain/community/tools/calculator';
|
|
7
|
+
import {
|
|
8
|
+
HumanMessage,
|
|
9
|
+
BaseMessage,
|
|
10
|
+
UsageMetadata,
|
|
11
|
+
} from '@langchain/core/messages';
|
|
12
|
+
import type * as t from '@/types';
|
|
13
|
+
import {
|
|
14
|
+
ToolEndHandler,
|
|
15
|
+
ModelEndHandler,
|
|
16
|
+
createMetadataAggregator,
|
|
17
|
+
} from '@/events';
|
|
18
|
+
import { ContentTypes, GraphEvents, Providers, TitleMethod } from '@/common';
|
|
19
|
+
import { ChatModelStreamHandler, createContentAggregator } from '@/stream';
|
|
20
|
+
import { capitalizeFirstLetter } from './spec.utils';
|
|
21
|
+
import { getLLMConfig } from '@/utils/llmConfig';
|
|
22
|
+
import { getArgs } from '@/scripts/args';
|
|
23
|
+
import { Run } from '@/run';
|
|
24
|
+
|
|
25
|
+
// Auto-skip this suite if Azure env vars are not present
|
|
26
|
+
const requiredAzureEnv = [
|
|
27
|
+
'AZURE_OPENAI_API_KEY',
|
|
28
|
+
'AZURE_OPENAI_API_INSTANCE',
|
|
29
|
+
'AZURE_OPENAI_API_DEPLOYMENT',
|
|
30
|
+
'AZURE_OPENAI_API_VERSION',
|
|
31
|
+
];
|
|
32
|
+
const hasAzure = requiredAzureEnv.every(
|
|
33
|
+
(k) => (process.env[k] ?? '').trim() !== ''
|
|
34
|
+
);
|
|
35
|
+
const describeIfAzure = hasAzure ? describe : describe.skip;
|
|
36
|
+
|
|
37
|
+
const provider = Providers.AZURE;
|
|
38
|
+
describeIfAzure(`${capitalizeFirstLetter(provider)} Streaming Tests`, () => {
|
|
39
|
+
jest.setTimeout(30000);
|
|
40
|
+
let run: Run<t.IState>;
|
|
41
|
+
let runningHistory: BaseMessage[];
|
|
42
|
+
let collectedUsage: UsageMetadata[];
|
|
43
|
+
let conversationHistory: BaseMessage[];
|
|
44
|
+
let aggregateContent: t.ContentAggregator;
|
|
45
|
+
let contentParts: t.MessageContentComplex[];
|
|
46
|
+
|
|
47
|
+
const config = {
|
|
48
|
+
configurable: {
|
|
49
|
+
thread_id: 'conversation-num-1',
|
|
50
|
+
},
|
|
51
|
+
streamMode: 'values',
|
|
52
|
+
version: 'v2' as const,
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
beforeEach(async () => {
|
|
56
|
+
conversationHistory = [];
|
|
57
|
+
collectedUsage = [];
|
|
58
|
+
const { contentParts: cp, aggregateContent: ac } =
|
|
59
|
+
createContentAggregator();
|
|
60
|
+
contentParts = cp as t.MessageContentComplex[];
|
|
61
|
+
aggregateContent = ac;
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
const onMessageDeltaSpy = jest.fn();
|
|
65
|
+
const onRunStepSpy = jest.fn();
|
|
66
|
+
|
|
67
|
+
afterAll(() => {
|
|
68
|
+
onMessageDeltaSpy.mockReset();
|
|
69
|
+
onRunStepSpy.mockReset();
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
const setupCustomHandlers = (): Record<
|
|
73
|
+
string | GraphEvents,
|
|
74
|
+
t.EventHandler
|
|
75
|
+
> => ({
|
|
76
|
+
[GraphEvents.TOOL_END]: new ToolEndHandler(),
|
|
77
|
+
[GraphEvents.CHAT_MODEL_END]: new ModelEndHandler(collectedUsage),
|
|
78
|
+
[GraphEvents.CHAT_MODEL_STREAM]: new ChatModelStreamHandler(),
|
|
79
|
+
[GraphEvents.ON_RUN_STEP_COMPLETED]: {
|
|
80
|
+
handle: (
|
|
81
|
+
event: GraphEvents.ON_RUN_STEP_COMPLETED,
|
|
82
|
+
data: t.StreamEventData
|
|
83
|
+
): void => {
|
|
84
|
+
aggregateContent({
|
|
85
|
+
event,
|
|
86
|
+
data: data as unknown as { result: t.ToolEndEvent },
|
|
87
|
+
});
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
[GraphEvents.ON_RUN_STEP]: {
|
|
91
|
+
handle: (
|
|
92
|
+
event: GraphEvents.ON_RUN_STEP,
|
|
93
|
+
data: t.StreamEventData,
|
|
94
|
+
metadata,
|
|
95
|
+
graph
|
|
96
|
+
): void => {
|
|
97
|
+
onRunStepSpy(event, data, metadata, graph);
|
|
98
|
+
aggregateContent({ event, data: data as t.RunStep });
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
[GraphEvents.ON_RUN_STEP_DELTA]: {
|
|
102
|
+
handle: (
|
|
103
|
+
event: GraphEvents.ON_RUN_STEP_DELTA,
|
|
104
|
+
data: t.StreamEventData
|
|
105
|
+
): void => {
|
|
106
|
+
aggregateContent({ event, data: data as t.RunStepDeltaEvent });
|
|
107
|
+
},
|
|
108
|
+
},
|
|
109
|
+
[GraphEvents.ON_MESSAGE_DELTA]: {
|
|
110
|
+
handle: (
|
|
111
|
+
event: GraphEvents.ON_MESSAGE_DELTA,
|
|
112
|
+
data: t.StreamEventData,
|
|
113
|
+
metadata,
|
|
114
|
+
graph
|
|
115
|
+
): void => {
|
|
116
|
+
onMessageDeltaSpy(event, data, metadata, graph);
|
|
117
|
+
aggregateContent({ event, data: data as t.MessageDeltaEvent });
|
|
118
|
+
},
|
|
119
|
+
},
|
|
120
|
+
[GraphEvents.TOOL_START]: {
|
|
121
|
+
handle: (
|
|
122
|
+
_event: string,
|
|
123
|
+
_data: t.StreamEventData,
|
|
124
|
+
_metadata?: Record<string, unknown>
|
|
125
|
+
): void => {
|
|
126
|
+
// Handle tool start
|
|
127
|
+
},
|
|
128
|
+
},
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
test(`${capitalizeFirstLetter(provider)}: should process a simple message, generate title`, async () => {
|
|
132
|
+
const { userName, location } = await getArgs();
|
|
133
|
+
const llmConfig = getLLMConfig(provider);
|
|
134
|
+
const customHandlers = setupCustomHandlers();
|
|
135
|
+
|
|
136
|
+
run = await Run.create<t.IState>({
|
|
137
|
+
runId: 'test-run-id',
|
|
138
|
+
graphConfig: {
|
|
139
|
+
type: 'standard',
|
|
140
|
+
llmConfig,
|
|
141
|
+
tools: [new Calculator()],
|
|
142
|
+
instructions:
|
|
143
|
+
'You are a friendly AI assistant. Always address the user by their name.',
|
|
144
|
+
additional_instructions: `The user's name is ${userName} and they are located in ${location}.`,
|
|
145
|
+
},
|
|
146
|
+
returnContent: true,
|
|
147
|
+
customHandlers,
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
const userMessage = 'hi';
|
|
151
|
+
conversationHistory.push(new HumanMessage(userMessage));
|
|
152
|
+
|
|
153
|
+
const inputs = {
|
|
154
|
+
messages: conversationHistory,
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
const finalContentParts = await run.processStream(inputs, config);
|
|
158
|
+
expect(finalContentParts).toBeDefined();
|
|
159
|
+
const allTextParts = finalContentParts?.every(
|
|
160
|
+
(part) => part.type === ContentTypes.TEXT
|
|
161
|
+
);
|
|
162
|
+
expect(allTextParts).toBe(true);
|
|
163
|
+
expect(collectedUsage.length).toBeGreaterThan(0);
|
|
164
|
+
expect(collectedUsage[0].input_tokens).toBeGreaterThan(0);
|
|
165
|
+
expect(collectedUsage[0].output_tokens).toBeGreaterThan(0);
|
|
166
|
+
|
|
167
|
+
const finalMessages = run.getRunMessages();
|
|
168
|
+
expect(finalMessages).toBeDefined();
|
|
169
|
+
conversationHistory.push(...(finalMessages ?? []));
|
|
170
|
+
expect(conversationHistory.length).toBeGreaterThan(1);
|
|
171
|
+
runningHistory = conversationHistory.slice();
|
|
172
|
+
|
|
173
|
+
expect(onMessageDeltaSpy).toHaveBeenCalled();
|
|
174
|
+
expect(onMessageDeltaSpy.mock.calls.length).toBeGreaterThan(1);
|
|
175
|
+
expect(onMessageDeltaSpy.mock.calls[0][3]).toBeDefined(); // Graph exists
|
|
176
|
+
|
|
177
|
+
expect(onRunStepSpy).toHaveBeenCalled();
|
|
178
|
+
expect(onRunStepSpy.mock.calls.length).toBeGreaterThan(0);
|
|
179
|
+
expect(onRunStepSpy.mock.calls[0][3]).toBeDefined(); // Graph exists
|
|
180
|
+
|
|
181
|
+
const { handleLLMEnd, collected } = createMetadataAggregator();
|
|
182
|
+
const titleResult = await run.generateTitle({
|
|
183
|
+
provider,
|
|
184
|
+
inputText: userMessage,
|
|
185
|
+
titleMethod: TitleMethod.STRUCTURED,
|
|
186
|
+
contentParts,
|
|
187
|
+
clientOptions: llmConfig,
|
|
188
|
+
chainOptions: {
|
|
189
|
+
callbacks: [
|
|
190
|
+
{
|
|
191
|
+
handleLLMEnd,
|
|
192
|
+
},
|
|
193
|
+
],
|
|
194
|
+
},
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
expect(titleResult).toBeDefined();
|
|
198
|
+
expect(titleResult.title).toBeDefined();
|
|
199
|
+
expect(titleResult.language).toBeDefined();
|
|
200
|
+
expect(collected).toBeDefined();
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
test(`${capitalizeFirstLetter(provider)}: should generate title using completion method`, async () => {
|
|
204
|
+
const { userName, location } = await getArgs();
|
|
205
|
+
const llmConfig = getLLMConfig(provider);
|
|
206
|
+
const customHandlers = setupCustomHandlers();
|
|
207
|
+
|
|
208
|
+
run = await Run.create<t.IState>({
|
|
209
|
+
runId: 'test-run-id-completion',
|
|
210
|
+
graphConfig: {
|
|
211
|
+
type: 'standard',
|
|
212
|
+
llmConfig,
|
|
213
|
+
tools: [new Calculator()],
|
|
214
|
+
instructions:
|
|
215
|
+
'You are a friendly AI assistant. Always address the user by their name.',
|
|
216
|
+
additional_instructions: `The user's name is ${userName} and they are located in ${location}.`,
|
|
217
|
+
},
|
|
218
|
+
returnContent: true,
|
|
219
|
+
customHandlers,
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
const userMessage = 'What is the weather like today?';
|
|
223
|
+
conversationHistory = [];
|
|
224
|
+
conversationHistory.push(new HumanMessage(userMessage));
|
|
225
|
+
|
|
226
|
+
const inputs = {
|
|
227
|
+
messages: conversationHistory,
|
|
228
|
+
};
|
|
229
|
+
|
|
230
|
+
const finalContentParts = await run.processStream(inputs, config);
|
|
231
|
+
expect(finalContentParts).toBeDefined();
|
|
232
|
+
|
|
233
|
+
const { handleLLMEnd, collected } = createMetadataAggregator();
|
|
234
|
+
const titleResult = await run.generateTitle({
|
|
235
|
+
provider,
|
|
236
|
+
inputText: userMessage,
|
|
237
|
+
titleMethod: TitleMethod.COMPLETION, // Using completion method
|
|
238
|
+
contentParts,
|
|
239
|
+
clientOptions: llmConfig,
|
|
240
|
+
chainOptions: {
|
|
241
|
+
callbacks: [
|
|
242
|
+
{
|
|
243
|
+
handleLLMEnd,
|
|
244
|
+
},
|
|
245
|
+
],
|
|
246
|
+
},
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
expect(titleResult).toBeDefined();
|
|
250
|
+
expect(titleResult.title).toBeDefined();
|
|
251
|
+
expect(titleResult.title).not.toBe('');
|
|
252
|
+
// Completion method doesn't return language
|
|
253
|
+
expect(titleResult.language).toBeUndefined();
|
|
254
|
+
expect(collected).toBeDefined();
|
|
255
|
+
console.log(`Completion method generated title: "${titleResult.title}"`);
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
test(`${capitalizeFirstLetter(provider)}: should follow-up`, async () => {
|
|
259
|
+
console.log('Previous conversation length:', runningHistory.length);
|
|
260
|
+
console.log(
|
|
261
|
+
'Last message:',
|
|
262
|
+
runningHistory[runningHistory.length - 1].content
|
|
263
|
+
);
|
|
264
|
+
const { userName, location } = await getArgs();
|
|
265
|
+
const llmConfig = getLLMConfig(provider);
|
|
266
|
+
const customHandlers = setupCustomHandlers();
|
|
267
|
+
|
|
268
|
+
run = await Run.create<t.IState>({
|
|
269
|
+
runId: 'test-run-id',
|
|
270
|
+
graphConfig: {
|
|
271
|
+
type: 'standard',
|
|
272
|
+
llmConfig,
|
|
273
|
+
tools: [new Calculator()],
|
|
274
|
+
instructions:
|
|
275
|
+
'You are a friendly AI assistant. Always address the user by their name.',
|
|
276
|
+
additional_instructions: `The user's name is ${userName} and they are located in ${location}.`,
|
|
277
|
+
},
|
|
278
|
+
returnContent: true,
|
|
279
|
+
customHandlers,
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
conversationHistory = runningHistory.slice();
|
|
283
|
+
conversationHistory.push(new HumanMessage('how are you?'));
|
|
284
|
+
|
|
285
|
+
const inputs = {
|
|
286
|
+
messages: conversationHistory,
|
|
287
|
+
};
|
|
288
|
+
|
|
289
|
+
const finalContentParts = await run.processStream(inputs, config);
|
|
290
|
+
expect(finalContentParts).toBeDefined();
|
|
291
|
+
const allTextParts = finalContentParts?.every(
|
|
292
|
+
(part) => part.type === ContentTypes.TEXT
|
|
293
|
+
);
|
|
294
|
+
expect(allTextParts).toBe(true);
|
|
295
|
+
expect(collectedUsage.length).toBeGreaterThan(0);
|
|
296
|
+
expect(collectedUsage[0].input_tokens).toBeGreaterThan(0);
|
|
297
|
+
expect(collectedUsage[0].output_tokens).toBeGreaterThan(0);
|
|
298
|
+
|
|
299
|
+
const finalMessages = run.getRunMessages();
|
|
300
|
+
expect(finalMessages).toBeDefined();
|
|
301
|
+
expect(finalMessages?.length).toBeGreaterThan(0);
|
|
302
|
+
console.log(
|
|
303
|
+
`${capitalizeFirstLetter(provider)} follow-up message:`,
|
|
304
|
+
finalMessages?.[finalMessages.length - 1]?.content
|
|
305
|
+
);
|
|
306
|
+
|
|
307
|
+
expect(onMessageDeltaSpy).toHaveBeenCalled();
|
|
308
|
+
expect(onMessageDeltaSpy.mock.calls.length).toBeGreaterThan(1);
|
|
309
|
+
|
|
310
|
+
expect(onRunStepSpy).toHaveBeenCalled();
|
|
311
|
+
expect(onRunStepSpy.mock.calls.length).toBeGreaterThan(0);
|
|
312
|
+
});
|
|
313
|
+
|
|
314
|
+
test('should handle errors appropriately', async () => {
|
|
315
|
+
// Test error scenarios
|
|
316
|
+
await expect(async () => {
|
|
317
|
+
await run.processStream(
|
|
318
|
+
{
|
|
319
|
+
messages: [],
|
|
320
|
+
},
|
|
321
|
+
{} as any
|
|
322
|
+
);
|
|
323
|
+
}).rejects.toThrow();
|
|
324
|
+
});
|
|
325
|
+
});
|