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.

build: Added config files for consistent dev env

- Added rust-toolchain.toml for consistent rust runtime
- Added justfile for easy running commands
- Updated CI to support toolchain and just, and cache

madclaws ac9d39aa 01ea71e9

+46 -17
+18 -4
.github/workflows/rust.yml
··· 16 16 17 17 steps: 18 18 - uses: actions/checkout@v4 19 - - name: Build 20 - run: cargo build --verbose 21 - - name: Run tests 22 - run: cargo test --verbose 19 + - uses: dtolnay/rust-toolchain@master 20 + - name: Cache cargo 21 + uses: actions/cache@v4 22 + with: 23 + path: | 24 + ~/.cargo/bin 25 + ~/.cargo/registry 26 + ~/.cargo/git 27 + target 28 + key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} 29 + restore-keys: | 30 + ${{ runner.os }}-cargo- 31 + 32 + - name: Install just 33 + run: command -v just || cargo install just 34 + 35 + - name: Run check 36 + run: just check
+12
justfile
··· 1 + default: check 2 + 3 + fmt: 4 + cargo fmt --all -- --check 5 + 6 + lint: 7 + cargo clippy --all-targets -- -D warnings 8 + 9 + check: 10 + just fmt 11 + just lint 12 + cargo test
+3
rust-toolchain.toml
··· 1 + [toolchain] 2 + channel = "1.90.0" 3 + components = ["rustfmt", "clippy", "rust-analyzer"]
+13 -13
src/runner/mlx.rs
··· 80 80 .context("Retrieving memory_path failed") 81 81 .unwrap(); 82 82 let modelname = modelfile.from.as_ref().unwrap(); 83 - load_model(&modelname, &memory_path).await.unwrap(); 83 + load_model(modelname, &memory_path).await.unwrap(); 84 84 println!("Running in interactive mode"); 85 85 loop { 86 86 print!(">> "); ··· 94 94 break; 95 95 } 96 96 _ => { 97 - if let Ok(response) = chat(input, &modelname).await { 97 + if let Ok(response) = chat(input, modelname).await { 98 98 println!(">> {}", response) 99 99 } else { 100 100 println!(">> failed to respond") ··· 105 105 Ok(()) 106 106 } 107 107 108 - async fn ping() -> reqwest::Result<()> { 109 - let client = Client::new(); 110 - let res = client.get("http://127.0.0.1:6969/ping").send().await?; 111 - println!("{}", res.text().await?); 112 - Ok(()) 113 - } 108 + // async fn ping() -> reqwest::Result<()> { 109 + // let client = Client::new(); 110 + // let res = client.get("http://127.0.0.1:6969/ping").send().await?; 111 + // println!("{}", res.text().await?); 112 + // Ok(()) 113 + // } 114 114 115 115 async fn load_model(model_name: &str, memory_path: &str) -> Result<(), String> { 116 116 let client = Client::new(); ··· 172 172 let tiles_data_dir = data_dir.join("tiles"); 173 173 let mut is_memory_path_found: bool = false; 174 174 let mut memory_path: String = String::from(""); 175 - if tiles_config_dir.is_dir() { 176 - if let Ok(content) = fs::read_to_string(tiles_config_dir.join(".memory_path")) { 177 - memory_path = content; 178 - is_memory_path_found = true; 179 - } 175 + if tiles_config_dir.is_dir() 176 + && let Ok(content) = fs::read_to_string(tiles_config_dir.join(".memory_path")) 177 + { 178 + memory_path = content; 179 + is_memory_path_found = true; 180 180 } 181 181 182 182 if is_memory_path_found {