@librechat/agents 2.4.322 → 3.0.0-rc2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/agents/AgentContext.cjs +218 -0
- package/dist/cjs/agents/AgentContext.cjs.map +1 -0
- package/dist/cjs/common/enum.cjs +14 -5
- package/dist/cjs/common/enum.cjs.map +1 -1
- package/dist/cjs/events.cjs +10 -6
- package/dist/cjs/events.cjs.map +1 -1
- package/dist/cjs/graphs/Graph.cjs +309 -212
- package/dist/cjs/graphs/Graph.cjs.map +1 -1
- package/dist/cjs/graphs/MultiAgentGraph.cjs +422 -0
- package/dist/cjs/graphs/MultiAgentGraph.cjs.map +1 -0
- package/dist/cjs/llm/anthropic/index.cjs +54 -9
- package/dist/cjs/llm/anthropic/index.cjs.map +1 -1
- package/dist/cjs/llm/anthropic/types.cjs.map +1 -1
- package/dist/cjs/llm/anthropic/utils/message_inputs.cjs +52 -6
- package/dist/cjs/llm/anthropic/utils/message_inputs.cjs.map +1 -1
- package/dist/cjs/llm/anthropic/utils/message_outputs.cjs +22 -2
- package/dist/cjs/llm/anthropic/utils/message_outputs.cjs.map +1 -1
- package/dist/cjs/llm/anthropic/utils/tools.cjs +29 -0
- package/dist/cjs/llm/anthropic/utils/tools.cjs.map +1 -0
- package/dist/cjs/llm/google/index.cjs +144 -0
- package/dist/cjs/llm/google/index.cjs.map +1 -0
- package/dist/cjs/llm/google/utils/common.cjs +477 -0
- package/dist/cjs/llm/google/utils/common.cjs.map +1 -0
- package/dist/cjs/llm/ollama/index.cjs +67 -0
- package/dist/cjs/llm/ollama/index.cjs.map +1 -0
- package/dist/cjs/llm/ollama/utils.cjs +158 -0
- package/dist/cjs/llm/ollama/utils.cjs.map +1 -0
- package/dist/cjs/llm/openai/index.cjs +389 -3
- package/dist/cjs/llm/openai/index.cjs.map +1 -1
- package/dist/cjs/llm/openai/utils/index.cjs +672 -0
- package/dist/cjs/llm/openai/utils/index.cjs.map +1 -0
- package/dist/cjs/llm/providers.cjs +15 -15
- package/dist/cjs/llm/providers.cjs.map +1 -1
- package/dist/cjs/llm/text.cjs +14 -3
- package/dist/cjs/llm/text.cjs.map +1 -1
- package/dist/cjs/llm/vertexai/index.cjs +330 -0
- package/dist/cjs/llm/vertexai/index.cjs.map +1 -0
- package/dist/cjs/main.cjs +11 -0
- package/dist/cjs/main.cjs.map +1 -1
- package/dist/cjs/run.cjs +120 -81
- package/dist/cjs/run.cjs.map +1 -1
- package/dist/cjs/stream.cjs +85 -51
- package/dist/cjs/stream.cjs.map +1 -1
- package/dist/cjs/tools/ToolNode.cjs +10 -4
- package/dist/cjs/tools/ToolNode.cjs.map +1 -1
- package/dist/cjs/tools/handlers.cjs +119 -13
- package/dist/cjs/tools/handlers.cjs.map +1 -1
- package/dist/cjs/tools/search/anthropic.cjs +40 -0
- package/dist/cjs/tools/search/anthropic.cjs.map +1 -0
- package/dist/cjs/tools/search/firecrawl.cjs +55 -9
- package/dist/cjs/tools/search/firecrawl.cjs.map +1 -1
- package/dist/cjs/tools/search/format.cjs +6 -6
- package/dist/cjs/tools/search/format.cjs.map +1 -1
- package/dist/cjs/tools/search/rerankers.cjs +7 -29
- package/dist/cjs/tools/search/rerankers.cjs.map +1 -1
- package/dist/cjs/tools/search/search.cjs +86 -16
- package/dist/cjs/tools/search/search.cjs.map +1 -1
- package/dist/cjs/tools/search/tool.cjs +4 -2
- package/dist/cjs/tools/search/tool.cjs.map +1 -1
- package/dist/cjs/tools/search/utils.cjs +1 -1
- package/dist/cjs/tools/search/utils.cjs.map +1 -1
- package/dist/cjs/utils/events.cjs +31 -0
- package/dist/cjs/utils/events.cjs.map +1 -0
- package/dist/cjs/utils/title.cjs +57 -21
- package/dist/cjs/utils/title.cjs.map +1 -1
- package/dist/cjs/utils/tokens.cjs +54 -7
- package/dist/cjs/utils/tokens.cjs.map +1 -1
- package/dist/esm/agents/AgentContext.mjs +216 -0
- package/dist/esm/agents/AgentContext.mjs.map +1 -0
- package/dist/esm/common/enum.mjs +15 -6
- package/dist/esm/common/enum.mjs.map +1 -1
- package/dist/esm/events.mjs +10 -6
- package/dist/esm/events.mjs.map +1 -1
- package/dist/esm/graphs/Graph.mjs +311 -214
- package/dist/esm/graphs/Graph.mjs.map +1 -1
- package/dist/esm/graphs/MultiAgentGraph.mjs +420 -0
- package/dist/esm/graphs/MultiAgentGraph.mjs.map +1 -0
- package/dist/esm/llm/anthropic/index.mjs +54 -9
- package/dist/esm/llm/anthropic/index.mjs.map +1 -1
- package/dist/esm/llm/anthropic/types.mjs.map +1 -1
- package/dist/esm/llm/anthropic/utils/message_inputs.mjs +52 -6
- package/dist/esm/llm/anthropic/utils/message_inputs.mjs.map +1 -1
- package/dist/esm/llm/anthropic/utils/message_outputs.mjs +22 -2
- package/dist/esm/llm/anthropic/utils/message_outputs.mjs.map +1 -1
- package/dist/esm/llm/anthropic/utils/tools.mjs +27 -0
- package/dist/esm/llm/anthropic/utils/tools.mjs.map +1 -0
- package/dist/esm/llm/google/index.mjs +142 -0
- package/dist/esm/llm/google/index.mjs.map +1 -0
- package/dist/esm/llm/google/utils/common.mjs +471 -0
- package/dist/esm/llm/google/utils/common.mjs.map +1 -0
- package/dist/esm/llm/ollama/index.mjs +65 -0
- package/dist/esm/llm/ollama/index.mjs.map +1 -0
- package/dist/esm/llm/ollama/utils.mjs +155 -0
- package/dist/esm/llm/ollama/utils.mjs.map +1 -0
- package/dist/esm/llm/openai/index.mjs +388 -4
- package/dist/esm/llm/openai/index.mjs.map +1 -1
- package/dist/esm/llm/openai/utils/index.mjs +666 -0
- package/dist/esm/llm/openai/utils/index.mjs.map +1 -0
- package/dist/esm/llm/providers.mjs +5 -5
- package/dist/esm/llm/providers.mjs.map +1 -1
- package/dist/esm/llm/text.mjs +14 -3
- package/dist/esm/llm/text.mjs.map +1 -1
- package/dist/esm/llm/vertexai/index.mjs +328 -0
- package/dist/esm/llm/vertexai/index.mjs.map +1 -0
- package/dist/esm/main.mjs +6 -5
- package/dist/esm/main.mjs.map +1 -1
- package/dist/esm/run.mjs +121 -83
- package/dist/esm/run.mjs.map +1 -1
- package/dist/esm/stream.mjs +87 -54
- package/dist/esm/stream.mjs.map +1 -1
- package/dist/esm/tools/ToolNode.mjs +10 -4
- package/dist/esm/tools/ToolNode.mjs.map +1 -1
- package/dist/esm/tools/handlers.mjs +119 -15
- package/dist/esm/tools/handlers.mjs.map +1 -1
- package/dist/esm/tools/search/anthropic.mjs +37 -0
- package/dist/esm/tools/search/anthropic.mjs.map +1 -0
- package/dist/esm/tools/search/firecrawl.mjs +55 -9
- package/dist/esm/tools/search/firecrawl.mjs.map +1 -1
- package/dist/esm/tools/search/format.mjs +7 -7
- package/dist/esm/tools/search/format.mjs.map +1 -1
- package/dist/esm/tools/search/rerankers.mjs +7 -29
- package/dist/esm/tools/search/rerankers.mjs.map +1 -1
- package/dist/esm/tools/search/search.mjs +86 -16
- package/dist/esm/tools/search/search.mjs.map +1 -1
- package/dist/esm/tools/search/tool.mjs +4 -2
- package/dist/esm/tools/search/tool.mjs.map +1 -1
- package/dist/esm/tools/search/utils.mjs +1 -1
- package/dist/esm/tools/search/utils.mjs.map +1 -1
- package/dist/esm/utils/events.mjs +29 -0
- package/dist/esm/utils/events.mjs.map +1 -0
- package/dist/esm/utils/title.mjs +57 -22
- package/dist/esm/utils/title.mjs.map +1 -1
- package/dist/esm/utils/tokens.mjs +54 -8
- package/dist/esm/utils/tokens.mjs.map +1 -1
- package/dist/types/agents/AgentContext.d.ts +91 -0
- package/dist/types/common/enum.d.ts +15 -6
- package/dist/types/events.d.ts +5 -4
- package/dist/types/graphs/Graph.d.ts +64 -67
- package/dist/types/graphs/MultiAgentGraph.d.ts +37 -0
- package/dist/types/graphs/index.d.ts +1 -0
- package/dist/types/llm/anthropic/index.d.ts +11 -0
- package/dist/types/llm/anthropic/types.d.ts +9 -3
- package/dist/types/llm/anthropic/utils/message_inputs.d.ts +1 -1
- package/dist/types/llm/anthropic/utils/output_parsers.d.ts +4 -4
- package/dist/types/llm/anthropic/utils/tools.d.ts +3 -0
- package/dist/types/llm/google/index.d.ts +13 -0
- package/dist/types/llm/google/types.d.ts +32 -0
- package/dist/types/llm/google/utils/common.d.ts +19 -0
- package/dist/types/llm/google/utils/tools.d.ts +10 -0
- package/dist/types/llm/google/utils/zod_to_genai_parameters.d.ts +14 -0
- package/dist/types/llm/ollama/index.d.ts +7 -0
- package/dist/types/llm/ollama/utils.d.ts +7 -0
- package/dist/types/llm/openai/index.d.ts +72 -3
- package/dist/types/llm/openai/types.d.ts +10 -0
- package/dist/types/llm/openai/utils/index.d.ts +20 -0
- package/dist/types/llm/text.d.ts +1 -1
- package/dist/types/llm/vertexai/index.d.ts +293 -0
- package/dist/types/messages/reducer.d.ts +9 -0
- package/dist/types/run.d.ts +19 -12
- package/dist/types/scripts/ant_web_search.d.ts +1 -0
- package/dist/types/scripts/args.d.ts +2 -1
- package/dist/types/scripts/handoff-test.d.ts +1 -0
- package/dist/types/scripts/multi-agent-conditional.d.ts +1 -0
- package/dist/types/scripts/multi-agent-parallel.d.ts +1 -0
- package/dist/types/scripts/multi-agent-sequence.d.ts +1 -0
- package/dist/types/scripts/multi-agent-supervisor.d.ts +1 -0
- package/dist/types/scripts/multi-agent-test.d.ts +1 -0
- package/dist/types/scripts/test-custom-prompt-key.d.ts +2 -0
- package/dist/types/scripts/test-handoff-input.d.ts +2 -0
- package/dist/types/scripts/test-multi-agent-list-handoff.d.ts +2 -0
- package/dist/types/stream.d.ts +10 -3
- package/dist/types/tools/CodeExecutor.d.ts +2 -2
- package/dist/types/tools/ToolNode.d.ts +1 -1
- package/dist/types/tools/handlers.d.ts +17 -4
- package/dist/types/tools/search/anthropic.d.ts +16 -0
- package/dist/types/tools/search/firecrawl.d.ts +15 -0
- package/dist/types/tools/search/rerankers.d.ts +0 -1
- package/dist/types/tools/search/types.d.ts +30 -9
- package/dist/types/types/graph.d.ts +129 -15
- package/dist/types/types/llm.d.ts +24 -10
- package/dist/types/types/run.d.ts +46 -8
- package/dist/types/types/stream.d.ts +16 -2
- package/dist/types/types/tools.d.ts +1 -1
- package/dist/types/utils/events.d.ts +6 -0
- package/dist/types/utils/title.d.ts +2 -1
- package/dist/types/utils/tokens.d.ts +24 -0
- package/package.json +37 -17
- package/src/agents/AgentContext.ts +315 -0
- package/src/common/enum.ts +14 -5
- package/src/events.ts +24 -13
- package/src/graphs/Graph.ts +495 -312
- package/src/graphs/MultiAgentGraph.ts +498 -0
- package/src/graphs/index.ts +2 -1
- package/src/llm/anthropic/Jacob_Lee_Resume_2023.pdf +0 -0
- package/src/llm/anthropic/index.ts +78 -13
- package/src/llm/anthropic/llm.spec.ts +491 -115
- package/src/llm/anthropic/types.ts +39 -3
- package/src/llm/anthropic/utils/message_inputs.ts +67 -11
- package/src/llm/anthropic/utils/message_outputs.ts +21 -2
- package/src/llm/anthropic/utils/output_parsers.ts +25 -6
- package/src/llm/anthropic/utils/tools.ts +29 -0
- package/src/llm/google/index.ts +218 -0
- package/src/llm/google/types.ts +43 -0
- package/src/llm/google/utils/common.ts +646 -0
- package/src/llm/google/utils/tools.ts +160 -0
- package/src/llm/google/utils/zod_to_genai_parameters.ts +86 -0
- package/src/llm/ollama/index.ts +89 -0
- package/src/llm/ollama/utils.ts +193 -0
- package/src/llm/openai/index.ts +600 -14
- package/src/llm/openai/types.ts +24 -0
- package/src/llm/openai/utils/index.ts +912 -0
- package/src/llm/openai/utils/isReasoningModel.test.ts +90 -0
- package/src/llm/providers.ts +10 -9
- package/src/llm/text.ts +26 -7
- package/src/llm/vertexai/index.ts +360 -0
- package/src/messages/reducer.ts +80 -0
- package/src/run.ts +181 -112
- package/src/scripts/ant_web_search.ts +158 -0
- package/src/scripts/args.ts +12 -8
- package/src/scripts/cli4.ts +29 -21
- package/src/scripts/cli5.ts +29 -21
- package/src/scripts/code_exec.ts +54 -23
- package/src/scripts/code_exec_files.ts +48 -17
- package/src/scripts/code_exec_simple.ts +46 -27
- package/src/scripts/handoff-test.ts +135 -0
- package/src/scripts/image.ts +52 -20
- package/src/scripts/multi-agent-conditional.ts +220 -0
- package/src/scripts/multi-agent-example-output.md +110 -0
- package/src/scripts/multi-agent-parallel.ts +341 -0
- package/src/scripts/multi-agent-sequence.ts +212 -0
- package/src/scripts/multi-agent-supervisor.ts +361 -0
- package/src/scripts/multi-agent-test.ts +186 -0
- package/src/scripts/search.ts +1 -9
- package/src/scripts/simple.ts +25 -10
- package/src/scripts/test-custom-prompt-key.ts +145 -0
- package/src/scripts/test-handoff-input.ts +110 -0
- package/src/scripts/test-multi-agent-list-handoff.ts +258 -0
- package/src/scripts/tools.ts +48 -18
- package/src/specs/anthropic.simple.test.ts +150 -34
- package/src/specs/azure.simple.test.ts +325 -0
- package/src/specs/openai.simple.test.ts +140 -33
- package/src/specs/openrouter.simple.test.ts +107 -0
- package/src/specs/prune.test.ts +4 -9
- package/src/specs/reasoning.test.ts +80 -44
- package/src/specs/token-memoization.test.ts +39 -0
- package/src/stream.test.ts +94 -0
- package/src/stream.ts +139 -60
- package/src/tools/ToolNode.ts +21 -7
- package/src/tools/handlers.ts +192 -18
- package/src/tools/search/anthropic.ts +51 -0
- package/src/tools/search/firecrawl.ts +69 -20
- package/src/tools/search/format.ts +6 -8
- package/src/tools/search/rerankers.ts +7 -40
- package/src/tools/search/search.ts +97 -16
- package/src/tools/search/tool.ts +5 -2
- package/src/tools/search/types.ts +30 -10
- package/src/tools/search/utils.ts +1 -1
- package/src/types/graph.ts +315 -103
- package/src/types/llm.ts +25 -12
- package/src/types/run.ts +51 -13
- package/src/types/stream.ts +22 -1
- package/src/types/tools.ts +16 -10
- package/src/utils/events.ts +32 -0
- package/src/utils/llmConfig.ts +19 -7
- package/src/utils/title.ts +104 -30
- package/src/utils/tokens.ts +69 -10
|
@@ -0,0 +1,361 @@
|
|
|
1
|
+
import { config } from 'dotenv';
|
|
2
|
+
config();
|
|
3
|
+
|
|
4
|
+
import { HumanMessage, BaseMessage } from '@langchain/core/messages';
|
|
5
|
+
import { Run } from '@/run';
|
|
6
|
+
import { Providers, GraphEvents } from '@/common';
|
|
7
|
+
import { ChatModelStreamHandler, createContentAggregator } from '@/stream';
|
|
8
|
+
import { ToolEndHandler, ModelEndHandler } from '@/events';
|
|
9
|
+
import type * as t from '@/types';
|
|
10
|
+
|
|
11
|
+
const conversationHistory: BaseMessage[] = [];
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Example of supervisor-based multi-agent system
|
|
15
|
+
*
|
|
16
|
+
* The supervisor has handoff tools for 5 different specialists.
|
|
17
|
+
* To demonstrate the concept while respecting LangGraph constraints,
|
|
18
|
+
* we show two approaches:
|
|
19
|
+
*
|
|
20
|
+
* 1. All 5 specialists exist but share the same adaptive configuration
|
|
21
|
+
* 2. Only 2 agents total by using a single adaptive specialist (requires workaround)
|
|
22
|
+
*/
|
|
23
|
+
async function testSupervisorMultiAgent() {
|
|
24
|
+
console.log('Testing Supervisor-Based Multi-Agent System...\n');
|
|
25
|
+
|
|
26
|
+
// NOTE: To truly have only 2 agents with 5 handoff tools, you would need:
|
|
27
|
+
// 1. Custom tool implementation (see multi-agent-supervisor-mock.ts)
|
|
28
|
+
// 2. Or modify MultiAgentGraph to support "virtual" agents
|
|
29
|
+
// 3. Or use a single conditional edge with role parameter
|
|
30
|
+
//
|
|
31
|
+
// This example shows the concept using 6 agents that share configuration
|
|
32
|
+
|
|
33
|
+
// Set up content aggregator
|
|
34
|
+
const { contentParts, aggregateContent } = createContentAggregator();
|
|
35
|
+
|
|
36
|
+
// Define configurations for all possible specialists
|
|
37
|
+
const specialistConfigs = {
|
|
38
|
+
data_analyst: {
|
|
39
|
+
provider: Providers.ANTHROPIC,
|
|
40
|
+
clientOptions: {
|
|
41
|
+
modelName: 'claude-3-5-sonnet-latest',
|
|
42
|
+
apiKey: process.env.ANTHROPIC_API_KEY,
|
|
43
|
+
},
|
|
44
|
+
instructions: `You are a Data Analyst specialist. Your expertise includes:
|
|
45
|
+
- Statistical analysis and data visualization
|
|
46
|
+
- SQL queries and database optimization
|
|
47
|
+
- Python/R for data science
|
|
48
|
+
- Machine learning model evaluation
|
|
49
|
+
- A/B testing and experiment design
|
|
50
|
+
|
|
51
|
+
Follow the supervisor's specific instructions carefully.`,
|
|
52
|
+
maxContextTokens: 8000,
|
|
53
|
+
},
|
|
54
|
+
security_expert: {
|
|
55
|
+
provider: Providers.ANTHROPIC,
|
|
56
|
+
clientOptions: {
|
|
57
|
+
modelName: 'claude-3-5-sonnet-latest',
|
|
58
|
+
apiKey: process.env.ANTHROPIC_API_KEY,
|
|
59
|
+
},
|
|
60
|
+
instructions: `You are a Security Expert. Your expertise includes:
|
|
61
|
+
- Cybersecurity best practices
|
|
62
|
+
- Vulnerability assessment and penetration testing
|
|
63
|
+
- Security architecture and threat modeling
|
|
64
|
+
- Compliance (GDPR, HIPAA, SOC2, etc.)
|
|
65
|
+
- Incident response and forensics
|
|
66
|
+
|
|
67
|
+
Follow the supervisor's specific instructions carefully.`,
|
|
68
|
+
maxContextTokens: 8000,
|
|
69
|
+
},
|
|
70
|
+
product_designer: {
|
|
71
|
+
provider: Providers.ANTHROPIC,
|
|
72
|
+
clientOptions: {
|
|
73
|
+
modelName: 'claude-3-5-sonnet-latest',
|
|
74
|
+
apiKey: process.env.ANTHROPIC_API_KEY,
|
|
75
|
+
},
|
|
76
|
+
instructions: `You are a Product Designer. Your expertise includes:
|
|
77
|
+
- User experience (UX) design principles
|
|
78
|
+
- User interface (UI) design and prototyping
|
|
79
|
+
- Design systems and component libraries
|
|
80
|
+
- User research and usability testing
|
|
81
|
+
- Accessibility and inclusive design
|
|
82
|
+
|
|
83
|
+
Follow the supervisor's specific instructions carefully.`,
|
|
84
|
+
maxContextTokens: 8000,
|
|
85
|
+
},
|
|
86
|
+
devops_engineer: {
|
|
87
|
+
provider: Providers.ANTHROPIC,
|
|
88
|
+
clientOptions: {
|
|
89
|
+
modelName: 'claude-3-5-sonnet-latest',
|
|
90
|
+
apiKey: process.env.ANTHROPIC_API_KEY,
|
|
91
|
+
},
|
|
92
|
+
instructions: `You are a DevOps Engineer. Your expertise includes:
|
|
93
|
+
- CI/CD pipeline design and optimization
|
|
94
|
+
- Infrastructure as Code (Terraform, CloudFormation)
|
|
95
|
+
- Container orchestration (Kubernetes, Docker)
|
|
96
|
+
- Cloud platforms (AWS, GCP, Azure)
|
|
97
|
+
- Monitoring, logging, and observability
|
|
98
|
+
|
|
99
|
+
Follow the supervisor's specific instructions carefully.`,
|
|
100
|
+
maxContextTokens: 8000,
|
|
101
|
+
},
|
|
102
|
+
legal_advisor: {
|
|
103
|
+
provider: Providers.ANTHROPIC,
|
|
104
|
+
clientOptions: {
|
|
105
|
+
modelName: 'claude-3-5-sonnet-latest',
|
|
106
|
+
apiKey: process.env.ANTHROPIC_API_KEY,
|
|
107
|
+
},
|
|
108
|
+
instructions: `You are a Legal Advisor specializing in technology. Your expertise includes:
|
|
109
|
+
- Software licensing and open source compliance
|
|
110
|
+
- Data privacy and protection laws
|
|
111
|
+
- Intellectual property and patents
|
|
112
|
+
- Contract review and negotiation
|
|
113
|
+
- Regulatory compliance for tech companies
|
|
114
|
+
|
|
115
|
+
Follow the supervisor's specific instructions carefully.`,
|
|
116
|
+
maxContextTokens: 8000,
|
|
117
|
+
},
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
// Track which specialist role was selected
|
|
121
|
+
let selectedRole = '';
|
|
122
|
+
let roleInstructions = '';
|
|
123
|
+
|
|
124
|
+
// Create custom handlers
|
|
125
|
+
const customHandlers = {
|
|
126
|
+
[GraphEvents.TOOL_END]: new ToolEndHandler(),
|
|
127
|
+
[GraphEvents.CHAT_MODEL_END]: new ModelEndHandler(),
|
|
128
|
+
[GraphEvents.CHAT_MODEL_STREAM]: new ChatModelStreamHandler(),
|
|
129
|
+
[GraphEvents.ON_RUN_STEP]: {
|
|
130
|
+
handle: (
|
|
131
|
+
event: GraphEvents.ON_RUN_STEP,
|
|
132
|
+
data: t.StreamEventData
|
|
133
|
+
): void => {
|
|
134
|
+
const runStepData = data as any;
|
|
135
|
+
if (runStepData?.name) {
|
|
136
|
+
console.log(`\n[${runStepData.name}] Processing...`);
|
|
137
|
+
}
|
|
138
|
+
aggregateContent({ event, data: data as t.RunStep });
|
|
139
|
+
},
|
|
140
|
+
},
|
|
141
|
+
[GraphEvents.ON_RUN_STEP_COMPLETED]: {
|
|
142
|
+
handle: (
|
|
143
|
+
event: GraphEvents.ON_RUN_STEP_COMPLETED,
|
|
144
|
+
data: t.StreamEventData
|
|
145
|
+
): void => {
|
|
146
|
+
aggregateContent({
|
|
147
|
+
event,
|
|
148
|
+
data: data as unknown as { result: t.ToolEndEvent },
|
|
149
|
+
});
|
|
150
|
+
},
|
|
151
|
+
},
|
|
152
|
+
[GraphEvents.ON_MESSAGE_DELTA]: {
|
|
153
|
+
handle: (
|
|
154
|
+
event: GraphEvents.ON_MESSAGE_DELTA,
|
|
155
|
+
data: t.StreamEventData
|
|
156
|
+
): void => {
|
|
157
|
+
aggregateContent({ event, data: data as t.MessageDeltaEvent });
|
|
158
|
+
},
|
|
159
|
+
},
|
|
160
|
+
[GraphEvents.TOOL_START]: {
|
|
161
|
+
handle: (
|
|
162
|
+
_event: string,
|
|
163
|
+
data: t.StreamEventData,
|
|
164
|
+
metadata?: Record<string, unknown>
|
|
165
|
+
): void => {
|
|
166
|
+
const toolData = data as any;
|
|
167
|
+
if (toolData?.name?.includes('transfer_to_')) {
|
|
168
|
+
const specialist = toolData.name.replace('transfer_to_', '');
|
|
169
|
+
console.log(`\n🔀 Transferring to ${specialist}...`);
|
|
170
|
+
selectedRole = specialist;
|
|
171
|
+
}
|
|
172
|
+
},
|
|
173
|
+
},
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
// Function to create the graph with supervisor having multiple handoff options
|
|
177
|
+
function createSupervisorGraph(): t.RunConfig {
|
|
178
|
+
console.log(`\nCreating graph with supervisor and 5 specialist agents.`);
|
|
179
|
+
console.log('All specialists share the same adaptive configuration.\n');
|
|
180
|
+
|
|
181
|
+
// Define the adaptive specialist configuration that will be reused
|
|
182
|
+
const specialistConfig = {
|
|
183
|
+
provider: Providers.ANTHROPIC,
|
|
184
|
+
clientOptions: {
|
|
185
|
+
modelName: 'claude-3-5-sonnet-latest',
|
|
186
|
+
apiKey: process.env.ANTHROPIC_API_KEY,
|
|
187
|
+
},
|
|
188
|
+
instructions: `You are an Adaptive Specialist. Your agent ID indicates your role:
|
|
189
|
+
|
|
190
|
+
- data_analyst: Focus on statistical analysis, metrics, ML evaluation, A/B testing
|
|
191
|
+
- security_expert: Focus on cybersecurity, vulnerability assessment, compliance
|
|
192
|
+
- product_designer: Focus on UX/UI design, user research, accessibility
|
|
193
|
+
- devops_engineer: Focus on CI/CD, infrastructure, cloud platforms, monitoring
|
|
194
|
+
- legal_advisor: Focus on licensing, privacy laws, contracts, regulatory compliance
|
|
195
|
+
|
|
196
|
+
The supervisor will provide specific instructions. Follow them while maintaining your expert perspective.`,
|
|
197
|
+
maxContextTokens: 8000,
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
// Create the graph with supervisor and all 5 specialists
|
|
201
|
+
// All specialists share the same adaptive configuration
|
|
202
|
+
const agents: t.AgentInputs[] = [
|
|
203
|
+
{
|
|
204
|
+
agentId: 'supervisor',
|
|
205
|
+
provider: Providers.ANTHROPIC,
|
|
206
|
+
clientOptions: {
|
|
207
|
+
modelName: 'claude-3-5-sonnet-latest',
|
|
208
|
+
apiKey: process.env.ANTHROPIC_API_KEY,
|
|
209
|
+
},
|
|
210
|
+
instructions: `You are a Task Supervisor with access to 5 specialist agents:
|
|
211
|
+
1. transfer_to_data_analyst - For statistical analysis and metrics
|
|
212
|
+
2. transfer_to_security_expert - For cybersecurity and vulnerability assessment
|
|
213
|
+
3. transfer_to_product_designer - For UX/UI design
|
|
214
|
+
4. transfer_to_devops_engineer - For infrastructure and deployment
|
|
215
|
+
5. transfer_to_legal_advisor - For compliance and licensing
|
|
216
|
+
|
|
217
|
+
Your role is to:
|
|
218
|
+
1. Analyze the incoming request
|
|
219
|
+
2. Decide which specialist is best suited
|
|
220
|
+
3. Use the appropriate transfer tool (e.g., transfer_to_data_analyst)
|
|
221
|
+
4. Provide specific instructions to guide their work
|
|
222
|
+
|
|
223
|
+
Be specific about what you need from the specialist.`,
|
|
224
|
+
maxContextTokens: 8000,
|
|
225
|
+
},
|
|
226
|
+
// Include all 5 specialists with the same adaptive configuration
|
|
227
|
+
{
|
|
228
|
+
agentId: 'data_analyst',
|
|
229
|
+
...specialistConfig,
|
|
230
|
+
},
|
|
231
|
+
{
|
|
232
|
+
agentId: 'security_expert',
|
|
233
|
+
...specialistConfig,
|
|
234
|
+
},
|
|
235
|
+
{
|
|
236
|
+
agentId: 'product_designer',
|
|
237
|
+
...specialistConfig,
|
|
238
|
+
},
|
|
239
|
+
{
|
|
240
|
+
agentId: 'devops_engineer',
|
|
241
|
+
...specialistConfig,
|
|
242
|
+
},
|
|
243
|
+
{
|
|
244
|
+
agentId: 'legal_advisor',
|
|
245
|
+
...specialistConfig,
|
|
246
|
+
},
|
|
247
|
+
];
|
|
248
|
+
|
|
249
|
+
// Create edges from supervisor to all 5 specialists
|
|
250
|
+
const edges: t.GraphEdge[] = [
|
|
251
|
+
{
|
|
252
|
+
from: 'supervisor',
|
|
253
|
+
to: 'data_analyst',
|
|
254
|
+
description:
|
|
255
|
+
'Transfer to data analyst for statistical analysis and metrics',
|
|
256
|
+
edgeType: 'handoff',
|
|
257
|
+
},
|
|
258
|
+
{
|
|
259
|
+
from: 'supervisor',
|
|
260
|
+
to: 'security_expert',
|
|
261
|
+
description: 'Transfer to security expert for cybersecurity assessment',
|
|
262
|
+
edgeType: 'handoff',
|
|
263
|
+
},
|
|
264
|
+
{
|
|
265
|
+
from: 'supervisor',
|
|
266
|
+
to: 'product_designer',
|
|
267
|
+
description: 'Transfer to product designer for UX/UI design',
|
|
268
|
+
edgeType: 'handoff',
|
|
269
|
+
},
|
|
270
|
+
{
|
|
271
|
+
from: 'supervisor',
|
|
272
|
+
to: 'devops_engineer',
|
|
273
|
+
description:
|
|
274
|
+
'Transfer to DevOps engineer for infrastructure and deployment',
|
|
275
|
+
edgeType: 'handoff',
|
|
276
|
+
},
|
|
277
|
+
{
|
|
278
|
+
from: 'supervisor',
|
|
279
|
+
to: 'legal_advisor',
|
|
280
|
+
description: 'Transfer to legal advisor for compliance and licensing',
|
|
281
|
+
edgeType: 'handoff',
|
|
282
|
+
},
|
|
283
|
+
];
|
|
284
|
+
|
|
285
|
+
return {
|
|
286
|
+
runId: `supervisor-multi-agent-${Date.now()}`,
|
|
287
|
+
graphConfig: {
|
|
288
|
+
type: 'multi-agent',
|
|
289
|
+
agents,
|
|
290
|
+
edges,
|
|
291
|
+
},
|
|
292
|
+
customHandlers,
|
|
293
|
+
returnContent: true,
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
try {
|
|
298
|
+
// Test with different queries
|
|
299
|
+
const testQueries = [
|
|
300
|
+
'How can we analyze user engagement metrics to improve our product?',
|
|
301
|
+
'What security measures should we implement for our new API?',
|
|
302
|
+
'Can you help design a better onboarding flow for our mobile app?',
|
|
303
|
+
'We need to set up a CI/CD pipeline for our microservices.',
|
|
304
|
+
'What are the legal implications of using GPL-licensed code in our product?',
|
|
305
|
+
];
|
|
306
|
+
|
|
307
|
+
const config = {
|
|
308
|
+
configurable: {
|
|
309
|
+
thread_id: 'supervisor-conversation-1',
|
|
310
|
+
},
|
|
311
|
+
streamMode: 'values',
|
|
312
|
+
version: 'v2' as const,
|
|
313
|
+
};
|
|
314
|
+
|
|
315
|
+
for (const query of testQueries) {
|
|
316
|
+
console.log(`\n${'='.repeat(60)}`);
|
|
317
|
+
console.log(`USER QUERY: "${query}"`);
|
|
318
|
+
console.log('='.repeat(60));
|
|
319
|
+
|
|
320
|
+
// Reset conversation
|
|
321
|
+
conversationHistory.length = 0;
|
|
322
|
+
conversationHistory.push(new HumanMessage(query));
|
|
323
|
+
|
|
324
|
+
// Create graph with supervisor having 5 handoff tools to 1 adaptive specialist
|
|
325
|
+
const runConfig = createSupervisorGraph();
|
|
326
|
+
const run = await Run.create(runConfig);
|
|
327
|
+
|
|
328
|
+
console.log('Processing request...');
|
|
329
|
+
|
|
330
|
+
// Process with streaming
|
|
331
|
+
const inputs = {
|
|
332
|
+
messages: conversationHistory,
|
|
333
|
+
};
|
|
334
|
+
|
|
335
|
+
const finalContentParts = await run.processStream(inputs, config);
|
|
336
|
+
const finalMessages = run.getRunMessages();
|
|
337
|
+
|
|
338
|
+
if (finalMessages) {
|
|
339
|
+
conversationHistory.push(...finalMessages);
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
// Show summary
|
|
343
|
+
console.log(`\n${'─'.repeat(60)}`);
|
|
344
|
+
console.log(`Agents in graph: 6 total (supervisor + 5 specialists)`);
|
|
345
|
+
console.log(`All specialists share the same adaptive configuration`);
|
|
346
|
+
console.log(
|
|
347
|
+
`Supervisor tools: transfer_to_data_analyst, transfer_to_security_expert,`
|
|
348
|
+
);
|
|
349
|
+
console.log(
|
|
350
|
+
` transfer_to_product_designer, transfer_to_devops_engineer,`
|
|
351
|
+
);
|
|
352
|
+
console.log(` transfer_to_legal_advisor`);
|
|
353
|
+
console.log('─'.repeat(60));
|
|
354
|
+
}
|
|
355
|
+
} catch (error) {
|
|
356
|
+
console.error('Error in supervisor multi-agent test:', error);
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
// Run the test
|
|
361
|
+
testSupervisorMultiAgent();
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import { config } from 'dotenv';
|
|
2
|
+
config();
|
|
3
|
+
|
|
4
|
+
import { HumanMessage, BaseMessage } from '@langchain/core/messages';
|
|
5
|
+
import { Run } from '@/run';
|
|
6
|
+
import { Providers, GraphEvents } from '@/common';
|
|
7
|
+
import { ChatModelStreamHandler, createContentAggregator } from '@/stream';
|
|
8
|
+
import { ToolEndHandler, ModelEndHandler } from '@/events';
|
|
9
|
+
import type * as t from '@/types';
|
|
10
|
+
|
|
11
|
+
const conversationHistory: BaseMessage[] = [];
|
|
12
|
+
|
|
13
|
+
async function testMultiAgentHandoff() {
|
|
14
|
+
console.log('Testing Multi-Agent Handoff System...\n');
|
|
15
|
+
|
|
16
|
+
// Set up content aggregator
|
|
17
|
+
const { contentParts, aggregateContent } = createContentAggregator();
|
|
18
|
+
|
|
19
|
+
// Define agent configurations
|
|
20
|
+
const agents: t.AgentInputs[] = [
|
|
21
|
+
{
|
|
22
|
+
agentId: 'flight_assistant',
|
|
23
|
+
provider: Providers.ANTHROPIC,
|
|
24
|
+
clientOptions: {
|
|
25
|
+
modelName: 'claude-3-5-sonnet-latest',
|
|
26
|
+
apiKey: process.env.ANTHROPIC_API_KEY,
|
|
27
|
+
},
|
|
28
|
+
instructions:
|
|
29
|
+
'You are a flight booking assistant. Help users book flights between airports.',
|
|
30
|
+
maxContextTokens: 28000,
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
agentId: 'hotel_assistant',
|
|
34
|
+
provider: Providers.ANTHROPIC,
|
|
35
|
+
clientOptions: {
|
|
36
|
+
modelName: 'claude-3-5-sonnet-latest',
|
|
37
|
+
apiKey: process.env.ANTHROPIC_API_KEY,
|
|
38
|
+
},
|
|
39
|
+
instructions:
|
|
40
|
+
'You are a hotel booking assistant. Help users book hotel stays.',
|
|
41
|
+
maxContextTokens: 28000,
|
|
42
|
+
},
|
|
43
|
+
];
|
|
44
|
+
|
|
45
|
+
// Define edges (handoff relationships)
|
|
46
|
+
// These edges create handoff tools that agents can use to transfer control dynamically
|
|
47
|
+
const edges: t.GraphEdge[] = [
|
|
48
|
+
{
|
|
49
|
+
from: 'flight_assistant',
|
|
50
|
+
to: 'hotel_assistant',
|
|
51
|
+
description:
|
|
52
|
+
'Transfer to hotel booking assistant when user needs hotel assistance',
|
|
53
|
+
// edgeType defaults to 'handoff' for single-to-single edges
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
from: 'hotel_assistant',
|
|
57
|
+
to: 'flight_assistant',
|
|
58
|
+
description:
|
|
59
|
+
'Transfer to flight booking assistant when user needs flight assistance',
|
|
60
|
+
// edgeType defaults to 'handoff' for single-to-single edges
|
|
61
|
+
},
|
|
62
|
+
];
|
|
63
|
+
|
|
64
|
+
// Create custom handlers similar to examples
|
|
65
|
+
const customHandlers = {
|
|
66
|
+
[GraphEvents.TOOL_END]: new ToolEndHandler(),
|
|
67
|
+
[GraphEvents.CHAT_MODEL_END]: new ModelEndHandler(),
|
|
68
|
+
[GraphEvents.CHAT_MODEL_STREAM]: new ChatModelStreamHandler(),
|
|
69
|
+
[GraphEvents.ON_RUN_STEP_COMPLETED]: {
|
|
70
|
+
handle: (
|
|
71
|
+
event: GraphEvents.ON_RUN_STEP_COMPLETED,
|
|
72
|
+
data: t.StreamEventData
|
|
73
|
+
): void => {
|
|
74
|
+
console.log('====== ON_RUN_STEP_COMPLETED ======');
|
|
75
|
+
console.dir(data, { depth: null });
|
|
76
|
+
aggregateContent({
|
|
77
|
+
event,
|
|
78
|
+
data: data as unknown as { result: t.ToolEndEvent },
|
|
79
|
+
});
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
[GraphEvents.ON_RUN_STEP]: {
|
|
83
|
+
handle: (
|
|
84
|
+
event: GraphEvents.ON_RUN_STEP,
|
|
85
|
+
data: t.StreamEventData
|
|
86
|
+
): void => {
|
|
87
|
+
console.log('====== ON_RUN_STEP ======');
|
|
88
|
+
console.dir(data, { depth: null });
|
|
89
|
+
aggregateContent({ event, data: data as t.RunStep });
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
[GraphEvents.ON_RUN_STEP_DELTA]: {
|
|
93
|
+
handle: (
|
|
94
|
+
event: GraphEvents.ON_RUN_STEP_DELTA,
|
|
95
|
+
data: t.StreamEventData
|
|
96
|
+
): void => {
|
|
97
|
+
console.log('====== ON_RUN_STEP_DELTA ======');
|
|
98
|
+
console.dir(data, { depth: null });
|
|
99
|
+
aggregateContent({ event, data: data as t.RunStepDeltaEvent });
|
|
100
|
+
},
|
|
101
|
+
},
|
|
102
|
+
[GraphEvents.ON_MESSAGE_DELTA]: {
|
|
103
|
+
handle: (
|
|
104
|
+
event: GraphEvents.ON_MESSAGE_DELTA,
|
|
105
|
+
data: t.StreamEventData
|
|
106
|
+
): void => {
|
|
107
|
+
console.log('====== ON_MESSAGE_DELTA ======');
|
|
108
|
+
console.dir(data, { depth: null });
|
|
109
|
+
aggregateContent({ event, data: data as t.MessageDeltaEvent });
|
|
110
|
+
},
|
|
111
|
+
},
|
|
112
|
+
[GraphEvents.ON_REASONING_DELTA]: {
|
|
113
|
+
handle: (
|
|
114
|
+
event: GraphEvents.ON_REASONING_DELTA,
|
|
115
|
+
data: t.StreamEventData
|
|
116
|
+
): void => {
|
|
117
|
+
console.log('====== ON_REASONING_DELTA ======');
|
|
118
|
+
console.dir(data, { depth: null });
|
|
119
|
+
aggregateContent({ event, data: data as t.ReasoningDeltaEvent });
|
|
120
|
+
},
|
|
121
|
+
},
|
|
122
|
+
[GraphEvents.TOOL_START]: {
|
|
123
|
+
handle: (
|
|
124
|
+
_event: string,
|
|
125
|
+
data: t.StreamEventData,
|
|
126
|
+
metadata?: Record<string, unknown>
|
|
127
|
+
): void => {
|
|
128
|
+
console.log('====== TOOL_START ======');
|
|
129
|
+
console.dir(data, { depth: null });
|
|
130
|
+
},
|
|
131
|
+
},
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
// Create multi-agent run configuration
|
|
135
|
+
const runConfig: t.RunConfig = {
|
|
136
|
+
runId: `multi-agent-test-${Date.now()}`,
|
|
137
|
+
graphConfig: {
|
|
138
|
+
type: 'multi-agent',
|
|
139
|
+
agents,
|
|
140
|
+
edges,
|
|
141
|
+
},
|
|
142
|
+
customHandlers,
|
|
143
|
+
returnContent: true,
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
try {
|
|
147
|
+
// Create and execute the run
|
|
148
|
+
const run = await Run.create(runConfig);
|
|
149
|
+
|
|
150
|
+
const userMessage =
|
|
151
|
+
'I need to book a flight from Boston to New York, and also need a hotel near Times Square.';
|
|
152
|
+
conversationHistory.push(new HumanMessage(userMessage));
|
|
153
|
+
|
|
154
|
+
console.log('Invoking multi-agent graph...\n');
|
|
155
|
+
|
|
156
|
+
const config = {
|
|
157
|
+
configurable: {
|
|
158
|
+
thread_id: 'multi-agent-conversation-1',
|
|
159
|
+
},
|
|
160
|
+
streamMode: 'values',
|
|
161
|
+
version: 'v2' as const,
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
// Process with streaming
|
|
165
|
+
const inputs = {
|
|
166
|
+
messages: conversationHistory,
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
const finalContentParts = await run.processStream(inputs, config);
|
|
170
|
+
const finalMessages = run.getRunMessages();
|
|
171
|
+
|
|
172
|
+
if (finalMessages) {
|
|
173
|
+
conversationHistory.push(...finalMessages);
|
|
174
|
+
console.log('\n\nConversation history:');
|
|
175
|
+
console.dir(conversationHistory, { depth: null });
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
console.log('\n\nFinal content parts:');
|
|
179
|
+
console.dir(contentParts, { depth: null });
|
|
180
|
+
} catch (error) {
|
|
181
|
+
console.error('Error in multi-agent test:', error);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// Run the test
|
|
186
|
+
testMultiAgentHandoff();
|
package/src/scripts/search.ts
CHANGED
|
@@ -39,8 +39,6 @@ async function testStandardStreaming(): Promise<void> {
|
|
|
39
39
|
event: GraphEvents.ON_RUN_STEP,
|
|
40
40
|
data: t.StreamEventData
|
|
41
41
|
): void => {
|
|
42
|
-
console.log('====== ON_RUN_STEP ======');
|
|
43
|
-
console.dir(data, { depth: null });
|
|
44
42
|
aggregateContent({ event, data: data as t.RunStep });
|
|
45
43
|
},
|
|
46
44
|
},
|
|
@@ -49,8 +47,6 @@ async function testStandardStreaming(): Promise<void> {
|
|
|
49
47
|
event: GraphEvents.ON_RUN_STEP_DELTA,
|
|
50
48
|
data: t.StreamEventData
|
|
51
49
|
): void => {
|
|
52
|
-
console.log('====== ON_RUN_STEP_DELTA ======');
|
|
53
|
-
console.dir(data, { depth: null });
|
|
54
50
|
aggregateContent({ event, data: data as t.RunStepDeltaEvent });
|
|
55
51
|
},
|
|
56
52
|
},
|
|
@@ -59,8 +55,6 @@ async function testStandardStreaming(): Promise<void> {
|
|
|
59
55
|
event: GraphEvents.ON_MESSAGE_DELTA,
|
|
60
56
|
data: t.StreamEventData
|
|
61
57
|
): void => {
|
|
62
|
-
console.log('====== ON_MESSAGE_DELTA ======');
|
|
63
|
-
console.dir(data, { depth: null });
|
|
64
58
|
aggregateContent({ event, data: data as t.MessageDeltaEvent });
|
|
65
59
|
},
|
|
66
60
|
},
|
|
@@ -133,9 +127,7 @@ async function testStandardStreaming(): Promise<void> {
|
|
|
133
127
|
}
|
|
134
128
|
|
|
135
129
|
process.on('unhandledRejection', (reason, promise) => {
|
|
136
|
-
console.
|
|
137
|
-
console.log('Conversation history:');
|
|
138
|
-
process.exit(1);
|
|
130
|
+
console.warn('Unhandled Rejection (non-fatal):', reason);
|
|
139
131
|
});
|
|
140
132
|
|
|
141
133
|
testStandardStreaming().catch((err) => {
|
package/src/scripts/simple.ts
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
// src/scripts/cli.ts
|
|
2
2
|
import { config } from 'dotenv';
|
|
3
|
+
import { v4 as uuidv4 } from 'uuid';
|
|
3
4
|
config();
|
|
4
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
HumanMessage,
|
|
7
|
+
BaseMessage,
|
|
8
|
+
UsageMetadata,
|
|
9
|
+
} from '@langchain/core/messages';
|
|
5
10
|
import { TavilySearchResults } from '@langchain/community/tools/tavily_search';
|
|
6
11
|
import type * as t from '@/types';
|
|
7
12
|
import { ChatModelStreamHandler, createContentAggregator } from '@/stream';
|
|
@@ -10,21 +15,27 @@ import {
|
|
|
10
15
|
ModelEndHandler,
|
|
11
16
|
createMetadataAggregator,
|
|
12
17
|
} from '@/events';
|
|
18
|
+
import { GraphEvents, Providers, TitleMethod } from '@/common';
|
|
13
19
|
import { getLLMConfig } from '@/utils/llmConfig';
|
|
14
20
|
import { getArgs } from '@/scripts/args';
|
|
15
|
-
import { GraphEvents, Providers } from '@/common';
|
|
16
21
|
import { Run } from '@/run';
|
|
17
22
|
|
|
18
23
|
const conversationHistory: BaseMessage[] = [];
|
|
19
24
|
let _contentParts: t.MessageContentComplex[] = [];
|
|
25
|
+
let collectedUsage: UsageMetadata[] = [];
|
|
20
26
|
|
|
21
27
|
async function testStandardStreaming(): Promise<void> {
|
|
22
|
-
const {
|
|
28
|
+
const {
|
|
29
|
+
userName,
|
|
30
|
+
location,
|
|
31
|
+
provider: _provider,
|
|
32
|
+
currentDate,
|
|
33
|
+
} = await getArgs();
|
|
23
34
|
const { contentParts, aggregateContent } = createContentAggregator();
|
|
24
35
|
_contentParts = contentParts as t.MessageContentComplex[];
|
|
25
36
|
const customHandlers = {
|
|
26
37
|
[GraphEvents.TOOL_END]: new ToolEndHandler(),
|
|
27
|
-
[GraphEvents.CHAT_MODEL_END]: new ModelEndHandler(),
|
|
38
|
+
[GraphEvents.CHAT_MODEL_END]: new ModelEndHandler(collectedUsage),
|
|
28
39
|
[GraphEvents.CHAT_MODEL_STREAM]: new ChatModelStreamHandler(),
|
|
29
40
|
[GraphEvents.ON_RUN_STEP_COMPLETED]: {
|
|
30
41
|
handle: (
|
|
@@ -32,7 +43,7 @@ async function testStandardStreaming(): Promise<void> {
|
|
|
32
43
|
data: t.StreamEventData
|
|
33
44
|
): void => {
|
|
34
45
|
console.log('====== ON_RUN_STEP_COMPLETED ======');
|
|
35
|
-
|
|
46
|
+
console.dir(data, { depth: null });
|
|
36
47
|
aggregateContent({
|
|
37
48
|
event,
|
|
38
49
|
data: data as unknown as { result: t.ToolEndEvent },
|
|
@@ -91,7 +102,7 @@ async function testStandardStreaming(): Promise<void> {
|
|
|
91
102
|
},
|
|
92
103
|
};
|
|
93
104
|
|
|
94
|
-
const llmConfig = getLLMConfig(
|
|
105
|
+
const llmConfig = getLLMConfig(_provider);
|
|
95
106
|
if (
|
|
96
107
|
'configuration' in llmConfig &&
|
|
97
108
|
(llmConfig as t.OpenAIClientOptions).configuration != null
|
|
@@ -99,7 +110,7 @@ async function testStandardStreaming(): Promise<void> {
|
|
|
99
110
|
const openAIConfig = llmConfig as t.OpenAIClientOptions;
|
|
100
111
|
if (openAIConfig.configuration) {
|
|
101
112
|
openAIConfig.configuration.fetch = (
|
|
102
|
-
url:
|
|
113
|
+
url: string | URL | Request,
|
|
103
114
|
init?: RequestInit
|
|
104
115
|
) => {
|
|
105
116
|
console.log('Fetching:', url);
|
|
@@ -107,6 +118,7 @@ async function testStandardStreaming(): Promise<void> {
|
|
|
107
118
|
};
|
|
108
119
|
}
|
|
109
120
|
}
|
|
121
|
+
const provider = llmConfig.provider;
|
|
110
122
|
|
|
111
123
|
if (provider === Providers.ANTHROPIC) {
|
|
112
124
|
(llmConfig as t.AnthropicClientOptions).clientOptions = {
|
|
@@ -118,12 +130,12 @@ async function testStandardStreaming(): Promise<void> {
|
|
|
118
130
|
}
|
|
119
131
|
|
|
120
132
|
const run = await Run.create<t.IState>({
|
|
121
|
-
runId:
|
|
133
|
+
runId: uuidv4(),
|
|
122
134
|
graphConfig: {
|
|
123
135
|
type: 'standard',
|
|
124
136
|
llmConfig,
|
|
125
137
|
// tools: [new TavilySearchResults()],
|
|
126
|
-
reasoningKey: 'reasoning',
|
|
138
|
+
// reasoningKey: 'reasoning',
|
|
127
139
|
instructions:
|
|
128
140
|
'You are a friendly AI assistant. Always address the user by their name.',
|
|
129
141
|
additional_instructions: `The user's name is ${userName} and they are located in ${location}.`,
|
|
@@ -160,8 +172,10 @@ async function testStandardStreaming(): Promise<void> {
|
|
|
160
172
|
console.dir(contentParts, { depth: null });
|
|
161
173
|
const { handleLLMEnd, collected } = createMetadataAggregator();
|
|
162
174
|
const titleOptions: t.RunTitleOptions = {
|
|
175
|
+
provider,
|
|
163
176
|
inputText: userMessage,
|
|
164
177
|
contentParts,
|
|
178
|
+
// titleMethod: TitleMethod.STRUCTURED,
|
|
165
179
|
chainOptions: {
|
|
166
180
|
callbacks: [
|
|
167
181
|
{
|
|
@@ -176,8 +190,9 @@ async function testStandardStreaming(): Promise<void> {
|
|
|
176
190
|
};
|
|
177
191
|
}
|
|
178
192
|
const titleResult = await run.generateTitle(titleOptions);
|
|
193
|
+
console.log('Collected usage metadata:', collectedUsage);
|
|
179
194
|
console.log('Generated Title:', titleResult);
|
|
180
|
-
console.log('Collected metadata:', collected);
|
|
195
|
+
console.log('Collected title usage metadata:', collected);
|
|
181
196
|
}
|
|
182
197
|
|
|
183
198
|
process.on('unhandledRejection', (reason, promise) => {
|