llm_brain_basic_demo/
llm_brain_basic_demo.rs

1use std::fs;
2use std::path::PathBuf;
3
4use anyhow::Result;
5use chrono::Utc;
6use llm_brain::LLMBrain;
7use serde_json::json;
8
9// Reusing the config helper from basic_demo.rs
10fn ensure_config_exists() -> Result<()> {
11    let config_dir = PathBuf::from("./config");
12    let default_config_path = config_dir.join("default.toml");
13
14    if default_config_path.exists() {
15        return Ok(());
16    }
17
18    if !config_dir.exists() {
19        fs::create_dir_all(&config_dir)?;
20    }
21
22    // Use a different DB path for this example to avoid conflicts
23    let default_toml_content = r#"
24[database]
25path = "./llm_brain_basic_demo_db"
26namespace = "demo_ns"
27database = "demo_db"
28
29[llm]
30# Provide necessary LLM config if LLMBrain::launch requires it
31# embedding_model = "text-embedding-3-small"
32# openai_api_key = "YOUR_API_KEY" # Set via env var preferably
33"#;
34    fs::write(&default_config_path, default_toml_content)?;
35    println!(
36        "Created default config file at {}",
37        default_config_path.display()
38    );
39    Ok(())
40}
41
42#[tokio::main]
43async fn main() -> Result<()> {
44    println!("\nStarting LLMBrain Basic Demo (Rust Version)...");
45
46    // Ensure config exists
47    ensure_config_exists()?;
48
49    // Initialize LLMBrain (handles DB connection based on config)
50    let llm_brain = LLMBrain::launch().await?;
51    println!("LLMBrain initialized.");
52
53    // --- Add Semantic Memory (Cat) ---
54    println!("\nAdding basic semantic memory for 'cat'...");
55    let cat_content = "A cat is a medium-sized, furry, agile, carnivorous animal often found in homes or outdoors. Common behaviors include hunting, sleeping, and grooming.".to_owned();
56    let cat_metadata = json!({
57        "entity_name": "cat",
58        "memory_type": "Semantic",
59        "properties": {
60            "type": "animal",
61            "size": "medium",
62            "characteristics": ["furry", "agile", "carnivorous"]
63        },
64        "relationships": {
65            "habitat": ["homes", "outdoors"],
66            "behavior": ["hunting", "sleeping", "grooming"]
67        }
68    });
69    match llm_brain
70        .add_memory(cat_content.clone(), cat_metadata.clone())
71        .await
72    {
73        Ok(id) => println!("Semantic memory added successfully. ID: {id}"),
74        Err(e) => println!("Failed to add semantic memory: {e}"),
75    }
76
77    // --- Add Episodic Memory (Cat Observation) ---
78    println!("\nAdding episodic memory...");
79    let episode_content = format!(
80        "Timestamp: {}. Observed cat behavior in the Garden: Cat was chasing a butterfly. Observed by human.",
81        Utc::now().to_rfc3339()
82    );
83    let episode_metadata = json!({
84        "entity_name": "cat_observation",
85        "memory_type": "Episodic",
86        "properties": {
87            "action": "Observed cat behavior",
88            "location": "Garden",
89            "details": "Cat was chasing a butterfly"
90        },
91        "relationships": {
92            "relates_to": ["cat"],
93            "observed_by": ["human"]
94        }
95    });
96    match llm_brain
97        .add_memory(episode_content.clone(), episode_metadata.clone())
98        .await
99    {
100        Ok(id) => println!("Episodic memory added successfully. ID: {id}"),
101        Err(e) => println!("Failed to add episodic memory: {e}"),
102    }
103
104    // --- Query and Display Results ---
105    println!("\nQuerying semantic memory for 'cat':");
106    let cat_query = "information about cats";
107    match llm_brain.recall(cat_query, 2).await {
108        // Recall top 2
109        Ok(results) => {
110            println!("Found {} memories:", results.len());
111            for (fragment, score) in results {
112                println!(
113                    "- Score: {:.4}, Content: {:.80}...",
114                    score, fragment.content
115                );
116                println!(
117                    "  Metadata: {}",
118                    serde_json::to_string_pretty(&fragment.metadata)?
119                );
120            }
121        }
122        Err(e) => println!("Failed to recall memories for '{cat_query}': {e}"),
123    }
124
125    println!("\nQuerying episodic memory:");
126    let episode_query = "cat observation in garden";
127    match llm_brain.recall(episode_query, 1).await {
128        Ok(results) => {
129            println!("Found {} memories:", results.len());
130            for (fragment, score) in results {
131                println!(
132                    "- Score: {:.4}, Content: {:.80}...",
133                    score, fragment.content
134                );
135                println!(
136                    "  Metadata: {}",
137                    serde_json::to_string_pretty(&fragment.metadata)?
138                );
139            }
140        }
141        Err(e) => println!("Failed to recall memories for '{episode_query}': {e}"),
142    }
143
144    println!("\nDemo completed successfully!");
145    println!("Note: Database file created at ./llm_brain_basic_demo_db (if it didn't exist).");
146
147    Ok(())
148}