Astreus - Docs

Chat

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()
  }
});
// 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?