Call Pi Agent on Bot's Machine
Pi is a command-line coding agent running on the bot's machine. It uses the DeepSeek Flash model by default with high thinking effort, and can read/write files, execute commands, and search the web. See docs/setup-guide.md in the repository for detailed installation and configuration. Scripts are located in ~/tools/pi-call/ (the bin/ directory of the repository).
Usage Strategy
The bot's own model usage is limited. Pi uses the user's own model account (default DeepSeek), so its quota is separate from the bot's. Therefore, heavy tasks are delegated to Pi by default; the bot only schedules and verifies.
Delegated to Pi:
- Batch file processing: bulk file editing, data organizing, format conversion.
- Writing code: scripts, small tools, tests, debugging.
- Long-form research and web searches.
- Long document drafts: first versions of docs, reports, articles.
- Tasks explicitly requested by the user to be done by Pi, or for a second opinion or comparison on the same topic.
Done by the bot itself:
- Short conversations and questions that can be answered in one or two steps.
- Connector operations (Gmail, X, GitHub, etc.) — Pi does not have these connections.
- Confirmation before sending, publishing, pushing, or deploying, and reporting back to the user.
Approach:
- Keep instructions concise: specify the goal, input location, output file path, and completion criteria in a few lines. Do not paste large blocks of text into the prompt; let Pi read the files directly.
- Save results directly to files: specify the output path in the prompt and let Pi write the file. After verification, the bot delivers that file directly without rewriting it. For modifications, use the same session to have Pi make changes.
- Capture key conclusions: important conclusions, decisions, or data from the task should be actively written into the bot's memory or related documents by the bot, not left only in Pi's session.
Steps
-
Determine the working directory: Give Pi only the directory needed for the task (repository or
/tmp/<task>), never/or the entire home directory. -
Set a session name: A short English kebab-case name, one per task (e.g.,
news-i18n). Subsequent modifications to the same task reuse the same name; to start over, use a new name. -
Set the output location: When no more suitable location exists, use
/tmp/pi-out/<session-name>/. For deliverables that need to be kept or synced, write them directly to their final location (the corresponding repository, document, or notes directory). -
Write the prompt: Keep it short but complete: specify the goal, constraints, output file path, and completion criteria, and finally ask it to report which files it wrote and a one-sentence conclusion. Pi cannot see the chat history, so provide necessary context in one or two sentences; for long materials, give file paths.
-
Call Pi. For tasks lasting more than a minute or two, always use
pi-task. It assigns a task ID, records status and progress, and saves the result as a file:~/tools/pi-call/pi-task run <working-directory> "<prompt>" --session <session-name> --owner <your-agent-id> [--timeout seconds] [--no-write] [--no-web]--owneris mandatory: it tags the task to the bot that dispatched it, so that completion notifications are routed correctly, andpending/ackoperations prevent different bots from snatching each other's tasks. Without it, the task still runs (owner is recorded asnull, and a warning is printed to stderr), but notifications cannot be routed back. (A default value can be provided by the environment variablePI_TASK_OWNER, but passing it explicitly is more reliable.) The agent's own ID can be found in its profile path (e.g.,/home/box/agent-data/agents/<your-agent-id>/profile.json).Use the Shell tool's built-in background execution (non-blocking). Do not use
nohup,&, orsetsid. The first line of output isTASK <task-id>; when finished, it prints the status and the path toresult.md. Exit codes: 0 success, 1 fail, 124 timeout, 130 cancelled.Other subcommands:
status <ID>(status, owner, duration, recent events),log <ID> [-n 30],list [--all] [--owner <id>|none],cancel <ID>,pending [--owner <id>|none](tasks that have finished but not yet been reported),ack <ID> [--owner <id>|none](mark as reported; rejected if owner does not match, exit code 1).Task data is stored in
~/.pi/tasks/<task-id>/:status.json,events.jsonl,result.md,prompt-<n>.txt. After a bot machine restart, still-running tasks are marked asinterrupted; ask the user whether to re-run them.Completion Notification: When
PI_NOTIFY_URLandPI_NOTIFY_SECRETare set in the environment (stored as environment variables on the bot's machine, not written to files),pi-tasksends a{source, id, owner, state, exit_code}message to this webhook upon every task completion, without task content. The routine task receiving this notification is awakened and runspending --owner <its own id>to check, report, andack --owner <its own id>. It only processes tasks where the owner matches its own id; tasks from other bots are neither checked nor acked; instead, useSendToAgent(with priority true) to forward them to the owner bot; if the routine task environment cannot send messages, hand them back to the main bot for forwarding. Tasks with no owner just trigger a user notification, without ack. If not configured, this step is automatically skipped; the send attempt result is recorded inevents.jsonlunder thenotifyevent. SetPI_NOTIFY_OFF=1to temporarily disable notifications.Fallback Reporting: Completion notifications may not be received. Therefore, every time the bot is awakened (by a user message, routine task, etc.) and there are tasks assigned to Pi, it should first run
pi-task pending --owner <its own id>to see only its own tasks. It checks finished but unreported tasks, delivers the results, then runsack <ID> --owner <its own id>. Only ack its own tasks; leave other bots' tasks to the dispatching bot.For short queries that can be completed within tens of seconds, a foreground call can be used:
~/tools/pi-call/pi-run <working-directory> "<prompt>" --session <session-name> [--timeout seconds]For read-only or model-switching needs, use the lower-level script:
~/tools/pi-call/pi-call.mjs <working-directory> deepseek/deepseek-flash "<prompt>" --thinking high [--allow-write] [--no-web] [--session <session-name>] [--timeout seconds]For
pi-runandpi-call.mjs: stdout contains only Pi's final response; default timeout is 300 seconds; exit codes: 0 success, 1 error, 124 timeout, 127 pi not found.Permissions:
pi-task runandpi-runallow all tools by default (read, search, execute commands, write files, web search);pi-call.mjswithout--allow-writeonly has read-only tools. -
Verify the result: Pi's reply is only its own claim. Use
git diff, run tests, or read the file to confirm it actually did the work before reporting to the user. Do not present unverified conclusions as facts. -
Continue modifications: For
pi-tasktasks, usepi-task reply <task-id> "<what to change>"(same session, same directory, inheriting the original task's owner; rejected if the task is still running). Forpi-runtasks, call it again with the same--session. The sessions for the two tools are stored separately and cannot be resumed across tools.
Rules
- Uses the user's own model quota (web search uses the user's own search service quota). Call on demand; do not run meaningless repetitions or large-scale empty runs.
- Do not delegate code pushing, deployment, DNS or online service changes, sending messages/emails, or deleting important files to Pi. These must be done by the bot itself, with explicit user consent first.
- Do not let Pi read or output
~/.pi/agent/auth.json, key files, or environment variable keys. - Do not ack other bots' tasks: always include
--owner <your-agent-id>withpending/ack; if the owner does not match, forward the task to the dispatching bot. - In user-visible replies, say "Let Pi do X" and explain what you verified.
Troubleshooting
pi: command not found: First runexport PATH=$HOME/.local/bin:$HOME/.node22/bin:$PATH.- Prompt says no available models: The DeepSeek login has expired. The user needs to run
piin their desktop terminal and execute/loginto re-login; the bot cannot do this for the user. - Timeout: Split the task into smaller pieces, or increase
--timeout. - Errors or incorrect results: First check the exit code and
--verboselogs; if the task itself made a mistake, use the same session to point out the problem and let Pi redo it, retrying at most once or twice. If it still fails, take over with the bot itself and tell the user what Pi did poorly; do not repeatedly run empty retries.