Skip to content

Use Cases & Patterns

DialogueDB is designed for a wide range of conversational applications. This guide covers common use cases and implementation patterns to help you build robust AI-powered experiences.

AI Chatbots

Build intelligent chatbots with persistent conversation history.

Basic Chatbot Pattern

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

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

async function handleUserMessage(dialogueId: string | null, userInput: string) {
  // Create new dialogue or use existing
  let dialogue;
  if (!dialogueId) {
    dialogue = await db.createDialogue({
      message: {
        role: 'system',
        content: 'You are a helpful customer support assistant.'
      }
    });
    dialogueId = dialogue.id;
  } else {
    dialogue = await db.getDialogue(dialogueId);
  }

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

  // Get conversation history for context
  const messages = await dialogue.loadMessages({});

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

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

  return { dialogueId, response: aiResponse };
}

Stateful Chatbot

Track conversation state for complex interactions:

typescript
async function handleStatefulChat(dialogueId: string, userInput: string) {
  // Get current dialogue with state
  const dialogue = await db.getDialogue(dialogueId);
  const currentState = dialogue.state || {};

  // Process intent
  const intent = detectIntent(userInput);

  // Update state based on conversation flow
  let newState = { ...currentState };

  if (intent === 'book_appointment') {
    newState = {
      ...currentState,
      flow: 'booking',
      step: 'date_selection',
      collectedData: {}
    };
  } else if (intent === 'provide_date' && currentState.flow === 'booking') {
    newState = {
      ...currentState,
      step: 'time_selection',
      collectedData: {
        ...currentState.collectedData,
        date: extractDate(userInput)
      }
    };
  }

  // Update dialogue state
  await dialogue.saveState(newState);

  // Continue conversation based on state
  const response = generateResponseForState(newState);

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

  return response;
}

Customer Support

Provide contextual customer support with full conversation history.

Support Ticket Integration

typescript
async function createSupportTicket(userId: string, issue: string) {
  // Create dialogue with metadata and tags
  const dialogue = await db.createDialogue({
    metadata: {
      userId,
      ticketId: generateTicketId(),
      priority: 'normal',
      department: 'general'
    },
    tags: ['support', 'customer-inquiry'],
    message: {
      role: 'user',
      content: issue
    }
  });

  // Auto-respond with acknowledgment
  await dialogue.saveMessage({
    role: 'assistant',
    content: 'Thank you for contacting support. A team member will assist you shortly.'
  });

  return dialogue.id;
}

// Agent handoff
async function agentTakeover(dialogueId: string, agentId: string) {
  const dialogue = await db.getDialogue(dialogueId);

  // Update state to indicate human agent
  await dialogue.saveState({
    handedOff: true,
    agentId,
    handoffTime: new Date().toISOString()
  });

  await dialogue.saveMessage({
    role: 'system',
    content: `Agent ${agentId} has joined the conversation.`
  });
}

Multi-Channel Support

Track conversations across different channels:

typescript
async function handleMultiChannelMessage(
  userId: string,
  message: string,
  channel: 'email' | 'chat' | 'phone' | 'social'
) {
  // Find or create dialogue for user
  const dialogues = await db.listDialogues({
    query: 'by-status',
    status: 'active'
  });

  const userDialogue = dialogues.items.find(
    d => d.metadata?.userId === userId
  );

  let dialogue;
  if (userDialogue) {
    dialogue = await db.getDialogue(userDialogue.id);
  } else {
    dialogue = await db.createDialogue({
      metadata: { userId },
      tags: [`channel:${channel}`]
    });
  }

  // Add message with channel info saved as a tag
  await dialogue.saveMessage({
    role: 'user',
    content: message
  });

  // Track channels via tags (metadata can't be changed after creation)
  const channelTag = `channel:${channel}`;
  if (!dialogue.tags?.includes(channelTag)) {
    dialogue.tags = [...(dialogue.tags || []), channelTag];
    await dialogue.save();
  }
}

Conversational Analytics

Track and analyze conversation patterns.

Conversation Metrics

typescript
async function analyzeDialogues(projectId: string) {
  // Get all dialogues
  const { items: dialogues } = await db.listDialogues({
    limit: 1000
  });

  // Calculate metrics
  const metrics = {
    totalDialogues: dialogues.length,
    averageMessages: dialogues.reduce((sum, d) => sum + d.totalMessages, 0) / dialogues.length,
    activeDialogues: dialogues.filter(d => d.status === 'active').length,
    completedDialogues: dialogues.filter(d => d.status === 'ended').length,
    averageThreads: dialogues.reduce((sum, d) => sum + (d.threadCount || 0), 0) / dialogues.length
  };

  return metrics;
}

// Sentiment analysis
async function analyzeSentiment(dialogueId: string) {
  const dialogue = await db.getDialogue(dialogueId);
  const messages = await dialogue.loadMessages({});

  const userMessages = messages.filter(m => m.role === 'user');

  const sentiments = userMessages.map(msg => ({
    messageId: msg.id,
    sentiment: analyzeSentimentScore(msg.content),
    timestamp: msg.created
  }));

  return {
    dialogueId,
    overallSentiment: calculateAverage(sentiments),
    sentimentTrend: sentiments
  };
}

Multi-Turn Agent Workflows

Build complex agent interactions with conversation branching.

Agent Orchestration

typescript
async function multiAgentWorkflow(userQuery: string) {
  // Create main dialogue
  const mainDialogue = await db.createDialogue({
    message: {
      role: 'user',
      content: userQuery
    },
    metadata: {
      workflow: 'multi-agent',
      stage: 'orchestration'
    }
  });

  // Route to specialized agents
  const intent = classifyIntent(userQuery);

  // Create thread for specific agent
  const agentThread = await mainDialogue.createThread({
    metadata: {
      agent: intent.agent,
      specialization: intent.domain
    }
  });

  await agentThread.saveMessage({
    role: 'system',
    content: `You are a ${intent.agent} specialized in ${intent.domain}.`
  });

  // Agent processes request
  const agentResponse = await processWithAgent(agentThread.id, userQuery);

  // Store result in main dialogue
  await mainDialogue.saveMessage({
    role: 'assistant',
    content: agentResponse
  });

  return mainDialogue.id;
}

Conversation Branching

Explore multiple conversation paths:

typescript
async function exploreAlternatives(originalDialogueId: string) {
  // Get original conversation
  const original = await db.getDialogue(originalDialogueId);
  const messages = await original.loadMessages({});
  const lastMessage = messages[messages.length - 1];

  // Create alternative response threads
  const alternatives = await Promise.all([
    createAlternative(original, 'creative', lastMessage),
    createAlternative(original, 'conservative', lastMessage),
    createAlternative(original, 'detailed', lastMessage)
  ]);

  return alternatives;
}

async function createAlternative(
  parentDialogue: any,
  style: string,
  lastMessage: any
) {
  const thread = await parentDialogue.createThread({
    metadata: {
      responseStyle: style,
      experimentId: generateExperimentId()
    }
  });

  // Generate alternative response
  const alternativeResponse = await generateWithStyle(lastMessage, style);

  await thread.saveMessage({
    role: 'assistant',
    content: alternativeResponse
  });

  return thread;
}

Long-Running Conversations

Manage extended conversations efficiently.

Conversation Compacting

typescript
async function manageLongConversation(dialogueId: string) {
  const dialogue = await db.getDialogue(dialogueId);

  // Check if conversation is getting long
  if (dialogue.totalMessages > 50) {
    // Compact conversation via REST API (not available in SDK)
    const summary = await fetch(`https://api.dialoguedb.com/v1/dialogues/${dialogueId}/actions/compact`, {
      method: 'POST',
      headers: { 'Authorization': `Bearer ${process.env.DIALOGUE_DB_API_KEY}` }
    }).then(res => res.json());

    // Create continuation with summary
    const continuation = await dialogue.createThread({
      metadata: {
        previousSummary: summary,
        continuationOf: dialogueId
      }
    });

    await continuation.saveMessage({
      role: 'system',
      content: `Previous conversation summary: ${summary}`
    });

    // End original dialogue
    await dialogue.end();

    return continuation.id;
  }

  return dialogueId;
}

Context Window Management

Keep conversations within LLM context limits:

typescript
async function getRecentContext(dialogueId: string, maxMessages: number = 20) {
  const dialogue = await db.getDialogue(dialogueId);
  const messages = await dialogue.loadMessages({});

  // Get most recent messages
  const recentMessages = messages.slice(-maxMessages);

  // If conversation is longer, include summary via REST API
  if (messages.length > maxMessages) {
    const summaryResponse = await fetch(`https://api.dialoguedb.com/v1/dialogues/${dialogueId}/actions/compact`, {
      method: 'POST',
      headers: { 'Authorization': `Bearer ${process.env.DIALOGUE_DB_API_KEY}` }
    }).then(res => res.json());

    return {
      summary: summaryResponse,
      recentMessages,
      totalMessages: messages.length
    };
  }

  return {
    recentMessages,
    totalMessages: messages.length
  };
}

Session Management

Handle user sessions and conversation resumption.

Session Persistence

typescript
async function getOrCreateSession(userId: string) {
  // Find active dialogue for user
  const { items } = await db.listDialogues({
    query: 'by-status',
    status: 'active'
  });

  const userDialogue = items.find(d =>
    d.metadata?.userId === userId &&
    d.state?.sessionActive === true
  );

  if (userDialogue) {
    // Resume existing session
    return userDialogue.id;
  }

  // Create new session
  const dialogue = await db.createDialogue({
    metadata: {
      userId
    },
    state: {
      sessionActive: true,
      sessionStart: new Date().toISOString()
    }
  });

  return dialogue.id;
}

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

  // Use state instead of metadata (metadata can't be changed after creation)
  await dialogue.saveState({
    sessionActive: false,
    sessionEnd: new Date().toISOString()
  });

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

Next Steps

Built with DialogueDB