-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathsessionManagerExample.ts
More file actions
345 lines (292 loc) Β· 13.4 KB
/
sessionManagerExample.ts
File metadata and controls
345 lines (292 loc) Β· 13.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
/**
* Session Manager Example
*
* This example demonstrates the enhanced session management capabilities:
* 1. Creating and switching between multiple conversation sessions
* 2. Session-isolated conversation histories
* 3. Temperature comparison tasks across different sessions
* 4. Session state persistence and restoration
*/
import {
StandardAgent,
AgentEventType,
AgentEvent,
AllConfig,
ITool,
LogLevel,
configureLogger,
} from '../src/index.js';
import { createWeatherTool, createSubTool } from './tools';
import dotenv from 'dotenv';
import { LLMChunkTextDelta, LLMChunkTextDone, MessageItem } from '../src/interfaces.js';
import { json } from 'stream/consumers';
dotenv.config();
/**
* Process conversation in a session and collect results
*/
async function processConversation(
agent: StandardAgent,
userMessage: string,
sessionId: string,
provider: string
): Promise<{ success: boolean; response?: string; error?: string }> {
try {
console.log(`\n㪠[${provider}] Session: ${sessionId}`);
console.log(`π€ User: ${userMessage}`);
const abortController = new AbortController();
let assistantResponse = '';
// Set timeout
setTimeout(() => {
console.log(`β° [${provider}] Session ${sessionId}: Timeout, aborting...`);
abortController.abort();
}, 45000);
// Process with session-aware method
const events = agent.processWithSession(userMessage, sessionId, abortController.signal);
for await (const event of events) {
switch (event.type) {
case AgentEventType.ToolExecutionStart:
const toolStartData = event.data as any;
console.log(`π§ [${provider}] Session ${sessionId}: Tool started: ${toolStartData.toolName}`);
break;
case AgentEventType.ToolExecutionDone:
const toolDoneData = event.data as any;
console.log(`π§ [${provider}] Session ${sessionId}: Tool completed: ${toolDoneData.toolName}`);
break;
case AgentEventType.ResponseChunkTextDelta:
const deltaData = event.data as LLMChunkTextDelta;
// process.stdout.write(deltaData.content.text_delta || '');
assistantResponse += deltaData.content.text_delta || '';
break;
case AgentEventType.ResponseChunkTextDone:
const textDoneData = event.data as LLMChunkTextDone;
console.log(`\nπ€ [${provider}] Assistant response completed \n [content] ${textDoneData.content.text}`);
break;
case AgentEventType.ResponseComplete:
console.log(`β
[${provider}] Session ${sessionId}: Turn complete`);
break;
case AgentEventType.Error:
const errorData = event.data as any;
console.error(`β [${provider}] Session ${sessionId}: ${errorData.message}`);
return { success: false, error: errorData.message };
}
}
return { success: true, response: assistantResponse };
} catch (error) {
console.error(`β [${provider}] Session ${sessionId} failed:`, error);
return { success: false, error: error instanceof Error ? error.message : String(error) };
}
}
/**
* Show session status
*/
function showSessionStatus(agent: StandardAgent, provider: string) {
console.log(`\nπ [${provider}] Session Status:`);
const sessions = agent.getSessions();
const currentSessionId = agent.getCurrentSessionId();
sessions.forEach((session, index) => {
const isCurrent = session.id === currentSessionId;
const indicator = isCurrent ? 'π' : ' ';
console.log(`${indicator} ${index + 1}. ${session.title} (${session.id})`);
console.log(` Created: ${new Date(session.createdAt).toLocaleString()}`);
console.log(` Last Active: ${new Date(session.lastActiveAt).toLocaleString()}`);
console.log(` Messages: ${session.messageHistory.length}`);
console.log(` Tokens: ${session.tokenUsage.totalTokens}`);
});
console.log(`\nTotal Sessions: ${sessions.length}`);
console.log(`Current Session: ${currentSessionId}`);
}
/**
* Test session management with temperature comparisons
*/
async function testSessionManagement(
provider: 'gemini' | 'openai'
): Promise<{ success: boolean; error?: string }> {
console.log(`\n${'='.repeat(70)}`);
console.log(`π§ͺ Testing Session Management with ${provider.toUpperCase()}`);
console.log(`${'='.repeat(70)}`);
try {
// Get API key
let apiKey: string;
let modelName: string;
switch (provider) {
case 'openai':
apiKey = process.env.OPENAI_API_KEY || '';
modelName = 'gpt-4o';
if (!apiKey) {
console.error('β OPENAI_API_KEY environment variable is not set');
return { success: false, error: 'Missing OPENAI_API_KEY' };
}
break;
case 'gemini':
default:
apiKey = process.env.GEMINI_API_KEY || '';
modelName = 'gemini-2.0-flash';
if (!apiKey) {
console.error('β GEMINI_API_KEY environment variable is not set');
return { success: false, error: 'Missing GEMINI_API_KEY' };
}
break;
}
// Create agent configuration
const config: AllConfig & { chatProvider?: 'gemini' | 'openai' } = {
chatProvider: provider,
agentConfig: {
model: modelName,
workingDirectory: process.cwd(),
apiKey: apiKey,
maxHistoryTokens: 100000,
},
chatConfig: {
apiKey: apiKey,
modelName: modelName,
tokenLimit: 100000,
systemPrompt: `You are a helpful weather assistant with access to weather and calculation tools.
IMPORTANT:
- Always use tools to get real weather data
- After getting data for both cities, calculate the temperature difference using the subtract tool
- Provide a clear summary of your findings
- Be concise but informative in your responses`,
},
toolSchedulerConfig: {
approvalMode: 'yolo', // Auto-approve for demo
},
};
console.log('π API Key configured: Yes');
console.log('π€ Model:', modelName);
console.log('');
// Create agent with tools
const tools = [createWeatherTool(), createSubTool()];
const agent = new StandardAgent(tools, config);
console.log('π€ Agent created with session management enabled');
// Show initial session status
showSessionStatus(agent, provider);
// ========================================================================
// Session 1: Beijing vs Shanghai temperature comparison
// ========================================================================
console.log(`\n${'β'.repeat(50)}`);
console.log('π Session 1: Beijing vs Shanghai Temperature Comparison');
console.log(`${'β'.repeat(50)}`);
const session1Id = agent.createNewSession('Beijing vs Shanghai');
console.log(`β
Created Session 1: ${session1Id}`);
const beijing_shanghai_query = `Compare the current temperature between Beijing (latitude: 39.9042, longitude: 116.4074) and Shanghai (latitude: 31.2304, longitude: 121.4737). Get the weather for both cities and calculate the temperature difference.`;
const result1 = await processConversation(agent, beijing_shanghai_query, session1Id, provider);
if (!result1.success) {
return { success: false, error: `Session 1 failed: ${result1.error}` };
}
// ========================================================================
// Session 2: Shanghai vs Guangzhou temperature comparison
// ========================================================================
console.log(`\n${'β'.repeat(50)}`);
console.log('π Session 2: Shanghai vs Guangzhou Temperature Comparison');
console.log(`${'β'.repeat(50)}`);
const session2Id = agent.createNewSession('Shanghai vs Guangzhou');
console.log(`β
Created Session 2: ${session2Id}`);
const shanghai_guangzhou_query = `Compare the current temperature between Shanghai (latitude: 31.2304, longitude: 121.4737) and Guangzhou (latitude: 23.1291, longitude: 113.2644). Get the weather for both cities and calculate the temperature difference.`;
const result2 = await processConversation(agent, shanghai_guangzhou_query, session2Id, provider);
if (!result2.success) {
return { success: false, error: `Session 2 failed: ${result2.error}` };
}
// ========================================================================
// Switch back to Session 1: Guangzhou vs Shenzhen comparison
// ========================================================================
console.log(`\n${'β'.repeat(50)}`);
console.log('π Back to Session 1: Guangzhou vs Shenzhen Temperature Comparison');
console.log(`${'β'.repeat(50)}`);
const switchSuccess = agent.switchToSession(session1Id);
if (!switchSuccess) {
return { success: false, error: 'Failed to switch back to Session 1' };
}
console.log(`β
Switched back to Session 1: ${session1Id}`);
const guangzhou_shenzhen_query = `Now compare the current temperature between Guangzhou (latitude: 23.1291, longitude: 113.2644) and Shenzhen (latitude: 22.5431, longitude: 114.0579). Get the weather for both cities and calculate the temperature difference.`;
const result3 = await processConversation(agent, guangzhou_shenzhen_query, session1Id, provider);
if (!result3.success) {
return { success: false, error: `Session 1 continuation failed: ${result3.error}` };
}
// ========================================================================
// Show final session status and conversation histories
// ========================================================================
console.log(`\n${'='.repeat(70)}`);
console.log('π Final Session Status and Conversation Histories');
console.log(`${'='.repeat(70)}`);
showSessionStatus(agent, provider);
// Show conversation history for each session
const sessions = agent.getSessions();
for (let i = 0; i < sessions.length; i++) {
const session = sessions[i];
console.log(`\n\n\nπ Session ${i + 1} (${session.title} ) Conversation History:`);
console.log(`${'β'.repeat(40)}`);
// let history = agent.sessionManager.getSession(session.id)!.messageHistory;
// Switch to session to get its history
agent.switchToSession(session.id);
const history = agent.getChat().getHistory();
let messageCount = 0;
for (const message of history) {
messageCount++;
console.log(` ${message.role}: ${JSON.stringify(message.content, null, 2)}`);
}
if (messageCount === 0) {
console.log(' (No conversation messages)');
}
}
// Show token usage summary
console.log(`\nπ [${provider}] Token Usage Summary:`);
const finalStatus = agent.getStatus();
console.log(` β’ Input tokens: ${finalStatus.tokenUsage.inputTokens}`);
console.log(` β’ Output tokens: ${finalStatus.tokenUsage.outputTokens}`);
console.log(` β’ Total tokens: ${finalStatus.tokenUsage.totalTokens}`);
console.log(` β’ Usage: ${finalStatus.tokenUsage.usagePercentage.toFixed(2)}%`);
console.log(`\nβ
[${provider}] Session management test completed successfully!`);
console.log('\nπ― Demonstrated Features:');
console.log(' β’ Created multiple isolated conversation sessions');
console.log(' β’ Switched between sessions while preserving context');
console.log(' β’ Each session maintained independent conversation history');
console.log(' β’ Session metadata tracking (creation time, activity, token usage)');
console.log(' β’ Session-aware weather comparisons across different city pairs');
return { success: true };
} catch (error) {
console.error(`β [${provider}] Session management test failed:`, error);
return { success: false, error: error instanceof Error ? error.message : String(error) };
}
}
/**
* Main demonstration function
*/
async function main() {
console.log('π Session Manager Example');
console.log('===========================\n');
console.log('This example demonstrates:');
console.log('β’ Creating multiple conversation sessions');
console.log('β’ Session-isolated weather comparisons:');
console.log(' - Session 1: Beijing vs Shanghai');
console.log(' - Session 2: Shanghai vs Guangzhou');
console.log(' - Back to Session 1: Guangzhou vs Shenzhen');
console.log('β’ Session state management and history preservation\n');
// Configure logger
configureLogger({
level: LogLevel.INFO,
autoDetectContext: true,
includeTimestamp: true,
enableColors: true,
});
// Determine provider from environment or default to gemini
const provider = (process.env.CHAT_PROVIDER as 'gemini' | 'openai') || 'openai';
console.log(`π§ͺ Testing with provider: ${provider.toUpperCase()}`);
// Run the session management test
const result = await testSessionManagement(provider);
if (result.success) {
console.log('\nβ
Session Manager Example completed successfully!');
} else {
console.log(`\nβ Session Manager Example failed: ${result.error}`);
process.exit(1);
}
}
// Handle graceful shutdown
process.on('SIGINT', () => {
console.log('\nπ Received interrupt signal, shutting down...');
process.exit(0);
});
// Run the example
if (import.meta.url === `file://${process.argv[1]}`) {
main().catch(console.error);
}
export { main as runSessionManagerExample };