basic_demo/
basic_demo.rs

1use std::fs;
2use std::path::PathBuf;
3
4use chrono::Utc;
5use llm_brain::{LLMBrain, Result};
6use serde_json::json;
7
8/// Basic demonstration of LLMBrain functionality
9#[tokio::main]
10async fn main() -> Result<()> {
11    println!("Initializing LLMBrain for basic demo...");
12
13    // Ensure config exists before launching
14    ensure_config_exists()?;
15
16    // Initialize LLMBrain
17    let llm_brain = LLMBrain::launch().await?;
18    println!("LLMBrain initialized.");
19
20    // Add a semantic memory
21    println!("\nAdding semantic memory...");
22    let cat_data = json!({
23        "name": "Cat",
24        "column": "Semantic",
25        "properties": {
26            "type": "Animal",
27            "features": ["fur", "whiskers", "tail"],
28            "diet": "carnivore"
29        },
30        "relationships": {
31            "preys_on": ["mice", "birds"],
32            "related_to": ["tiger", "lion"]
33        }
34    });
35
36    let cat_content = "The cat is a small carnivorous mammal with fur, whiskers, and a tail. It preys on mice and birds, and is related to tigers and lions.";
37    let result = llm_brain
38        .add_memory(cat_content.to_owned(), cat_data)
39        .await?;
40    println!("Semantic memory added with ID: {result}");
41
42    // Add an episodic memory
43    println!("\nAdding episodic memory...");
44    let event_data = json!({
45        "name": "First Pet",
46        "column": "Episodic",
47        "properties": {
48            "timestamp": Utc::now().to_rfc3339(),
49            "action": "Got my first cat",
50            "location": "Pet Store",
51            "emotion": "happy",
52            "participants": ["family", "pet store staff"]
53        }
54    });
55
56    let event_content = "Today I went to the pet store with my family and got my first cat. Everyone was very happy.";
57    let result = llm_brain
58        .add_memory(event_content.to_owned(), event_data)
59        .await?;
60    println!("Episodic memory added with ID: {result}");
61
62    // Add a procedural memory
63    println!("\nAdding procedural memory...");
64    let procedure_data = json!({
65        "name": "Feed Cat",
66        "column": "Procedural",
67        "properties": {
68            "steps": [
69                "Get cat food from cabinet",
70                "Fill bowl with appropriate amount",
71                "Add fresh water to water bowl",
72                "Call cat for feeding"
73            ],
74            "frequency": "twice daily",
75            "importance": "high"
76        }
77    });
78
79    let procedure_content = "To feed a cat: First, get cat food from the cabinet. Then fill the bowl with an appropriate amount. Add fresh water to the water bowl. Finally, call the cat for feeding. This should be done twice daily.";
80    let result = llm_brain
81        .add_memory(procedure_content.to_owned(), procedure_data)
82        .await?;
83    println!("Procedural memory added with ID: {result}");
84
85    // Query memories
86    println!("\nQuerying cat-related memories...");
87    let cat_results = llm_brain.recall("cat animal features", 3).await?;
88    println!("Cat-related memories:");
89    for (memory, score) in cat_results {
90        println!("Score: {:.4}, Content: {}", score, memory.content);
91        println!(
92            "Metadata: {}",
93            serde_json::to_string_pretty(&memory.metadata)?
94        );
95        println!();
96    }
97
98    println!("\nQuerying feeding procedure...");
99    let feeding_results = llm_brain.recall("how to feed a cat", 2).await?;
100    println!("Feeding procedure results:");
101    for (memory, score) in feeding_results {
102        println!("Score: {:.4}, Content: {}", score, memory.content);
103        println!(
104            "Metadata: {}",
105            serde_json::to_string_pretty(&memory.metadata)?
106        );
107        println!();
108    }
109
110    println!("\nDemo completed.");
111    println!("Note: Database file created at ./llm_brain_example_db (if it didn't exist).");
112
113    Ok(())
114}
115
116// Helper function to ensure config exists for the example
117// In a real app, config loading would likely be handled centrally.
118fn ensure_config_exists() -> Result<()> {
119    let config_dir = PathBuf::from("./config");
120    let default_config_path = config_dir.join("default.toml");
121
122    if default_config_path.exists() {
123        return Ok(()); // Config already exists
124    }
125
126    if !config_dir.exists() {
127        fs::create_dir_all(&config_dir)?;
128    }
129
130    // Create a minimal default.toml for the example
131    let default_toml_content = r#"
132[database]
133path = "./llm_brain_example_db" # Use a separate db path for the example
134namespace = "example_ns"
135database = "example_db"
136
137[llm]
138# Provide necessary LLM config if LLMBrain::launch requires it
139# embedding_model = "text-embedding-3-small"
140# openai_api_key = "YOUR_API_KEY" # Set via env var preferably
141"#;
142    fs::write(&default_config_path, default_toml_content)?;
143    println!(
144        "Created default config file at {}",
145        default_config_path.display()
146    );
147    Ok(())
148}