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.

added the count flag and made the code scalable to add future flags if needed (#35)

authored by

Kshitij Taneja and committed by
GitHub
400c373d 8a1fcfc5

+53 -29
+2 -18
tiles/src/commands/mod.rs
··· 1 1 // Module that handles CLI commands 2 2 3 - use anyhow::Result; 4 - use tilekit::{modelfile, modelfile::Modelfile}; 5 3 use tiles::runtime::Runtime; 6 4 use tiles::{core::health, runtime::RunArgs}; 7 - const DEFAULT_MODELFILE: &str = " 8 - FROM driaforall/mem-agent-mlx-4bit 9 - "; 10 5 11 - pub async fn run(runtime: &Runtime, modelfile: Option<String>) { 12 - let modelfile_parse_result: Result<Modelfile, String> = if let Some(modelfile_str) = modelfile { 13 - modelfile::parse_from_file(modelfile_str.as_str()) 14 - } else { 15 - modelfile::parse(DEFAULT_MODELFILE) 16 - }; 17 - match modelfile_parse_result { 18 - Ok(modelfile) => { 19 - let run_args = RunArgs { modelfile }; 20 - runtime.run(run_args).await; 21 - } 22 - Err(_err) => println!("Invalid Modelfile"), 23 - } 6 + pub async fn run(runtime: &Runtime, run_args: RunArgs) { 7 + runtime.run(run_args).await; 24 8 } 25 9 26 10 pub fn check_health() {
+25 -4
tiles/src/main.rs
··· 1 1 use std::error::Error; 2 2 3 3 use clap::{Args, Parser, Subcommand}; 4 - use tiles::runtime::build_runtime; 4 + use tiles::runtime::{build_runtime, RunArgs}; 5 5 mod commands; 6 6 #[derive(Debug, Parser)] 7 7 #[command(name = "tiles")] ··· 14 14 #[derive(Subcommand, Debug)] 15 15 enum Commands { 16 16 /// Runs the given Modelfile (runs the default model if none passed) 17 - Run { modelfile_path: Option<String> }, 17 + Run { 18 + /// Path to the Modelfile (uses default model if not provided) 19 + modelfile_path: Option<String>, 20 + 21 + #[command(flatten)] 22 + flags: RunFlags, 23 + }, 18 24 19 25 /// Checks the status of dependencies 20 26 Health, ··· 24 30 } 25 31 26 32 #[derive(Debug, Args)] 33 + struct RunFlags { 34 + /// Number of chat retries before giving up (default: 6) 35 + #[arg(short = 'r', long, default_value_t = 6)] 36 + retry_count: u32, 37 + 38 + // Future flags go here: 39 + // #[arg(long, default_value_t = 6969)] 40 + // port: u16, 41 + } 42 + 43 + #[derive(Debug, Args)] 27 44 #[command(args_conflicts_with_subcommands = true)] 28 45 #[command(flatten_help = true)] 29 46 struct ServerArgs { ··· 44 61 let cli = Cli::parse(); 45 62 let runtime = build_runtime(); 46 63 match cli.command { 47 - Commands::Run { modelfile_path } => { 48 - commands::run(&runtime, modelfile_path).await; 64 + Commands::Run { modelfile_path, flags } => { 65 + let run_args = RunArgs { 66 + modelfile_path, 67 + retry_count: flags.retry_count, 68 + }; 69 + commands::run(&runtime, run_args).await; 49 70 } 50 71 Commands::Health => { 51 72 commands::check_health();
+23 -5
tiles/src/runtime/mlx.rs
··· 34 34 } 35 35 36 36 pub async fn run(&self, run_args: super::RunArgs) { 37 - let model = run_args.modelfile.from.as_ref().unwrap(); 37 + const DEFAULT_MODELFILE: &str = "FROM driaforall/mem-agent-mlx-4bit"; 38 + 39 + // Parse modelfile 40 + let modelfile_parse_result = if let Some(modelfile_str) = run_args.modelfile_path { 41 + tilekit::modelfile::parse_from_file(modelfile_str.as_str()) 42 + } else { 43 + tilekit::modelfile::parse(DEFAULT_MODELFILE) 44 + }; 45 + 46 + let modelfile = match modelfile_parse_result { 47 + Ok(mf) => mf, 48 + Err(_err) => { 49 + println!("Invalid Modelfile"); 50 + return; 51 + } 52 + }; 53 + 54 + let model = modelfile.from.as_ref().unwrap(); 38 55 if model.starts_with("driaforall/mem-agent") { 39 - let _res = run_model_with_server(self, run_args.modelfile).await; 56 + let _res = run_model_with_server(self, modelfile, run_args.retry_count).await; 40 57 } else { 41 - run_model_by_sub_process(run_args.modelfile); 58 + run_model_by_sub_process(modelfile); 42 59 } 43 60 } 44 61 ··· 155 172 async fn run_model_with_server( 156 173 mlx_runtime: &MLXRuntime, 157 174 modelfile: Modelfile, 175 + retry_count: u32, 158 176 ) -> reqwest::Result<()> { 159 177 if !cfg!(debug_assertions) { 160 178 let _res = mlx_runtime.start_server_daemon().await; ··· 185 203 break; 186 204 } 187 205 _ => { 188 - let mut remaining_count = 6; 206 + let mut remaining_count = retry_count; 189 207 let mut g_reply: String = "".to_owned(); 190 208 let mut python_code: String = "".to_owned(); 191 209 loop { 192 210 if remaining_count > 0 { 193 - let chat_start = remaining_count == 6; 211 + let chat_start = remaining_count == retry_count; 194 212 if let Ok(response) = chat(input, modelname, chat_start, &python_code).await 195 213 { 196 214 if response.reply.is_empty() {
+3 -2
tiles/src/runtime/mod.rs
··· 2 2 use crate::runtime::cpu::CPURuntime; 3 3 use crate::runtime::mlx::MLXRuntime; 4 4 use anyhow::Result; 5 - use tilekit::modelfile::Modelfile; 6 5 pub mod cpu; 7 6 pub mod mlx; 8 7 9 8 pub struct RunArgs { 10 - pub modelfile: Modelfile, 9 + pub modelfile_path: Option<String>, 10 + pub retry_count: u32, 11 + // Future flags go here 11 12 } 12 13 13 14 pub enum Runtime {