@librechat/agents 3.0.0-rc5 ā 3.0.0-rc7
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/common/enum.cjs +1 -0
- package/dist/cjs/common/enum.cjs.map +1 -1
- package/dist/cjs/graphs/MultiAgentGraph.cjs +2 -1
- package/dist/cjs/graphs/MultiAgentGraph.cjs.map +1 -1
- package/dist/cjs/llm/openai/index.cjs +6 -6
- package/dist/cjs/llm/openai/index.cjs.map +1 -1
- package/dist/cjs/stream.cjs +1 -1
- package/dist/cjs/stream.cjs.map +1 -1
- package/dist/esm/common/enum.mjs +1 -0
- package/dist/esm/common/enum.mjs.map +1 -1
- package/dist/esm/graphs/MultiAgentGraph.mjs +2 -1
- package/dist/esm/graphs/MultiAgentGraph.mjs.map +1 -1
- package/dist/esm/llm/openai/index.mjs +6 -6
- package/dist/esm/llm/openai/index.mjs.map +1 -1
- package/dist/esm/stream.mjs +1 -1
- package/dist/esm/stream.mjs.map +1 -1
- package/dist/types/common/enum.d.ts +2 -1
- package/dist/types/scripts/test-handoff-input.d.ts +0 -1
- package/package.json +1 -1
- package/src/common/enum.ts +1 -0
- package/src/graphs/MultiAgentGraph.ts +2 -1
- package/src/llm/openai/index.ts +6 -6
- package/src/scripts/multi-agent-supervisor.ts +26 -25
- package/src/scripts/test-handoff-input.ts +65 -5
- package/src/scripts/test-multi-agent-list-handoff.ts +6 -3
- package/src/stream.ts +4 -1
|
@@ -36,10 +36,10 @@ async function testSupervisorMultiAgent() {
|
|
|
36
36
|
// Define configurations for all possible specialists
|
|
37
37
|
const specialistConfigs = {
|
|
38
38
|
data_analyst: {
|
|
39
|
-
provider: Providers.
|
|
39
|
+
provider: Providers.OPENAI,
|
|
40
40
|
clientOptions: {
|
|
41
|
-
modelName: '
|
|
42
|
-
apiKey: process.env.
|
|
41
|
+
modelName: 'gpt-4.1',
|
|
42
|
+
apiKey: process.env.OPENAI_API_KEY,
|
|
43
43
|
},
|
|
44
44
|
instructions: `You are a Data Analyst specialist. Your expertise includes:
|
|
45
45
|
- Statistical analysis and data visualization
|
|
@@ -52,10 +52,10 @@ async function testSupervisorMultiAgent() {
|
|
|
52
52
|
maxContextTokens: 8000,
|
|
53
53
|
},
|
|
54
54
|
security_expert: {
|
|
55
|
-
provider: Providers.
|
|
55
|
+
provider: Providers.OPENAI,
|
|
56
56
|
clientOptions: {
|
|
57
|
-
modelName: '
|
|
58
|
-
apiKey: process.env.
|
|
57
|
+
modelName: 'gpt-4.1',
|
|
58
|
+
apiKey: process.env.OPENAI_API_KEY,
|
|
59
59
|
},
|
|
60
60
|
instructions: `You are a Security Expert. Your expertise includes:
|
|
61
61
|
- Cybersecurity best practices
|
|
@@ -68,10 +68,10 @@ async function testSupervisorMultiAgent() {
|
|
|
68
68
|
maxContextTokens: 8000,
|
|
69
69
|
},
|
|
70
70
|
product_designer: {
|
|
71
|
-
provider: Providers.
|
|
71
|
+
provider: Providers.OPENAI,
|
|
72
72
|
clientOptions: {
|
|
73
|
-
modelName: '
|
|
74
|
-
apiKey: process.env.
|
|
73
|
+
modelName: 'gpt-4.1',
|
|
74
|
+
apiKey: process.env.OPENAI_API_KEY,
|
|
75
75
|
},
|
|
76
76
|
instructions: `You are a Product Designer. Your expertise includes:
|
|
77
77
|
- User experience (UX) design principles
|
|
@@ -84,10 +84,10 @@ async function testSupervisorMultiAgent() {
|
|
|
84
84
|
maxContextTokens: 8000,
|
|
85
85
|
},
|
|
86
86
|
devops_engineer: {
|
|
87
|
-
provider: Providers.
|
|
87
|
+
provider: Providers.OPENAI,
|
|
88
88
|
clientOptions: {
|
|
89
|
-
modelName: '
|
|
90
|
-
apiKey: process.env.
|
|
89
|
+
modelName: 'gpt-4.1',
|
|
90
|
+
apiKey: process.env.OPENAI_API_KEY,
|
|
91
91
|
},
|
|
92
92
|
instructions: `You are a DevOps Engineer. Your expertise includes:
|
|
93
93
|
- CI/CD pipeline design and optimization
|
|
@@ -100,10 +100,10 @@ async function testSupervisorMultiAgent() {
|
|
|
100
100
|
maxContextTokens: 8000,
|
|
101
101
|
},
|
|
102
102
|
legal_advisor: {
|
|
103
|
-
provider: Providers.
|
|
103
|
+
provider: Providers.OPENAI,
|
|
104
104
|
clientOptions: {
|
|
105
|
-
modelName: '
|
|
106
|
-
apiKey: process.env.
|
|
105
|
+
modelName: 'gpt-4.1',
|
|
106
|
+
apiKey: process.env.OPENAI_API_KEY,
|
|
107
107
|
},
|
|
108
108
|
instructions: `You are a Legal Advisor specializing in technology. Your expertise includes:
|
|
109
109
|
- Software licensing and open source compliance
|
|
@@ -154,6 +154,7 @@ async function testSupervisorMultiAgent() {
|
|
|
154
154
|
event: GraphEvents.ON_MESSAGE_DELTA,
|
|
155
155
|
data: t.StreamEventData
|
|
156
156
|
): void => {
|
|
157
|
+
console.dir(data, { depth: null });
|
|
157
158
|
aggregateContent({ event, data: data as t.MessageDeltaEvent });
|
|
158
159
|
},
|
|
159
160
|
},
|
|
@@ -180,10 +181,10 @@ async function testSupervisorMultiAgent() {
|
|
|
180
181
|
|
|
181
182
|
// Define the adaptive specialist configuration that will be reused
|
|
182
183
|
const specialistConfig = {
|
|
183
|
-
provider: Providers.
|
|
184
|
+
provider: Providers.OPENAI,
|
|
184
185
|
clientOptions: {
|
|
185
|
-
modelName: '
|
|
186
|
-
apiKey: process.env.
|
|
186
|
+
modelName: 'gpt-4.1',
|
|
187
|
+
apiKey: process.env.OPENAI_API_KEY,
|
|
187
188
|
},
|
|
188
189
|
instructions: `You are an Adaptive Specialist. Your agent ID indicates your role:
|
|
189
190
|
|
|
@@ -202,10 +203,10 @@ async function testSupervisorMultiAgent() {
|
|
|
202
203
|
const agents: t.AgentInputs[] = [
|
|
203
204
|
{
|
|
204
205
|
agentId: 'supervisor',
|
|
205
|
-
provider: Providers.
|
|
206
|
+
provider: Providers.OPENAI,
|
|
206
207
|
clientOptions: {
|
|
207
|
-
modelName: '
|
|
208
|
-
apiKey: process.env.
|
|
208
|
+
modelName: 'gpt-4.1-mini',
|
|
209
|
+
apiKey: process.env.OPENAI_API_KEY,
|
|
209
210
|
},
|
|
210
211
|
instructions: `You are a Task Supervisor with access to 5 specialist agents:
|
|
211
212
|
1. transfer_to_data_analyst - For statistical analysis and metrics
|
|
@@ -298,10 +299,10 @@ async function testSupervisorMultiAgent() {
|
|
|
298
299
|
// Test with different queries
|
|
299
300
|
const testQueries = [
|
|
300
301
|
'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?',
|
|
302
|
+
// 'What security measures should we implement for our new API?',
|
|
303
|
+
// 'Can you help design a better onboarding flow for our mobile app?',
|
|
304
|
+
// 'We need to set up a CI/CD pipeline for our microservices.',
|
|
305
|
+
// 'What are the legal implications of using GPL-licensed code in our product?',
|
|
305
306
|
];
|
|
306
307
|
|
|
307
308
|
const config = {
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
#!/usr/bin/env bun
|
|
2
|
-
|
|
3
1
|
import { config } from 'dotenv';
|
|
4
2
|
config();
|
|
5
3
|
|
|
6
4
|
import { HumanMessage } from '@langchain/core/messages';
|
|
7
5
|
import { Run } from '@/run';
|
|
8
|
-
import { Providers } from '@/common';
|
|
6
|
+
import { Providers, GraphEvents } from '@/common';
|
|
7
|
+
import { ChatModelStreamHandler, createContentAggregator } from '@/stream';
|
|
8
|
+
import { ToolEndHandler, ModelEndHandler } from '@/events';
|
|
9
9
|
import type * as t from '@/types';
|
|
10
10
|
|
|
11
11
|
/**
|
|
@@ -14,8 +14,68 @@ import type * as t from '@/types';
|
|
|
14
14
|
*/
|
|
15
15
|
async function testHandoffInput() {
|
|
16
16
|
console.log('Testing Handoff Input Feature...\n');
|
|
17
|
+
// Set up content aggregator
|
|
18
|
+
const { contentParts, aggregateContent } = createContentAggregator();
|
|
19
|
+
|
|
20
|
+
// Track which specialist role was selected
|
|
21
|
+
let selectedRole = '';
|
|
22
|
+
let roleInstructions = '';
|
|
23
|
+
|
|
24
|
+
// Create custom handlers
|
|
25
|
+
const customHandlers = {
|
|
26
|
+
[GraphEvents.TOOL_END]: new ToolEndHandler(),
|
|
27
|
+
[GraphEvents.CHAT_MODEL_END]: new ModelEndHandler(),
|
|
28
|
+
[GraphEvents.CHAT_MODEL_STREAM]: new ChatModelStreamHandler(),
|
|
29
|
+
[GraphEvents.ON_RUN_STEP]: {
|
|
30
|
+
handle: (
|
|
31
|
+
event: GraphEvents.ON_RUN_STEP,
|
|
32
|
+
data: t.StreamEventData
|
|
33
|
+
): void => {
|
|
34
|
+
const runStepData = data as any;
|
|
35
|
+
if (runStepData?.name) {
|
|
36
|
+
console.log(`\n[${runStepData.name}] Processing...`);
|
|
37
|
+
}
|
|
38
|
+
aggregateContent({ event, data: data as t.RunStep });
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
[GraphEvents.ON_RUN_STEP_COMPLETED]: {
|
|
42
|
+
handle: (
|
|
43
|
+
event: GraphEvents.ON_RUN_STEP_COMPLETED,
|
|
44
|
+
data: t.StreamEventData
|
|
45
|
+
): void => {
|
|
46
|
+
aggregateContent({
|
|
47
|
+
event,
|
|
48
|
+
data: data as unknown as { result: t.ToolEndEvent },
|
|
49
|
+
});
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
[GraphEvents.ON_MESSAGE_DELTA]: {
|
|
53
|
+
handle: (
|
|
54
|
+
event: GraphEvents.ON_MESSAGE_DELTA,
|
|
55
|
+
data: t.StreamEventData
|
|
56
|
+
): void => {
|
|
57
|
+
console.dir(data, { depth: null });
|
|
58
|
+
aggregateContent({ event, data: data as t.MessageDeltaEvent });
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
[GraphEvents.TOOL_START]: {
|
|
62
|
+
handle: (
|
|
63
|
+
_event: string,
|
|
64
|
+
data: t.StreamEventData,
|
|
65
|
+
metadata?: Record<string, unknown>
|
|
66
|
+
): void => {
|
|
67
|
+
const toolData = data as any;
|
|
68
|
+
if (toolData?.name?.includes('transfer_to_')) {
|
|
69
|
+
const specialist = toolData.name.replace('transfer_to_', '');
|
|
70
|
+
console.log(`\nš Transferring to ${specialist}...`);
|
|
71
|
+
selectedRole = specialist;
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
};
|
|
17
76
|
|
|
18
77
|
const runConfig: t.RunConfig = {
|
|
78
|
+
customHandlers,
|
|
19
79
|
runId: `test-handoff-input-${Date.now()}`,
|
|
20
80
|
graphConfig: {
|
|
21
81
|
type: 'multi-agent',
|
|
@@ -76,7 +136,7 @@ async function testHandoffInput() {
|
|
|
76
136
|
|
|
77
137
|
// Test queries that should result in different handoffs with specific instructions
|
|
78
138
|
const testQueries = [
|
|
79
|
-
'Analyze our Q4 sales data and identify the top 3 performing products',
|
|
139
|
+
// 'Analyze our Q4 sales data and identify the top 3 performing products',
|
|
80
140
|
'Write a blog post about the benefits of remote work for software developers',
|
|
81
141
|
];
|
|
82
142
|
|
|
@@ -97,7 +157,7 @@ async function testHandoffInput() {
|
|
|
97
157
|
messages: [new HumanMessage(query)],
|
|
98
158
|
};
|
|
99
159
|
|
|
100
|
-
await run.processStream(inputs, config);
|
|
160
|
+
const finalContentParts = await run.processStream(inputs, config);
|
|
101
161
|
|
|
102
162
|
console.log(`\n${'ā'.repeat(60)}`);
|
|
103
163
|
console.log('Notice how the supervisor passes specific instructions');
|
|
@@ -5,8 +5,8 @@ config();
|
|
|
5
5
|
|
|
6
6
|
import { HumanMessage, BaseMessage } from '@langchain/core/messages';
|
|
7
7
|
import { Run } from '@/run';
|
|
8
|
-
import { Providers, GraphEvents } from '@/common';
|
|
9
8
|
import { ChatModelStreamHandler, createContentAggregator } from '@/stream';
|
|
9
|
+
import { Providers, GraphEvents, Constants } from '@/common';
|
|
10
10
|
import { ToolEndHandler, ModelEndHandler } from '@/events';
|
|
11
11
|
import type * as t from '@/types';
|
|
12
12
|
|
|
@@ -70,8 +70,11 @@ async function testSupervisorListHandoff() {
|
|
|
70
70
|
metadata?: Record<string, unknown>
|
|
71
71
|
): void => {
|
|
72
72
|
const toolData = data as any;
|
|
73
|
-
if (toolData?.name?.
|
|
74
|
-
const specialist = toolData.name.replace(
|
|
73
|
+
if (toolData?.name?.startsWith(Constants.LC_TRANSFER_TO_)) {
|
|
74
|
+
const specialist = toolData.name.replace(
|
|
75
|
+
Constants.LC_TRANSFER_TO_,
|
|
76
|
+
''
|
|
77
|
+
);
|
|
75
78
|
console.log(`\nš Transferring to ${specialist}...`);
|
|
76
79
|
selectedRole = specialist;
|
|
77
80
|
}
|
package/src/stream.ts
CHANGED
|
@@ -153,7 +153,10 @@ export class ChatModelStreamHandler implements t.EventHandler {
|
|
|
153
153
|
if (
|
|
154
154
|
chunk.tool_calls &&
|
|
155
155
|
chunk.tool_calls.length > 0 &&
|
|
156
|
-
chunk.tool_calls.every(
|
|
156
|
+
chunk.tool_calls.every(
|
|
157
|
+
(tc) =>
|
|
158
|
+
tc.id != null && tc.id !== '' && tc.name != null && tc.name !== ''
|
|
159
|
+
)
|
|
157
160
|
) {
|
|
158
161
|
hasToolCalls = true;
|
|
159
162
|
await handleToolCalls(chunk.tool_calls, metadata, graph);
|