illuma-agents 1.0.8 → 1.0.10
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/LICENSE +1 -5
- package/dist/cjs/common/enum.cjs +1 -2
- package/dist/cjs/common/enum.cjs.map +1 -1
- package/dist/cjs/events.cjs +11 -0
- package/dist/cjs/events.cjs.map +1 -1
- package/dist/cjs/graphs/Graph.cjs +2 -1
- package/dist/cjs/graphs/Graph.cjs.map +1 -1
- package/dist/cjs/instrumentation.cjs +3 -1
- package/dist/cjs/instrumentation.cjs.map +1 -1
- package/dist/cjs/llm/anthropic/types.cjs.map +1 -1
- package/dist/cjs/llm/anthropic/utils/message_inputs.cjs +79 -2
- package/dist/cjs/llm/anthropic/utils/message_inputs.cjs.map +1 -1
- package/dist/cjs/llm/anthropic/utils/tools.cjs.map +1 -1
- package/dist/cjs/llm/bedrock/index.cjs +99 -0
- package/dist/cjs/llm/bedrock/index.cjs.map +1 -0
- package/dist/cjs/llm/fake.cjs.map +1 -1
- package/dist/cjs/llm/openai/index.cjs +102 -0
- package/dist/cjs/llm/openai/index.cjs.map +1 -1
- package/dist/cjs/llm/openai/utils/index.cjs +87 -1
- package/dist/cjs/llm/openai/utils/index.cjs.map +1 -1
- package/dist/cjs/llm/openrouter/index.cjs +175 -1
- package/dist/cjs/llm/openrouter/index.cjs.map +1 -1
- package/dist/cjs/llm/providers.cjs +13 -16
- package/dist/cjs/llm/providers.cjs.map +1 -1
- package/dist/cjs/llm/text.cjs.map +1 -1
- package/dist/cjs/messages/core.cjs +14 -14
- package/dist/cjs/messages/core.cjs.map +1 -1
- package/dist/cjs/messages/ids.cjs.map +1 -1
- package/dist/cjs/messages/prune.cjs.map +1 -1
- package/dist/cjs/run.cjs +18 -1
- package/dist/cjs/run.cjs.map +1 -1
- package/dist/cjs/splitStream.cjs.map +1 -1
- package/dist/cjs/stream.cjs +24 -1
- package/dist/cjs/stream.cjs.map +1 -1
- package/dist/cjs/tools/ToolNode.cjs +20 -1
- package/dist/cjs/tools/ToolNode.cjs.map +1 -1
- package/dist/cjs/tools/handlers.cjs +29 -25
- package/dist/cjs/tools/handlers.cjs.map +1 -1
- package/dist/cjs/tools/search/anthropic.cjs.map +1 -1
- package/dist/cjs/tools/search/content.cjs.map +1 -1
- package/dist/cjs/tools/search/firecrawl.cjs.map +1 -1
- package/dist/cjs/tools/search/format.cjs.map +1 -1
- package/dist/cjs/tools/search/highlights.cjs.map +1 -1
- package/dist/cjs/tools/search/rerankers.cjs.map +1 -1
- package/dist/cjs/tools/search/schema.cjs +27 -25
- package/dist/cjs/tools/search/schema.cjs.map +1 -1
- package/dist/cjs/tools/search/search.cjs +6 -1
- package/dist/cjs/tools/search/search.cjs.map +1 -1
- package/dist/cjs/tools/search/serper-scraper.cjs.map +1 -1
- package/dist/cjs/tools/search/tool.cjs +182 -35
- package/dist/cjs/tools/search/tool.cjs.map +1 -1
- package/dist/cjs/tools/search/utils.cjs.map +1 -1
- package/dist/cjs/utils/graph.cjs.map +1 -1
- package/dist/cjs/utils/llm.cjs +0 -1
- package/dist/cjs/utils/llm.cjs.map +1 -1
- package/dist/cjs/utils/misc.cjs.map +1 -1
- package/dist/cjs/utils/run.cjs.map +1 -1
- package/dist/cjs/utils/title.cjs +7 -7
- package/dist/cjs/utils/title.cjs.map +1 -1
- package/dist/esm/common/enum.mjs +1 -2
- package/dist/esm/common/enum.mjs.map +1 -1
- package/dist/esm/events.mjs +11 -0
- package/dist/esm/events.mjs.map +1 -1
- package/dist/esm/graphs/Graph.mjs +2 -1
- package/dist/esm/graphs/Graph.mjs.map +1 -1
- package/dist/esm/instrumentation.mjs +3 -1
- package/dist/esm/instrumentation.mjs.map +1 -1
- package/dist/esm/llm/anthropic/types.mjs.map +1 -1
- package/dist/esm/llm/anthropic/utils/message_inputs.mjs +79 -2
- package/dist/esm/llm/anthropic/utils/message_inputs.mjs.map +1 -1
- package/dist/esm/llm/anthropic/utils/tools.mjs.map +1 -1
- package/dist/esm/llm/bedrock/index.mjs +97 -0
- package/dist/esm/llm/bedrock/index.mjs.map +1 -0
- package/dist/esm/llm/fake.mjs.map +1 -1
- package/dist/esm/llm/openai/index.mjs +103 -1
- package/dist/esm/llm/openai/index.mjs.map +1 -1
- package/dist/esm/llm/openai/utils/index.mjs +88 -2
- package/dist/esm/llm/openai/utils/index.mjs.map +1 -1
- package/dist/esm/llm/openrouter/index.mjs +175 -1
- package/dist/esm/llm/openrouter/index.mjs.map +1 -1
- package/dist/esm/llm/providers.mjs +2 -5
- package/dist/esm/llm/providers.mjs.map +1 -1
- package/dist/esm/llm/text.mjs.map +1 -1
- package/dist/esm/messages/core.mjs +14 -14
- package/dist/esm/messages/core.mjs.map +1 -1
- package/dist/esm/messages/ids.mjs.map +1 -1
- package/dist/esm/messages/prune.mjs.map +1 -1
- package/dist/esm/run.mjs +18 -1
- package/dist/esm/run.mjs.map +1 -1
- package/dist/esm/splitStream.mjs.map +1 -1
- package/dist/esm/stream.mjs +24 -1
- package/dist/esm/stream.mjs.map +1 -1
- package/dist/esm/tools/ToolNode.mjs +20 -1
- package/dist/esm/tools/ToolNode.mjs.map +1 -1
- package/dist/esm/tools/handlers.mjs +30 -26
- package/dist/esm/tools/handlers.mjs.map +1 -1
- package/dist/esm/tools/search/anthropic.mjs.map +1 -1
- package/dist/esm/tools/search/content.mjs.map +1 -1
- package/dist/esm/tools/search/firecrawl.mjs.map +1 -1
- package/dist/esm/tools/search/format.mjs.map +1 -1
- package/dist/esm/tools/search/highlights.mjs.map +1 -1
- package/dist/esm/tools/search/rerankers.mjs.map +1 -1
- package/dist/esm/tools/search/schema.mjs +27 -25
- package/dist/esm/tools/search/schema.mjs.map +1 -1
- package/dist/esm/tools/search/search.mjs +6 -1
- package/dist/esm/tools/search/search.mjs.map +1 -1
- package/dist/esm/tools/search/serper-scraper.mjs.map +1 -1
- package/dist/esm/tools/search/tool.mjs +182 -35
- package/dist/esm/tools/search/tool.mjs.map +1 -1
- package/dist/esm/tools/search/utils.mjs.map +1 -1
- package/dist/esm/utils/graph.mjs.map +1 -1
- package/dist/esm/utils/llm.mjs +0 -1
- package/dist/esm/utils/llm.mjs.map +1 -1
- package/dist/esm/utils/misc.mjs.map +1 -1
- package/dist/esm/utils/run.mjs.map +1 -1
- package/dist/esm/utils/title.mjs +7 -7
- package/dist/esm/utils/title.mjs.map +1 -1
- package/dist/types/common/enum.d.ts +1 -2
- package/dist/types/llm/bedrock/index.d.ts +36 -0
- package/dist/types/llm/openai/index.d.ts +1 -0
- package/dist/types/llm/openai/utils/index.d.ts +10 -1
- package/dist/types/llm/openrouter/index.d.ts +4 -1
- package/dist/types/tools/search/types.d.ts +2 -0
- package/dist/types/types/llm.d.ts +3 -8
- package/package.json +16 -12
- package/src/common/enum.ts +1 -2
- package/src/common/index.ts +1 -1
- package/src/events.ts +11 -0
- package/src/graphs/Graph.ts +2 -1
- package/src/instrumentation.ts +25 -22
- package/src/llm/anthropic/llm.spec.ts +1442 -1442
- package/src/llm/anthropic/types.ts +140 -140
- package/src/llm/anthropic/utils/message_inputs.ts +757 -660
- package/src/llm/anthropic/utils/output_parsers.ts +133 -133
- package/src/llm/anthropic/utils/tools.ts +29 -29
- package/src/llm/bedrock/index.ts +128 -0
- package/src/llm/fake.ts +133 -133
- package/src/llm/google/llm.spec.ts +3 -1
- package/src/llm/google/utils/tools.ts +160 -160
- package/src/llm/openai/index.ts +126 -0
- package/src/llm/openai/types.ts +24 -24
- package/src/llm/openai/utils/index.ts +116 -1
- package/src/llm/openai/utils/isReasoningModel.test.ts +90 -90
- package/src/llm/openrouter/index.ts +222 -1
- package/src/llm/providers.ts +2 -7
- package/src/llm/text.ts +94 -94
- package/src/messages/core.ts +463 -463
- package/src/messages/formatAgentMessages.tools.test.ts +400 -400
- package/src/messages/formatMessage.test.ts +693 -693
- package/src/messages/ids.ts +26 -26
- package/src/messages/prune.ts +567 -567
- package/src/messages/shiftIndexTokenCountMap.test.ts +81 -81
- package/src/mockStream.ts +98 -98
- package/src/prompts/collab.ts +5 -5
- package/src/prompts/index.ts +1 -1
- package/src/prompts/taskmanager.ts +61 -61
- package/src/run.ts +22 -4
- package/src/scripts/ant_web_search_edge_case.ts +162 -0
- package/src/scripts/ant_web_search_error_edge_case.ts +148 -0
- package/src/scripts/args.ts +48 -48
- package/src/scripts/caching.ts +123 -123
- package/src/scripts/code_exec_files.ts +193 -193
- package/src/scripts/empty_input.ts +137 -137
- package/src/scripts/memory.ts +97 -97
- package/src/scripts/test-tools-before-handoff.ts +1 -5
- package/src/scripts/thinking.ts +149 -149
- package/src/scripts/tools.ts +1 -4
- package/src/specs/anthropic.simple.test.ts +67 -0
- package/src/specs/spec.utils.ts +3 -3
- package/src/specs/token-distribution-edge-case.test.ts +316 -316
- package/src/specs/tool-error.test.ts +193 -193
- package/src/splitStream.test.ts +691 -691
- package/src/splitStream.ts +234 -234
- package/src/stream.test.ts +94 -94
- package/src/stream.ts +30 -1
- package/src/tools/ToolNode.ts +24 -1
- package/src/tools/handlers.ts +32 -28
- package/src/tools/search/anthropic.ts +51 -51
- package/src/tools/search/content.test.ts +173 -173
- package/src/tools/search/content.ts +147 -147
- package/src/tools/search/direct-url.test.ts +530 -0
- package/src/tools/search/firecrawl.ts +210 -210
- package/src/tools/search/format.ts +250 -250
- package/src/tools/search/highlights.ts +320 -320
- package/src/tools/search/index.ts +2 -2
- package/src/tools/search/jina-reranker.test.ts +126 -126
- package/src/tools/search/output.md +2775 -2775
- package/src/tools/search/rerankers.ts +242 -242
- package/src/tools/search/schema.ts +65 -63
- package/src/tools/search/search.ts +766 -759
- package/src/tools/search/serper-scraper.ts +155 -155
- package/src/tools/search/test.html +883 -883
- package/src/tools/search/test.md +642 -642
- package/src/tools/search/test.ts +159 -159
- package/src/tools/search/tool.ts +641 -471
- package/src/tools/search/types.ts +689 -687
- package/src/tools/search/utils.ts +79 -79
- package/src/types/index.ts +6 -6
- package/src/types/llm.ts +2 -8
- package/src/utils/graph.ts +10 -10
- package/src/utils/llm.ts +26 -27
- package/src/utils/llmConfig.ts +13 -5
- package/src/utils/logging.ts +48 -48
- package/src/utils/misc.ts +57 -57
- package/src/utils/run.ts +100 -100
- package/src/utils/title.ts +165 -165
- package/dist/cjs/llm/ollama/index.cjs +0 -70
- package/dist/cjs/llm/ollama/index.cjs.map +0 -1
- package/dist/cjs/llm/ollama/utils.cjs +0 -158
- package/dist/cjs/llm/ollama/utils.cjs.map +0 -1
- package/dist/esm/llm/ollama/index.mjs +0 -68
- package/dist/esm/llm/ollama/index.mjs.map +0 -1
- package/dist/esm/llm/ollama/utils.mjs +0 -155
- package/dist/esm/llm/ollama/utils.mjs.map +0 -1
- package/dist/types/llm/ollama/index.d.ts +0 -8
- package/dist/types/llm/ollama/utils.d.ts +0 -7
- package/src/llm/ollama/index.ts +0 -92
- package/src/llm/ollama/utils.ts +0 -193
- package/src/proto/CollabGraph.ts +0 -269
- package/src/proto/TaskManager.ts +0 -243
- package/src/proto/collab.ts +0 -200
- package/src/proto/collab_design.ts +0 -184
- package/src/proto/collab_design_v2.ts +0 -224
- package/src/proto/collab_design_v3.ts +0 -255
- package/src/proto/collab_design_v4.ts +0 -220
- package/src/proto/collab_design_v5.ts +0 -251
- package/src/proto/collab_graph.ts +0 -181
- package/src/proto/collab_original.ts +0 -123
- package/src/proto/example.ts +0 -93
- package/src/proto/example_new.ts +0 -68
- package/src/proto/example_old.ts +0 -201
- package/src/proto/example_test.ts +0 -152
- package/src/proto/example_test_anthropic.ts +0 -100
- package/src/proto/log_stream.ts +0 -202
- package/src/proto/main_collab_community_event.ts +0 -133
- package/src/proto/main_collab_design_v2.ts +0 -96
- package/src/proto/main_collab_design_v4.ts +0 -100
- package/src/proto/main_collab_design_v5.ts +0 -135
- package/src/proto/main_collab_global_analysis.ts +0 -122
- package/src/proto/main_collab_hackathon_event.ts +0 -153
- package/src/proto/main_collab_space_mission.ts +0 -153
- package/src/proto/main_philosophy.ts +0 -210
- package/src/proto/original_script.ts +0 -126
- package/src/proto/standard.ts +0 -100
- package/src/proto/stream.ts +0 -56
- package/src/proto/tasks.ts +0 -118
- package/src/proto/tools/global_analysis_tools.ts +0 -86
- package/src/proto/tools/space_mission_tools.ts +0 -60
- package/src/proto/vertexai.ts +0 -54
- package/src/scripts/image.ts +0 -178
package/src/scripts/memory.ts
CHANGED
|
@@ -1,97 +1,97 @@
|
|
|
1
|
-
// src/scripts/cli.ts
|
|
2
|
-
import { config } from 'dotenv';
|
|
3
|
-
config();
|
|
4
|
-
|
|
5
|
-
import z from 'zod';
|
|
6
|
-
import { tool } from '@langchain/core/tools';
|
|
7
|
-
import { HumanMessage, BaseMessage } from '@langchain/core/messages';
|
|
8
|
-
import type * as t from '@/types';
|
|
9
|
-
import { getArgs } from '@/scripts/args';
|
|
10
|
-
import { Providers } from '@/common';
|
|
11
|
-
import { Run } from '@/run';
|
|
12
|
-
|
|
13
|
-
const conversationHistory: BaseMessage[] = [];
|
|
14
|
-
|
|
15
|
-
const memoryKv: Record<string, string> = {};
|
|
16
|
-
|
|
17
|
-
const setMemory = tool(
|
|
18
|
-
async ({ key, value }) => {
|
|
19
|
-
if (!/^[a-z_]+$/.test(key)) {
|
|
20
|
-
throw new Error('Key must only contain lowercase letters and underscores');
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
memoryKv[key] = value;
|
|
24
|
-
|
|
25
|
-
return { ok: true };
|
|
26
|
-
},
|
|
27
|
-
{
|
|
28
|
-
name: 'set_memory',
|
|
29
|
-
description: 'Saves important data about the user into memory.',
|
|
30
|
-
schema: z.object({
|
|
31
|
-
key: z.string().describe('The key of the memory value. Always use lowercase and underscores, no other characters.'),
|
|
32
|
-
value: z.string().describe('Value can be anything represented as a string')
|
|
33
|
-
}),
|
|
34
|
-
}
|
|
35
|
-
);
|
|
36
|
-
|
|
37
|
-
async function testStandardStreaming(): Promise<void> {
|
|
38
|
-
const { userName, provider } = await getArgs();
|
|
39
|
-
|
|
40
|
-
const run = await Run.create<t.IState>({
|
|
41
|
-
runId: 'memory-run',
|
|
42
|
-
graphConfig: {
|
|
43
|
-
type: 'standard',
|
|
44
|
-
llmConfig: {
|
|
45
|
-
provider: Providers.OPENAI,
|
|
46
|
-
model: 'gpt-4o-mini',
|
|
47
|
-
temperature: 0.5,
|
|
48
|
-
streaming: false,
|
|
49
|
-
},
|
|
50
|
-
tools: [setMemory],
|
|
51
|
-
instructions: 'You can use the `set_memory` tool to save important data about the user into memory. If there is nothing to note about the user specifically, respond with `nothing`.',
|
|
52
|
-
toolEnd: true,
|
|
53
|
-
},
|
|
54
|
-
returnContent: true,
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
const config = {
|
|
58
|
-
configurable: {
|
|
59
|
-
provider,
|
|
60
|
-
thread_id: 'conversation-num-1',
|
|
61
|
-
},
|
|
62
|
-
streamMode: 'values',
|
|
63
|
-
version: 'v2' as const,
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
console.log('Test 1: Simple message test');
|
|
67
|
-
|
|
68
|
-
const userMessage = `hi`;
|
|
69
|
-
|
|
70
|
-
conversationHistory.push(new HumanMessage(userMessage));
|
|
71
|
-
|
|
72
|
-
const inputs = {
|
|
73
|
-
messages: conversationHistory,
|
|
74
|
-
};
|
|
75
|
-
await run.processStream(inputs, config);
|
|
76
|
-
const finalMessages = run.getRunMessages();
|
|
77
|
-
if (finalMessages) {
|
|
78
|
-
conversationHistory.push(...finalMessages);
|
|
79
|
-
console.dir(conversationHistory, { depth: null });
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
console.log('\n\n====================\n\n');
|
|
83
|
-
console.dir(memoryKv, { depth: null });
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
process.on('unhandledRejection', (reason, promise) => {
|
|
87
|
-
console.error('Unhandled Rejection at:', promise, 'reason:', reason);
|
|
88
|
-
console.log('Conversation history:');
|
|
89
|
-
process.exit(1);
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
testStandardStreaming().catch((err) => {
|
|
93
|
-
console.error(err);
|
|
94
|
-
console.log('Conversation history:');
|
|
95
|
-
console.dir(conversationHistory, { depth: null });
|
|
96
|
-
process.exit(1);
|
|
97
|
-
});
|
|
1
|
+
// src/scripts/cli.ts
|
|
2
|
+
import { config } from 'dotenv';
|
|
3
|
+
config();
|
|
4
|
+
|
|
5
|
+
import z from 'zod';
|
|
6
|
+
import { tool } from '@langchain/core/tools';
|
|
7
|
+
import { HumanMessage, BaseMessage } from '@langchain/core/messages';
|
|
8
|
+
import type * as t from '@/types';
|
|
9
|
+
import { getArgs } from '@/scripts/args';
|
|
10
|
+
import { Providers } from '@/common';
|
|
11
|
+
import { Run } from '@/run';
|
|
12
|
+
|
|
13
|
+
const conversationHistory: BaseMessage[] = [];
|
|
14
|
+
|
|
15
|
+
const memoryKv: Record<string, string> = {};
|
|
16
|
+
|
|
17
|
+
const setMemory = tool(
|
|
18
|
+
async ({ key, value }) => {
|
|
19
|
+
if (!/^[a-z_]+$/.test(key)) {
|
|
20
|
+
throw new Error('Key must only contain lowercase letters and underscores');
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
memoryKv[key] = value;
|
|
24
|
+
|
|
25
|
+
return { ok: true };
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
name: 'set_memory',
|
|
29
|
+
description: 'Saves important data about the user into memory.',
|
|
30
|
+
schema: z.object({
|
|
31
|
+
key: z.string().describe('The key of the memory value. Always use lowercase and underscores, no other characters.'),
|
|
32
|
+
value: z.string().describe('Value can be anything represented as a string')
|
|
33
|
+
}),
|
|
34
|
+
}
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
async function testStandardStreaming(): Promise<void> {
|
|
38
|
+
const { userName, provider } = await getArgs();
|
|
39
|
+
|
|
40
|
+
const run = await Run.create<t.IState>({
|
|
41
|
+
runId: 'memory-run',
|
|
42
|
+
graphConfig: {
|
|
43
|
+
type: 'standard',
|
|
44
|
+
llmConfig: {
|
|
45
|
+
provider: Providers.OPENAI,
|
|
46
|
+
model: 'gpt-4o-mini',
|
|
47
|
+
temperature: 0.5,
|
|
48
|
+
streaming: false,
|
|
49
|
+
},
|
|
50
|
+
tools: [setMemory],
|
|
51
|
+
instructions: 'You can use the `set_memory` tool to save important data about the user into memory. If there is nothing to note about the user specifically, respond with `nothing`.',
|
|
52
|
+
toolEnd: true,
|
|
53
|
+
},
|
|
54
|
+
returnContent: true,
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
const config = {
|
|
58
|
+
configurable: {
|
|
59
|
+
provider,
|
|
60
|
+
thread_id: 'conversation-num-1',
|
|
61
|
+
},
|
|
62
|
+
streamMode: 'values',
|
|
63
|
+
version: 'v2' as const,
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
console.log('Test 1: Simple message test');
|
|
67
|
+
|
|
68
|
+
const userMessage = `hi`;
|
|
69
|
+
|
|
70
|
+
conversationHistory.push(new HumanMessage(userMessage));
|
|
71
|
+
|
|
72
|
+
const inputs = {
|
|
73
|
+
messages: conversationHistory,
|
|
74
|
+
};
|
|
75
|
+
await run.processStream(inputs, config);
|
|
76
|
+
const finalMessages = run.getRunMessages();
|
|
77
|
+
if (finalMessages) {
|
|
78
|
+
conversationHistory.push(...finalMessages);
|
|
79
|
+
console.dir(conversationHistory, { depth: null });
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
console.log('\n\n====================\n\n');
|
|
83
|
+
console.dir(memoryKv, { depth: null });
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
process.on('unhandledRejection', (reason, promise) => {
|
|
87
|
+
console.error('Unhandled Rejection at:', promise, 'reason:', reason);
|
|
88
|
+
console.log('Conversation history:');
|
|
89
|
+
process.exit(1);
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
testStandardStreaming().catch((err) => {
|
|
93
|
+
console.error(err);
|
|
94
|
+
console.log('Conversation history:');
|
|
95
|
+
console.dir(conversationHistory, { depth: null });
|
|
96
|
+
process.exit(1);
|
|
97
|
+
});
|
|
@@ -5,7 +5,7 @@ import { HumanMessage, BaseMessage } from '@langchain/core/messages';
|
|
|
5
5
|
import { Run } from '@/run';
|
|
6
6
|
import { Providers, GraphEvents } from '@/common';
|
|
7
7
|
import { ChatModelStreamHandler, createContentAggregator } from '@/stream';
|
|
8
|
-
import {
|
|
8
|
+
import { ModelEndHandler } from '@/events';
|
|
9
9
|
import type * as t from '@/types';
|
|
10
10
|
|
|
11
11
|
const conversationHistory: BaseMessage[] = [];
|
|
@@ -28,10 +28,6 @@ async function testToolsBeforeHandoff() {
|
|
|
28
28
|
|
|
29
29
|
// Create custom handlers
|
|
30
30
|
const customHandlers = {
|
|
31
|
-
[GraphEvents.TOOL_END]: new ToolEndHandler(undefined, (name?: string) => {
|
|
32
|
-
console.log(`\n✅ Tool completed: ${name}`);
|
|
33
|
-
return true;
|
|
34
|
-
}),
|
|
35
31
|
[GraphEvents.CHAT_MODEL_END]: new ModelEndHandler(),
|
|
36
32
|
[GraphEvents.CHAT_MODEL_STREAM]: new ChatModelStreamHandler(),
|
|
37
33
|
[GraphEvents.ON_RUN_STEP]: {
|
package/src/scripts/thinking.ts
CHANGED
|
@@ -1,150 +1,150 @@
|
|
|
1
|
-
// src/scripts/test-thinking.ts
|
|
2
|
-
import { config } from 'dotenv';
|
|
3
|
-
config();
|
|
4
|
-
import { HumanMessage, SystemMessage, BaseMessage } from '@langchain/core/messages';
|
|
5
|
-
import type { UsageMetadata } from '@langchain/core/messages';
|
|
6
|
-
import * as t from '@/types';
|
|
7
|
-
import { ChatModelStreamHandler, createContentAggregator } from '@/stream';
|
|
8
|
-
import { createCodeExecutionTool } from '@/tools/CodeExecutor';
|
|
9
|
-
import { ToolEndHandler, ModelEndHandler } from '@/events';
|
|
10
|
-
import { GraphEvents, Providers } from '@/common';
|
|
11
|
-
import { getLLMConfig } from '@/utils/llmConfig';
|
|
12
|
-
import { getArgs } from '@/scripts/args';
|
|
13
|
-
import { Run } from '@/run';
|
|
14
|
-
|
|
15
|
-
const conversationHistory: BaseMessage[] = [];
|
|
16
|
-
let _contentParts: t.MessageContentComplex[] = [];
|
|
17
|
-
const collectedUsage: UsageMetadata[] = [];
|
|
18
|
-
|
|
19
|
-
async function testThinking(): Promise<void> {
|
|
20
|
-
const { userName } = await getArgs();
|
|
21
|
-
const instructions = `You are a helpful AI assistant for ${userName}. When answering questions, be thorough in your reasoning.`;
|
|
22
|
-
const { contentParts, aggregateContent } = createContentAggregator();
|
|
23
|
-
_contentParts = contentParts as t.MessageContentComplex[];
|
|
24
|
-
|
|
25
|
-
// Set up event handlers
|
|
26
|
-
const customHandlers = {
|
|
27
|
-
[GraphEvents.TOOL_END]: new ToolEndHandler(),
|
|
28
|
-
[GraphEvents.CHAT_MODEL_END]: new ModelEndHandler(collectedUsage),
|
|
29
|
-
[GraphEvents.CHAT_MODEL_STREAM]: new ChatModelStreamHandler(),
|
|
30
|
-
[GraphEvents.ON_RUN_STEP_COMPLETED]: {
|
|
31
|
-
handle: (event: GraphEvents.ON_RUN_STEP_COMPLETED, data: t.StreamEventData): void => {
|
|
32
|
-
console.log('====== ON_RUN_STEP_COMPLETED ======');
|
|
33
|
-
aggregateContent({ event, data: data as unknown as { result: t.ToolEndEvent } });
|
|
34
|
-
}
|
|
35
|
-
},
|
|
36
|
-
[GraphEvents.ON_RUN_STEP]: {
|
|
37
|
-
handle: (event: GraphEvents.ON_RUN_STEP, data: t.RunStep) => {
|
|
38
|
-
aggregateContent({ event, data });
|
|
39
|
-
},
|
|
40
|
-
},
|
|
41
|
-
[GraphEvents.ON_RUN_STEP_DELTA]: {
|
|
42
|
-
handle: (event: GraphEvents.ON_RUN_STEP_DELTA, data: t.RunStepDeltaEvent) => {
|
|
43
|
-
aggregateContent({ event, data });
|
|
44
|
-
},
|
|
45
|
-
},
|
|
46
|
-
[GraphEvents.ON_MESSAGE_DELTA]: {
|
|
47
|
-
handle: (event: GraphEvents.ON_MESSAGE_DELTA, data: t.MessageDeltaEvent) => {
|
|
48
|
-
aggregateContent({ event, data });
|
|
49
|
-
},
|
|
50
|
-
},
|
|
51
|
-
[GraphEvents.ON_REASONING_DELTA]: {
|
|
52
|
-
handle: (event: GraphEvents.ON_REASONING_DELTA, data: t.ReasoningDeltaEvent) => {
|
|
53
|
-
aggregateContent({ event, data });
|
|
54
|
-
},
|
|
55
|
-
},
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
const baseLlmConfig: t.LLMConfig = getLLMConfig(Providers.ANTHROPIC);
|
|
59
|
-
|
|
60
|
-
// Enable thinking with token budget
|
|
61
|
-
const llmConfig = {
|
|
62
|
-
...baseLlmConfig,
|
|
63
|
-
model: 'claude-3-7-sonnet-latest',
|
|
64
|
-
thinking: { type: "enabled", budget_tokens: 2000 }
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
const run = await Run.create<t.IState>({
|
|
68
|
-
runId: 'test-thinking-id',
|
|
69
|
-
graphConfig: {
|
|
70
|
-
instructions,
|
|
71
|
-
type: 'standard',
|
|
72
|
-
tools: [createCodeExecutionTool()],
|
|
73
|
-
llmConfig,
|
|
74
|
-
},
|
|
75
|
-
returnContent: true,
|
|
76
|
-
customHandlers: customHandlers as t.RunConfig['customHandlers'],
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
const config = {
|
|
80
|
-
configurable: {
|
|
81
|
-
thread_id: 'thinking-test-thread',
|
|
82
|
-
},
|
|
83
|
-
streamMode: 'values',
|
|
84
|
-
version: 'v2' as const,
|
|
85
|
-
};
|
|
86
|
-
|
|
87
|
-
// Test 1: Regular thinking mode
|
|
88
|
-
console.log('\n\nTest 1: Regular thinking mode');
|
|
89
|
-
// const userMessage1 = `What would be the environmental and economic impacts if all cars globally were replaced by electric vehicles overnight?`;
|
|
90
|
-
const userMessage1 = `Please print 'hello world' in python`;
|
|
91
|
-
conversationHistory.push(new HumanMessage(userMessage1));
|
|
92
|
-
|
|
93
|
-
console.log('Running first query with thinking enabled...');
|
|
94
|
-
const firstInputs = { messages: [...conversationHistory] };
|
|
95
|
-
await run.processStream(firstInputs, config);
|
|
96
|
-
|
|
97
|
-
// Extract and display thinking blocks
|
|
98
|
-
const finalMessages = run.getRunMessages();
|
|
99
|
-
|
|
100
|
-
// Test 2: Try multi-turn conversation
|
|
101
|
-
console.log('\n\nTest 2: Multi-turn conversation with thinking enabled');
|
|
102
|
-
const userMessage2 = `Given your previous analysis, what would be the most significant technical challenges in making this transition?`;
|
|
103
|
-
conversationHistory.push(new HumanMessage(userMessage2));
|
|
104
|
-
|
|
105
|
-
console.log('Running second query with thinking enabled...');
|
|
106
|
-
const secondInputs = { messages: [...conversationHistory] };
|
|
107
|
-
await run.processStream(secondInputs, config);
|
|
108
|
-
|
|
109
|
-
// Display thinking blocks for second response
|
|
110
|
-
const finalMessages2 = run.getRunMessages();
|
|
111
|
-
|
|
112
|
-
// Test 3: Redacted thinking mode
|
|
113
|
-
console.log('\n\nTest 3: Redacted thinking mode');
|
|
114
|
-
const magicString = "ANTHROPIC_MAGIC_STRING_TRIGGER_REDACTED_THINKING_46C9A13E193C177646C7398A98432ECCCE4C1253D5E2D82641AC0E52CC2876CB";
|
|
115
|
-
const userMessage3 = `${magicString}\n\nExplain how quantum computing works in simple terms.`;
|
|
116
|
-
|
|
117
|
-
// Reset conversation for clean test
|
|
118
|
-
conversationHistory.length = 0;
|
|
119
|
-
conversationHistory.push(new HumanMessage(userMessage3));
|
|
120
|
-
|
|
121
|
-
console.log('Running query with redacted thinking...');
|
|
122
|
-
const thirdInputs = { messages: [...conversationHistory] };
|
|
123
|
-
await run.processStream(thirdInputs, config);
|
|
124
|
-
|
|
125
|
-
// Display redacted thinking blocks
|
|
126
|
-
const finalMessages3 = run.getRunMessages();
|
|
127
|
-
console.log('\n\nThinking feature test completed!');
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
process.on('unhandledRejection', (reason, promise) => {
|
|
131
|
-
console.error('Unhandled Rejection at:', promise, 'reason:', reason);
|
|
132
|
-
console.log('Conversation history:');
|
|
133
|
-
console.dir(conversationHistory, { depth: null });
|
|
134
|
-
console.log('Content parts:');
|
|
135
|
-
console.dir(_contentParts, { depth: null });
|
|
136
|
-
process.exit(1);
|
|
137
|
-
});
|
|
138
|
-
|
|
139
|
-
process.on('uncaughtException', (err) => {
|
|
140
|
-
console.error('Uncaught Exception:', err);
|
|
141
|
-
});
|
|
142
|
-
|
|
143
|
-
testThinking().catch((err) => {
|
|
144
|
-
console.error(err);
|
|
145
|
-
console.log('Conversation history:');
|
|
146
|
-
console.dir(conversationHistory, { depth: null });
|
|
147
|
-
console.log('Content parts:');
|
|
148
|
-
console.dir(_contentParts, { depth: null });
|
|
149
|
-
process.exit(1);
|
|
1
|
+
// src/scripts/test-thinking.ts
|
|
2
|
+
import { config } from 'dotenv';
|
|
3
|
+
config();
|
|
4
|
+
import { HumanMessage, SystemMessage, BaseMessage } from '@langchain/core/messages';
|
|
5
|
+
import type { UsageMetadata } from '@langchain/core/messages';
|
|
6
|
+
import * as t from '@/types';
|
|
7
|
+
import { ChatModelStreamHandler, createContentAggregator } from '@/stream';
|
|
8
|
+
import { createCodeExecutionTool } from '@/tools/CodeExecutor';
|
|
9
|
+
import { ToolEndHandler, ModelEndHandler } from '@/events';
|
|
10
|
+
import { GraphEvents, Providers } from '@/common';
|
|
11
|
+
import { getLLMConfig } from '@/utils/llmConfig';
|
|
12
|
+
import { getArgs } from '@/scripts/args';
|
|
13
|
+
import { Run } from '@/run';
|
|
14
|
+
|
|
15
|
+
const conversationHistory: BaseMessage[] = [];
|
|
16
|
+
let _contentParts: t.MessageContentComplex[] = [];
|
|
17
|
+
const collectedUsage: UsageMetadata[] = [];
|
|
18
|
+
|
|
19
|
+
async function testThinking(): Promise<void> {
|
|
20
|
+
const { userName } = await getArgs();
|
|
21
|
+
const instructions = `You are a helpful AI assistant for ${userName}. When answering questions, be thorough in your reasoning.`;
|
|
22
|
+
const { contentParts, aggregateContent } = createContentAggregator();
|
|
23
|
+
_contentParts = contentParts as t.MessageContentComplex[];
|
|
24
|
+
|
|
25
|
+
// Set up event handlers
|
|
26
|
+
const customHandlers = {
|
|
27
|
+
[GraphEvents.TOOL_END]: new ToolEndHandler(),
|
|
28
|
+
[GraphEvents.CHAT_MODEL_END]: new ModelEndHandler(collectedUsage),
|
|
29
|
+
[GraphEvents.CHAT_MODEL_STREAM]: new ChatModelStreamHandler(),
|
|
30
|
+
[GraphEvents.ON_RUN_STEP_COMPLETED]: {
|
|
31
|
+
handle: (event: GraphEvents.ON_RUN_STEP_COMPLETED, data: t.StreamEventData): void => {
|
|
32
|
+
console.log('====== ON_RUN_STEP_COMPLETED ======');
|
|
33
|
+
aggregateContent({ event, data: data as unknown as { result: t.ToolEndEvent } });
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
[GraphEvents.ON_RUN_STEP]: {
|
|
37
|
+
handle: (event: GraphEvents.ON_RUN_STEP, data: t.RunStep) => {
|
|
38
|
+
aggregateContent({ event, data });
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
[GraphEvents.ON_RUN_STEP_DELTA]: {
|
|
42
|
+
handle: (event: GraphEvents.ON_RUN_STEP_DELTA, data: t.RunStepDeltaEvent) => {
|
|
43
|
+
aggregateContent({ event, data });
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
[GraphEvents.ON_MESSAGE_DELTA]: {
|
|
47
|
+
handle: (event: GraphEvents.ON_MESSAGE_DELTA, data: t.MessageDeltaEvent) => {
|
|
48
|
+
aggregateContent({ event, data });
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
[GraphEvents.ON_REASONING_DELTA]: {
|
|
52
|
+
handle: (event: GraphEvents.ON_REASONING_DELTA, data: t.ReasoningDeltaEvent) => {
|
|
53
|
+
aggregateContent({ event, data });
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
const baseLlmConfig: t.LLMConfig = getLLMConfig(Providers.ANTHROPIC);
|
|
59
|
+
|
|
60
|
+
// Enable thinking with token budget
|
|
61
|
+
const llmConfig = {
|
|
62
|
+
...baseLlmConfig,
|
|
63
|
+
model: 'claude-3-7-sonnet-latest',
|
|
64
|
+
thinking: { type: "enabled", budget_tokens: 2000 }
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
const run = await Run.create<t.IState>({
|
|
68
|
+
runId: 'test-thinking-id',
|
|
69
|
+
graphConfig: {
|
|
70
|
+
instructions,
|
|
71
|
+
type: 'standard',
|
|
72
|
+
tools: [createCodeExecutionTool()],
|
|
73
|
+
llmConfig,
|
|
74
|
+
},
|
|
75
|
+
returnContent: true,
|
|
76
|
+
customHandlers: customHandlers as t.RunConfig['customHandlers'],
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
const config = {
|
|
80
|
+
configurable: {
|
|
81
|
+
thread_id: 'thinking-test-thread',
|
|
82
|
+
},
|
|
83
|
+
streamMode: 'values',
|
|
84
|
+
version: 'v2' as const,
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
// Test 1: Regular thinking mode
|
|
88
|
+
console.log('\n\nTest 1: Regular thinking mode');
|
|
89
|
+
// const userMessage1 = `What would be the environmental and economic impacts if all cars globally were replaced by electric vehicles overnight?`;
|
|
90
|
+
const userMessage1 = `Please print 'hello world' in python`;
|
|
91
|
+
conversationHistory.push(new HumanMessage(userMessage1));
|
|
92
|
+
|
|
93
|
+
console.log('Running first query with thinking enabled...');
|
|
94
|
+
const firstInputs = { messages: [...conversationHistory] };
|
|
95
|
+
await run.processStream(firstInputs, config);
|
|
96
|
+
|
|
97
|
+
// Extract and display thinking blocks
|
|
98
|
+
const finalMessages = run.getRunMessages();
|
|
99
|
+
|
|
100
|
+
// Test 2: Try multi-turn conversation
|
|
101
|
+
console.log('\n\nTest 2: Multi-turn conversation with thinking enabled');
|
|
102
|
+
const userMessage2 = `Given your previous analysis, what would be the most significant technical challenges in making this transition?`;
|
|
103
|
+
conversationHistory.push(new HumanMessage(userMessage2));
|
|
104
|
+
|
|
105
|
+
console.log('Running second query with thinking enabled...');
|
|
106
|
+
const secondInputs = { messages: [...conversationHistory] };
|
|
107
|
+
await run.processStream(secondInputs, config);
|
|
108
|
+
|
|
109
|
+
// Display thinking blocks for second response
|
|
110
|
+
const finalMessages2 = run.getRunMessages();
|
|
111
|
+
|
|
112
|
+
// Test 3: Redacted thinking mode
|
|
113
|
+
console.log('\n\nTest 3: Redacted thinking mode');
|
|
114
|
+
const magicString = "ANTHROPIC_MAGIC_STRING_TRIGGER_REDACTED_THINKING_46C9A13E193C177646C7398A98432ECCCE4C1253D5E2D82641AC0E52CC2876CB";
|
|
115
|
+
const userMessage3 = `${magicString}\n\nExplain how quantum computing works in simple terms.`;
|
|
116
|
+
|
|
117
|
+
// Reset conversation for clean test
|
|
118
|
+
conversationHistory.length = 0;
|
|
119
|
+
conversationHistory.push(new HumanMessage(userMessage3));
|
|
120
|
+
|
|
121
|
+
console.log('Running query with redacted thinking...');
|
|
122
|
+
const thirdInputs = { messages: [...conversationHistory] };
|
|
123
|
+
await run.processStream(thirdInputs, config);
|
|
124
|
+
|
|
125
|
+
// Display redacted thinking blocks
|
|
126
|
+
const finalMessages3 = run.getRunMessages();
|
|
127
|
+
console.log('\n\nThinking feature test completed!');
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
process.on('unhandledRejection', (reason, promise) => {
|
|
131
|
+
console.error('Unhandled Rejection at:', promise, 'reason:', reason);
|
|
132
|
+
console.log('Conversation history:');
|
|
133
|
+
console.dir(conversationHistory, { depth: null });
|
|
134
|
+
console.log('Content parts:');
|
|
135
|
+
console.dir(_contentParts, { depth: null });
|
|
136
|
+
process.exit(1);
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
process.on('uncaughtException', (err) => {
|
|
140
|
+
console.error('Uncaught Exception:', err);
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
testThinking().catch((err) => {
|
|
144
|
+
console.error(err);
|
|
145
|
+
console.log('Conversation history:');
|
|
146
|
+
console.dir(conversationHistory, { depth: null });
|
|
147
|
+
console.log('Content parts:');
|
|
148
|
+
console.dir(_contentParts, { depth: null });
|
|
149
|
+
process.exit(1);
|
|
150
150
|
});
|
package/src/scripts/tools.ts
CHANGED
|
@@ -6,7 +6,7 @@ config();
|
|
|
6
6
|
import { HumanMessage, BaseMessage } from '@langchain/core/messages';
|
|
7
7
|
import type * as t from '@/types';
|
|
8
8
|
import { ChatModelStreamHandler, createContentAggregator } from '@/stream';
|
|
9
|
-
import {
|
|
9
|
+
import { ModelEndHandler } from '@/events';
|
|
10
10
|
import { GraphEvents, Providers } from '@/common';
|
|
11
11
|
import { getLLMConfig } from '@/utils/llmConfig';
|
|
12
12
|
import { Calculator } from '@/tools/Calculator';
|
|
@@ -18,9 +18,6 @@ async function testStandardStreaming(): Promise<void> {
|
|
|
18
18
|
const { userName, location, provider, currentDate } = await getArgs();
|
|
19
19
|
const { contentParts, aggregateContent } = createContentAggregator();
|
|
20
20
|
const customHandlers = {
|
|
21
|
-
[GraphEvents.TOOL_END]: new ToolEndHandler(undefined, (name?: string) => {
|
|
22
|
-
return true;
|
|
23
|
-
}),
|
|
24
21
|
[GraphEvents.CHAT_MODEL_END]: new ModelEndHandler(),
|
|
25
22
|
[GraphEvents.CHAT_MODEL_STREAM]: new ChatModelStreamHandler(),
|
|
26
23
|
[GraphEvents.ON_RUN_STEP_COMPLETED]: {
|
|
@@ -306,6 +306,73 @@ describe(`${capitalizeFirstLetter(provider)} Streaming Tests`, () => {
|
|
|
306
306
|
expect(onRunStepSpy.mock.calls.length).toBeGreaterThan(0);
|
|
307
307
|
});
|
|
308
308
|
|
|
309
|
+
test(`${capitalizeFirstLetter(provider)}: should handle parallel tool usage (web search + calculator)`, async () => {
|
|
310
|
+
const llmConfig = getLLMConfig(provider);
|
|
311
|
+
const customHandlers = setupCustomHandlers();
|
|
312
|
+
|
|
313
|
+
run = await Run.create<t.IState>({
|
|
314
|
+
runId: 'test-parallel-tools',
|
|
315
|
+
graphConfig: {
|
|
316
|
+
type: 'standard',
|
|
317
|
+
llmConfig,
|
|
318
|
+
tools: [
|
|
319
|
+
{
|
|
320
|
+
type: 'web_search_20250305',
|
|
321
|
+
name: 'web_search',
|
|
322
|
+
max_uses: 5,
|
|
323
|
+
},
|
|
324
|
+
new Calculator(),
|
|
325
|
+
],
|
|
326
|
+
instructions: 'You are a helpful AI assistant.',
|
|
327
|
+
},
|
|
328
|
+
returnContent: true,
|
|
329
|
+
customHandlers,
|
|
330
|
+
});
|
|
331
|
+
|
|
332
|
+
// Use the same query as the edge case script to test actual parallel tool usage
|
|
333
|
+
const userMessage =
|
|
334
|
+
'Can you search the web for the current population of Tokyo, and also calculate what 15% of that population would be? Do both at the same time.';
|
|
335
|
+
conversationHistory = [];
|
|
336
|
+
conversationHistory.push(new HumanMessage(userMessage));
|
|
337
|
+
|
|
338
|
+
const inputs = {
|
|
339
|
+
messages: conversationHistory,
|
|
340
|
+
};
|
|
341
|
+
|
|
342
|
+
// This should complete without errors despite using both server tools and regular tools in parallel
|
|
343
|
+
const finalContentParts = await run.processStream(inputs, config);
|
|
344
|
+
expect(finalContentParts).toBeDefined();
|
|
345
|
+
|
|
346
|
+
const finalMessages = run.getRunMessages();
|
|
347
|
+
expect(finalMessages).toBeDefined();
|
|
348
|
+
expect(finalMessages?.length).toBeGreaterThan(0);
|
|
349
|
+
|
|
350
|
+
const hasWebSearch = contentParts.some(
|
|
351
|
+
(part) =>
|
|
352
|
+
!!(
|
|
353
|
+
part.type === 'tool_call' &&
|
|
354
|
+
part.tool_call?.name === 'web_search' &&
|
|
355
|
+
part.tool_call?.id?.startsWith('srvtoolu_') === true
|
|
356
|
+
)
|
|
357
|
+
);
|
|
358
|
+
const hasCalculator = contentParts.some(
|
|
359
|
+
(part) =>
|
|
360
|
+
!!(
|
|
361
|
+
part.type === 'tool_call' &&
|
|
362
|
+
part.tool_call?.name === 'calculator' &&
|
|
363
|
+
part.tool_call?.id?.startsWith('toolu_') === true
|
|
364
|
+
)
|
|
365
|
+
);
|
|
366
|
+
|
|
367
|
+
// Both tools should have been used for this query
|
|
368
|
+
expect(hasWebSearch).toBe(true);
|
|
369
|
+
expect(hasCalculator).toBe(true);
|
|
370
|
+
|
|
371
|
+
console.log(
|
|
372
|
+
`${capitalizeFirstLetter(provider)} parallel tools test: web_search (server tool) + calculator (regular tool) both used successfully`
|
|
373
|
+
);
|
|
374
|
+
});
|
|
375
|
+
|
|
309
376
|
test('should handle errors appropriately', async () => {
|
|
310
377
|
// Test error scenarios
|
|
311
378
|
await expect(async () => {
|
package/src/specs/spec.utils.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export function capitalizeFirstLetter(string: string): string {
|
|
2
|
-
return string.charAt(0).toUpperCase() + string.slice(1);
|
|
3
|
-
}
|
|
1
|
+
export function capitalizeFirstLetter(string: string): string {
|
|
2
|
+
return string.charAt(0).toUpperCase() + string.slice(1);
|
|
3
|
+
}
|