A local-first private AI assistant for everyday use. Runs on-device models with encrypted P2P sync, and supports sharing chats publicly on ATProto.
10
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat: arg optional in tiles run, runs mem-agent-4bit by default

madclaws eb692778 28e434ca

+32 -29
+1 -1
mem-agent
··· 1 - FROM driaforall/mem-agent 1 + FROM driaforall/mem-agent-mlx-4bit
-1
memgpt.modelfile
··· 1 - FROM driaforall/mem-agent
+14 -3
src/commands/mod.rs
··· 1 1 // Module that handles CLI commands 2 2 3 + use anyhow::Result; 3 4 use tiles::{ 4 5 core::{ 5 6 health, 6 - modelfile::{self}, 7 + modelfile::{self, Modelfile}, 7 8 }, 8 9 runner::mlx, 9 10 }; 10 11 11 - pub async fn run(modelfile: &str) { 12 - match modelfile::parse_from_file(modelfile) { 12 + const DEFAULT_MODELFILE: &str = " 13 + FROM driaforall/mem-agent-mlx-4bit 14 + "; 15 + 16 + pub async fn run(modelfile: Option<String>) { 17 + let modelfile_parse_result: Result<Modelfile, String> = if let Some(modelfile_str) = modelfile { 18 + modelfile::parse_from_file(modelfile_str.as_str()) 19 + } else { 20 + modelfile::parse(DEFAULT_MODELFILE) 21 + }; 22 + 23 + match modelfile_parse_result { 13 24 Ok(modelfile) => { 14 25 mlx::run(modelfile).await; 15 26 }
+3 -3
src/main.rs
··· 12 12 13 13 #[derive(Subcommand, Debug)] 14 14 enum Commands { 15 - /// Runs the given modelfile Path 16 - Run { modelfile_path: String }, 15 + /// Runs the given Modelfile (runs the default model if none passed) 16 + Run { modelfile_path: Option<String> }, 17 17 18 18 /// Checks the status of dependencies 19 19 Health, ··· 43 43 let cli = Cli::parse(); 44 44 match cli.command { 45 45 Commands::Run { modelfile_path } => { 46 - commands::run(modelfile_path.as_str()).await; 46 + commands::run(modelfile_path).await; 47 47 } 48 48 Commands::Health => { 49 49 commands::check_health();
+14 -21
src/runner/mlx.rs
··· 13 13 use std::{io, process::Command}; 14 14 use tokio::time::sleep; 15 15 pub struct ChatResponse { 16 - think: String, 16 + // think: String, 17 17 reply: String, 18 18 code: String, 19 19 } ··· 270 270 271 271 let mut stream = res.bytes_stream(); 272 272 let mut accumulated = String::new(); 273 - let mut chat_response = ChatResponse { 274 - think: String::new(), 275 - reply: String::new(), 276 - code: String::new(), 277 - }; 278 273 // let mut inside_python = false; 279 274 // let mut tag_buffer = String::new(); 280 275 print!("\n"); ··· 289 284 let data = line.trim_start_matches("data: "); 290 285 291 286 if data == "[DONE]" { 292 - chat_response = convert_to_chat_response(&accumulated); 293 - return Ok(chat_response); 287 + return Ok(convert_to_chat_response(&accumulated)); 294 288 } 295 289 // Parse JSON 296 290 let v: Value = serde_json::from_str(data).unwrap(); ··· 321 315 fn convert_to_chat_response(content: &str) -> ChatResponse { 322 316 // content.split() 323 317 ChatResponse { 324 - think: extract_think(content), 325 318 reply: extract_reply(content), 326 319 code: extract_python(content), 327 320 } ··· 347 340 } 348 341 } 349 342 350 - fn extract_think(content: &str) -> String { 351 - if content.contains("<think>") && content.contains("</think>") { 352 - let list_a = content.split("<think>").collect::<Vec<&str>>(); 353 - let list_b = list_a[1].split("</think>").collect::<Vec<&str>>(); 354 - list_b[0].to_owned() 355 - } else if content.contains("</think") { 356 - let list_a = content.split("</think>").collect::<Vec<&str>>(); 357 - list_a[0].to_owned() 358 - } else { 359 - "".to_owned() 360 - } 361 - } 343 + // fn extract_think(content: &str) -> String { 344 + // if content.contains("<think>") && content.contains("</think>") { 345 + // let list_a = content.split("<think>").collect::<Vec<&str>>(); 346 + // let list_b = list_a[1].split("</think>").collect::<Vec<&str>>(); 347 + // list_b[0].to_owned() 348 + // } else if content.contains("</think") { 349 + // let list_a = content.split("</think>").collect::<Vec<&str>>(); 350 + // list_a[0].to_owned() 351 + // } else { 352 + // "".to_owned() 353 + // } 354 + // } 362 355 363 356 fn get_memory_path() -> Result<String> { 364 357 let tiles_config_dir = get_config_dir()?;