Memory

Conversation memory and history management in PraisonAI Rust SDK

Memory stores conversation history, enabling agents to maintain context across interactions.

Diagram

Memory System

🤖 Agent

🧠 Memory

💬 Short-term

📚 Long-term

Quick Start

  1. Enable Agent Memory
    rust
    use praisonai::Agent;
    
    let agent = Agent::new()
        .name("Assistant")
        .instructions("Remember our conversation")
        .memory(true)  // Enable memory
        .build()?;
    
    // Conversation context persists between calls
    agent.chat("My name is Alice").await?;
    let response = agent.chat("What's my name?").await?;
    // response: "Your name is Alice"
  2. Clear Memory
    rust
    use praisonai::Agent;
    
    let agent = Agent::new()
        .name("Assistant")
        .memory(true)
        .build()?;
    
    agent.chat("Remember: secret code is 1234").await?;
    agent.clear_memory().await?;
    agent.chat("What's the secret code?").await?;
    // Agent no longer remembers the code

User Interaction Flow

Diagram
LLMMemoryAgentUserLLMMemoryAgentUserchat(“My name is Alice”)Get history[]System + User message“Nice to meet you, Alice!”Store user + assistant messageschat(“What’s my name?”)Get history[Previous messages]System + History + User message“Your name is Alice”

Memory

Main memory manager for agents.

rust
pub struct Memory {
    adapter: Box<dyn MemoryAdapter>,
    config: MemoryConfig,
}

Factory Methods

MethodSignatureDescription
new(adapter, config)fn new(impl MemoryAdapter, MemoryConfig) -> SelfCreate with custom adapter
in_memory(config)fn in_memory(MemoryConfig) -> SelfCreate in-memory storage
default_memory()fn default_memory() -> SelfCreate with default config

Instance Methods

MethodSignatureDescription
store(message)async fn store(&mut self, Message) -> Result<()>Store a message
history()`async fn history(&self) -> Result<Vec

` | Get conversation history |

| search(query, limit) | `async fn search(&self, &str, usize) -> Result<Vec

` | Search messages |

| clear() | async fn clear(&mut self) -> Result<()> | Clear all memory | | config() | fn config(&self) -> &MemoryConfig | Get config reference |


MemoryConfig

Configuration for memory behavior.

rust
pub struct MemoryConfig {
    pub use_short_term: bool,
    pub max_messages: usize,
}

Configuration Options

OptionTypeDefaultDescription
use_short_termbooltrueEnable short-term memory
max_messagesusize100Max messages to retain

ConversationHistory

Low-level message storage with automatic trimming.

rust
pub struct ConversationHistory {
    messages: VecDeque<Message>,
    max_messages: usize,
}

Methods

MethodSignatureDescription
new(max)fn new(usize) -> SelfCreate with max messages
add(message)fn add(&mut self, Message)Add message (auto-trims)
messages()`fn messages(&self) -> Vec

| Get all messages | | clear() | fn clear(&mut self) | Clear all messages | | len() | fn len(&self) -> usize | Message count | | is_empty() | fn is_empty(&self) -> bool` | Check if empty |

Note: When trimming, system messages are preserved – only user/assistant messages are removed.


MemoryAdapter Trait

Interface for custom memory backends.

rust
#[async_trait]
pub trait MemoryAdapter: Send + Sync {
    async fn store_short_term(&mut self, message: Message) -> Result<()>;
    async fn search_short_term(&self, query: &str, limit: usize) -> Result<Vec<Message>>;
    async fn get_short_term(&self) -> Result<Vec<Message>>;
    async fn clear_short_term(&mut self) -> Result<()>;

    // Optional long-term methods (default no-op)
    async fn store_long_term(&mut self, text: &str, metadata: Option<Value>) -> Result<()>;
    async fn search_long_term(&self, query: &str, limit: usize) -> Result<Vec<String>>;
}

InMemoryAdapter

Default in-memory implementation.

rust
pub struct InMemoryAdapter {
    history: ConversationHistory,
}

Methods

MethodSignatureDescription
new(max)fn new(usize) -> SelfCreate with max messages
default()fn default() -> SelfCreate with 100 max messages

Custom Memory Adapter

rust
use praisonai::{MemoryAdapter, Message, async_trait, Result};

struct RedisMemory {
    client: redis::Client,
}

#[async_trait]
impl MemoryAdapter for RedisMemory {
    async fn store_short_term(&mut self, message: Message) -> Result<()> {
        // Store to Redis
        Ok(())
    }

    async fn search_short_term(&self, query: &str, limit: usize) -> Result<Vec<Message>> {
        // Search Redis
        Ok(vec![])
    }

    async fn get_short_term(&self) -> Result<Vec<Message>> {
        // Get from Redis
        Ok(vec![])
    }

    async fn clear_short_term(&mut self) -> Result<()> {
        // Clear Redis keys
        Ok(())
    }
}

Best Practices

Set appropriate max_messages

Too many messages increase token usage and cost. Start with 50-100.

Clear memory for new contexts

Use clear_memory() when starting unrelated conversations.

System messages are preserved

The trimming algorithm keeps system messages – only user/assistant messages are removed when exceeding limits.

Use search for relevant context

For long histories, use search() to find relevant past messages instead of loading everything.


Related