Skip to main content

bob_runtime/
memory_context.rs

1//! # Memory Context Injection
2//!
3//! Memory context injection logic for injecting session memory summaries
4//! into system prompts on a per-request basis.
5//!
6//! ## Overview
7//!
8//! This module provides functionality to inject memory summaries from
9//! `SessionState` into system instructions, enabling persistent context
10//! across conversation turns.
11//!
12//! ## Components
13//!
14//! - **Memory Injection**: Appends memory summary to system instructions
15//! - **Per-request Support**: Works with AgentLoop's RequestContext system
16//!
17//! ## Usage
18//!
19//! ```rust,ignore
20//! use bob_runtime::memory_context::inject_memory_prompt;
21//!
22//! let system_instructions = "You are a helpful assistant.";
23//! let memory_summary = Some("Previous conversation about Rust programming".to_string());
24//!
25//! let injected = inject_memory_prompt(system_instructions, memory_summary.as_deref());
26//! ```
27
28/// Injects memory summary into system instructions if available.
29///
30/// This function appends memory context to the base system instructions,
31/// enabling the agent to maintain persistent context across conversation turns.
32///
33/// # Arguments
34///
35/// * `system_instructions` - The base system instructions
36/// * `memory_summary` - Optional memory summary from session state
37///
38/// # Returns
39///
40/// System instructions with memory context injected, or original instructions if no memory
41pub fn inject_memory_prompt(system_instructions: &str, memory_summary: Option<&str>) -> String {
42    let Some(memory) = memory_summary else {
43        return system_instructions.to_string();
44    };
45
46    if memory.trim().is_empty() {
47        return system_instructions.to_string();
48    }
49
50    format!("{}\n\nMemory Context:\n{}", system_instructions, memory.trim())
51}
52
53#[cfg(test)]
54mod tests {
55    use super::*;
56
57    #[test]
58    fn inject_memory_prompt_with_memory() {
59        let base = "You are a helpful assistant.";
60        let memory = "Previous conversation about Rust programming.";
61
62        let result = inject_memory_prompt(base, Some(memory));
63
64        assert!(result.contains(base));
65        assert!(result.contains("Memory Context:"));
66        assert!(result.contains(memory));
67    }
68
69    #[test]
70    fn inject_memory_prompt_without_memory() {
71        let base = "You are a helpful assistant.";
72
73        let result = inject_memory_prompt(base, None);
74
75        assert_eq!(result, base);
76    }
77
78    #[test]
79    fn inject_memory_prompt_with_empty_memory() {
80        let base = "You are a helpful assistant.";
81
82        let result = inject_memory_prompt(base, Some(""));
83
84        assert_eq!(result, base);
85    }
86
87    #[test]
88    fn inject_memory_prompt_with_whitespace_memory() {
89        let base = "You are a helpful assistant.";
90
91        let result = inject_memory_prompt(base, Some("   \n\t   "));
92
93        assert_eq!(result, base);
94    }
95
96    #[test]
97    fn inject_memory_prompt_preserves_formatting() {
98        let base = "You are a helpful assistant.\nThink step by step.";
99        let memory = "User prefers detailed explanations.";
100
101        let result = inject_memory_prompt(base, Some(memory));
102
103        assert!(result.starts_with(base));
104        assert!(result.contains("\n\nMemory Context:\n"));
105        assert!(result.ends_with(memory));
106    }
107}