feat(runner): add Pi and Oh My Pi unattended presets - #421
Conversation
Add runner presets for `pi` and `omp` (Oh My Pi): print-mode JSON streams, session resume, and --auto-approve on omp so unattended issue runs do not wait for a person.
|
All contributors have signed the CLA ✍️ ✅ |
|
I have read the CLA Document and I hereby sign the CLA |
|
@sinmingx I have a draft, but I haven’t had time to test it before opening the PR. I’m going to do a cross-check between this and what I have, and I’ll give you feedback as soon as possible 🙏🏻 |
|
@sinmingx As I said, I had a local draft of the same pi preset and never got as far as opening it, so please carry on with this one. I'll discard mine. A few things I had tried, in case they are useful:
|
Pi emits a message_end for the user turn before any text delta, carrying the prompt. The reader took the first message_end as the answer, so the chat printed the prompt ahead of the reply.
|
Thanks, and thanks for letting this one go ahead 🙏 The message_end thing was a real bug. I ran pi 0.85.1 to see the order, and it emits the user message_end (which is just the prompt) before any text delta, then the assistant one. So the reader was printing the prompt and then the answer. It now only falls back to a message_end with role assistant, and I added a test that feeds that order. Pushed in a3c8f7b. Agreed on --session-id, and glad the shared pi-json reader makes sense to you too. I'll keep the task as an argument for now since that's how the other presets do it, but stdin is a good option if a chat ever outgrows an argument. Usage already keeps the last message_update and adds cacheRead to the input, so that lines up with what you saw. |
|
@sinmingx Great work! I've pushed minor fixes to the instructions and bumped the version. Thanks! |
What
Add
piandomppresets to@itsaplan/runner. A fresh run ispi -p --mode jsonoromp -p --mode json --auto-approve, with--append-system-promptfor the run context.piresumes with--session-id.ompresumes with--resume. Both streams are read aspi-json: text deltas, tool calls, and the session id from the openingsessionline.Why
The other coding CLIs already have a preset that sets the unattended flags and the session resume. Pi and Oh My Pi did not, so a run used a custom command. That command does not resume a session and does not parse the JSON stream, so the chat only sees the final text.
Related to #289. The issue asks for
pionly.ompis in the same pull request because both CLIs write the same--mode jsonstream, so onepi-jsonreader serves both; a separate pull request forompwould add two flags and nothing else.piresumes with--session-id <id>(exact project session id) rather than the--session <id>the issue names; both flags exist in pi 0.85.1, and--session-iddoes not do a partial-id lookup.@henry2man wrote in #289 that they were working on an MVP. If that is further along, I am happy to close this in favour of it or fold the
pi-jsonreader into theirs.How to test
From
packages/runner:bun test src/__tests__/presets.test.ts src/__tests__/agui.test.ts39 pass, 0 fail (bun 1.4.2, 2026-09-22). The whole
packages/runnersuite (bun test) is 46 pass, 0 fail.The preset tests pin the argv:
pi, no session: starts-p --mode json, includes--append-system-prompt, task last, no--session-id.pi, sessionsess-9:-p --mode json --session-id sess-9, then the task.omp, no session: includes--auto-approve, no--resume.omp, session01a0c317:-p --mode json --auto-approve --resume 01a0c317, plus--append-system-prompt, task last.The stream test feeds a
pi-jsonsession line, text deltas, a tool call, andmessage_end. It expects session idsess-9, textLooking it over., and tool resulthello from alpha. Amessage_endwith no delta is used as the answer.Flags checked against the installed CLIs: pi 0.85.1 has
--session-id <id>,--append-system-prompt,--mode json; omp 18.2.8 has--resume=<value>(id prefix),--auto-approve,--append-system-prompt,--mode json.With the CLIs installed, set
"agent": "pi"or"agent": "omp"initsaplan-runner.jsonand send two chat messages. The second message should resume the session named on the first line of the first stream. This was not run here.Checklist
bun run typecheckpassesbun run lintandbun run format:checkpasspackages/runnerpreset andpi-jsontests, 39 pass)bun run db:generateand committed.env.exampledocs/runner.md,packages/runner/README.md)Screenshots
N/A. No UI change.