Skip to content

Complete Examples

This page provides full end-to-end examples demonstrating real-world use cases with DialogueDB.

Example 1: Customer Support Chatbot

A complete customer support chatbot with session management, agent handoff, and conversation history.

typescript
import { DialogueDB } from 'dialogue-db';
import { generateAIResponse } from './llm-service';

const db = new DialogueDB({
  apiKey: process.env.DIALOGUE_DB_API_KEY
});

class SupportChatbot {
  async handleNewConversation(userId: string, initialMessage: string) {
    // Create dialogue with metadata (can't be changed after creation)
    const dialogue = await db.createDialogue({
      metadata: {
        userId,
        channel: 'web-chat',
        ticketId: `TICK-${Date.now()}`
      },
      tags: ['support', 'ai-chat'],
      message: {
        role: 'system',
        content: 'You are a helpful customer support assistant. Be friendly, professional, and solve problems efficiently.'
      }
    });

    // Track mutable status in state
    await dialogue.saveState({
      status: 'open',
      aiHandled: true
    });

    // Add user's initial message
    await dialogue.saveMessage({
      role: 'user',
      content: initialMessage,
      metadata: { timestamp: new Date().toISOString() }
    });

    // Generate AI response
    const response = await this.generateResponse(dialogue.id);

    return {
      dialogueId: dialogue.id,
      response
    };
  }

  async handleFollowUp(dialogueId: string, userMessage: string) {
    // Get the dialogue instance
    const dialogue = await db.getDialogue(dialogueId);

    // Add user message
    await dialogue.saveMessage({
      role: 'user',
      content: userMessage
    });

    // Load messages to check for escalation
    const messages = await dialogue.loadMessages();
    const shouldEscalate = this.checkEscalation(messages, userMessage);

    if (shouldEscalate) {
      return await this.escalateToHuman(dialogueId);
    }

    // Continue with AI
    return await this.generateResponse(dialogueId);
  }

  async generateResponse(dialogueId: string) {
    // Get conversation history
    const dialogue = await db.getDialogue(dialogueId);
    const messages = await dialogue.loadMessages();

    // Generate AI response with context
    const aiResponse = await generateAIResponse(messages);

    // Store AI response
    await dialogue.saveMessage({
      role: 'assistant',
      content: aiResponse,
      metadata: {
        generatedAt: new Date().toISOString(),
        model: 'gpt-4'
      }
    });

    return aiResponse;
  }

  checkEscalation(messages: any[], latestMessage: string): boolean {
    // Escalate if user is frustrated (multiple repeated questions)
    const userMessages = messages.filter(m => m.role === 'user');
    if (userMessages.length > 5) {
      const recentMessages = userMessages.slice(-3).map(m => m.content.toLowerCase());
      if (recentMessages.some(msg => msg.includes('speak to human') || msg.includes('agent'))) {
        return true;
      }
    }

    // Escalate for complex issues
    const complexKeywords = ['refund', 'cancellation', 'account access', 'billing issue'];
    if (complexKeywords.some(keyword => latestMessage.toLowerCase().includes(keyword))) {
      return true;
    }

    return false;
  }

  async escalateToHuman(dialogueId: string) {
    const dialogue = await db.getDialogue(dialogueId);

    // Update dialogue state with escalation info
    await dialogue.saveState({
      escalated: true,
      escalationTime: new Date().toISOString(),
      aiHandled: false,
      status: 'awaiting-agent'
    });

    // Add system message
    await dialogue.saveMessage({
      role: 'system',
      content: 'This conversation has been escalated to a human agent. An agent will be with you shortly.'
    });

    // Notify agent queue
    await this.notifyAgentQueue(dialogueId);

    return 'A human agent will be with you shortly. Thank you for your patience.';
  }

  async notifyAgentQueue(dialogueId: string) {
    // Implementation to notify your agent queue system
    console.log(`Dialogue ${dialogueId} added to agent queue`);
  }

  async endConversation(dialogueId: string, resolved: boolean) {
    const dialogue = await db.getDialogue(dialogueId);

    // Track resolution status in state
    await dialogue.saveState({
      status: resolved ? 'resolved' : 'closed',
      endedAt: new Date().toISOString()
    });

    // End the dialogue
    await dialogue.end();
  }
}

// Usage
const chatbot = new SupportChatbot();

// New conversation
const { dialogueId, response } = await chatbot.handleNewConversation(
  'user_123',
  'I need help with my order'
);

console.log('Bot:', response);

// Follow-up
const followUp = await chatbot.handleFollowUp(
  dialogueId,
  'My tracking number isn\'t working'
);

console.log('Bot:', followUp);

Example 2: Multi-Agent Research Assistant

Coordinate multiple specialized AI agents for complex research tasks.

typescript
import { DialogueDB } from 'dialogue-db';

const db = new DialogueDB({
  apiKey: process.env.DIALOGUE_DB_API_KEY
});

class ResearchAssistant {
  private agents = {
    researcher: 'Research Agent - finds and summarizes information',
    analyst: 'Analysis Agent - interprets data and identifies patterns',
    writer: 'Writing Agent - creates clear, structured reports'
  };

  async conductResearch(query: string) {
    // Create main research dialogue
    const mainDialogue = await db.createDialogue({
      metadata: {
        type: 'research-task',
        query
      },
      tags: ['research', 'multi-agent'],
      message: {
        role: 'user',
        content: query
      }
    });

    // Track mutable stage in state
    await mainDialogue.saveState({ stage: 'initiated' });

    // Phase 1: Research
    const researchResults = await this.runAgent(
      mainDialogue,
      'researcher',
      `Research the following topic thoroughly: ${query}`
    );

    // Phase 2: Analysis
    const analysis = await this.runAgent(
      mainDialogue,
      'analyst',
      `Analyze this research and identify key insights: ${researchResults}`
    );

    // Phase 3: Report Writing
    const report = await this.runAgent(
      mainDialogue,
      'writer',
      `Create a comprehensive report based on this analysis: ${analysis}`
    );

    // Store final report
    await mainDialogue.saveMessage({
      role: 'assistant',
      content: report,
      metadata: {
        type: 'final-report',
        completedAt: new Date().toISOString()
      }
    });

    // End the dialogue
    await mainDialogue.end();

    return {
      dialogueId: mainDialogue.id,
      report
    };
  }

  async runAgent(parentDialogue: any, agentType: keyof typeof this.agents, prompt: string) {
    // Create thread for this agent's work using the parent dialogue
    const agentThread = await parentDialogue.createThread({
      metadata: {
        agent: agentType,
        purpose: this.agents[agentType]
      }
    });

    // Add system prompt and task prompt
    await agentThread.saveMessage({
      role: 'system',
      content: this.agents[agentType]
    });

    await agentThread.saveMessage({
      role: 'user',
      content: prompt
    });

    // Simulate agent work (replace with actual AI call)
    const result = await this.executeAgentTask(agentType, prompt);

    // Store result
    await agentThread.saveMessage({
      role: 'assistant',
      content: result,
      metadata: {
        completedAt: new Date().toISOString()
      }
    });

    return result;
  }

  async executeAgentTask(agentType: string, prompt: string): Promise<string> {
    // Replace with actual AI implementation
    return `[${agentType} completed work for: ${prompt.substring(0, 50)}...]`;
  }
}

// Usage
const assistant = new ResearchAssistant();

const { dialogueId, report } = await assistant.conductResearch(
  'What are the latest trends in renewable energy technology?'
);

console.log('Research Complete!');
console.log('Dialogue ID:', dialogueId);
console.log('Report:', report);

Example 3: Conversation Analytics Dashboard

Build analytics to track conversation metrics and performance.

typescript
import { DialogueDB } from 'dialogue-db';

const db = new DialogueDB({
  apiKey: process.env.DIALOGUE_DB_API_KEY
});

class ConversationAnalytics {
  async getProjectMetrics(startDate: Date, endDate: Date) {
    const dialogues = await this.getAllDialogues();

    // Filter by date range
    const filtered = dialogues.filter(d => {
      const created = new Date(d.created);
      return created >= startDate && created <= endDate;
    });

    return {
      total: filtered.length,
      byStatus: this.groupByStatus(filtered),
      averageMessages: this.calculateAverage(filtered.map(d => d.totalMessages)),
      averageThreads: this.calculateAverage(filtered.map(d => d.threadCount || 0)),
      byTag: this.groupByTags(filtered),
      activeConversations: filtered.filter(d => d.status === 'active').length,
      completionRate: this.calculateCompletionRate(filtered)
    };
  }

  async getAllDialogues() {
    const allDialogues = [];
    let nextToken = null;

    do {
      const { items, next } = await db.listDialogues({
        limit: 100,
        next: nextToken
      });

      allDialogues.push(...items);
      nextToken = next;
    } while (nextToken);

    return allDialogues;
  }

  groupByStatus(dialogues: any[]) {
    return dialogues.reduce((acc, d) => {
      acc[d.status] = (acc[d.status] || 0) + 1;
      return acc;
    }, {});
  }

  groupByTags(dialogues: any[]) {
    const tagCounts: Record<string, number> = {};

    dialogues.forEach(d => {
      (d.tags || []).forEach((tag: string) => {
        tagCounts[tag] = (tagCounts[tag] || 0) + 1;
      });
    });

    return tagCounts;
  }

  calculateAverage(numbers: number[]) {
    if (numbers.length === 0) return 0;
    return numbers.reduce((sum, n) => sum + n, 0) / numbers.length;
  }

  calculateCompletionRate(dialogues: any[]) {
    const ended = dialogues.filter(d => d.status === 'ended' || d.status === 'archived').length;
    return dialogues.length > 0 ? (ended / dialogues.length) * 100 : 0;
  }

  async analyzeConversationQuality(dialogueId: string) {
    const dialogue = await db.getDialogue(dialogueId);
    const messages = await dialogue.loadMessages();

    const userMessages = messages.filter((m: any) => m.role === 'user');
    const assistantMessages = messages.filter((m: any) => m.role === 'assistant');

    return {
      dialogueId,
      totalMessages: messages.length,
      userMessages: userMessages.length,
      assistantMessages: assistantMessages.length,
      averageResponseTime: this.calculateAverageResponseTime(messages),
      conversationLength: this.calculateConversationDuration(dialogue),
      messageBalance: userMessages.length / assistantMessages.length
    };
  }

  calculateAverageResponseTime(messages: any[]) {
    // Calculate time between user message and assistant response
    const responseTimes = [];

    for (let i = 0; i < messages.length - 1; i++) {
      if (messages[i].role === 'user' && messages[i + 1].role === 'assistant') {
        const userTime = new Date(messages[i].created).getTime();
        const assistantTime = new Date(messages[i + 1].created).getTime();
        responseTimes.push(assistantTime - userTime);
      }
    }

    return responseTimes.length > 0
      ? responseTimes.reduce((sum, time) => sum + time, 0) / responseTimes.length
      : 0;
  }

  calculateConversationDuration(dialogue: any) {
    const start = new Date(dialogue.created).getTime();
    const end = new Date(dialogue.modified).getTime();
    return end - start;
  }
}

// Usage
const analytics = new ConversationAnalytics();

// Get overall metrics
const metrics = await analytics.getProjectMetrics(
  new Date('2025-01-01'),
  new Date('2025-01-31')
);

console.log('Project Metrics:', metrics);

// Analyze specific conversation
const quality = await analytics.analyzeConversationQuality('dialogue_123');
console.log('Conversation Quality:', quality);

Example 4: Session-Based Chat Application

Implement persistent chat sessions with user authentication.

typescript
import { DialogueDB } from 'dialogue-db';

const db = new DialogueDB({
  apiKey: process.env.DIALOGUE_DB_API_KEY
});

class ChatSessionManager {
  async getOrCreateSession(userId: string, sessionId?: string) {
    if (sessionId) {
      // Try to resume existing session
      try {
        const dialogue = await db.getDialogue(sessionId);
        if (dialogue.metadata?.userId === userId && dialogue.status === 'active') {
          return dialogue;
        }
      } catch (error) {
        // Session not found or expired, create new one
      }
    }

    // Create new session
    return await this.createNewSession(userId);
  }

  async createNewSession(userId: string) {
    // Metadata is set at creation time and can't be changed
    const dialogue = await db.createDialogue({
      metadata: {
        userId,
        sessionStart: new Date().toISOString()
      },
      tags: ['chat-session', `user:${userId}`]
    });

    // Use state for mutable session data
    await dialogue.saveState({
      sessionActive: true,
      preferences: await this.getUserPreferences(userId)
    });

    return dialogue;
  }

  async getUserPreferences(userId: string) {
    // Fetch from your user database
    return {
      theme: 'dark',
      language: 'en',
      notificationsEnabled: true
    };
  }

  async sendMessage(sessionId: string, userId: string, content: string) {
    // Get session dialogue and verify ownership
    const dialogue = await db.getDialogue(sessionId);

    if (dialogue.metadata?.userId !== userId) {
      throw new Error('Unauthorized access to session');
    }

    // Add user message
    await dialogue.saveMessage({
      role: 'user',
      content,
      metadata: {
        userId,
        timestamp: new Date().toISOString()
      }
    });

    // Generate and store AI response
    const aiResponse = await this.generateResponse(dialogue);

    await dialogue.saveMessage({
      role: 'assistant',
      content: aiResponse
    });

    return aiResponse;
  }

  async generateResponse(dialogue: any) {
    const messages = await dialogue.loadMessages();
    // Use your LLM service here
    return 'AI response based on conversation history';
  }

  async endSession(sessionId: string, userId: string) {
    const dialogue = await db.getDialogue(sessionId);

    if (dialogue.metadata?.userId !== userId) {
      throw new Error('Unauthorized');
    }

    // Track session end in state (metadata can't be changed)
    await dialogue.saveState({
      sessionActive: false,
      sessionEnd: new Date().toISOString()
    });

    // End the dialogue
    await dialogue.end();
  }

  async getUserSessions(userId: string) {
    const { items } = await db.listDialogues({
      limit: 100
    });

    return items.filter(d => d.metadata?.userId === userId);
  }
}

// Usage
const sessionManager = new ChatSessionManager();

// Start or resume session
const session = await sessionManager.getOrCreateSession('user_123');
console.log('Session ID:', session.id);

// Send messages
const response1 = await sessionManager.sendMessage(
  session.id,
  'user_123',
  'Hello! I need help with my account'
);

const response2 = await sessionManager.sendMessage(
  session.id,
  'user_123',
  'Can you check my subscription status?'
);

// End session
await sessionManager.endSession(session.id, 'user_123');

// Get all sessions for user
const userSessions = await sessionManager.getUserSessions('user_123');
console.log(`User has ${userSessions.length} total sessions`);

Next Steps

Built with DialogueDB