mirror of
https://github.com/harivansh-afk/nix.git
synced 2026-04-15 05:02:10 +00:00
pi-agent stack (#46)
* pi-agent stack * fix: hardcode pi binary path, set XDG env for npm npm prefix discovery fails in systemd and activation contexts because NPM_CONFIG_USERCONFIG and XDG_DATA_HOME are not set. Hardcode the known path ~/.local/share/npm/bin/pi instead.
This commit is contained in:
parent
e19ee2405e
commit
588d8b8d6a
4 changed files with 128 additions and 0 deletions
|
|
@ -21,6 +21,7 @@
|
||||||
./mise.nix
|
./mise.nix
|
||||||
./migration.nix
|
./migration.nix
|
||||||
./nvim.nix
|
./nvim.nix
|
||||||
|
./pi.nix
|
||||||
./prompt.nix
|
./prompt.nix
|
||||||
./skills.nix
|
./skills.nix
|
||||||
./scripts.nix
|
./scripts.nix
|
||||||
|
|
|
||||||
52
home/pi.nix
Normal file
52
home/pi.nix
Normal file
|
|
@ -0,0 +1,52 @@
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
hostConfig,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
npmDir = "${config.xdg.dataHome}/npm";
|
||||||
|
piBin = "${npmDir}/bin/pi";
|
||||||
|
in
|
||||||
|
lib.mkIf hostConfig.isLinux {
|
||||||
|
# Install pi-coding-agent globally via npm at activation time.
|
||||||
|
home.activation.installPiAgent = lib.hm.dag.entryAfter [ "writeBoundary" ] ''
|
||||||
|
export PATH="${
|
||||||
|
lib.makeBinPath [
|
||||||
|
pkgs.nodejs_22
|
||||||
|
pkgs.coreutils
|
||||||
|
]
|
||||||
|
}:$PATH"
|
||||||
|
export NPM_CONFIG_USERCONFIG="${config.xdg.configHome}/npm/npmrc"
|
||||||
|
export XDG_DATA_HOME="${config.xdg.dataHome}"
|
||||||
|
export XDG_CACHE_HOME="${config.xdg.cacheHome}"
|
||||||
|
|
||||||
|
if [ ! -d "${npmDir}/lib/node_modules/@mariozechner/pi-coding-agent" ]; then
|
||||||
|
npm install -g @mariozechner/pi-coding-agent 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
|
||||||
|
# Install Pi extensions at activation time:
|
||||||
|
# - @e9n/pi-channels: Telegram/Slack bridge with RPC-based persistent sessions
|
||||||
|
# - pi-schedule-prompt: cron/interval scheduled prompts
|
||||||
|
# - pi-subagents: background task delegation with async execution
|
||||||
|
home.activation.installPiExtensions = lib.hm.dag.entryAfter [ "installPiAgent" ] ''
|
||||||
|
export PATH="${
|
||||||
|
lib.makeBinPath [
|
||||||
|
pkgs.nodejs_22
|
||||||
|
pkgs.coreutils
|
||||||
|
pkgs.git
|
||||||
|
]
|
||||||
|
}:$PATH"
|
||||||
|
export NPM_CONFIG_USERCONFIG="${config.xdg.configHome}/npm/npmrc"
|
||||||
|
export XDG_DATA_HOME="${config.xdg.dataHome}"
|
||||||
|
export XDG_CACHE_HOME="${config.xdg.cacheHome}"
|
||||||
|
|
||||||
|
if [ -x "${piBin}" ]; then
|
||||||
|
for pkg in "@e9n/pi-channels" "pi-schedule-prompt" "pi-subagents"; do
|
||||||
|
"${piBin}" install "npm:$pkg" 2>/dev/null || true
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
|
@ -18,6 +18,7 @@ in
|
||||||
./vaultwarden.nix
|
./vaultwarden.nix
|
||||||
./forgejo.nix
|
./forgejo.nix
|
||||||
./betternas.nix
|
./betternas.nix
|
||||||
|
./pi-agent.nix
|
||||||
../../modules/base.nix
|
../../modules/base.nix
|
||||||
(modulesPath + "/profiles/minimal.nix")
|
(modulesPath + "/profiles/minimal.nix")
|
||||||
(modulesPath + "/profiles/headless.nix")
|
(modulesPath + "/profiles/headless.nix")
|
||||||
|
|
|
||||||
74
hosts/netty/pi-agent.nix
Normal file
74
hosts/netty/pi-agent.nix
Normal file
|
|
@ -0,0 +1,74 @@
|
||||||
|
{
|
||||||
|
pkgs,
|
||||||
|
username,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
piAgentEnvFile = "/var/lib/pi-agent/pi-agent.env";
|
||||||
|
piAgentEnvCheck = pkgs.writeShellScript "pi-agent-env-check" ''
|
||||||
|
[ -f "${piAgentEnvFile}" ]
|
||||||
|
'';
|
||||||
|
|
||||||
|
piBin = "/home/${username}/.local/share/npm/bin/pi";
|
||||||
|
|
||||||
|
# Wrapper that exec's pi inside tmux's foreground process so systemd
|
||||||
|
# tracks the actual PID. When pi dies, tmux exits, systemd sees it
|
||||||
|
# and triggers Restart=on-failure.
|
||||||
|
piAgentStart = pkgs.writeShellScript "start-pi-agent" ''
|
||||||
|
if [ ! -x "${piBin}" ]; then
|
||||||
|
echo "pi binary not found at ${piBin}" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# tmux runs in the foreground (-D) so systemd tracks this process.
|
||||||
|
# The inner shell exec's pi so the tmux pane PID *is* the pi PID.
|
||||||
|
exec ${pkgs.tmux}/bin/tmux new-session -D -s pi-agent \
|
||||||
|
"exec ${piBin} --chat-bridge"
|
||||||
|
'';
|
||||||
|
in
|
||||||
|
{
|
||||||
|
# Ensure state directory and env file have correct permissions.
|
||||||
|
systemd.tmpfiles.rules = [
|
||||||
|
"d /var/lib/pi-agent 0750 ${username} users -"
|
||||||
|
"z ${piAgentEnvFile} 0600 ${username} users -"
|
||||||
|
];
|
||||||
|
|
||||||
|
# Pi agent running 24/7 in a foreground tmux session.
|
||||||
|
# Extensions (pi-channels, pi-schedule-prompt, pi-subagents) load
|
||||||
|
# inside Pi's process and handle Telegram bridging, scheduled tasks,
|
||||||
|
# and background subagent delegation.
|
||||||
|
#
|
||||||
|
# The --chat-bridge flag auto-enables the Telegram bridge on startup.
|
||||||
|
# Telegram bot token lives in ~/.pi/agent/settings.json (see pi-channels docs).
|
||||||
|
# ANTHROPIC_API_KEY comes from the env file.
|
||||||
|
#
|
||||||
|
# tmux session name: pi-agent
|
||||||
|
# Attach for debugging: tmux attach -t pi-agent
|
||||||
|
systemd.services.pi-agent = {
|
||||||
|
description = "Pi Coding Agent (24/7)";
|
||||||
|
after = [ "network-online.target" ];
|
||||||
|
wants = [ "network-online.target" ];
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
path = [
|
||||||
|
pkgs.nodejs_22
|
||||||
|
pkgs.git
|
||||||
|
pkgs.tmux
|
||||||
|
pkgs.coreutils
|
||||||
|
];
|
||||||
|
environment = {
|
||||||
|
HOME = "/home/${username}";
|
||||||
|
NODE_NO_WARNINGS = "1";
|
||||||
|
};
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "simple";
|
||||||
|
User = username;
|
||||||
|
Group = "users";
|
||||||
|
WorkingDirectory = "/home/${username}";
|
||||||
|
ExecCondition = piAgentEnvCheck;
|
||||||
|
EnvironmentFile = piAgentEnvFile;
|
||||||
|
ExecStart = piAgentStart;
|
||||||
|
Restart = "on-failure";
|
||||||
|
RestartSec = 10;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue