Swap Agentd persistent-agent spawner from pi to Omni/Agent

t-759.3·WorkTask·
·
·
Parent:t-759·Created1 week ago·Updated1 week ago·pipeline runs →

Description

Edit

Goal

Replace pi --mode rpc with agent (no args, stdin-mode) as the persistent agent runner in Omni/Agentd/Daemon.hs. This unifies persistent and one-shot runs under a single binary and gives persistent agents access to agentd's replay/debug tooling.

Current state

Omni/Agentd/Daemon.hs spawns persistent agents as pi --mode rpc, holds the stdin/stdout pipes in an in-memory RunningAgent map, and parses pi's bespoke JSONL schema from stdout.

New state

  • Spawn agent (via whatever path lookup already exists for oneshot runs) with no script argument, so it enters stdin-prompt mode.
  • Hold the stdin pipe the same way.
  • Writing a prompt = hPutStr stdin promptText >> hPutChar stdin '\NUL' >> hFlush stdin.
  • Cancel = signalProcess sigINT agentPid (no stdin message).
  • Shutdown = close stdin (EOF) or send sigTERM.
  • Stdout parser changes from pi JSONL to Trace.Event JSONL — which is the same format the oneshot path already parses, so this should share code with the existing oneshot event reader.

Acceptance criteria

  • Creating a persistent agent via agentd's existing API (POST /agents) spawns agent (not pi) and the agent accepts prompts via null-delimited stdin writes.
  • POST /agents/<id>/send successfully delivers a prompt and the agent responds.
  • POST /agents/<id>/stop cleanly terminates the agent.
  • Cancellation mid-prompt works via SIGINT (requires t-759.2).
  • agentd replay <run-id> and agentd debug <run-id> both work for persistent agents — same as they already do for oneshot, because they read Trace.Event from the same event log.
  • Existing persistent agent metrics (cost, tokens, iterations) still populate correctly, sourced from Trace.Event instead of pi JSONL.

Depends on

t-759.1 (stdin mode) and t-759.2 (signal handling) must land first.

Files likely to touch

  • Omni/Agentd/Daemon.hs — main spawn code and stdin/stdout handling for RunningAgent
  • Possibly shared event-parsing helpers between oneshot and persistent paths

Git Commits

c21cf2a1agentd: run persistent agents via agent stdin mode
Coder Agent11 days ago1 files

Timeline (5)

🔄[human]Open → InProgress1 week ago
💬[human]1 week ago

Implemented pi->agent swap for daemon-managed persistent runner in Omni/Agentd/Daemon.hs. Spawner now launches agent in stdin mode (no prompt arg) with --provider/--model/--json. Prompt delivery uses NUL framing (hPutStr + hPutChar '\NUL' + hFlush). Stop path now sends SIGTERM and closes stdin for graceful exit. Output reader now parses Trace.Event JSONL and updates running/idle state, summary, and cost from Trace events. HTTP handlers /agents, /agents/:id/send, /agents/:id/stop now use the in-process runner map so POST flows hit the new agent runner directly. Updated mock runner script in tests to emit Trace.Event JSON and read NUL-delimited prompts. Verified with typecheck.sh Omni/Agentd/Daemon.hs, bild Omni/Agentd/Daemon.hs, bild --test Omni/Agentd/Daemon.hs.

🔄[human]InProgress → Review1 week ago
🔄[human]Review → Approved1 week ago