Chat
The Chat System in Astreus is agent-centric and provides powerful real-time streaming capabilities with advanced chat management. The enhanced chat service features improved response handling, robust conversation history management, and seamless provider compatibility. Everything flows through the agent with built-in session management, chat organization, and metadata support.
Agent-Centric Chat Architecture
With the enhanced approach, chat functionality is built directly into agents with full chat management:
// ✅ Enhanced Agent-Centric Approach with Chat Management
const agent = await createAgent({
name: 'ChatAgent',
provider: myProvider,
memory: myMemory,
chat: myChatManager // Chat management system
});
// Create structured chats with metadata
const chat = await agent.createChat({
chatId: "consultation-123",
title: "Business Consultation",
metadata: { type: "business", priority: "high" }
});
// Real-time streaming chat
await agent.chat({
message: "Hello!",
sessionId: "consultation-123",
stream: true,
onChunk: (chunk) => console.log(chunk)
});
// Standard chat with chat IDs
const response = await agent.chatWithId({
message: "How are you?",
chatId: "consultation-123"
});
// Advanced chat management
const chats = await agent.listChats({ status: 'active' });
const stats = await agent.getChatStats();
const searchResults = await agent.searchChats({ query: "business" });
// Legacy session management (still supported)
const sessions = await agent.listSessions();
const history = await agent.getHistory("session-123");
Chat Management
Create, organize, and manage structured chats with metadata and lifecycle management:
Creating and Managing Chats
import { createAgent, createProvider, createMemory, createDatabase, createChat } from '@astreus-ai/astreus';
async function setupChatAgent() {
const db = await createDatabase();
const memory = await createMemory({ database: db });
const chatManager = await createChat({
database: db,
memory: memory,
tableName: "chats",
maxChats: 100,
autoGenerateTitles: true
});
const provider = createProvider({
type: 'openai',
model: 'gpt-4o-mini',
apiKey: process.env.OPENAI_API_KEY
});
return await createAgent({
name: 'ChatManagementAgent',
provider: provider,
memory: memory,
chat: chatManager,
systemPrompt: "You are a helpful assistant with advanced chat management."
});
}
const agent = await setupChatAgent();
// Create a new chat with metadata
const chat = await agent.createChat({
chatId: "support-ticket-456",
userId: "user-123",
title: "Technical Support Request",
metadata: {
type: "support",
priority: "high",
department: "technical",
language: "en",
tags: ["bug", "urgent"]
}
});
// Get chat details
const chatDetails = await agent.getChat("support-ticket-456");
console.log('Chat created:', chatDetails);
// Update chat metadata
await agent.updateChat("support-ticket-456", {
title: "Resolved: Technical Support Request",
metadata: {
...chatDetails.metadata,
status: "resolved",
resolvedAt: new Date().toISOString()
}
});
Chat Organization and Search
// List chats with filtering
const activeChats = await agent.listChats({
userId: "user-123",
status: 'active',
limit: 20,
offset: 0
});
console.log(`Found ${activeChats.length} active chats`);
// Search chats by content
const searchResults = await agent.searchChats({
query: "technical support",
userId: "user-123",
limit: 10
});
console.log(`Found ${searchResults.length} matching chats`);
// Get comprehensive chat statistics
const stats = await agent.getChatStats({
userId: "user-123"
});
console.log(`Total chats: ${stats.totalChats}`);
console.log(`Active chats: ${stats.activeChats}`);
console.log(`Archived chats: ${stats.archivedChats}`);
console.log(`Total messages: ${stats.totalMessages}`);
// Archive old chats
await agent.archiveChat("old-chat-id");
// Delete unwanted chats permanently
await agent.deleteChat("spam-chat-id");
Real-Time Streaming Chat
The enhanced chat system provides real-time streaming with both chat IDs and legacy session support:
Streaming with Session IDs
// Real-time streaming with enhanced response handling
await agent.chat({
message: "Explain machine learning in simple terms",
sessionId: "ml-tutorial-789",
temperature: 0.7,
maxTokens: 1000,
metadata: { topic: 'education', level: 'beginner' },
stream: true,
onChunk: (chunk) => {
// Each chunk arrives in real-time with improved provider compatibility
process.stdout.write(chunk);
// Send to frontend via WebSocket
// websocket.send(JSON.stringify({ type: 'chunk', content: chunk }));
}
});
Streaming with Chat IDs
// Streaming with chat ID and user management
await agent.chat({
message: "Tell me about quantum computing",
sessionId: "physics-discussion",
temperature: 0.6,
stream: true,
onChunk: (chunk) => {
console.log('Chunk:', chunk);
}
});
WebSocket Integration with Chat Management
Here's how to integrate streaming with WebSocket for real-time frontend updates with chat management:
import WebSocket from 'ws';
import { createAgent, createProvider, createMemory, createDatabase, createChat } from '@astreus-ai/astreus';
// WebSocket server for real-time streaming with chat management
const wss = new WebSocket.Server({ port: 8080 });
async function setupAgent() {
const db = await createDatabase();
const memory = await createMemory({ database: db });
const chatManager = await createChat({ database: db, memory: memory });
const provider = createProvider({ type: 'openai', model: 'gpt-4o-mini' });
return await createAgent({
name: 'StreamingChatAgent',
provider: provider,
memory: memory,
chat: chatManager,
systemPrompt: "You are a helpful assistant that provides detailed, informative responses."
});
}
wss.on('connection', async (ws) => {
const agent = await setupAgent();
ws.on('message', async (data) => {
const { action, message, chatId, userId, ...params } = JSON.parse(data.toString());
try {
if (action === 'create_chat') {
// Create a new chat
const chat = await agent.createChat({
chatId,
userId,
title: params.title || "New Conversation",
metadata: params.metadata || {}
});
ws.send(JSON.stringify({
type: 'chat_created',
chat
}));
return;
}
if (action === 'list_chats') {
// List user's chats
const chats = await agent.listChats({
userId,
status: 'active',
limit: 20
});
ws.send(JSON.stringify({
type: 'chats_list',
chats
}));
return;
}
if (action === 'stream_chat') {
// Stream response to client in real-time
await agent.chat({
message,
sessionId: chatId,
stream: true,
onChunk: (chunk) => {
ws.send(JSON.stringify({
type: 'chunk',
content: chunk,
chatId
}));
}
});
// Signal completion
ws.send(JSON.stringify({
type: 'complete',
chatId
}));
}
} catch (error) {
ws.send(JSON.stringify({
type: 'error',
message: error.message
}));
}
});
});
console.log('WebSocket server with chat management running on ws://localhost:8080');
Frontend Integration Example
Here's how to connect from a frontend application:
// Frontend WebSocket client
const ws = new WebSocket('ws://localhost:8080');
// Create a new chat
function createChat(userId, title, metadata = {}) {
const chatId = `chat-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
ws.send(JSON.stringify({
action: 'create_chat',
chatId,
userId,
title,
metadata
}));
return chatId;
}
// List user's chats
function listChats(userId) {
ws.send(JSON.stringify({
action: 'list_chats',
userId
}));
}
// Send a streaming message
function sendMessage(message, chatId, userId) {
ws.send(JSON.stringify({
action: 'stream_chat',
message,
chatId,
userId
}));
}
// Handle incoming messages
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
switch (data.type) {
case 'chat_created':
console.log('Chat created:', data.chat);
break;
case 'chats_list':
console.log('User chats:', data.chats);
break;
case 'chunk':
// Display chunk in real-time
document.getElementById('response').innerHTML += data.content;
break;
case 'complete':
console.log('Response complete for chat:', data.chatId);
break;
case 'error':
console.error('Error:', data.message);
break;
}
};
// Example usage
const userId = 'user-123';
const chatId = createChat(userId, 'AI Discussion', { topic: 'technology' });
setTimeout(() => {
sendMessage('Hello! Tell me about artificial intelligence.', chatId, userId);
}, 1000);
Standard Chat (Non-Streaming)
For scenarios where streaming isn't needed:
Basic Chat with Session IDs
// Simple chat with session ID
const response = await agent.chat({
message: "What's the capital of France?",
sessionId: "geography-session",
temperature: 0.3
});
console.log('Response:', response);
Chat with Chat IDs and User Management
// Enhanced chat with chat ID and user context
const response = await agent.chatWithId({
message: "Help me understand quantum physics",
chatId: "physics-tutorial",
userId: "student-456",
systemPrompt: "You are a physics teacher. Explain concepts clearly with examples.",
temperature: 0.7,
maxTokens: 800,
metadata: { subject: 'physics', level: 'intermediate' }
});
console.log('Teacher response:', response);
Chat Configuration
Configure the chat system with various options:
const chatManager = await createChat({
database: db,
memory: memory,
tableName: "custom_chats", // Custom table name
maxChats: 200, // Maximum chats to retrieve at once
autoGenerateTitles: true // Auto-generate titles from first message
});
const agent = await createAgent({
name: 'ConfiguredAgent',
provider: provider,
memory: memory,
chat: chatManager,
systemPrompt: "You are a helpful assistant with custom chat configuration."
});
Memory Integration
The chat system seamlessly integrates with the memory system:
// Chat IDs work as session IDs in memory
const chatId = "consultation-123";
// Chat with the agent
await agent.chatWithId({
message: "Hello, I need help with exports",
chatId: chatId,
userId: "business-user"
});
// Get conversation history using the same chat ID
const history = await agent.getHistory(chatId);
console.log(`Found ${history.length} messages in chat`);
// Add custom memory entries
await agent.addToMemory({
sessionId: chatId,
role: 'system',
content: "User is interested in export regulations",
metadata: { context: 'business_consultation' }
});
// Clear chat messages
await agent.clearHistory(chatId);
Chat Metadata and Organization
Use metadata to organize and track conversations:
// Create chats with rich metadata
const supportChat = await agent.createChat({
chatId: "support-001",
userId: "customer-123",
title: "Payment Issue",
metadata: {
type: "support",
category: "billing",
priority: "high",
assignedTo: "agent-sarah",
created: new Date().toISOString(),
tags: ["payment", "urgent", "billing"],
customerTier: "premium"
}
});
const salesChat = await agent.createChat({
chatId: "sales-002",
userId: "prospect-456",
title: "Product Demo Request",
metadata: {
type: "sales",
stage: "demo",
product: "enterprise",
source: "website",
expectedValue: 50000,
followUpDate: "2024-02-15"
}
});
// Search by metadata patterns
const highPriorityChats = await agent.searchChats({
query: "priority high",
userId: "customer-123"
});
const billingChats = await agent.searchChats({
query: "billing payment",
limit: 10
});
Chat Lifecycle Management
Manage chat states and lifecycle:
// Archive completed chats
await agent.archiveChat("completed-consultation");
// Delete spam or test chats
await agent.deleteChat("test-chat-001");
// Update chat status
await agent.updateChat("support-001", {
metadata: {
status: "resolved",
resolvedBy: "agent-sarah",
resolvedAt: new Date().toISOString(),
resolution: "Payment processed successfully"
}
});
// Get chat statistics for reporting
const userStats = await agent.getChatStats({
userId: "customer-123"
});
console.log(`Customer has ${userStats.totalChats} total chats`);
console.log(`${userStats.activeChats} are currently active`);
console.log(`${userStats.archivedChats} have been archived`);
Best Practices
1. Use Chat IDs for Structured Conversations
// ✅ Good: Use chat IDs for business conversations
await agent.chatWithId({
message: "I need help with my order",
chatId: "order-support-789",
userId: "customer-123"
});
// ⚠️ Acceptable: Session IDs for simple interactions
await agent.chat({
message: "What's the weather?",
sessionId: "weather-query"
});
2. Leverage Metadata for Organization
// ✅ Good: Rich metadata for business context
await agent.createChat({
chatId: "consultation-456",
userId: "business-user",
title: "Export Compliance Consultation",
metadata: {
type: "consultation",
department: "compliance",
urgency: "high",
regulations: ["ITAR", "EAR"],
industry: "aerospace"
}
});
3. Use Streaming for Long Responses
// ✅ Good: Stream long explanations
await agent.chat({
message: "Explain the complete export licensing process",
sessionId: "licensing-tutorial",
stream: true,
onChunk: (chunk) => updateProgressiveUI(chunk)
});
4. Implement Proper Error Handling
try {
await agent.chatWithId({
message: "Help me",
chatId: "support-chat",
userId: "user123"
});
} catch (error) {
if (error.message.includes('ChatManager is required')) {
console.error('Chat manager not configured');
} else {
console.error('Chat error:', error);
}
}
5. Regular Chat Maintenance
// Archive old chats periodically
const oldChats = await agent.listChats({
status: 'active',
limit: 100
});
for (const chat of oldChats) {
const daysSinceUpdate = (Date.now() - chat.updatedAt.getTime()) / (1000 * 60 * 60 * 24);
if (daysSinceUpdate > 30) {
await agent.archiveChat(chat.id);
}
}
Next Steps
- Learn about Memory for conversation storage
- Explore Agents for the complete agent interface
- Check out Providers for different LLM options
- See Tasks for complex operation management
- Review Plugins for extending chat capabilities
How is this guide?