Astreus - Documentation
Guides

Quick Start Guide

This guide will help you get started with Astreus by setting up your development environment and creating your first AI agent with streaming capabilities and advanced chat management.

Installation

Install Astreus via npm:

npm install @astreus-ai/astreus

Or using yarn:

yarn add @astreus-ai/astreus

Environment Setup

Create a .env file in your project root with your API keys:

# OpenAI API Key (Required for OpenAI provider)
OPENAI_API_KEY=your_openai_api_key

# Database Configuration (tables created automatically when needed)
DATABASE_TYPE=sqlite  # or postgresql
DATABASE_PATH=./astreus.db  # Only for SQLite
# DATABASE_URL=postgresql://user:password@localhost:5432/astreus  # For PostgreSQL

# Ollama Configuration (Optional)
# OLLAMA_BASE_URL=http://localhost:11434

# Logging
LOG_LEVEL=info  # debug, info, warn, error

Creating Your First Agent with Chat Management

With Astreus, everything revolves around the Agent with enhanced chat management. Each component automatically creates its required database tables when first used. Create a file named my-agent.js (or .ts if using TypeScript):

import { 
  createAgent, 
  createProvider,
  createMemory,
  createDatabase,
  createChat,
  logger
} from '@astreus-ai/astreus';

async function main() {
  try {
    // Initialize the database (no need to setup schema)
    const db = await createDatabase();
    
    // Create memory instance (automatically creates memories table)
    const memory = await createMemory({
      database: db,
      tableName: "conversations" // Custom table name
    });

    // Create chat manager instance (automatically creates chats table)
    const chatManager = await createChat({
      database: db,
      memory: memory,
      tableName: "chats", // Custom table name
      maxChats: 100,
      autoGenerateTitles: true
    });

    // Configure your provider
    const provider = createProvider({
      type: 'openai',
      model: 'gpt-4o-mini'  // Fast and affordable option
    });

    // Create an agent - automatically creates agents table when needed
    const agent = await createAgent({
      name: 'MyFirstAgent',
      description: 'A helpful AI assistant with streaming and chat management capabilities',
      provider: provider,
      memory: memory,
      chat: chatManager, // Chat management system
      systemPrompt: "You are a friendly and helpful AI assistant. Answer questions concisely and accurately."
    });

    // 📊 Create a structured chat with metadata
    console.log('=== Creating Chat ===');
    const chat = await agent.createChat({
      chatId: "welcome-chat-123",
      userId: "user-456",
      title: "Welcome Conversation",
      metadata: {
        type: "onboarding",
        priority: "normal",
        language: "en"
      }
    });
    console.log('Chat created:', chat);

    // 🚀 Basic chat with chat ID (recommended)
    console.log('\n=== Basic Chat with Chat ID ===');
    const response = await agent.chatWithId({
      message: "Hello! What can you do for me?",
      chatId: "welcome-chat-123",
      userId: "user-456"
    });
    console.log('Agent:', response);

    // ⚡ Streaming chat with chat ID (real-time responses)
    console.log('\n=== Streaming Chat with Chat ID ===');
    const streamResponse = await agent.streamChatWithId({
      message: "Tell me about the benefits of AI in 3 points",
      chatId: "welcome-chat-123",
      userId: "user-456",
      onChunk: (chunk) => {
        process.stdout.write(chunk); // Print each chunk as it arrives
      }
    });
    console.log('\n✅ Streaming complete!');

    // 📊 Chat management operations
    console.log('\n=== Chat Management ===');
    
    // List chats
    const chats = await agent.listChats({
      userId: "user-456",
      status: 'active',
      limit: 10
    });
    console.log(`Found ${chats.length} active chats`);

    // Get chat statistics
    const stats = await agent.getChatStats({
      userId: "user-456"
    });
    console.log(`Total chats: ${stats.totalChats}, Messages: ${stats.totalMessages}`);

    // Search chats
    const searchResults = await agent.searchChats({
      query: "AI benefits",
      userId: "user-456",
      limit: 5
    });
    console.log(`Found ${searchResults.length} matching chats`);

    // 📊 Check session history (works with chat IDs)
    console.log('\n=== Session History ===');
    const history = await agent.getHistory("welcome-chat-123");
    console.log(`Found ${history.length} messages in chat`);

    // 📋 List all sessions (legacy support)
    console.log('\n=== All Sessions ===');
    const sessions = await agent.listSessions();
    sessions.forEach(session => {
      console.log(`Session: ${session.sessionId} (${session.messageCount} messages)`);
    });
    
  } catch (error) {
    logger.error('Error:', error);
  }
}

main();

Run your agent:

node my-agent.js

Database Table Creation

One of the key improvements in Astreus is automatic table creation. Each module creates its required tables when first used:

// These operations automatically create their respective tables:

// Creates 'conversations' table when first called
const memory = await createMemory({
  database: db,
  tableName: "conversations"
});

// Creates 'chats' table when first called  
const chatManager = await createChat({
  database: db,
  memory: memory,
  tableName: "chats"
});

// Creates 'agents' table when agent is saved
const agent = await createAgent({
  name: 'MyAgent',
  provider: provider,
  memory: memory
});

// Creates 'tasks' table when task is created
const task = await createTask({
  name: 'ProcessData',
  description: 'Process the data'
});

// Creates 'users' table when user is created
const userId = await createUser('john_doe');

Real-Time Streaming with Chat Management

Here's how to implement real-time streaming with chat management in a web application:

import { createAgent, createProvider, createMemory, createDatabase, createChat } from '@astreus-ai/astreus';
import WebSocket from 'ws';

// WebSocket server for real-time streaming with chat management
const wss = new WebSocket.Server({ port: 8080 });

async function setupAgent() {
  const db = await createDatabase();
  
  // Tables created automatically when modules are used
  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 === 'chat_stats') {
        // Get chat statistics
        const stats = await agent.getChatStats({ userId });
        
        ws.send(JSON.stringify({ 
          type: 'chat_stats', 
          stats 
        }));
        return;
      }
      
      if (action === 'stream_chat') {
        // Stream response to client in real-time
        await agent.streamChatWithId({
          message,
          chatId,
          userId,
          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);

Adding Custom Tools

Enhance your agent with custom capabilities:

import { createAgent, createProvider, createMemory, createDatabase, createChat } from '@astreus-ai/astreus';

// Create a weather tool
const weatherTool = {
  name: "get_weather",
  description: "Get current weather information for a city",
  parameters: [
    {
      name: "city",
      type: "string",
      description: "The city name to get weather for",
      required: true
    }
  ],
  execute: async (params) => {
    // In a real app, you'd call a weather API
    return {
      success: true,
      output: `The weather in ${params.city} is sunny with 22°C`
    };
  }
};

async function main() {
  const db = await createDatabase();
  
  // Tables created automatically
  const memory = await createMemory({ database: db });
  const chatManager = await createChat({ database: db, memory: memory });
  const provider = createProvider({ type: 'openai', model: 'gpt-4o-mini' });

  // Create agent with tools
  const agent = await createAgent({
    name: 'WeatherAgent',
    provider: provider,
    memory: memory,
    chat: chatManager,
    tools: [weatherTool], // Add tools here
    systemPrompt: "You are a helpful assistant that can provide weather information. Use the get_weather tool when asked about weather."
  });

  // Add more tools dynamically
  const calculatorTool = {
    name: "calculator",
    description: "Perform mathematical calculations",
    parameters: [
      {
        name: "expression",
        type: "string",
        description: "Mathematical expression to evaluate",
        required: true
      }
    ],
    execute: async (params) => {
      try {
        // Use a proper math parser in production
        const result = Function(`'use strict'; return (${params.expression})`)();
        return { success: true, output: `Result: ${result}` };
      } catch (error) {
        return { success: false, error: error.message };
      }
    }
  };

  // Add tool to existing agent
  agent.addTool(calculatorTool);

  // Test the tools
  console.log('Available tools:', agent.getAvailableTools());

  // Chat with tool usage
  const response = await agent.streamChat({
    message: "What's the weather in London and what's 15 * 24?",
    sessionId: "tools-session",
    onChunk: (chunk) => process.stdout.write(chunk)
  });
}

main();

Memory and Session Management

Access and manage conversation history:

async function memoryExample() {
  const agent = await setupAgent(); // Your agent setup

  // Add custom memory entries
  await agent.addToMemory({
    sessionId: "custom-session",
    role: 'system',
    content: "User prefers detailed explanations",
    metadata: { preference: 'detailed' }
  });

  // Get conversation history
  const history = await agent.getHistory("custom-session", 10);
  console.log('Recent messages:', history);

  // Clear a session
  await agent.clearHistory("old-session");

  // List all sessions with metadata
  const sessions = await agent.listSessions(20);
  sessions.forEach(session => {
    console.log(`Session: ${session.sessionId}`);
    console.log(`Last message: ${session.lastMessage}`);
    console.log(`Messages: ${session.messageCount}`);
    console.log(`Last activity: ${session.lastActivity}`);
  });

  // Access memory directly for advanced operations
  const memory = agent.config.memory;
  const searchResults = await memory.searchByText("weather", 5);
  console.log('Weather-related messages:', searchResults);
}

Advanced Configuration

Access all components through the agent:

async function advancedExample() {
  const agent = await setupAgent();

  // Access provider
  const provider = agent.getProvider();
  if (provider) {
    console.log('Available models:', provider.listModels());
    console.log('Current model:', agent.getModel().name);
  }

  // Access database directly
  const db = agent.config.database;
  const customQuery = await db.knex('memories')
    .where('agentId', agent.id)
    .count('* as total');
  console.log('Total memories:', customQuery[0].total);

  // Access memory for advanced operations
  const memory = agent.config.memory;
  const agentMemories = await memory.getByAgent(agent.id, 50);
  console.log(`Agent has ${agentMemories.length} memories`);

  // Switch models dynamically
  const newModel = provider?.getModel('gpt-4');
  if (newModel) {
    agent.config.model = newModel;
    console.log('Switched to GPT-4');
  }
}

Next Steps

Now that you have a working agent with streaming capabilities and automatic table creation:

  1. Explore Concepts: Learn about Agents, Memory, and Chat
  2. Add Plugins: Check out Custom Plugins to extend functionality
  3. Setup RAG: Follow the RAG Setup Guide for document search capabilities
  4. Production Deployment: Configure PostgreSQL and proper error handling for production use

Troubleshooting

Tables not created automatically?

  • Check database connection and permissions
  • Ensure you're calling the create functions (createMemory, createChat, etc.)
  • Verify database type is supported (SQLite or PostgreSQL)

Streaming not working?

  • Ensure you're using OpenAI provider with a valid API key
  • Check that onChunk callback is properly defined
  • Verify your model supports streaming (most OpenAI models do)

Memory issues?

  • Check database connection and table creation
  • Verify session IDs are consistent
  • Use agent.getHistory() to debug conversation flow

Tool not being called?

  • Ensure tool description clearly explains when to use it
  • Check parameter definitions match expected input
  • Use detailed system prompts that mention available tools

How is this guide?