Standalone. It runs with nobody attached.
The daemon is the standalone foundation: a persistent task queue, a worker that drains it, recurring schedules, per-task driver selection, outcome notifications, and a durable per-run event log. On macOS, tachi-agent service install is the primary path — one command bootstraps a launchd LaunchAgent that starts at login and restarts on crash.
macOS: one command, starts at login.
tachi-agent service install reads env vars from your environment (or an --env-file), writes a 0600 plist under ~/Library/LaunchAgents, and bootstraps the service with launchctl.
GATEWAY_TOKEN + all TACHI_* vars from the file and bakes them into the plist.~/.tachi-agent).1export GATEWAY_TOKEN="change-me"2tachi-agent service install --env-file .env # bootstrap launchd LaunchAgent3# starts at login · restarts on crash4# logs: ~/Library/Logs/tachi-agent/daemon.log5 6tachi-agent service status # check whether the agent is running7tachi-agent service uninstall # remove the plist + unload1[Unit]2Description=tachi-agent daemon3After=network.target4 5[Service]6ExecStart=/usr/bin/node /path/to/dist/daemon/index.js7WorkingDirectory=/path/to/.tachi-agent8EnvironmentFile=/path/to/.env9Restart=always10RestartSec=511 12[Install]13WantedBy=multi-user.targetMarkdown recipes that shape what a run sees.
Drop a .md file in .tachi/skills/ (override with TACHI_SKILLS_DIR). The body is appended to the system prompt; frontmatter carries the name, a fail-closed tools allowlist, and a driver preset.
Driver precedence: --driver flag / /driver command > skill's driver field > TACHI_DRIVER.
Ready-made recipes in examples/skills/
1---2name: researcher3description: Deep-research mode — searches and synthesizes a cited report.4tools: tachibot_grok_search, tachibot_perplexity_ask, tachibot_nextThought5driver: openai6---7You are a careful research assistant. Your output must be accurate and traceable.1tachi-agent --skill researcher "explain the CAP theorem trade-offs"2# or inside the interactive REPL3# /skill researcherBare tachi-agent opens a REPL.
The prompt shows the active session: tachi [driver·skill] ›. History persists at ~/.tachi-agent/repl_history (capped at 1000 lines). Rewritten tasks from /jury, /search, /think are echoed as → task.
| Command | What it does |
|---|---|
| /help | Show the command list |
| /tools | List the agent's available tools |
| /model | Show the current model |
| /status | Show session state (driver, skill, mode) |
| /driver <name>|off | Set or clear the session driver |
| /skill <name>|off | Activate or clear a skill bundle |
| /reset | Clear the full session (driver + skill + conversation history) |
| /jury <question> | Run a cross-model jury verdict via tachibot_jury |
| /search <query> | Search with tachibot_grok_search or Perplexity |
| /think <question> | Reason step by step over a question |
| /task add <text> | Queue a task on the daemon |
| /task list | List queued tasks |
| /task show <id> | Show task detail |
| /schedule list | List scheduled jobs |
| /exit, /quit | Leave (REPL: Ctrl-D also exits) |
/reset. This is short-term session memory; dokoro stays the long-term memory across sessions.A daemon under a supervisor. A queue that survives it.
Run node dist/daemon/index.js under launchd (macOS LaunchAgent with KeepAlive) or systemd (Restart=always). The supervisor keeps the process alive; the queue keeps the work alive.
The queue (.tachi/queue.json) is crash-safe: a task left running by a dead daemon is re-queued on restart with its spent attempt counted. Failed tasks retry with exponential backoff (default 3 attempts).
Queue work from outside. External cron is the scheduler.
POST /tasks enqueues durable work — unlike POST /runs, a queued task survives restarts and retries with backoff.
1# crontab — nightly digest at 02:30, run on the OpenAI heart230 2 * * * curl -s -X POST -H "Authorization: Bearer $TACHI_TOKEN" -H "Content-Type: application/json" \3 -d '{"task":"summarize yesterdays inbox and post to slack","driver":"openai"}' http://127.0.0.1:8787/tasks| Method & path | Purpose |
|---|---|
| POST /tasks {task, driver?, maxAttempts?} | Enqueue a durable task — survives restarts, retries with exponential backoff. |
| GET /tasks | The live queue: status, attempts, driver, answer/error per task. |
| GET /tasks/:id | One task in full — including the recorded error after a loud failure. |
A JSON file you edit by hand. Re-read live.
For self-contained recurrence, the daemon evaluates .tachi/schedules.json (TACHI_SCHEDULES_FILE) every TACHI_SCHEDULES_POLL_MS (default 30s) and enqueues due entries into the same queue.
kind: "daily" + at: "HH:MM"kind: "every" + everyMinutes: N.tachi/schedules-state.json, so a restart doesn't re-fire a schedule that already ran.1{2 "schedules": [3 { "id": "morning-digest", "task": "compile the morning digest", "driver": "openai", "kind": "daily", "at": "07:00" },4 { "id": "poll", "task": "check the feed for updates", "kind": "every", "everyMinutes": 30 }5 ]6}One default brain. A different heart per task.
TACHI_DRIVER picks the daemon's default brain (ollama — local, private). A task's optional "driver" field overrides it for that task only.
| Driver | What it is | Needs |
|---|---|---|
| ollama | Local model via Ollama — private, offline. The default. | — |
| hermes | Self-hosted OpenAI-compatible endpoint. | HERMES_BASE_URL / HERMES_MODEL |
| openai | GPT via the OpenAI API. | OPENAI_API_KEY |
| openrouter | Any model behind OpenRouter. | OPENROUTER_API_KEY |
1# the daemon's default heart stays local2export TACHI_DRIVER=ollama3 4# this one task runs on GPT — for that task only5curl -s -X POST -H "Authorization: Bearer $TACHI_TOKEN" -H "Content-Type: application/json" \6 -d '{"task":"deep-audit the quarter logs","driver":"openai"}' http://127.0.0.1:8787/tasksopenai without OPENAI_API_KEY) fails loudly: the actionable error is recorded on the task, normal retry/backoff applies, and the failed task stays inspectable in the queue.The agent reaches out. You don't poll.
Set TACHI_NOTIFY and the worker pushes every task outcome — success or failure — to those targets, using the existing TELEGRAM_BOT_TOKEN / SLACK_BOT_TOKEN.
1export TACHI_NOTIFY="telegram:123456789,slack:C0123ABC"Everything an unattended run did, on disk.
The same visibility from the CLI — point it at the daemon with TACHI_DAEMON_URL + GATEWAY_TOKEN.
| Where | What |
|---|---|
| GET /tasks, GET /tasks/:id | Live queue: status, attempts, driver, answer/error. |
| .tachi/queue.json | The queue on disk (survives restarts; readable JSON). |
| .tachi/runs/*.jsonl | Durable per-run event log (TACHI_RUN_LOG_DIR) — every step, append-only. Post-hoc debugging for runs nobody watched. |
1export TACHI_DAEMON_URL="http://127.0.0.1:8787" GATEWAY_TOKEN="change-me"2 3tachi-agent task add "compile the weekly report" --driver openai --max-attempts 54tachi-agent task list # id · status · attempt n/max · driver · excerpt5tachi-agent task show <id> # one task in full — answer or recorded error6tachi-agent runs log <run-id> # replay the durable JSONL event log of a run