[Unit] Description=zcode mail-bridge (AgentMail ↔ ZCode headless CLI) Documentation=file:/home/program/agentmail/plugins/zcode-mail-bridge/README.md After=network-online.target agentmail-gateway.service Wants=network-online.target [Service] Type=simple # 驱动自己不需要工作目录(每一轮 cwd 来自邮件寻址的 path 位), # 但 systemd 要求一个存在的目录,且相对路径(`../hooks/hooks.json` 的自检) # 以进程启动位置为准。 # 生产跑**快照**,不跑仓库工作区:仓库会被我们随手编辑,而邮件驱动的服务 # 重启后会直接跑起当前 HEAD —— 一次未完成的修改就变成线上行为。 # 与 pi / opencode / dsh 同一条约定,切换靠 deploy/redeploy-plugin.sh 的原子软链。 WorkingDirectory=/opt/agentmail/plugins/zcode-mail-bridge/current ExecStart=/usr/bin/node /opt/agentmail/plugins/zcode-mail-bridge/current/src/index.mjs # ZCode 靠 HOME 定位 ~/.zcode(OAuth 凭据、cli/config.json、会话库、日志)。 # systemd 不会自动注入 HOME,不显式给就: # - 读不到登录凭据 → 每一轮都报「Model config is missing」,全部回成失败信 # - 插件发现落到 /.zcode → 空目录,MCP 工具一个都没有 Environment=HOME=/root EnvironmentFile=/etc/agentmail/zcode.env Restart=always RestartSec=10 # 异常退出邮件上报:进程内的钩子捕获不了 SIGKILL/OOM,只能由 systemd 覆盖。 # 正常 stop/restart 不上报(脚本内 isAbnormalExit 提前返回)。 ExecStopPost=-/usr/bin/node /home/program/agentmail/deploy/service-failure-notify.mjs --report --service zcode-mail-bridge.service # 补发上次网关不可达时暂存的报告(per-agent spool) ExecStartPost=-/usr/bin/node /home/program/agentmail/deploy/service-failure-notify.mjs --flush --service zcode-mail-bridge.service # 一轮 ZCode 会派生一个 node 进程(模型 + 工具),内存占用比另三个桥高。 # 给一个上限让它被 OOM killer 挑中而不是拖垮整机;Restart=always 会拉回来。 MemoryMax=4G # 停机:驱动收到 SIGTERM 后会终止在途回合(否则会留下跑工具的孤儿), # 再关掉 SSE。默认 90 秒太长,15 秒够。 TimeoutStopSec=15 [Install] WantedBy=multi-user.target