@illuma-ai/agents 1.1.20 → 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/llm/bedrock/index.cjs +14 -0
- package/dist/cjs/llm/bedrock/index.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/llm/bedrock/index.mjs +14 -0
- package/dist/esm/llm/bedrock/index.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/llm/bedrock/index.ts +17 -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,114 +0,0 @@
|
|
|
1
|
-
// src/scripts/tool_search.ts
|
|
2
|
-
/**
|
|
3
|
-
* Test script for the Tool Search Regex tool.
|
|
4
|
-
* Run with: npm run tool_search
|
|
5
|
-
*
|
|
6
|
-
* Demonstrates runtime registry injection - the tool registry is passed
|
|
7
|
-
* at invocation time, not at initialization time.
|
|
8
|
-
*/
|
|
9
|
-
import { config } from 'dotenv';
|
|
10
|
-
config();
|
|
11
|
-
import { createToolSearch } from '@/tools/ToolSearch';
|
|
12
|
-
import { createToolSearchToolRegistry } from '@/test/mockTools';
|
|
13
|
-
async function runTest(searchTool, testName, query, options) {
|
|
14
|
-
console.log(`\n${'='.repeat(60)}`);
|
|
15
|
-
console.log(`TEST: ${testName}`);
|
|
16
|
-
console.log(`Query: "${query}"`);
|
|
17
|
-
if (options.fields)
|
|
18
|
-
console.log(`Fields: ${options.fields.join(', ')}`);
|
|
19
|
-
if (options.max_results)
|
|
20
|
-
console.log(`Max Results: ${options.max_results}`);
|
|
21
|
-
console.log('='.repeat(60));
|
|
22
|
-
try {
|
|
23
|
-
const startTime = Date.now();
|
|
24
|
-
// Manual testing uses schema params directly
|
|
25
|
-
// (ToolNode uses different param structure when injecting)
|
|
26
|
-
const result = await searchTool.invoke({
|
|
27
|
-
query,
|
|
28
|
-
fields: options.fields,
|
|
29
|
-
max_results: options.max_results,
|
|
30
|
-
});
|
|
31
|
-
const duration = Date.now() - startTime;
|
|
32
|
-
console.log(`\nResult (${duration}ms):`);
|
|
33
|
-
if (Array.isArray(result)) {
|
|
34
|
-
console.log(result[0]);
|
|
35
|
-
if (options.showArtifact) {
|
|
36
|
-
console.log('\n--- Artifact ---');
|
|
37
|
-
console.dir(result[1], { depth: null });
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
else {
|
|
41
|
-
console.log(result);
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
catch (error) {
|
|
45
|
-
console.error('Error:', error instanceof Error ? error.message : error);
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
async function main() {
|
|
49
|
-
console.log('Tool Search Regex - Test Script');
|
|
50
|
-
console.log('================================');
|
|
51
|
-
console.log('Demonstrating runtime tool registry injection\n');
|
|
52
|
-
const apiKey = process.env.CODE_EXECUTOR_API_KEY;
|
|
53
|
-
if (!apiKey) {
|
|
54
|
-
console.error('Error: CODE_EXECUTOR_API_KEY environment variable is not set.');
|
|
55
|
-
console.log('Please set it in your .env file or environment.');
|
|
56
|
-
process.exit(1);
|
|
57
|
-
}
|
|
58
|
-
console.log('Creating sample tool registry...');
|
|
59
|
-
const toolRegistry = createToolSearchToolRegistry();
|
|
60
|
-
console.log(`Registry contains ${toolRegistry.size} tools (${Array.from(toolRegistry.values()).filter((t) => t.defer_loading).length} deferred)`);
|
|
61
|
-
console.log('\nCreating Tool Search Regex tool WITH registry for testing...');
|
|
62
|
-
const searchTool = createToolSearch({ apiKey, toolRegistry });
|
|
63
|
-
console.log('Tool created successfully!');
|
|
64
|
-
console.log('Note: In production, ToolNode injects toolRegistry via params when invoked through the graph.\n');
|
|
65
|
-
const baseOptions = { toolRegistry, onlyDeferred: true };
|
|
66
|
-
// Test 1: Simple keyword search (with artifact display)
|
|
67
|
-
await runTest(searchTool, 'Simple keyword search', 'expense', {
|
|
68
|
-
...baseOptions,
|
|
69
|
-
showArtifact: true,
|
|
70
|
-
});
|
|
71
|
-
// Test 2: Search for weather-related tools
|
|
72
|
-
await runTest(searchTool, 'Weather tools', 'weather|forecast', baseOptions);
|
|
73
|
-
// Test 3: Search with case variations
|
|
74
|
-
await runTest(searchTool, 'Case insensitive search', 'EMAIL', baseOptions);
|
|
75
|
-
// Test 4: Search in description only
|
|
76
|
-
await runTest(searchTool, 'Description-only search', 'database', {
|
|
77
|
-
...baseOptions,
|
|
78
|
-
fields: ['description'],
|
|
79
|
-
});
|
|
80
|
-
// Test 5: Search with parameters field
|
|
81
|
-
await runTest(searchTool, 'Parameters search', 'query', {
|
|
82
|
-
...baseOptions,
|
|
83
|
-
fields: ['parameters'],
|
|
84
|
-
});
|
|
85
|
-
// Test 6: Limited results
|
|
86
|
-
await runTest(searchTool, 'Limited to 2 results', 'get', {
|
|
87
|
-
...baseOptions,
|
|
88
|
-
max_results: 2,
|
|
89
|
-
});
|
|
90
|
-
// Test 7: Pattern that matches nothing
|
|
91
|
-
await runTest(searchTool, 'No matches', 'xyznonexistent123', baseOptions);
|
|
92
|
-
// Test 8: Regex pattern with character class
|
|
93
|
-
await runTest(searchTool, 'Regex with character class', 'get_[a-z]+', baseOptions);
|
|
94
|
-
// Test 9: Dangerous pattern (should be sanitized)
|
|
95
|
-
await runTest(searchTool, 'Dangerous pattern (sanitized)', '(a+)+', baseOptions);
|
|
96
|
-
// Test 10: Search all fields
|
|
97
|
-
await runTest(searchTool, 'All fields search', 'text', {
|
|
98
|
-
...baseOptions,
|
|
99
|
-
fields: ['name', 'description', 'parameters'],
|
|
100
|
-
});
|
|
101
|
-
// Test 11: Search ALL tools (not just deferred)
|
|
102
|
-
await runTest(searchTool, 'Search ALL tools (incl. non-deferred)', 'calc', {
|
|
103
|
-
toolRegistry,
|
|
104
|
-
onlyDeferred: false, // Include non-deferred tools
|
|
105
|
-
});
|
|
106
|
-
console.log('\n' + '='.repeat(60));
|
|
107
|
-
console.log('All tests completed!');
|
|
108
|
-
console.log('='.repeat(60) + '\n');
|
|
109
|
-
}
|
|
110
|
-
main().catch((err) => {
|
|
111
|
-
console.error('Fatal error:', err);
|
|
112
|
-
process.exit(1);
|
|
113
|
-
});
|
|
114
|
-
//# sourceMappingURL=tool_search.js.map
|
package/src/scripts/tools.js
DELETED
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
/* eslint-disable no-console */
|
|
2
|
-
// src/scripts/cli.ts
|
|
3
|
-
import { config } from 'dotenv';
|
|
4
|
-
config();
|
|
5
|
-
import { HumanMessage } from '@langchain/core/messages';
|
|
6
|
-
import { ChatModelStreamHandler, createContentAggregator } from '@/stream';
|
|
7
|
-
import { ToolEndHandler, ModelEndHandler } from '@/events';
|
|
8
|
-
import { GraphEvents, Providers } from '@/common';
|
|
9
|
-
import { getLLMConfig } from '@/utils/llmConfig';
|
|
10
|
-
import { Calculator } from '@/tools/Calculator';
|
|
11
|
-
import { getArgs } from '@/scripts/args';
|
|
12
|
-
import { Run } from '@/run';
|
|
13
|
-
const conversationHistory = [];
|
|
14
|
-
async function testStandardStreaming() {
|
|
15
|
-
const { userName, location, provider, currentDate } = await getArgs();
|
|
16
|
-
const { contentParts, aggregateContent } = createContentAggregator();
|
|
17
|
-
const customHandlers = {
|
|
18
|
-
[GraphEvents.TOOL_END]: new ToolEndHandler(),
|
|
19
|
-
[GraphEvents.CHAT_MODEL_END]: new ModelEndHandler(),
|
|
20
|
-
[GraphEvents.CHAT_MODEL_START]: {
|
|
21
|
-
handle: (_event, _data, metadata) => {
|
|
22
|
-
console.log('\n====== CHAT_MODEL_START METADATA ======');
|
|
23
|
-
console.dir(metadata, { depth: null });
|
|
24
|
-
},
|
|
25
|
-
},
|
|
26
|
-
[GraphEvents.CHAT_MODEL_STREAM]: new ChatModelStreamHandler(),
|
|
27
|
-
[GraphEvents.ON_RUN_STEP_COMPLETED]: {
|
|
28
|
-
handle: (event, data, metadata) => {
|
|
29
|
-
console.log('====== ON_RUN_STEP_COMPLETED ======');
|
|
30
|
-
console.log('METADATA:');
|
|
31
|
-
console.dir(metadata, { depth: null });
|
|
32
|
-
aggregateContent({
|
|
33
|
-
event,
|
|
34
|
-
data: data,
|
|
35
|
-
});
|
|
36
|
-
},
|
|
37
|
-
},
|
|
38
|
-
[GraphEvents.ON_RUN_STEP]: {
|
|
39
|
-
handle: (event, data, metadata) => {
|
|
40
|
-
console.log('====== ON_RUN_STEP ======');
|
|
41
|
-
console.log('DATA:');
|
|
42
|
-
console.dir(data, { depth: null });
|
|
43
|
-
console.log('METADATA:');
|
|
44
|
-
console.dir(metadata, { depth: null });
|
|
45
|
-
aggregateContent({ event, data: data });
|
|
46
|
-
},
|
|
47
|
-
},
|
|
48
|
-
[GraphEvents.ON_RUN_STEP_DELTA]: {
|
|
49
|
-
handle: (event, data) => {
|
|
50
|
-
aggregateContent({ event, data: data });
|
|
51
|
-
},
|
|
52
|
-
},
|
|
53
|
-
[GraphEvents.ON_MESSAGE_DELTA]: {
|
|
54
|
-
handle: (event, data) => {
|
|
55
|
-
aggregateContent({ event, data: data });
|
|
56
|
-
},
|
|
57
|
-
},
|
|
58
|
-
[GraphEvents.ON_REASONING_DELTA]: {
|
|
59
|
-
handle: (event, data) => {
|
|
60
|
-
aggregateContent({ event, data: data });
|
|
61
|
-
},
|
|
62
|
-
},
|
|
63
|
-
[GraphEvents.TOOL_START]: {
|
|
64
|
-
handle: (_event, data, metadata) => {
|
|
65
|
-
console.log('====== TOOL_START ======');
|
|
66
|
-
console.log('METADATA:');
|
|
67
|
-
console.dir(metadata, { depth: null });
|
|
68
|
-
},
|
|
69
|
-
},
|
|
70
|
-
};
|
|
71
|
-
const llmConfig = getLLMConfig(provider);
|
|
72
|
-
if (llmConfig.provider === Providers.BEDROCK) {
|
|
73
|
-
llmConfig.promptCache = true;
|
|
74
|
-
}
|
|
75
|
-
const run = await Run.create({
|
|
76
|
-
runId: 'test-run-id',
|
|
77
|
-
graphConfig: {
|
|
78
|
-
type: 'standard',
|
|
79
|
-
llmConfig,
|
|
80
|
-
tools: [new Calculator()],
|
|
81
|
-
instructions: 'You are a friendly AI assistant. Always address the user by their name.',
|
|
82
|
-
additional_instructions: `The user's name is ${userName} and they are located in ${location}.`,
|
|
83
|
-
maxContextTokens: 89000,
|
|
84
|
-
},
|
|
85
|
-
indexTokenCountMap: { 0: 35 },
|
|
86
|
-
returnContent: true,
|
|
87
|
-
skipCleanup: true,
|
|
88
|
-
customHandlers,
|
|
89
|
-
});
|
|
90
|
-
const config = {
|
|
91
|
-
configurable: {
|
|
92
|
-
provider,
|
|
93
|
-
thread_id: 'conversation-num-1',
|
|
94
|
-
},
|
|
95
|
-
streamMode: 'values',
|
|
96
|
-
version: 'v2',
|
|
97
|
-
};
|
|
98
|
-
console.log('Test 1: Calculation query');
|
|
99
|
-
const userMessage = `What is 1123123 + 123123 / 20348? After that, run some interesting calculations based off the result`;
|
|
100
|
-
conversationHistory.push(new HumanMessage(userMessage));
|
|
101
|
-
const inputs = {
|
|
102
|
-
messages: conversationHistory,
|
|
103
|
-
};
|
|
104
|
-
const finalContentParts = await run.processStream(inputs, config);
|
|
105
|
-
const finalMessages = run.getRunMessages();
|
|
106
|
-
if (finalMessages) {
|
|
107
|
-
conversationHistory.push(...finalMessages);
|
|
108
|
-
console.dir(conversationHistory, { depth: null });
|
|
109
|
-
}
|
|
110
|
-
// console.dir(finalContentParts, { depth: null });
|
|
111
|
-
console.log('\n\n====================\n\n');
|
|
112
|
-
console.dir(contentParts, { depth: null });
|
|
113
|
-
}
|
|
114
|
-
process.on('unhandledRejection', (reason, promise) => {
|
|
115
|
-
console.error('Unhandled Rejection at:', promise, 'reason:', reason);
|
|
116
|
-
console.log('Conversation history:');
|
|
117
|
-
process.exit(1);
|
|
118
|
-
});
|
|
119
|
-
testStandardStreaming().catch((err) => {
|
|
120
|
-
console.error(err);
|
|
121
|
-
console.log('Conversation history:');
|
|
122
|
-
console.dir(conversationHistory, { depth: null });
|
|
123
|
-
process.exit(1);
|
|
124
|
-
});
|
|
125
|
-
//# sourceMappingURL=tools.js.map
|
|
@@ -1,280 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Integration test: Agent Handoff with Bedrock
|
|
3
|
-
*
|
|
4
|
-
* Verifies end-to-end that:
|
|
5
|
-
* 1. Handoff tool descriptions are enriched with agent name + description
|
|
6
|
-
* 2. The LLM (Bedrock Claude) can see and use these descriptions to route correctly
|
|
7
|
-
* 3. The handoff actually transfers control to the correct agent
|
|
8
|
-
*
|
|
9
|
-
* Requires: BEDROCK_AWS_ACCESS_KEY_ID, BEDROCK_AWS_SECRET_ACCESS_KEY, BEDROCK_AWS_REGION
|
|
10
|
-
*/
|
|
11
|
-
import { config } from 'dotenv';
|
|
12
|
-
import { resolve } from 'path';
|
|
13
|
-
// Load from local .env first, then fall back to ranger's .env for Bedrock credentials
|
|
14
|
-
config();
|
|
15
|
-
config({
|
|
16
|
-
path: resolve(process.cwd(), '..', 'ranger', '.env'),
|
|
17
|
-
override: false,
|
|
18
|
-
});
|
|
19
|
-
import { HumanMessage } from '@langchain/core/messages';
|
|
20
|
-
import { Providers, Constants, GraphEvents } from '@/common';
|
|
21
|
-
import { ChatModelStreamHandler, createContentAggregator } from '@/stream';
|
|
22
|
-
import { ToolEndHandler, ModelEndHandler } from '@/events';
|
|
23
|
-
import { Run } from '@/run';
|
|
24
|
-
const bedrockRegion = process.env.BEDROCK_AWS_REGION != null &&
|
|
25
|
-
process.env.BEDROCK_AWS_REGION !== ''
|
|
26
|
-
? process.env.BEDROCK_AWS_REGION
|
|
27
|
-
: process.env.BEDROCK_AWS_DEFAULT_REGION;
|
|
28
|
-
const hasBedrock = process.env.BEDROCK_AWS_ACCESS_KEY_ID != null &&
|
|
29
|
-
process.env.BEDROCK_AWS_ACCESS_KEY_ID !== '' &&
|
|
30
|
-
process.env.BEDROCK_AWS_SECRET_ACCESS_KEY != null &&
|
|
31
|
-
process.env.BEDROCK_AWS_SECRET_ACCESS_KEY !== '' &&
|
|
32
|
-
bedrockRegion != null &&
|
|
33
|
-
bedrockRegion !== '';
|
|
34
|
-
const describeIf = hasBedrock ? describe : describe.skip;
|
|
35
|
-
/** Helper to safely get tool description from tool object */
|
|
36
|
-
const getToolDescription = (tool) => {
|
|
37
|
-
return tool.description;
|
|
38
|
-
};
|
|
39
|
-
/** Helper to safely get tool name from tool object */
|
|
40
|
-
const getToolName = (tool) => {
|
|
41
|
-
return tool.name;
|
|
42
|
-
};
|
|
43
|
-
/** Helper to find tool by name */
|
|
44
|
-
const findToolByName = (tools, name) => {
|
|
45
|
-
return tools?.find((tool) => getToolName(tool) === name);
|
|
46
|
-
};
|
|
47
|
-
describeIf('Agent Handoff E2E with Bedrock', () => {
|
|
48
|
-
jest.setTimeout(120000);
|
|
49
|
-
const bedrockOptions = {
|
|
50
|
-
model: 'us.anthropic.claude-3-5-haiku-20241022-v1:0',
|
|
51
|
-
region: bedrockRegion != null && bedrockRegion !== ''
|
|
52
|
-
? bedrockRegion
|
|
53
|
-
: 'us-east-1',
|
|
54
|
-
credentials: {
|
|
55
|
-
accessKeyId: process.env.BEDROCK_AWS_ACCESS_KEY_ID,
|
|
56
|
-
secretAccessKey: process.env.BEDROCK_AWS_SECRET_ACCESS_KEY,
|
|
57
|
-
},
|
|
58
|
-
};
|
|
59
|
-
const createBedrockAgent = (agentId, name, description, instructions) => ({
|
|
60
|
-
agentId,
|
|
61
|
-
name,
|
|
62
|
-
description,
|
|
63
|
-
provider: Providers.BEDROCK,
|
|
64
|
-
clientOptions: bedrockOptions,
|
|
65
|
-
instructions,
|
|
66
|
-
maxContextTokens: 28000,
|
|
67
|
-
});
|
|
68
|
-
describe('Tool Description Enrichment (no edge.description)', () => {
|
|
69
|
-
it('should generate tool descriptions from agent name + description when edge has no description', async () => {
|
|
70
|
-
const agents = [
|
|
71
|
-
createBedrockAgent('supervisor_abc123', 'Supervisor', 'Routes requests to specialists', 'You are a supervisor. Route requests to the appropriate specialist.'),
|
|
72
|
-
createBedrockAgent('agent_W47hBnn2RoVZEOy5595GC', 'Sales Expert', 'Handles product pricing, quotes, and purchase orders for enterprise clients', 'You are a sales expert.'),
|
|
73
|
-
createBedrockAgent('agent_X92kLmn4TpQR8vw3221HD', 'Technical Support', 'Troubleshoots technical issues, resolves bugs, and handles escalations', 'You are a technical support agent.'),
|
|
74
|
-
];
|
|
75
|
-
// Edges WITHOUT explicit descriptions - simulates what happens in production
|
|
76
|
-
// when users add handoffs through the UI without typing descriptions
|
|
77
|
-
const edges = [
|
|
78
|
-
{
|
|
79
|
-
from: 'supervisor_abc123',
|
|
80
|
-
to: 'agent_W47hBnn2RoVZEOy5595GC',
|
|
81
|
-
edgeType: 'handoff',
|
|
82
|
-
// No description - should auto-generate from agent name + description
|
|
83
|
-
},
|
|
84
|
-
{
|
|
85
|
-
from: 'supervisor_abc123',
|
|
86
|
-
to: 'agent_X92kLmn4TpQR8vw3221HD',
|
|
87
|
-
edgeType: 'handoff',
|
|
88
|
-
// No description
|
|
89
|
-
},
|
|
90
|
-
];
|
|
91
|
-
const run = await Run.create({
|
|
92
|
-
runId: `bedrock-handoff-desc-${Date.now()}`,
|
|
93
|
-
graphConfig: {
|
|
94
|
-
type: 'multi-agent',
|
|
95
|
-
agents,
|
|
96
|
-
edges,
|
|
97
|
-
},
|
|
98
|
-
returnContent: true,
|
|
99
|
-
});
|
|
100
|
-
const supervisorContext = run.Graph.agentContexts.get('supervisor_abc123');
|
|
101
|
-
// Verify the handoff tools have enriched descriptions
|
|
102
|
-
const salesTool = findToolByName(supervisorContext?.tools, `${Constants.LC_TRANSFER_TO_}agent_W47hBnn2RoVZEOy5595GC`);
|
|
103
|
-
const supportTool = findToolByName(supervisorContext?.tools, `${Constants.LC_TRANSFER_TO_}agent_X92kLmn4TpQR8vw3221HD`);
|
|
104
|
-
expect(salesTool).toBeDefined();
|
|
105
|
-
expect(supportTool).toBeDefined();
|
|
106
|
-
const salesDesc = getToolDescription(salesTool);
|
|
107
|
-
const supportDesc = getToolDescription(supportTool);
|
|
108
|
-
// CRITICAL: Descriptions must NOT be just "Transfer control to agent 'agent_W47hBnn...'"
|
|
109
|
-
// They must include the human-readable name and description
|
|
110
|
-
expect(salesDesc).toContain('Sales Expert');
|
|
111
|
-
expect(salesDesc).toContain('pricing');
|
|
112
|
-
expect(salesDesc).not.toContain('agent_W47hBnn2RoVZEOy5595GC');
|
|
113
|
-
expect(supportDesc).toContain('Technical Support');
|
|
114
|
-
expect(supportDesc).toContain('Troubleshoots');
|
|
115
|
-
expect(supportDesc).not.toContain('agent_X92kLmn4TpQR8vw3221HD');
|
|
116
|
-
/* eslint-disable no-console */
|
|
117
|
-
console.log('[PASS] Sales tool description:', salesDesc);
|
|
118
|
-
console.log('[PASS] Support tool description:', supportDesc);
|
|
119
|
-
/* eslint-enable no-console */
|
|
120
|
-
});
|
|
121
|
-
});
|
|
122
|
-
describe('Live Bedrock Handoff Routing', () => {
|
|
123
|
-
it('should route a sales question to the Sales Expert agent', async () => {
|
|
124
|
-
const agents = [
|
|
125
|
-
createBedrockAgent('router', 'Router', 'Routes user requests to specialists', `You are a request router. You must analyze the user's message and transfer to the appropriate specialist.
|
|
126
|
-
|
|
127
|
-
IMPORTANT: Do NOT answer the question yourself. You MUST use one of your transfer tools to hand off to a specialist.
|
|
128
|
-
Pick the specialist whose description best matches the user's request.`),
|
|
129
|
-
createBedrockAgent('sales_agent', 'Sales Expert', 'Handles product pricing, quotes, and purchase orders', 'You are a sales expert. Answer questions about pricing and products. Be concise.'),
|
|
130
|
-
createBedrockAgent('support_agent', 'Technical Support', 'Troubleshoots technical issues and resolves bugs', 'You are technical support. Help with technical problems. Be concise.'),
|
|
131
|
-
];
|
|
132
|
-
const edges = [
|
|
133
|
-
{ from: 'router', to: 'sales_agent', edgeType: 'handoff' },
|
|
134
|
-
{ from: 'router', to: 'support_agent', edgeType: 'handoff' },
|
|
135
|
-
];
|
|
136
|
-
const { contentParts: _contentParts, aggregateContent } = createContentAggregator();
|
|
137
|
-
const customHandlers = {
|
|
138
|
-
[GraphEvents.TOOL_END]: new ToolEndHandler(),
|
|
139
|
-
[GraphEvents.CHAT_MODEL_END]: new ModelEndHandler(),
|
|
140
|
-
[GraphEvents.CHAT_MODEL_STREAM]: new ChatModelStreamHandler(),
|
|
141
|
-
[GraphEvents.ON_RUN_STEP]: {
|
|
142
|
-
handle: (event, data) => {
|
|
143
|
-
aggregateContent({
|
|
144
|
-
event: event,
|
|
145
|
-
data: data,
|
|
146
|
-
});
|
|
147
|
-
},
|
|
148
|
-
},
|
|
149
|
-
[GraphEvents.ON_RUN_STEP_COMPLETED]: {
|
|
150
|
-
handle: (event, data) => {
|
|
151
|
-
aggregateContent({
|
|
152
|
-
event: event,
|
|
153
|
-
data: data,
|
|
154
|
-
});
|
|
155
|
-
},
|
|
156
|
-
},
|
|
157
|
-
[GraphEvents.ON_MESSAGE_DELTA]: {
|
|
158
|
-
handle: (event, data) => {
|
|
159
|
-
aggregateContent({
|
|
160
|
-
event: event,
|
|
161
|
-
data: data,
|
|
162
|
-
});
|
|
163
|
-
},
|
|
164
|
-
},
|
|
165
|
-
};
|
|
166
|
-
const run = await Run.create({
|
|
167
|
-
runId: `bedrock-live-handoff-${Date.now()}`,
|
|
168
|
-
graphConfig: {
|
|
169
|
-
type: 'multi-agent',
|
|
170
|
-
agents,
|
|
171
|
-
edges,
|
|
172
|
-
},
|
|
173
|
-
customHandlers,
|
|
174
|
-
returnContent: true,
|
|
175
|
-
});
|
|
176
|
-
const config = {
|
|
177
|
-
configurable: { thread_id: 'bedrock-handoff-test' },
|
|
178
|
-
streamMode: 'values',
|
|
179
|
-
version: 'v2',
|
|
180
|
-
};
|
|
181
|
-
// Send a sales-related question
|
|
182
|
-
const messages = [
|
|
183
|
-
new HumanMessage('What is the pricing for your enterprise plan?'),
|
|
184
|
-
];
|
|
185
|
-
await run.processStream({ messages }, config);
|
|
186
|
-
const finalMessages = run.getRunMessages();
|
|
187
|
-
expect(finalMessages).toBeDefined();
|
|
188
|
-
expect(finalMessages.length).toBeGreaterThan(1);
|
|
189
|
-
// Verify the handoff happened to the sales agent (not support)
|
|
190
|
-
const toolMessages = finalMessages.filter((msg) => msg.getType() === 'tool');
|
|
191
|
-
const salesHandoff = toolMessages.find((msg) => msg.name === `${Constants.LC_TRANSFER_TO_}sales_agent`);
|
|
192
|
-
const supportHandoff = toolMessages.find((msg) => msg.name === `${Constants.LC_TRANSFER_TO_}support_agent`);
|
|
193
|
-
expect(salesHandoff).toBeDefined();
|
|
194
|
-
expect(supportHandoff).toBeUndefined();
|
|
195
|
-
/* eslint-disable no-console */
|
|
196
|
-
console.log('[PASS] Router correctly handed off to Sales Expert');
|
|
197
|
-
console.log('[PASS] Handoff tool message:', salesHandoff?.content);
|
|
198
|
-
/* eslint-enable no-console */
|
|
199
|
-
// Verify the sales agent actually responded
|
|
200
|
-
const aiMessages = finalMessages.filter((msg) => msg.getType() === 'ai');
|
|
201
|
-
expect(aiMessages.length).toBeGreaterThanOrEqual(2); // Router + Sales responses
|
|
202
|
-
});
|
|
203
|
-
it('should route a technical question to the Support agent', async () => {
|
|
204
|
-
const agents = [
|
|
205
|
-
createBedrockAgent('router', 'Router', 'Routes user requests to specialists', `You are a request router. You must analyze the user's message and transfer to the appropriate specialist.
|
|
206
|
-
|
|
207
|
-
IMPORTANT: Do NOT answer the question yourself. You MUST use one of your transfer tools to hand off to a specialist.
|
|
208
|
-
Pick the specialist whose description best matches the user's request.`),
|
|
209
|
-
createBedrockAgent('sales_agent', 'Sales Expert', 'Handles product pricing, quotes, and purchase orders', 'You are a sales expert. Answer questions about pricing. Be concise.'),
|
|
210
|
-
createBedrockAgent('support_agent', 'Technical Support', 'Troubleshoots technical issues, resolves bugs, and handles error messages', 'You are technical support. Help with technical problems. Be concise.'),
|
|
211
|
-
];
|
|
212
|
-
const edges = [
|
|
213
|
-
{ from: 'router', to: 'sales_agent', edgeType: 'handoff' },
|
|
214
|
-
{ from: 'router', to: 'support_agent', edgeType: 'handoff' },
|
|
215
|
-
];
|
|
216
|
-
const { contentParts: _contentParts, aggregateContent } = createContentAggregator();
|
|
217
|
-
const customHandlers = {
|
|
218
|
-
[GraphEvents.TOOL_END]: new ToolEndHandler(),
|
|
219
|
-
[GraphEvents.CHAT_MODEL_END]: new ModelEndHandler(),
|
|
220
|
-
[GraphEvents.CHAT_MODEL_STREAM]: new ChatModelStreamHandler(),
|
|
221
|
-
[GraphEvents.ON_RUN_STEP]: {
|
|
222
|
-
handle: (event, data) => {
|
|
223
|
-
aggregateContent({
|
|
224
|
-
event: event,
|
|
225
|
-
data: data,
|
|
226
|
-
});
|
|
227
|
-
},
|
|
228
|
-
},
|
|
229
|
-
[GraphEvents.ON_RUN_STEP_COMPLETED]: {
|
|
230
|
-
handle: (event, data) => {
|
|
231
|
-
aggregateContent({
|
|
232
|
-
event: event,
|
|
233
|
-
data: data,
|
|
234
|
-
});
|
|
235
|
-
},
|
|
236
|
-
},
|
|
237
|
-
[GraphEvents.ON_MESSAGE_DELTA]: {
|
|
238
|
-
handle: (event, data) => {
|
|
239
|
-
aggregateContent({
|
|
240
|
-
event: event,
|
|
241
|
-
data: data,
|
|
242
|
-
});
|
|
243
|
-
},
|
|
244
|
-
},
|
|
245
|
-
};
|
|
246
|
-
const run = await Run.create({
|
|
247
|
-
runId: `bedrock-live-handoff-support-${Date.now()}`,
|
|
248
|
-
graphConfig: {
|
|
249
|
-
type: 'multi-agent',
|
|
250
|
-
agents,
|
|
251
|
-
edges,
|
|
252
|
-
},
|
|
253
|
-
customHandlers,
|
|
254
|
-
returnContent: true,
|
|
255
|
-
});
|
|
256
|
-
const config = {
|
|
257
|
-
configurable: { thread_id: 'bedrock-handoff-support-test' },
|
|
258
|
-
streamMode: 'values',
|
|
259
|
-
version: 'v2',
|
|
260
|
-
};
|
|
261
|
-
// Send a technical question
|
|
262
|
-
const messages = [
|
|
263
|
-
new HumanMessage('I am getting an error 500 when trying to login. The page crashes after entering my password.'),
|
|
264
|
-
];
|
|
265
|
-
await run.processStream({ messages }, config);
|
|
266
|
-
const finalMessages = run.getRunMessages();
|
|
267
|
-
expect(finalMessages).toBeDefined();
|
|
268
|
-
const toolMessages = finalMessages.filter((msg) => msg.getType() === 'tool');
|
|
269
|
-
const supportHandoff = toolMessages.find((msg) => msg.name === `${Constants.LC_TRANSFER_TO_}support_agent`);
|
|
270
|
-
const salesHandoff = toolMessages.find((msg) => msg.name === `${Constants.LC_TRANSFER_TO_}sales_agent`);
|
|
271
|
-
expect(supportHandoff).toBeDefined();
|
|
272
|
-
expect(salesHandoff).toBeUndefined();
|
|
273
|
-
/* eslint-disable no-console */
|
|
274
|
-
console.log('[PASS] Router correctly handed off to Technical Support');
|
|
275
|
-
console.log('[PASS] Handoff tool message:', supportHandoff?.content);
|
|
276
|
-
/* eslint-enable no-console */
|
|
277
|
-
});
|
|
278
|
-
});
|
|
279
|
-
});
|
|
280
|
-
//# sourceMappingURL=agent-handoffs-bedrock.integration.test.js.map
|