@illuma-ai/agents 1.1.21 → 1.1.22
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/graphs/Graph.cjs +12 -1
- package/dist/cjs/graphs/Graph.cjs.map +1 -1
- package/dist/cjs/graphs/MultiAgentGraph.cjs +85 -1
- package/dist/cjs/graphs/MultiAgentGraph.cjs.map +1 -1
- package/dist/cjs/run.cjs +20 -9
- package/dist/cjs/run.cjs.map +1 -1
- package/dist/esm/graphs/Graph.mjs +12 -1
- package/dist/esm/graphs/Graph.mjs.map +1 -1
- package/dist/esm/graphs/MultiAgentGraph.mjs +85 -1
- package/dist/esm/graphs/MultiAgentGraph.mjs.map +1 -1
- package/dist/esm/run.mjs +20 -9
- package/dist/esm/run.mjs.map +1 -1
- package/dist/types/graphs/MultiAgentGraph.d.ts +17 -0
- package/package.json +1 -1
- package/src/graphs/Graph.ts +12 -1
- package/src/graphs/MultiAgentGraph.ts +105 -1
- package/src/graphs/__tests__/multi-agent-delegate.test.ts +191 -0
- package/src/run.ts +20 -11
- package/src/scripts/test-bedrock-handoff-autonomous.ts +231 -0
- package/src/agents/AgentContext.js +0 -782
- package/src/agents/AgentContext.test.js +0 -421
- package/src/agents/__tests__/AgentContext.test.js +0 -678
- package/src/agents/__tests__/resolveStructuredOutputMode.test.js +0 -117
- package/src/common/enum.js +0 -192
- package/src/common/index.js +0 -3
- package/src/events.js +0 -166
- package/src/graphs/Graph.js +0 -1857
- package/src/graphs/MultiAgentGraph.js +0 -1092
- package/src/graphs/__tests__/structured-output.integration.test.js +0 -624
- package/src/graphs/__tests__/structured-output.test.js +0 -144
- package/src/graphs/contextManagement.e2e.test.js +0 -718
- package/src/graphs/contextManagement.test.js +0 -485
- package/src/graphs/handoffValidation.test.js +0 -276
- package/src/graphs/index.js +0 -3
- package/src/index.js +0 -28
- package/src/instrumentation.js +0 -21
- package/src/llm/anthropic/index.js +0 -319
- package/src/llm/anthropic/types.js +0 -46
- package/src/llm/anthropic/utils/message_inputs.js +0 -627
- package/src/llm/anthropic/utils/message_outputs.js +0 -290
- package/src/llm/anthropic/utils/output_parsers.js +0 -89
- package/src/llm/anthropic/utils/tools.js +0 -25
- package/src/llm/bedrock/__tests__/bedrock-caching.test.js +0 -392
- package/src/llm/bedrock/index.js +0 -303
- package/src/llm/bedrock/types.js +0 -2
- package/src/llm/bedrock/utils/index.js +0 -6
- package/src/llm/bedrock/utils/message_inputs.js +0 -463
- package/src/llm/bedrock/utils/message_outputs.js +0 -269
- package/src/llm/fake.js +0 -92
- package/src/llm/google/index.js +0 -215
- package/src/llm/google/types.js +0 -12
- package/src/llm/google/utils/common.js +0 -670
- package/src/llm/google/utils/tools.js +0 -111
- package/src/llm/google/utils/zod_to_genai_parameters.js +0 -47
- package/src/llm/openai/index.js +0 -1033
- package/src/llm/openai/types.js +0 -2
- package/src/llm/openai/utils/index.js +0 -756
- package/src/llm/openai/utils/isReasoningModel.test.js +0 -79
- package/src/llm/openrouter/index.js +0 -261
- package/src/llm/openrouter/reasoning.test.js +0 -181
- package/src/llm/providers.js +0 -36
- package/src/llm/text.js +0 -65
- package/src/llm/vertexai/index.js +0 -402
- package/src/messages/__tests__/tools.test.js +0 -392
- package/src/messages/cache.js +0 -404
- package/src/messages/cache.test.js +0 -1167
- package/src/messages/content.js +0 -48
- package/src/messages/content.test.js +0 -314
- package/src/messages/core.js +0 -359
- package/src/messages/ensureThinkingBlock.test.js +0 -997
- package/src/messages/format.js +0 -973
- package/src/messages/formatAgentMessages.test.js +0 -2278
- package/src/messages/formatAgentMessages.tools.test.js +0 -362
- package/src/messages/formatMessage.test.js +0 -608
- package/src/messages/ids.js +0 -18
- package/src/messages/index.js +0 -9
- package/src/messages/labelContentByAgent.test.js +0 -725
- package/src/messages/prune.js +0 -438
- package/src/messages/reducer.js +0 -60
- package/src/messages/shiftIndexTokenCountMap.test.js +0 -63
- package/src/messages/summarize.js +0 -146
- package/src/messages/summarize.test.js +0 -332
- package/src/messages/tools.js +0 -90
- package/src/mockStream.js +0 -81
- package/src/prompts/collab.js +0 -7
- package/src/prompts/index.js +0 -3
- package/src/prompts/taskmanager.js +0 -58
- package/src/run.js +0 -427
- package/src/schemas/index.js +0 -3
- package/src/schemas/schema-preparation.test.js +0 -370
- package/src/schemas/validate.js +0 -314
- package/src/schemas/validate.test.js +0 -264
- package/src/scripts/abort.js +0 -127
- package/src/scripts/ant_web_search.js +0 -130
- package/src/scripts/ant_web_search_edge_case.js +0 -133
- package/src/scripts/ant_web_search_error_edge_case.js +0 -119
- package/src/scripts/args.js +0 -41
- package/src/scripts/bedrock-cache-debug.js +0 -186
- package/src/scripts/bedrock-content-aggregation-test.js +0 -195
- package/src/scripts/bedrock-merge-test.js +0 -80
- package/src/scripts/bedrock-parallel-tools-test.js +0 -150
- package/src/scripts/caching.js +0 -106
- package/src/scripts/cli.js +0 -152
- package/src/scripts/cli2.js +0 -119
- package/src/scripts/cli3.js +0 -163
- package/src/scripts/cli4.js +0 -165
- package/src/scripts/cli5.js +0 -165
- package/src/scripts/code_exec.js +0 -171
- package/src/scripts/code_exec_files.js +0 -180
- package/src/scripts/code_exec_multi_session.js +0 -185
- package/src/scripts/code_exec_ptc.js +0 -265
- package/src/scripts/code_exec_session.js +0 -217
- package/src/scripts/code_exec_simple.js +0 -120
- package/src/scripts/content.js +0 -111
- package/src/scripts/empty_input.js +0 -125
- package/src/scripts/handoff-test.js +0 -96
- package/src/scripts/image.js +0 -138
- package/src/scripts/memory.js +0 -83
- package/src/scripts/multi-agent-chain.js +0 -271
- package/src/scripts/multi-agent-conditional.js +0 -185
- package/src/scripts/multi-agent-document-review-chain.js +0 -171
- package/src/scripts/multi-agent-hybrid-flow.js +0 -264
- package/src/scripts/multi-agent-parallel-start.js +0 -214
- package/src/scripts/multi-agent-parallel.js +0 -346
- package/src/scripts/multi-agent-sequence.js +0 -184
- package/src/scripts/multi-agent-supervisor.js +0 -324
- package/src/scripts/multi-agent-test.js +0 -147
- package/src/scripts/parallel-asymmetric-tools-test.js +0 -202
- package/src/scripts/parallel-full-metadata-test.js +0 -176
- package/src/scripts/parallel-tools-test.js +0 -256
- package/src/scripts/programmatic_exec.js +0 -277
- package/src/scripts/programmatic_exec_agent.js +0 -168
- package/src/scripts/search.js +0 -118
- package/src/scripts/sequential-full-metadata-test.js +0 -143
- package/src/scripts/simple.js +0 -174
- package/src/scripts/single-agent-metadata-test.js +0 -152
- package/src/scripts/stream.js +0 -113
- package/src/scripts/test-custom-prompt-key.js +0 -132
- package/src/scripts/test-handoff-input.js +0 -143
- package/src/scripts/test-handoff-preamble.js +0 -227
- package/src/scripts/test-handoff-steering.js +0 -353
- package/src/scripts/test-multi-agent-list-handoff.js +0 -318
- package/src/scripts/test-parallel-agent-labeling.js +0 -253
- package/src/scripts/test-parallel-handoffs.js +0 -229
- package/src/scripts/test-thinking-handoff-bedrock.js +0 -132
- package/src/scripts/test-thinking-handoff.js +0 -132
- package/src/scripts/test-thinking-to-thinking-handoff-bedrock.js +0 -140
- package/src/scripts/test-tool-before-handoff-role-order.js +0 -223
- package/src/scripts/test-tools-before-handoff.js +0 -187
- package/src/scripts/test_code_api.js +0 -263
- package/src/scripts/thinking-bedrock.js +0 -128
- package/src/scripts/thinking-vertexai.js +0 -130
- package/src/scripts/thinking.js +0 -134
- package/src/scripts/tool_search.js +0 -114
- package/src/scripts/tools.js +0 -125
- package/src/specs/agent-handoffs-bedrock.integration.test.js +0 -280
- package/src/specs/agent-handoffs.test.js +0 -924
- package/src/specs/anthropic.simple.test.js +0 -287
- package/src/specs/azure.simple.test.js +0 -381
- package/src/specs/cache.simple.test.js +0 -282
- package/src/specs/custom-event-await.test.js +0 -148
- package/src/specs/deepseek.simple.test.js +0 -189
- package/src/specs/emergency-prune.test.js +0 -308
- package/src/specs/moonshot.simple.test.js +0 -237
- package/src/specs/observability.integration.test.js +0 -1337
- package/src/specs/openai.simple.test.js +0 -233
- package/src/specs/openrouter.simple.test.js +0 -202
- package/src/specs/prune.test.js +0 -733
- package/src/specs/reasoning.test.js +0 -144
- package/src/specs/spec.utils.js +0 -4
- package/src/specs/thinking-handoff.test.js +0 -486
- package/src/specs/thinking-prune.test.js +0 -600
- package/src/specs/token-distribution-edge-case.test.js +0 -246
- package/src/specs/token-memoization.test.js +0 -32
- package/src/specs/tokens.test.js +0 -49
- package/src/specs/tool-error.test.js +0 -139
- package/src/splitStream.js +0 -204
- package/src/splitStream.test.js +0 -504
- package/src/stream.js +0 -650
- package/src/stream.test.js +0 -225
- package/src/test/mockTools.js +0 -340
- package/src/tools/BrowserTools.js +0 -245
- package/src/tools/Calculator.js +0 -38
- package/src/tools/Calculator.test.js +0 -225
- package/src/tools/CodeExecutor.js +0 -233
- package/src/tools/ProgrammaticToolCalling.js +0 -602
- package/src/tools/StreamingToolCallBuffer.js +0 -179
- package/src/tools/ToolNode.js +0 -930
- package/src/tools/ToolSearch.js +0 -904
- package/src/tools/__tests__/BrowserTools.test.js +0 -306
- package/src/tools/__tests__/ProgrammaticToolCalling.integration.test.js +0 -276
- package/src/tools/__tests__/ProgrammaticToolCalling.test.js +0 -807
- package/src/tools/__tests__/StreamingToolCallBuffer.test.js +0 -175
- package/src/tools/__tests__/ToolApproval.test.js +0 -675
- package/src/tools/__tests__/ToolNode.recovery.test.js +0 -200
- package/src/tools/__tests__/ToolNode.session.test.js +0 -319
- package/src/tools/__tests__/ToolSearch.integration.test.js +0 -125
- package/src/tools/__tests__/ToolSearch.test.js +0 -812
- package/src/tools/__tests__/handlers.test.js +0 -799
- package/src/tools/__tests__/truncation-recovery.integration.test.js +0 -362
- package/src/tools/handlers.js +0 -306
- package/src/tools/schema.js +0 -25
- package/src/tools/search/anthropic.js +0 -34
- package/src/tools/search/content.js +0 -116
- package/src/tools/search/content.test.js +0 -133
- package/src/tools/search/firecrawl.js +0 -173
- package/src/tools/search/format.js +0 -198
- package/src/tools/search/highlights.js +0 -241
- package/src/tools/search/index.js +0 -3
- package/src/tools/search/jina-reranker.test.js +0 -106
- package/src/tools/search/rerankers.js +0 -165
- package/src/tools/search/schema.js +0 -102
- package/src/tools/search/search.js +0 -561
- package/src/tools/search/serper-scraper.js +0 -126
- package/src/tools/search/test.js +0 -129
- package/src/tools/search/tool.js +0 -453
- package/src/tools/search/types.js +0 -2
- package/src/tools/search/utils.js +0 -59
- package/src/types/graph.js +0 -24
- package/src/types/graph.test.js +0 -192
- package/src/types/index.js +0 -7
- package/src/types/llm.js +0 -2
- package/src/types/messages.js +0 -2
- package/src/types/run.js +0 -2
- package/src/types/stream.js +0 -2
- package/src/types/tools.js +0 -2
- package/src/utils/contextAnalytics.js +0 -79
- package/src/utils/contextAnalytics.test.js +0 -166
- package/src/utils/events.js +0 -26
- package/src/utils/graph.js +0 -11
- package/src/utils/handlers.js +0 -65
- package/src/utils/index.js +0 -10
- package/src/utils/llm.js +0 -21
- package/src/utils/llmConfig.js +0 -205
- package/src/utils/logging.js +0 -37
- package/src/utils/misc.js +0 -51
- package/src/utils/run.js +0 -69
- package/src/utils/schema.js +0 -21
- package/src/utils/title.js +0 -119
- package/src/utils/tokens.js +0 -92
- package/src/utils/toonFormat.js +0 -379
|
@@ -1,233 +0,0 @@
|
|
|
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 '@/tools/Calculator';
|
|
7
|
-
import { HumanMessage, } from '@langchain/core/messages';
|
|
8
|
-
import { ToolEndHandler, ModelEndHandler, createMetadataAggregator, } from '@/events';
|
|
9
|
-
import { ContentTypes, GraphEvents, Providers, TitleMethod } from '@/common';
|
|
10
|
-
import { capitalizeFirstLetter } from './spec.utils';
|
|
11
|
-
import { createContentAggregator } from '@/stream';
|
|
12
|
-
import { getLLMConfig } from '@/utils/llmConfig';
|
|
13
|
-
import { getArgs } from '@/scripts/args';
|
|
14
|
-
import { Run } from '@/run';
|
|
15
|
-
const provider = Providers.OPENAI;
|
|
16
|
-
describe(`${capitalizeFirstLetter(provider)} Streaming Tests`, () => {
|
|
17
|
-
jest.setTimeout(30000);
|
|
18
|
-
let run;
|
|
19
|
-
let runningHistory;
|
|
20
|
-
let collectedUsage;
|
|
21
|
-
let conversationHistory;
|
|
22
|
-
let aggregateContent;
|
|
23
|
-
let contentParts;
|
|
24
|
-
const config = {
|
|
25
|
-
configurable: {
|
|
26
|
-
thread_id: 'conversation-num-1',
|
|
27
|
-
},
|
|
28
|
-
streamMode: 'values',
|
|
29
|
-
version: 'v2',
|
|
30
|
-
};
|
|
31
|
-
beforeEach(async () => {
|
|
32
|
-
conversationHistory = [];
|
|
33
|
-
collectedUsage = [];
|
|
34
|
-
const { contentParts: cp, aggregateContent: ac } = createContentAggregator();
|
|
35
|
-
contentParts = cp;
|
|
36
|
-
aggregateContent = ac;
|
|
37
|
-
});
|
|
38
|
-
const onMessageDeltaSpy = jest.fn();
|
|
39
|
-
const onRunStepSpy = jest.fn();
|
|
40
|
-
afterAll(() => {
|
|
41
|
-
onMessageDeltaSpy.mockReset();
|
|
42
|
-
onRunStepSpy.mockReset();
|
|
43
|
-
});
|
|
44
|
-
const setupCustomHandlers = () => ({
|
|
45
|
-
[GraphEvents.TOOL_END]: new ToolEndHandler(),
|
|
46
|
-
[GraphEvents.CHAT_MODEL_END]: new ModelEndHandler(collectedUsage),
|
|
47
|
-
[GraphEvents.ON_RUN_STEP_COMPLETED]: {
|
|
48
|
-
handle: (event, data) => {
|
|
49
|
-
aggregateContent({
|
|
50
|
-
event,
|
|
51
|
-
data: data,
|
|
52
|
-
});
|
|
53
|
-
},
|
|
54
|
-
},
|
|
55
|
-
[GraphEvents.ON_RUN_STEP]: {
|
|
56
|
-
handle: (event, data, metadata, graph) => {
|
|
57
|
-
onRunStepSpy(event, data, metadata, graph);
|
|
58
|
-
aggregateContent({ event, data: data });
|
|
59
|
-
},
|
|
60
|
-
},
|
|
61
|
-
[GraphEvents.ON_RUN_STEP_DELTA]: {
|
|
62
|
-
handle: (event, data) => {
|
|
63
|
-
aggregateContent({ event, data: data });
|
|
64
|
-
},
|
|
65
|
-
},
|
|
66
|
-
[GraphEvents.ON_MESSAGE_DELTA]: {
|
|
67
|
-
handle: (event, data, metadata, graph) => {
|
|
68
|
-
onMessageDeltaSpy(event, data, metadata, graph);
|
|
69
|
-
aggregateContent({ event, data: data });
|
|
70
|
-
},
|
|
71
|
-
},
|
|
72
|
-
[GraphEvents.TOOL_START]: {
|
|
73
|
-
handle: (_event, _data, _metadata) => {
|
|
74
|
-
// Handle tool start
|
|
75
|
-
},
|
|
76
|
-
},
|
|
77
|
-
});
|
|
78
|
-
test(`${capitalizeFirstLetter(provider)}: should process a simple message, generate title`, async () => {
|
|
79
|
-
const { userName, location } = await getArgs();
|
|
80
|
-
const llmConfig = getLLMConfig(provider);
|
|
81
|
-
const customHandlers = setupCustomHandlers();
|
|
82
|
-
run = await Run.create({
|
|
83
|
-
runId: 'test-run-id',
|
|
84
|
-
graphConfig: {
|
|
85
|
-
type: 'standard',
|
|
86
|
-
llmConfig,
|
|
87
|
-
tools: [new Calculator()],
|
|
88
|
-
instructions: 'You are a friendly AI assistant. Always address the user by their name.',
|
|
89
|
-
additional_instructions: `The user's name is ${userName} and they are located in ${location}.`,
|
|
90
|
-
},
|
|
91
|
-
returnContent: true,
|
|
92
|
-
skipCleanup: true,
|
|
93
|
-
customHandlers,
|
|
94
|
-
});
|
|
95
|
-
const userMessage = 'hi';
|
|
96
|
-
conversationHistory.push(new HumanMessage(userMessage));
|
|
97
|
-
const inputs = {
|
|
98
|
-
messages: conversationHistory,
|
|
99
|
-
};
|
|
100
|
-
const finalContentParts = await run.processStream(inputs, config);
|
|
101
|
-
expect(finalContentParts).toBeDefined();
|
|
102
|
-
const allTextParts = finalContentParts?.every((part) => part.type === ContentTypes.TEXT);
|
|
103
|
-
expect(allTextParts).toBe(true);
|
|
104
|
-
expect(collectedUsage.length).toBeGreaterThan(0);
|
|
105
|
-
expect(collectedUsage[0].input_tokens).toBeGreaterThan(0);
|
|
106
|
-
expect(collectedUsage[0].output_tokens).toBeGreaterThan(0);
|
|
107
|
-
const finalMessages = run.getRunMessages();
|
|
108
|
-
expect(finalMessages).toBeDefined();
|
|
109
|
-
conversationHistory.push(...(finalMessages ?? []));
|
|
110
|
-
expect(conversationHistory.length).toBeGreaterThan(1);
|
|
111
|
-
runningHistory = conversationHistory.slice();
|
|
112
|
-
expect(onMessageDeltaSpy).toHaveBeenCalled();
|
|
113
|
-
expect(onMessageDeltaSpy.mock.calls.length).toBeGreaterThan(1);
|
|
114
|
-
expect(onMessageDeltaSpy.mock.calls[0][3]).toBeDefined(); // Graph exists
|
|
115
|
-
expect(onRunStepSpy).toHaveBeenCalled();
|
|
116
|
-
expect(onRunStepSpy.mock.calls.length).toBeGreaterThan(0);
|
|
117
|
-
expect(onRunStepSpy.mock.calls[0][3]).toBeDefined(); // Graph exists
|
|
118
|
-
const { handleLLMEnd, collected } = createMetadataAggregator();
|
|
119
|
-
const titleResult = await run.generateTitle({
|
|
120
|
-
provider,
|
|
121
|
-
inputText: userMessage,
|
|
122
|
-
titleMethod: TitleMethod.STRUCTURED,
|
|
123
|
-
contentParts,
|
|
124
|
-
chainOptions: {
|
|
125
|
-
callbacks: [
|
|
126
|
-
{
|
|
127
|
-
handleLLMEnd,
|
|
128
|
-
},
|
|
129
|
-
],
|
|
130
|
-
},
|
|
131
|
-
});
|
|
132
|
-
expect(titleResult).toBeDefined();
|
|
133
|
-
expect(titleResult.title).toBeDefined();
|
|
134
|
-
expect(titleResult.language).toBeDefined();
|
|
135
|
-
expect(collected).toBeDefined();
|
|
136
|
-
});
|
|
137
|
-
test(`${capitalizeFirstLetter(provider)}: should generate title using completion method`, async () => {
|
|
138
|
-
const { userName, location } = await getArgs();
|
|
139
|
-
const llmConfig = getLLMConfig(provider);
|
|
140
|
-
const customHandlers = setupCustomHandlers();
|
|
141
|
-
run = await Run.create({
|
|
142
|
-
runId: 'test-run-id-completion',
|
|
143
|
-
graphConfig: {
|
|
144
|
-
type: 'standard',
|
|
145
|
-
llmConfig,
|
|
146
|
-
tools: [new Calculator()],
|
|
147
|
-
instructions: 'You are a friendly AI assistant. Always address the user by their name.',
|
|
148
|
-
additional_instructions: `The user's name is ${userName} and they are located in ${location}.`,
|
|
149
|
-
},
|
|
150
|
-
returnContent: true,
|
|
151
|
-
skipCleanup: true,
|
|
152
|
-
customHandlers,
|
|
153
|
-
});
|
|
154
|
-
const userMessage = 'What is the weather like today?';
|
|
155
|
-
conversationHistory = [];
|
|
156
|
-
conversationHistory.push(new HumanMessage(userMessage));
|
|
157
|
-
const inputs = {
|
|
158
|
-
messages: conversationHistory,
|
|
159
|
-
};
|
|
160
|
-
const finalContentParts = await run.processStream(inputs, config);
|
|
161
|
-
expect(finalContentParts).toBeDefined();
|
|
162
|
-
const { handleLLMEnd, collected } = createMetadataAggregator();
|
|
163
|
-
const titleResult = await run.generateTitle({
|
|
164
|
-
provider,
|
|
165
|
-
inputText: userMessage,
|
|
166
|
-
titleMethod: TitleMethod.COMPLETION, // Using completion method
|
|
167
|
-
contentParts,
|
|
168
|
-
chainOptions: {
|
|
169
|
-
callbacks: [
|
|
170
|
-
{
|
|
171
|
-
handleLLMEnd,
|
|
172
|
-
},
|
|
173
|
-
],
|
|
174
|
-
},
|
|
175
|
-
});
|
|
176
|
-
expect(titleResult).toBeDefined();
|
|
177
|
-
expect(titleResult.title).toBeDefined();
|
|
178
|
-
expect(titleResult.title).not.toBe('');
|
|
179
|
-
// Completion method doesn't return language
|
|
180
|
-
expect(titleResult.language).toBeUndefined();
|
|
181
|
-
expect(collected).toBeDefined();
|
|
182
|
-
console.log(`Completion method generated title: "${titleResult.title}"`);
|
|
183
|
-
});
|
|
184
|
-
test(`${capitalizeFirstLetter(provider)}: should follow-up`, async () => {
|
|
185
|
-
console.log('Previous conversation length:', runningHistory.length);
|
|
186
|
-
console.log('Last message:', runningHistory[runningHistory.length - 1].content);
|
|
187
|
-
const { userName, location } = await getArgs();
|
|
188
|
-
const llmConfig = getLLMConfig(provider);
|
|
189
|
-
const customHandlers = setupCustomHandlers();
|
|
190
|
-
run = await Run.create({
|
|
191
|
-
runId: 'test-run-id',
|
|
192
|
-
graphConfig: {
|
|
193
|
-
type: 'standard',
|
|
194
|
-
llmConfig,
|
|
195
|
-
tools: [new Calculator()],
|
|
196
|
-
instructions: 'You are a friendly AI assistant. Always address the user by their name.',
|
|
197
|
-
additional_instructions: `The user's name is ${userName} and they are located in ${location}.`,
|
|
198
|
-
},
|
|
199
|
-
returnContent: true,
|
|
200
|
-
skipCleanup: true,
|
|
201
|
-
customHandlers,
|
|
202
|
-
});
|
|
203
|
-
conversationHistory = runningHistory.slice();
|
|
204
|
-
conversationHistory.push(new HumanMessage('how are you?'));
|
|
205
|
-
const inputs = {
|
|
206
|
-
messages: conversationHistory,
|
|
207
|
-
};
|
|
208
|
-
const finalContentParts = await run.processStream(inputs, config);
|
|
209
|
-
expect(finalContentParts).toBeDefined();
|
|
210
|
-
const allTextParts = finalContentParts?.every((part) => part.type === ContentTypes.TEXT);
|
|
211
|
-
expect(allTextParts).toBe(true);
|
|
212
|
-
expect(collectedUsage.length).toBeGreaterThan(0);
|
|
213
|
-
expect(collectedUsage[0].input_tokens).toBeGreaterThan(0);
|
|
214
|
-
expect(collectedUsage[0].output_tokens).toBeGreaterThan(0);
|
|
215
|
-
const finalMessages = run.getRunMessages();
|
|
216
|
-
expect(finalMessages).toBeDefined();
|
|
217
|
-
expect(finalMessages?.length).toBeGreaterThan(0);
|
|
218
|
-
console.log(`${capitalizeFirstLetter(provider)} follow-up message:`, finalMessages?.[finalMessages.length - 1]?.content);
|
|
219
|
-
expect(onMessageDeltaSpy).toHaveBeenCalled();
|
|
220
|
-
expect(onMessageDeltaSpy.mock.calls.length).toBeGreaterThan(1);
|
|
221
|
-
expect(onRunStepSpy).toHaveBeenCalled();
|
|
222
|
-
expect(onRunStepSpy.mock.calls.length).toBeGreaterThan(0);
|
|
223
|
-
});
|
|
224
|
-
test('should handle errors appropriately', async () => {
|
|
225
|
-
// Test error scenarios
|
|
226
|
-
await expect(async () => {
|
|
227
|
-
await run.processStream({
|
|
228
|
-
messages: [],
|
|
229
|
-
}, {});
|
|
230
|
-
}).rejects.toThrow();
|
|
231
|
-
});
|
|
232
|
-
});
|
|
233
|
-
//# sourceMappingURL=openai.simple.test.js.map
|
|
@@ -1,202 +0,0 @@
|
|
|
1
|
-
import { config } from 'dotenv';
|
|
2
|
-
config();
|
|
3
|
-
import { Calculator } from '@/tools/Calculator';
|
|
4
|
-
import { HumanMessage, } from '@langchain/core/messages';
|
|
5
|
-
import { ToolEndHandler, ModelEndHandler } from '@/events';
|
|
6
|
-
import { ContentTypes, GraphEvents, Providers, TitleMethod } from '@/common';
|
|
7
|
-
import { capitalizeFirstLetter } from './spec.utils';
|
|
8
|
-
import { createContentAggregator } from '@/stream';
|
|
9
|
-
import { getLLMConfig } from '@/utils/llmConfig';
|
|
10
|
-
import { getArgs } from '@/scripts/args';
|
|
11
|
-
import { Run } from '@/run';
|
|
12
|
-
// Auto-skip if OpenRouter env is missing
|
|
13
|
-
const hasOpenRouter = (process.env.OPENROUTER_API_KEY ?? '').trim() !== '';
|
|
14
|
-
const describeIf = hasOpenRouter ? describe : describe.skip;
|
|
15
|
-
const provider = Providers.OPENROUTER;
|
|
16
|
-
describeIf(`${capitalizeFirstLetter(provider)} Streaming Tests`, () => {
|
|
17
|
-
jest.setTimeout(60000);
|
|
18
|
-
let run;
|
|
19
|
-
let collectedUsage;
|
|
20
|
-
let conversationHistory;
|
|
21
|
-
let contentParts;
|
|
22
|
-
const configV2 = {
|
|
23
|
-
configurable: { thread_id: 'or-convo-1' },
|
|
24
|
-
streamMode: 'values',
|
|
25
|
-
version: 'v2',
|
|
26
|
-
};
|
|
27
|
-
const baseLLMConfig = getLLMConfig(provider);
|
|
28
|
-
beforeEach(async () => {
|
|
29
|
-
conversationHistory = [];
|
|
30
|
-
collectedUsage = [];
|
|
31
|
-
const { contentParts: cp } = createContentAggregator();
|
|
32
|
-
contentParts = cp;
|
|
33
|
-
});
|
|
34
|
-
const onMessageDeltaSpy = jest.fn();
|
|
35
|
-
const onRunStepSpy = jest.fn();
|
|
36
|
-
afterAll(() => {
|
|
37
|
-
onMessageDeltaSpy.mockReset();
|
|
38
|
-
onRunStepSpy.mockReset();
|
|
39
|
-
});
|
|
40
|
-
const setupCustomHandlers = () => ({
|
|
41
|
-
[GraphEvents.TOOL_END]: new ToolEndHandler(),
|
|
42
|
-
[GraphEvents.CHAT_MODEL_END]: new ModelEndHandler(collectedUsage),
|
|
43
|
-
});
|
|
44
|
-
/**
|
|
45
|
-
* Helper: run a reasoning test against a specific model with the given reasoning config.
|
|
46
|
-
* Asserts that reasoning tokens are reported and content is produced.
|
|
47
|
-
*/
|
|
48
|
-
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
|
|
49
|
-
async function runReasoningTest(opts) {
|
|
50
|
-
const { reasoning: _baseReasoning, ...baseWithoutReasoning } = baseLLMConfig;
|
|
51
|
-
const llmConfig = {
|
|
52
|
-
...baseWithoutReasoning,
|
|
53
|
-
model: opts.model,
|
|
54
|
-
...(opts.reasoning != null ? { reasoning: opts.reasoning } : {}),
|
|
55
|
-
};
|
|
56
|
-
const customHandlers = setupCustomHandlers();
|
|
57
|
-
run = await Run.create({
|
|
58
|
-
runId: opts.runId,
|
|
59
|
-
graphConfig: {
|
|
60
|
-
type: 'standard',
|
|
61
|
-
llmConfig,
|
|
62
|
-
instructions: 'You are a helpful AI assistant. Think step by step.',
|
|
63
|
-
},
|
|
64
|
-
returnContent: true,
|
|
65
|
-
skipCleanup: true,
|
|
66
|
-
customHandlers,
|
|
67
|
-
});
|
|
68
|
-
const userMessage = 'What is 15 * 37 + 128 / 4? Show your work.';
|
|
69
|
-
conversationHistory.push(new HumanMessage(userMessage));
|
|
70
|
-
const finalContentParts = await run.processStream({ messages: conversationHistory }, { ...configV2, configurable: { thread_id: opts.threadId } });
|
|
71
|
-
expect(finalContentParts).toBeDefined();
|
|
72
|
-
expect(finalContentParts?.length).toBeGreaterThan(0);
|
|
73
|
-
// Verify usage metadata was collected
|
|
74
|
-
expect(collectedUsage.length).toBeGreaterThan(0);
|
|
75
|
-
const usage = collectedUsage[0];
|
|
76
|
-
expect(usage.input_tokens).toBeGreaterThan(0);
|
|
77
|
-
expect(usage.output_tokens).toBeGreaterThan(0);
|
|
78
|
-
// Verify reasoning tokens are reported in output_token_details
|
|
79
|
-
const reasoningTokens = usage.output_token_details
|
|
80
|
-
?.reasoning ?? 0;
|
|
81
|
-
expect(reasoningTokens).toBeGreaterThan(0);
|
|
82
|
-
// Verify the final message has content
|
|
83
|
-
const finalMessages = run.getRunMessages();
|
|
84
|
-
expect(finalMessages).toBeDefined();
|
|
85
|
-
expect(finalMessages?.length).toBeGreaterThan(0);
|
|
86
|
-
const assistantMsg = finalMessages?.[0];
|
|
87
|
-
expect(typeof assistantMsg?.content).toBe('string');
|
|
88
|
-
expect((assistantMsg?.content).length).toBeGreaterThan(0);
|
|
89
|
-
return { usage, reasoningTokens, finalMessages };
|
|
90
|
-
}
|
|
91
|
-
test(`${capitalizeFirstLetter(provider)}: simple stream + title`, async () => {
|
|
92
|
-
const { userName, location } = await getArgs();
|
|
93
|
-
const customHandlers = setupCustomHandlers();
|
|
94
|
-
run = await Run.create({
|
|
95
|
-
runId: 'or-run-1',
|
|
96
|
-
graphConfig: {
|
|
97
|
-
type: 'standard',
|
|
98
|
-
llmConfig: baseLLMConfig,
|
|
99
|
-
tools: [new Calculator()],
|
|
100
|
-
instructions: 'You are a friendly AI assistant.',
|
|
101
|
-
additional_instructions: `The user's name is ${userName} and they are located in ${location}.`,
|
|
102
|
-
},
|
|
103
|
-
returnContent: true,
|
|
104
|
-
skipCleanup: true,
|
|
105
|
-
customHandlers,
|
|
106
|
-
});
|
|
107
|
-
const userMessage = 'hi';
|
|
108
|
-
conversationHistory.push(new HumanMessage(userMessage));
|
|
109
|
-
const finalContentParts = await run.processStream({ messages: conversationHistory }, configV2);
|
|
110
|
-
expect(finalContentParts).toBeDefined();
|
|
111
|
-
const allTextParts = finalContentParts?.every((part) => part.type === ContentTypes.TEXT);
|
|
112
|
-
expect(allTextParts).toBe(true);
|
|
113
|
-
expect((collectedUsage[0]?.input_tokens ?? 0) +
|
|
114
|
-
(collectedUsage[0]?.output_tokens ?? 0)).toBeGreaterThan(0);
|
|
115
|
-
const finalMessages = run.getRunMessages();
|
|
116
|
-
expect(finalMessages).toBeDefined();
|
|
117
|
-
conversationHistory.push(...(finalMessages ?? []));
|
|
118
|
-
const titleRes = await run.generateTitle({
|
|
119
|
-
provider,
|
|
120
|
-
inputText: userMessage,
|
|
121
|
-
titleMethod: TitleMethod.COMPLETION,
|
|
122
|
-
contentParts,
|
|
123
|
-
});
|
|
124
|
-
expect(titleRes.title).toBeDefined();
|
|
125
|
-
});
|
|
126
|
-
test(`${capitalizeFirstLetter(provider)}: Anthropic does NOT reason by default (no config)`, async () => {
|
|
127
|
-
const { reasoning: _baseReasoning, ...baseWithoutReasoning } = baseLLMConfig;
|
|
128
|
-
const llmConfig = {
|
|
129
|
-
...baseWithoutReasoning,
|
|
130
|
-
model: 'anthropic/claude-sonnet-4',
|
|
131
|
-
};
|
|
132
|
-
const customHandlers = setupCustomHandlers();
|
|
133
|
-
run = await Run.create({
|
|
134
|
-
runId: 'or-anthropic-default-1',
|
|
135
|
-
graphConfig: {
|
|
136
|
-
type: 'standard',
|
|
137
|
-
llmConfig,
|
|
138
|
-
instructions: 'You are a helpful AI assistant.',
|
|
139
|
-
},
|
|
140
|
-
returnContent: true,
|
|
141
|
-
skipCleanup: true,
|
|
142
|
-
customHandlers,
|
|
143
|
-
});
|
|
144
|
-
conversationHistory.push(new HumanMessage('What is 15 * 37 + 128 / 4? Show your work.'));
|
|
145
|
-
await run.processStream({ messages: conversationHistory }, { ...configV2, configurable: { thread_id: 'or-anthropic-default-1' } });
|
|
146
|
-
expect(collectedUsage.length).toBeGreaterThan(0);
|
|
147
|
-
const usage = collectedUsage[0];
|
|
148
|
-
// Anthropic requires explicit reasoning config — no reasoning tokens by default
|
|
149
|
-
const reasoningTokens = usage.output_token_details
|
|
150
|
-
?.reasoning ?? 0;
|
|
151
|
-
expect(reasoningTokens).toBe(0);
|
|
152
|
-
});
|
|
153
|
-
test(`${capitalizeFirstLetter(provider)}: Gemini 3 reasons by default (no config)`, async () => {
|
|
154
|
-
await runReasoningTest({
|
|
155
|
-
model: 'google/gemini-3-pro-preview',
|
|
156
|
-
reasoning: undefined,
|
|
157
|
-
threadId: 'or-gemini-default-1',
|
|
158
|
-
runId: 'or-gemini-default-1',
|
|
159
|
-
});
|
|
160
|
-
});
|
|
161
|
-
test(`${capitalizeFirstLetter(provider)}: Gemini reasoning with max_tokens`, async () => {
|
|
162
|
-
await runReasoningTest({
|
|
163
|
-
model: 'google/gemini-3-pro-preview',
|
|
164
|
-
reasoning: { max_tokens: 4000 },
|
|
165
|
-
threadId: 'or-gemini-reasoning-1',
|
|
166
|
-
runId: 'or-gemini-reasoning-1',
|
|
167
|
-
});
|
|
168
|
-
});
|
|
169
|
-
test(`${capitalizeFirstLetter(provider)}: Gemini reasoning with effort`, async () => {
|
|
170
|
-
await runReasoningTest({
|
|
171
|
-
model: 'google/gemini-3-flash-preview',
|
|
172
|
-
reasoning: { effort: 'low' },
|
|
173
|
-
threadId: 'or-gemini-effort-1',
|
|
174
|
-
runId: 'or-gemini-effort-1',
|
|
175
|
-
});
|
|
176
|
-
});
|
|
177
|
-
test(`${capitalizeFirstLetter(provider)}: Anthropic reasoning with max_tokens`, async () => {
|
|
178
|
-
await runReasoningTest({
|
|
179
|
-
model: 'anthropic/claude-sonnet-4',
|
|
180
|
-
reasoning: { max_tokens: 4000 },
|
|
181
|
-
threadId: 'or-anthropic-reasoning-1',
|
|
182
|
-
runId: 'or-anthropic-reasoning-1',
|
|
183
|
-
});
|
|
184
|
-
});
|
|
185
|
-
test(`${capitalizeFirstLetter(provider)}: Anthropic sonnet-4 reasoning with effort`, async () => {
|
|
186
|
-
await runReasoningTest({
|
|
187
|
-
model: 'anthropic/claude-sonnet-4',
|
|
188
|
-
reasoning: { effort: 'medium' },
|
|
189
|
-
threadId: 'or-anthropic-effort-s4-1',
|
|
190
|
-
runId: 'or-anthropic-effort-s4-1',
|
|
191
|
-
});
|
|
192
|
-
});
|
|
193
|
-
test(`${capitalizeFirstLetter(provider)}: Anthropic sonnet-4-6 reasoning with effort`, async () => {
|
|
194
|
-
await runReasoningTest({
|
|
195
|
-
model: 'anthropic/claude-sonnet-4-6',
|
|
196
|
-
reasoning: { effort: 'medium' },
|
|
197
|
-
threadId: 'or-anthropic-effort-s46-1',
|
|
198
|
-
runId: 'or-anthropic-effort-s46-1',
|
|
199
|
-
});
|
|
200
|
-
});
|
|
201
|
-
});
|
|
202
|
-
//# sourceMappingURL=openrouter.simple.test.js.map
|