Skip to content

Persistent Conversations

Overview

Persistent conversations allow you to save and restore agent conversation history, enabling continuity across sessions and application restarts. This is essential for building chatbots and applications that maintain context over time.

Quick Start

csharp
using LlmTornado.Agents;

TornadoAgent agent = new TornadoAgent(api, ChatModel.OpenAi.Gpt41.V41Mini);

// First conversation
Conversation result = await agent.RunAsync("My name is Alice and I like programming.");

// Save conversation
result.Messages.ToList().SaveConversation("conversation.json");

// Later, load and continue
List<ChatMessage> messages = new List<ChatMessage>();
await messages.LoadMessagesAsync("conversation.json");

Conversation continued = await agent.RunAsync(
    "What's my name?",
    appendMessages: messages
);
// Output: "Your name is Alice."

Saving Conversations

Save to File

csharp
Conversation result = await agent.RunAsync("Hello, I'm working on a C# project.");

// Save to JSON file
result.Messages.ToList().SaveConversation("my-conversation.json");

// Save to specific path
result.Messages.ToList().SaveConversation("/path/to/conversations/session-123.json");

Loading Conversations

Load from File

csharp
List<ChatMessage> messages = new List<ChatMessage>();
await messages.LoadMessagesAsync("my-conversation.json");

// Continue conversation with loaded history
Conversation result = await agent.RunAsync(
    "What were we discussing?",
    appendMessages: messages
);

Conversation Management

Trimming History

csharp
// Trim old messages to manage token limits
List<ChatMessage> messages = result.Messages.ToList();

// Keep only last N messages
int maxMessages = 20;
if (messages.Count > maxMessages)
{
    messages = messages.Skip(messages.Count - maxMessages).ToList();
}

// Continue with trimmed history
Conversation continued = await agent.RunAsync(input, appendMessages: messages);

Selective Preservation

csharp
// Keep system message and recent exchanges
List<ChatMessage> messages = result.Messages.ToList();

// Preserve system message
ChatMessage? systemMsg = messages.FirstOrDefault(m => m.Role == ChatMessageRoles.System);

// Get recent messages
List<ChatMessage> recentMessages = messages.TakeLast(10).ToList();

// Combine
List<ChatMessage> preservedMessages = new List<ChatMessage>();
if (systemMsg != null)
{
    preservedMessages.Add(systemMsg);
}
preservedMessages.AddRange(recentMessages.Where(m => m.Role != ChatMessageRoles.System));

Conversation continued = await agent.RunAsync(input, appendMessages: preservedMessages);

Best Practices

Storage Strategy

  • Use unique identifiers for each conversation
  • Implement cleanup for old conversations
  • Consider compression for large histories
  • Backup critical conversations

Token Management

  • Monitor message count and token usage
  • Trim old messages when approaching limits
  • Preserve important context (system messages, key facts)
  • Use summarization for very long conversations

Security

  • Encrypt sensitive conversation data
  • Implement access controls
  • Sanitize user inputs before saving
  • Comply with data retention policies

Advanced Usage

Conversation Snapshots

csharp
// Save at key points
Conversation result = await agent.RunAsync("Complete task 1");
result.Messages.ToList().SaveConversation("checkpoint-1.json");

result = await agent.RunAsync("Complete task 2", appendMessages: result.Messages.ToList());
result.Messages.ToList().SaveConversation("checkpoint-2.json");

// Rollback if needed
List<ChatMessage> checkpoint = new List<ChatMessage>();
await checkpoint.LoadMessagesAsync("checkpoint-1.json");

Common Issues

Message History Too Large

Solutions:

  • Trim old messages regularly
  • Implement rolling window of recent messages
  • Use conversation summarization
  • Increase context window if model supports it

Lost Context After Loading

Solutions:

  • Verify all messages are saved
  • Check deserialization is correct
  • Ensure system message is preserved
  • Test save/load functionality

Storage Overhead

Solutions:

  • Use compression (gzip)
  • Store only essential information
  • Implement cleanup policies
  • Consider database storage for large scale