The Voice Agent SDK provides comprehensive conversation history management with configurable memory limits, automatic trimming, and methods to persist and restore conversation state.
import { VoiceAgent } from 'voice-agent-ai-sdk';const agent = new VoiceAgent({ /* ... */ });await agent.sendText("What's the weather?");await agent.sendText("How about tomorrow?");const history = agent.getHistory();console.log(`Total messages: ${history.length}`);history.forEach((msg, i) => { console.log(`${i + 1}. [${msg.role}] ${msg.content}`);});
Output:
Total messages: 41. [user] What's the weather?2. [assistant] It's currently 72°F and sunny.3. [user] How about tomorrow?4. [assistant] Tomorrow will be partly cloudy with a high of 68°F.
import { ModelMessage } from 'ai';// Load history from database/storageconst savedHistory: ModelMessage[] = await loadFromDatabase(sessionId);// Restore to agentagent.setHistory(savedHistory);// Continue conversation with contextawait agent.sendText("What were we talking about?");
setHistory()replaces the entire conversation history. It does not append.
Configure automatic history limits to manage memory and context window usage:
const agent = new VoiceAgent({ model: openai('gpt-4o'), history: { maxMessages: 50, // Keep last 50 messages maxTotalChars: 100_000 // Or trim when total exceeds 100k chars }});
Maximum number of messages to keep in history. When exceeded, oldest messages are trimmed in pairs (user + assistant) to preserve conversation turns.Set to 0 for unlimited.
history: { maxMessages: 50 // Keep last 50 messages}
Maximum total character count across all messages. When exceeded, oldest messages are trimmed one at a time until under the limit.Set to 0 for unlimited (default).
history: { maxTotalChars: 100_000 // 100k character limit}
// From ConversationManager.ts:74-121private trimHistory(): void { const { maxMessages, maxTotalChars } = this.historyConfig; // Trim by message count if (maxMessages > 0 && this.conversationHistory.length > maxMessages) { const excess = this.conversationHistory.length - maxMessages; // Round up to even number to preserve turn pairs const toRemove = excess % 2 === 0 ? excess : excess + 1; this.conversationHistory.splice(0, toRemove); this.emit('history_trimmed', { removedCount: toRemove, reason: 'max_messages', }); } // Trim by total character count if (maxTotalChars > 0) { let totalChars = this.conversationHistory.reduce((sum, msg) => { const content = typeof msg.content === 'string' ? msg.content : JSON.stringify(msg.content); return sum + content.length; }, 0); let removedCount = 0; while ( totalChars > maxTotalChars && this.conversationHistory.length > 2 ) { const removed = this.conversationHistory.shift(); if (removed) { const content = typeof removed.content === 'string' ? removed.content : JSON.stringify(removed.content); totalChars -= content.length; removedCount++; } } if (removedCount > 0) { this.emit('history_trimmed', { removedCount, reason: 'max_total_chars', }); } }}
Important: When trimming by maxMessages, messages are removed in pairs (user + assistant) to maintain conversation turn structure. When trimming by maxTotalChars, messages are removed one at a time.
import { VoiceAgent } from 'voice-agent-ai-sdk';import { db } from './database';const agent = new VoiceAgent({ /* ... */ });// Save after each interactionagent.on('text', async ({ role, text }) => { if (role === 'assistant') { const history = agent.getHistory(); await db.conversations.update(sessionId, { history: JSON.stringify(history), lastUpdated: new Date() }); }});// Or save periodicallysetInterval(async () => { const history = agent.getHistory(); await db.conversations.update(sessionId, { history: JSON.stringify(history) });}, 60000); // Every minute
async function restoreConversation(sessionId: string) { // Load from database const session = await db.conversations.findById(sessionId); if (!session) { throw new Error('Session not found'); } // Parse history const history = JSON.parse(session.history); // Create agent with restored history const agent = new VoiceAgent({ model: openai('gpt-4o'), // ... other config }); agent.setHistory(history); return agent;}// Usageconst agent = await restoreConversation('session-123');await agent.sendText('Continue where we left off');
function clearHistoryIfNeeded(agent: VoiceAgent) { const history = agent.getHistory(); // Clear if last message was more than 1 hour ago const lastMessage = history[history.length - 1]; if (lastMessage && isOlderThan(lastMessage, 60 * 60 * 1000)) { console.log('Clearing stale conversation'); agent.clearHistory(); return true; } return false;}// Check on new inputagent.on('text', ({ role }) => { if (role === 'user') { clearHistoryIfNeeded(agent); }});
VideoAgent extends history management with frame context:
import { VideoAgent } from 'voice-agent-ai-sdk';const videoAgent = new VideoAgent({ model: openai('gpt-4o'), // Vision-enabled model required maxContextFrames: 10, // Keep last 10 frames in context history: { maxMessages: 50 }});// Get frame contextconst frameContext = videoAgent.getFrameContext();console.log(`Frames in context: ${frameContext.length}`);// Clear both message and frame historyvideoAgent.clearHistory();