Expand description
PersistentSubprocessController: manages agent CLI as a long-running process with bidirectional NDJSON streaming via stdin/stdout.
Architecture: A single CLI process is spawned on first message and kept alive for the entire session. User messages are written as NDJSON lines to stdin without closing it. This enables mid-turn input (redirecting the agent while it is still processing).
State machine: INIT ─(first message)─> RUNNING ─(idle between turns)─> RUNNING RUNNING ─(kill/stop)─> DONE RUNNING ─(process crash)─> DONE (auto-restart possible via session_id)
I/O model (3 async tasks per session):
- stdin_writer: mpsc channel → process stdin (NDJSON lines)
- stdout_reader: process stdout → .jsonl persistence + WPS blockfile events
- process_waiter: wait for exit, update status
Structs§
- Persistent
Inner 🔒 - Inner state protected by mutex.
- Persistent
Spawn Config - Configuration for spawning the persistent process.
- Persistent
Subprocess Controller - PersistentSubprocessController keeps a long-running CLI process alive, sending user messages as NDJSON lines on stdin.
Constants§
- ANSWER_
RESUME_ 🔒FALLBACK_ MS - How long to wait after delivering an AskUserQuestion answer before assuming
the turn did not resume and re-delivering the answer as a follow-up message.
See
answer_questionand SPEC_ASK_USER_QUESTION_2026_06_15.md §10.1. - BLOCK_
CONTROLLER_ PERSISTENT - PERSISTENT_
OUTPUT_ SUBJECT - WPS file subject name for persistent subprocess output.
Functions§
- build_
answer_ 🔒resume_ message - Compose the directive follow-up message used by the AskUserQuestion dead-air
fallback.
answersmaps each question’s text to the selected label(s) or free text (the same object delivered in the control_response). The message is deliberately directive so the model resumes the task instead of treating it as a no-op (the “user sent an empty message” failure mode). - muxbus_
agent_ 🔒id_ from_ env - Resolve the muxbus address (the agent’s display name) from a spawn env map.
AGENTMUX_AGENT_ID(=agent.name, set at block creation) is canonical;WAVEMUX_AGENT_IDis the legacy fallback. ReturnsNone— i.e. not muxbus-addressable — when neither is present (a non-agent persistent block).