1use std::fs;
2use std::path::PathBuf;
3
4use chrono::Utc;
5use llm_brain::{LLMBrain, Result};
6use serde_json::json;
7
8#[tokio::main]
10async fn main() -> Result<()> {
11 println!("Initializing LLMBrain for basic demo...");
12
13 ensure_config_exists()?;
15
16 let llm_brain = LLMBrain::launch().await?;
18 println!("LLMBrain initialized.");
19
20 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 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 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 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
116fn 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(()); }
125
126 if !config_dir.exists() {
127 fs::create_dir_all(&config_dir)?;
128 }
129
130 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}