diff options
| author | Ben Sima <ben@bensima.com> | 2025-12-17 13:29:24 -0500 |
|---|---|---|
| committer | Ben Sima <ben@bensima.com> | 2025-12-17 13:29:24 -0500 |
| commit | 337648981cc5a55935116141341521f4fce83214 (patch) | |
| tree | aa5934ee9edd5413e16d76525b2e12efc0aec98c /Omni/Dev | |
| parent | 91dff1309ceb0729bc3fdde61878f81fd3df4eec (diff) | |
Add Ava systemd deployment with dedicated user and workspace
- Add Omni.Agent.Paths module for configurable AVA_DATA_ROOT
- Create ava Linux user in Users.nix with SSH key
- Add systemd service in Beryllium/Ava.nix with graceful shutdown
- Update Skills.hs and Outreach.hs to use configurable paths
- Add startup logging of resolved paths in Telegram.hs
- Create migration script for moving data from _/var/ava to /home/ava
- Add deployment documentation in Beryllium/AVA.md
In dev: AVA_DATA_ROOT unset uses _/var/ava/
In prod: AVA_DATA_ROOT=/home/ava via systemd
Amp-Thread-ID: https://ampcode.com/threads/T-019b2d7e-bd88-7355-8133-275c65157aaf
Co-authored-by: Amp <amp@ampcode.com>
Diffstat (limited to 'Omni/Dev')
| -rwxr-xr-x | Omni/Dev/Beryllium.nix | 1 | ||||
| -rw-r--r-- | Omni/Dev/Beryllium/AVA.md | 111 | ||||
| -rw-r--r-- | Omni/Dev/Beryllium/Ava.nix | 48 | ||||
| -rwxr-xr-x | Omni/Dev/Beryllium/migrate-ava.sh | 102 |
4 files changed, 262 insertions, 0 deletions
diff --git a/Omni/Dev/Beryllium.nix b/Omni/Dev/Beryllium.nix index 023523e..4d9ed09 100755 --- a/Omni/Dev/Beryllium.nix +++ b/Omni/Dev/Beryllium.nix @@ -5,6 +5,7 @@ bild.os { ../Os/Base.nix ../Packages.nix ../Users.nix + ./Beryllium/Ava.nix ./Beryllium/Configuration.nix ./Beryllium/Hardware.nix ./Beryllium/Ollama.nix diff --git a/Omni/Dev/Beryllium/AVA.md b/Omni/Dev/Beryllium/AVA.md new file mode 100644 index 0000000..620592b --- /dev/null +++ b/Omni/Dev/Beryllium/AVA.md @@ -0,0 +1,111 @@ +# Ava Deployment on Beryllium + +Ava runs as a systemd service under the `ava` user. + +## Architecture + +``` +/home/ava/ # Ava's home directory (AVA_DATA_ROOT) +├── omni/ # Clone of the omni repo +├── skills/ # Ava's skills directory +│ ├── shared/ # Skills available to all users +│ └── <username>/ # User-specific skills +├── outreach/ # Outreach approval queue +│ ├── pending/ +│ ├── approved/ +│ ├── rejected/ +│ └── sent/ +├── users/ # Per-user scratch space +│ └── <username>/ +└── .local/share/omni/ + └── memory.db # SQLite memory database +``` + +## Configuration + +The service is configured in `Ava.nix` and requires these environment variables in `/run/secrets/ava.env`: + +```bash +TELEGRAM_BOT_TOKEN=xxx +OPENROUTER_API_KEY=xxx +KAGI_API_KEY=xxx # optional +ALLOWED_TELEGRAM_USER_IDS=xxx,yyy # or * for all +``` + +## Commands + +```bash +# View logs +journalctl -u ava -f + +# Restart service +sudo systemctl restart ava + +# Check status +sudo systemctl status ava + +# Stop/Start +sudo systemctl stop ava +sudo systemctl start ava +``` + +## SSH Access + +The Ava private key is at `~/.ssh/ava_ed25519`. Use it to SSH as ava: + +```bash +ssh -i ~/.ssh/ava_ed25519 ava@beryl.bensima.com +``` + +Ben can also access ava's workspace via his own SSH key since ava is in the git group. + +## Git Setup + +Ava has its own clone of the omni repo at `/home/ava/omni`. To fetch changes from ben: + +```bash +# As ava: +cd /home/ava/omni +git fetch origin +git pull origin main +``` + +Ben can also push directly to ava's repo if needed: + +```bash +# From /home/ben/omni: +git remote add ava /home/ava/omni +git push ava main +``` + +## Redeploy + +To redeploy Ava with code changes: + +```bash +# 1. Rebuild the NixOS config +push.sh Omni/Dev/Beryllium.nix + +# 2. Or just restart the service if only env changes +sudo systemctl restart ava +``` + +## Migration from tmux + +If migrating from the old tmux-based deployment: + +1. Deploy the NixOS config with the new ava user +2. Run the migration script: `sudo ./Omni/Dev/Beryllium/migrate-ava.sh` +3. Create `/run/secrets/ava.env` with the required secrets +4. Stop the tmux ava process +5. Start the systemd service: `sudo systemctl start ava` +6. Enable on boot: `sudo systemctl enable ava` + +## Environment Variable: AVA_DATA_ROOT + +The `AVA_DATA_ROOT` environment variable controls where Ava stores its data: + +- **Development** (unset): Uses `_/var/ava/` (relative to repo) +- **Production**: Set to `/home/ava` via the systemd service + +This allows the same codebase to run in both environments without changes. diff --git a/Omni/Dev/Beryllium/Ava.nix b/Omni/Dev/Beryllium/Ava.nix new file mode 100644 index 0000000..6957352 --- /dev/null +++ b/Omni/Dev/Beryllium/Ava.nix @@ -0,0 +1,48 @@ +{...}: let + bild = import ../../Bild.nix {}; + avaPkg = bild.run ../../Ava.hs; +in { + systemd.services.ava = { + description = "Ava Telegram assistant"; + after = ["network-online.target" "ollama.service"]; + wants = ["network-online.target" "ollama.service"]; + wantedBy = ["multi-user.target"]; + + serviceConfig = { + Type = "simple"; + User = "ava"; + Group = "users"; + WorkingDirectory = "/home/ava/omni"; + + Environment = [ + "AVA_DATA_ROOT=/home/ava" + "HOME=/home/ava" + "OLLAMA_URL=http://localhost:11434" + ]; + + EnvironmentFile = "/run/secrets/ava.env"; + + ExecStart = "${avaPkg}/bin/ava"; + + Restart = "on-failure"; + RestartSec = 5; + + TimeoutStopSec = 90; + KillMode = "mixed"; + KillSignal = "SIGTERM"; + }; + }; + + systemd.tmpfiles.rules = [ + "d /home/ava 0755 ava users -" + "d /home/ava/omni 0755 ava users -" + "d /home/ava/skills 0755 ava users -" + "d /home/ava/outreach 0755 ava users -" + "d /home/ava/outreach/pending 0755 ava users -" + "d /home/ava/outreach/approved 0755 ava users -" + "d /home/ava/outreach/rejected 0755 ava users -" + "d /home/ava/outreach/sent 0755 ava users -" + "d /home/ava/users 0755 ava users -" + "d /home/ava/.local/share/omni 0755 ava users -" + ]; +} diff --git a/Omni/Dev/Beryllium/migrate-ava.sh b/Omni/Dev/Beryllium/migrate-ava.sh new file mode 100755 index 0000000..91d2740 --- /dev/null +++ b/Omni/Dev/Beryllium/migrate-ava.sh @@ -0,0 +1,102 @@ +#!/usr/bin/env bash +# Migration script: move Ava data from _/var/ava to /home/ava +# +# Run this ONCE after deploying the NixOS config with the new ava user. +# +# Usage: +# sudo ./migrate-ava.sh +# +# This script: +# 1. Copies existing data from _/var/ava to /home/ava +# 2. Copies memory.db from ben's .local to ava's .local +# 3. Clones the omni repo into /home/ava/omni +# 4. Sets proper ownership + +set -euo pipefail + +GRN='\033[0;32m' +YLW='\033[0;33m' +RED='\033[0;31m' +NC='\033[0m' + +OMNI_REPO="/home/ben/omni" +AVA_HOME="/home/ava" +OLD_DATA_ROOT="$OMNI_REPO/_/var/ava" + +echo -e "${YLW}=== Ava Migration Script ===${NC}" + +# Check we're running as root +if [[ $EUID -ne 0 ]]; then + echo -e "${RED}Error: This script must be run as root${NC}" + exit 1 +fi + +# Check ava user exists +if ! id ava &>/dev/null; then + echo -e "${RED}Error: ava user does not exist. Deploy the NixOS config first.${NC}" + exit 1 +fi + +# Create directory structure (tmpfiles should handle this, but just in case) +echo -e "${YLW}Creating directory structure...${NC}" +mkdir -p "$AVA_HOME"/{skills,outreach,users,omni,.local/share/omni} +mkdir -p "$AVA_HOME"/outreach/{pending,approved,rejected,sent} + +# Copy skills +if [[ -d "$OLD_DATA_ROOT/skills" ]]; then + echo -e "${YLW}Copying skills...${NC}" + rsync -av --progress "$OLD_DATA_ROOT/skills/" "$AVA_HOME/skills/" +else + echo -e "${YLW}No skills to migrate${NC}" +fi + +# Copy outreach +if [[ -d "$OLD_DATA_ROOT/outreach" ]]; then + echo -e "${YLW}Copying outreach data...${NC}" + rsync -av --progress "$OLD_DATA_ROOT/outreach/" "$AVA_HOME/outreach/" +else + echo -e "${YLW}No outreach data to migrate${NC}" +fi + +# Copy memory.db if it exists +BEN_MEMORY="/home/ben/.local/share/omni/memory.db" +AVA_MEMORY="$AVA_HOME/.local/share/omni/memory.db" +if [[ -f "$BEN_MEMORY" ]]; then + echo -e "${YLW}Copying memory database...${NC}" + cp -v "$BEN_MEMORY" "$AVA_MEMORY" +else + echo -e "${YLW}No memory.db found at $BEN_MEMORY${NC}" +fi + +# Clone or update the omni repo +if [[ -d "$AVA_HOME/omni/.git" ]]; then + echo -e "${YLW}Omni repo already exists, updating...${NC}" + cd "$AVA_HOME/omni" + sudo -u ava git fetch origin +else + echo -e "${YLW}Cloning omni repo...${NC}" + sudo -u ava git clone "$OMNI_REPO" "$AVA_HOME/omni" +fi + +# Set ownership +echo -e "${YLW}Setting ownership...${NC}" +chown -R ava:users "$AVA_HOME" + +# Show summary +echo "" +echo -e "${GRN}=== Migration Complete ===${NC}" +echo "" +echo "Directory structure:" +ls -la "$AVA_HOME" +echo "" +echo "Next steps:" +echo "1. Create /run/secrets/ava.env with:" +echo " TELEGRAM_BOT_TOKEN=xxx" +echo " OPENROUTER_API_KEY=xxx" +echo " KAGI_API_KEY=xxx (optional)" +echo " ALLOWED_TELEGRAM_USER_IDS=xxx (or * for all)" +echo "" +echo "2. Stop the tmux Ava process" +echo "3. Start the systemd service: sudo systemctl start ava" +echo "4. Watch logs: journalctl -u ava -f" +echo "5. Enable on boot: sudo systemctl enable ava" |
