@librechat/agents 3.0.17 → 3.0.18

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.
@@ -0,0 +1,153 @@
1
+ #!/usr/bin/env bun
2
+
3
+ import { config } from 'dotenv';
4
+ config();
5
+
6
+ import { HumanMessage, BaseMessage } from '@langchain/core/messages';
7
+ import { Run } from '@/run';
8
+ import { ChatModelStreamHandler } from '@/stream';
9
+ import { Providers, GraphEvents } from '@/common';
10
+ import { ToolEndHandler, ModelEndHandler } from '@/events';
11
+ import type * as t from '@/types';
12
+
13
+ const conversationHistory: BaseMessage[] = [];
14
+
15
+ /**
16
+ * Test edge case: switching from OpenAI supervisor (no thinking) to Bedrock specialist (with thinking enabled)
17
+ * This should not throw an error about missing thinking blocks
18
+ */
19
+ async function testBedrockThinkingHandoff() {
20
+ console.log('Testing OpenAI → Bedrock (with thinking) handoff...\n');
21
+
22
+ // Create custom handlers
23
+ const customHandlers = {
24
+ [GraphEvents.TOOL_END]: new ToolEndHandler(),
25
+ [GraphEvents.CHAT_MODEL_END]: new ModelEndHandler(),
26
+ [GraphEvents.CHAT_MODEL_STREAM]: new ChatModelStreamHandler(),
27
+ [GraphEvents.TOOL_START]: {
28
+ handle: (_event: string, data: t.StreamEventData): void => {
29
+ const toolData = data as any;
30
+ if (toolData?.name) {
31
+ console.log(`\nšŸ”§ Tool called: ${toolData.name}`);
32
+ }
33
+ },
34
+ },
35
+ };
36
+
37
+ // Create the graph configuration
38
+ function createGraphConfig(): t.RunConfig {
39
+ console.log(
40
+ 'Creating graph with OpenAI supervisor and Bedrock specialist with thinking enabled.\n'
41
+ );
42
+
43
+ const agents: t.AgentInputs[] = [
44
+ {
45
+ agentId: 'supervisor',
46
+ provider: Providers.OPENAI,
47
+ clientOptions: {
48
+ modelName: 'gpt-4o-mini',
49
+ apiKey: process.env.OPENAI_API_KEY,
50
+ },
51
+ instructions: `You are a task supervisor. When the user asks about code review, use transfer_to_code_reviewer to hand off to the specialist.`,
52
+ maxContextTokens: 8000,
53
+ },
54
+ {
55
+ agentId: 'code_reviewer',
56
+ provider: Providers.BEDROCK,
57
+ clientOptions: {
58
+ region: process.env.BEDROCK_AWS_REGION || 'us-east-1',
59
+ model: 'us.anthropic.claude-3-7-sonnet-20250219-v1:0',
60
+ credentials: {
61
+ accessKeyId: process.env.BEDROCK_AWS_ACCESS_KEY_ID!,
62
+ secretAccessKey: process.env.BEDROCK_AWS_SECRET_ACCESS_KEY!,
63
+ },
64
+ additionalModelRequestFields: {
65
+ thinking: {
66
+ type: 'enabled',
67
+ budget_tokens: 2000,
68
+ },
69
+ },
70
+ },
71
+ instructions: `You are a code review specialist using Bedrock with extended thinking. Think carefully about the code quality, best practices, and potential issues. Provide thoughtful feedback.`,
72
+ maxContextTokens: 8000,
73
+ },
74
+ ];
75
+
76
+ const edges: t.GraphEdge[] = [
77
+ {
78
+ from: 'supervisor',
79
+ to: ['code_reviewer'],
80
+ description: 'Transfer to code review specialist',
81
+ edgeType: 'handoff',
82
+ },
83
+ ];
84
+
85
+ return {
86
+ runId: `bedrock-thinking-handoff-test-${Date.now()}`,
87
+ graphConfig: {
88
+ type: 'multi-agent',
89
+ agents,
90
+ edges,
91
+ },
92
+ customHandlers,
93
+ returnContent: true,
94
+ };
95
+ }
96
+
97
+ try {
98
+ // Test query that should trigger a handoff
99
+ const query =
100
+ 'Can you review this function and tell me if there are any issues?\n\nfunction add(a, b) { return a + b; }';
101
+
102
+ console.log(`${'='.repeat(60)}`);
103
+ console.log(`USER QUERY: "${query}"`);
104
+ console.log('='.repeat(60));
105
+
106
+ // Initialize conversation
107
+ conversationHistory.push(new HumanMessage(query));
108
+
109
+ // Create and run the graph
110
+ const runConfig = createGraphConfig();
111
+ const run = await Run.create(runConfig);
112
+
113
+ const config = {
114
+ configurable: {
115
+ thread_id: 'bedrock-thinking-handoff-test-1',
116
+ },
117
+ streamMode: 'values',
118
+ version: 'v2' as const,
119
+ };
120
+
121
+ console.log('\nProcessing request...\n');
122
+
123
+ // Process with streaming
124
+ const inputs = {
125
+ messages: conversationHistory,
126
+ };
127
+
128
+ await run.processStream(inputs, config);
129
+ const finalMessages = run.getRunMessages();
130
+
131
+ if (finalMessages) {
132
+ conversationHistory.push(...finalMessages);
133
+ }
134
+
135
+ // Success!
136
+ console.log(`\n${'='.repeat(60)}`);
137
+ console.log('āœ… TEST PASSED');
138
+ console.log('='.repeat(60));
139
+ console.log('\nSuccessfully handed off from OpenAI (no thinking) to');
140
+ console.log('Bedrock with thinking enabled without errors!');
141
+ console.log('\nThe ensureThinkingBlockInMessages() function correctly');
142
+ console.log('handled the transition by converting tool sequences to');
143
+ console.log('HumanMessages before calling the Bedrock API.');
144
+ } catch (error) {
145
+ console.error('\nāŒ TEST FAILED');
146
+ console.error('='.repeat(60));
147
+ console.error('Error:', error);
148
+ process.exit(1);
149
+ }
150
+ }
151
+
152
+ // Run the test
153
+ testBedrockThinkingHandoff();
@@ -0,0 +1,147 @@
1
+ #!/usr/bin/env bun
2
+
3
+ import { config } from 'dotenv';
4
+ config();
5
+
6
+ import { HumanMessage, BaseMessage } from '@langchain/core/messages';
7
+ import type * as t from '@/types';
8
+ import { ToolEndHandler, ModelEndHandler } from '@/events';
9
+ import { ChatModelStreamHandler } from '@/stream';
10
+ import { Providers, GraphEvents } from '@/common';
11
+ import { Run } from '@/run';
12
+
13
+ const conversationHistory: BaseMessage[] = [];
14
+
15
+ /**
16
+ * Test edge case: switching from OpenAI supervisor (no thinking) to Anthropic specialist (with thinking enabled)
17
+ * This should not throw an error about missing thinking blocks
18
+ */
19
+ async function testThinkingHandoff() {
20
+ console.log('Testing OpenAI → Anthropic (with thinking) handoff...\n');
21
+
22
+ // Create custom handlers
23
+ const customHandlers = {
24
+ [GraphEvents.TOOL_END]: new ToolEndHandler(),
25
+ [GraphEvents.CHAT_MODEL_END]: new ModelEndHandler(),
26
+ [GraphEvents.CHAT_MODEL_STREAM]: new ChatModelStreamHandler(),
27
+ [GraphEvents.TOOL_START]: {
28
+ handle: (_event: string, data: t.StreamEventData): void => {
29
+ const toolData = data as any;
30
+ if (toolData?.name) {
31
+ console.log(`\nšŸ”§ Tool called: ${toolData.name}`);
32
+ }
33
+ },
34
+ },
35
+ };
36
+
37
+ // Create the graph configuration
38
+ function createGraphConfig(): t.RunConfig {
39
+ console.log(
40
+ 'Creating graph with OpenAI supervisor and Anthropic specialist with thinking enabled.\n'
41
+ );
42
+
43
+ const agents: t.AgentInputs[] = [
44
+ {
45
+ agentId: 'supervisor',
46
+ provider: Providers.OPENAI,
47
+ clientOptions: {
48
+ modelName: 'gpt-4o-mini',
49
+ apiKey: process.env.OPENAI_API_KEY,
50
+ },
51
+ instructions: `You are a task supervisor. When the user asks about code review, use transfer_to_code_reviewer to hand off to the specialist.`,
52
+ maxContextTokens: 8000,
53
+ },
54
+ {
55
+ agentId: 'code_reviewer',
56
+ provider: Providers.ANTHROPIC,
57
+ clientOptions: {
58
+ modelName: 'claude-3-7-sonnet-20250219',
59
+ apiKey: process.env.ANTHROPIC_API_KEY,
60
+ thinking: {
61
+ type: 'enabled',
62
+ budget_tokens: 2000,
63
+ },
64
+ },
65
+ instructions: `You are a code review specialist. Think carefully about the code quality, best practices, and potential issues. Provide thoughtful feedback.`,
66
+ maxContextTokens: 8000,
67
+ },
68
+ ];
69
+
70
+ const edges: t.GraphEdge[] = [
71
+ {
72
+ from: 'supervisor',
73
+ to: ['code_reviewer'],
74
+ description: 'Transfer to code review specialist',
75
+ edgeType: 'handoff',
76
+ },
77
+ ];
78
+
79
+ return {
80
+ runId: `thinking-handoff-test-${Date.now()}`,
81
+ graphConfig: {
82
+ type: 'multi-agent',
83
+ agents,
84
+ edges,
85
+ },
86
+ customHandlers,
87
+ returnContent: true,
88
+ };
89
+ }
90
+
91
+ try {
92
+ // Test query that should trigger a handoff
93
+ const query =
94
+ 'Can you review this function and tell me if there are any issues?\n\nfunction add(a, b) { return a + b; }';
95
+
96
+ console.log(`${'='.repeat(60)}`);
97
+ console.log(`USER QUERY: "${query}"`);
98
+ console.log('='.repeat(60));
99
+
100
+ // Initialize conversation
101
+ conversationHistory.push(new HumanMessage(query));
102
+
103
+ // Create and run the graph
104
+ const runConfig = createGraphConfig();
105
+ const run = await Run.create(runConfig);
106
+
107
+ const config = {
108
+ configurable: {
109
+ thread_id: 'thinking-handoff-test-1',
110
+ },
111
+ streamMode: 'values',
112
+ version: 'v2' as const,
113
+ };
114
+
115
+ console.log('\nProcessing request...\n');
116
+
117
+ // Process with streaming
118
+ const inputs = {
119
+ messages: conversationHistory,
120
+ };
121
+
122
+ await run.processStream(inputs, config);
123
+ const finalMessages = run.getRunMessages();
124
+
125
+ if (finalMessages) {
126
+ conversationHistory.push(...finalMessages);
127
+ }
128
+
129
+ // Success!
130
+ console.log(`\n${'='.repeat(60)}`);
131
+ console.log('āœ… TEST PASSED');
132
+ console.log('='.repeat(60));
133
+ console.log('\nSuccessfully handed off from OpenAI (no thinking) to');
134
+ console.log('Anthropic with thinking enabled without errors!');
135
+ console.log('\nThe ensureThinkingBlockInMessages() function correctly');
136
+ console.log('added a placeholder thinking block to the last assistant');
137
+ console.log('message before calling the Anthropic API.');
138
+ } catch (error) {
139
+ console.error('\nāŒ TEST FAILED');
140
+ console.error('='.repeat(60));
141
+ console.error('Error:', error);
142
+ process.exit(1);
143
+ }
144
+ }
145
+
146
+ // Run the test
147
+ testThinkingHandoff();