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.

fix: fixed binary not starting server issue + stop server on repl exit

tiles binary was not starting the server, it its executed on
anywhere other that tiles dev directory. This was due to
default cwd.

Removed `uv` dependency for running server.

Server will auto-terminate on repl exit, which unloads the model
from memory too.

madclaws e1a3fd2d 08796019

+33 -26
+2 -2
scripts/install.sh
··· 2 2 set -euo pipefail 3 3 4 4 ENV="prod" # prod is another env, try taking it from github env 5 - REPO="tilesprivacy/tilekit" 5 + REPO="tilesprivacy/tiles" 6 6 # VERSION="${TILES_VERSION:-latest}" 7 7 VERSION="0.2.0" 8 8 INSTALL_DIR="$HOME/.local/bin" # CLI install location ··· 71 71 log "Installing Python 3.13 via Homebrew..." 72 72 brew install python@3.13 || err "Failed to install Python 3.13" 73 73 else 74 - err "Python 3.13 is required but not found. Please install it manually. And retry installing tiles" 74 + err "Python 3.13 is required but not found. Please install it manuallyv and retry installing tiles" 75 75 fi 76 76 fi 77 77
+12 -9
server/main.py
··· 1 1 import uvicorn 2 2 from .api import app 3 - from .config import PORT 3 + from .config import PORT 4 4 import logging 5 5 import sys 6 - from fastapi import Request 6 + from fastapi import Request 7 7 8 8 # --- logging setup --- 9 9 logging.basicConfig( ··· 22 22 except Exception: 23 23 body = None 24 24 25 - logger.info({ 26 - "method": request.method, 27 - "url": str(request.url), 28 - "client": request.client.host, 29 - "body": body, 30 - }) 25 + logger.info( 26 + { 27 + "method": request.method, 28 + "url": str(request.url), 29 + "client": request.client.host, 30 + "body": body, 31 + } 32 + ) 31 33 32 34 response = await call_next(request) 33 35 logger.info(f"<-- {request.method} {request.url.path} {response.status_code}") 34 36 return response 37 + 35 38 36 39 def run(): 37 40 uvicorn.run(app, host="127.0.0.1", port=PORT) 38 41 42 + 39 43 if __name__ == "__main__": 40 44 run() 41 -
+2 -2
src/commands/mod.rs
··· 36 36 let _ = mlx::start_server_daemon().await; 37 37 } 38 38 39 - pub fn stop_server() { 40 - let _ = mlx::stop_server_daemon(); 39 + pub async fn stop_server() { 40 + let _ = mlx::stop_server_daemon().await; 41 41 }
+1 -1
src/main.rs
··· 50 50 } 51 51 Commands::Server(server) => match server.command { 52 52 Some(ServerCommands::Start) => commands::start_server().await, 53 - Some(ServerCommands::Stop) => commands::stop_server(), 53 + Some(ServerCommands::Stop) => commands::stop_server().await, 54 54 _ => println!("Expected start or stop"), 55 55 }, 56 56 }
+16 -12
src/runner/mlx.rs
··· 94 94 } 95 95 96 96 let config_dir = get_config_dir()?; 97 - let server_dir = get_server_dir()?; 97 + let mut server_dir = get_server_dir()?; 98 98 let pid_file = config_dir.join("server.pid"); 99 99 fs::create_dir_all(&config_dir).context("Failed to create config directory")?; 100 100 101 101 let stdout_log = File::create(config_dir.join("server.out.log"))?; 102 102 let stderr_log = File::create(config_dir.join("server.err.log"))?; 103 - let child = Command::new("uv") 104 - .args([ 105 - "run", 106 - "--project", 107 - server_dir.to_str().unwrap(), 108 - "python", 109 - "-m", 110 - "server.main", 111 - ]) 103 + let server_path = server_dir.join(".venv/bin/python3"); 104 + println!("{:?}", server_path); 105 + server_dir.pop(); 106 + let child = Command::new(server_path) 107 + .args(["-m", "server.main"]) 108 + .current_dir(server_dir) 112 109 .stdin(Stdio::null()) 113 110 .stdout(Stdio::from(stdout_log)) 114 111 .stderr(Stdio::from(stderr_log)) ··· 121 118 Ok(()) 122 119 } 123 120 124 - pub fn stop_server_daemon() -> Result<()> { 121 + pub async fn stop_server_daemon() -> Result<()> { 122 + if (ping().await).is_err() { 123 + println!("Server is not running"); 124 + return Ok(()); 125 + } 125 126 let pid_file = get_config_dir()?.join("server.pid"); 126 127 127 128 if !pid_file.exists() { 128 - eprintln!("Server is not running"); 129 + eprintln!("server pid doesnt exist"); 129 130 return Ok(()); 130 131 } 131 132 ··· 159 160 match input { 160 161 "exit" => { 161 162 println!("Exiting interactive mode"); 163 + if !cfg!(debug_assertions) { 164 + let _res = stop_server_daemon().await; 165 + } 162 166 break; 163 167 } 164 168 _ => {