mirror of
https://github.com/openai/codex.git
synced 2026-05-26 14:04:48 +00:00
4.0 KiB
4.0 KiB
run_codex_convo CLI Plan
Goal
Single-command Rust utility that takes a user message, runs it through Codex app-server (JSON-RPC over stdio), and prints the streamed assistant output until the turn finishes.
Assumptions
codex-app-serverbinary is discoverable in$PATH.- User already configured Codex (auth, model defaults) so a fresh conversation can run without extra prompts.
- Project will live in its own cargo crate (
run_codex_convoworkspace member).
Functional Requirements
- Accept a single positional argument
user_message; optional flags:--cwd,--model,--approval-policy,--sandbox(pass-through overrides).
- Launch
codex-app-serveras a child process with stdio pipes. - Perform JSON-RPC handshake (
initialize,initialized). - Start a conversation (
newConversation) with optional overrides. - Send the user message (
sendUserMessage). - Subscribe to the conversation (
addConversationListener). - Stream
codex/event/*notifications:- Print assistant text (
agent_message,agent_message_delta). - Surface approvals/errors for visibility.
- Print assistant text (
- Stop once the server emits
task_completeorturn_abortedfor that request. - Shutdown child process gracefully (send EOF / kill on timeout).
Implementation Outline
1. Workspace Setup
- Create new binary crate with
tokio+anyhow+serde+serde_json+clap+tracing. - Add helper module re-exporting Codex protocol types or lightweight copies for requests/responses (consider depending on
codex-rsworkspace crate if feasible).
2. Process & IO Management
- Use
tokio::process::Commandto spawncodex-app-serverwith piped stdin/stdout/stderr. - Wrap stdio with framed readers/writers (
tokio_util::codec::LinesCodecor manual line buffering) to handle newline-delimited JSON. - Spawn task to log stderr from the child for troubleshooting.
3. JSON-RPC Layer
- Define structs for requests/responses using
serde. - Implement
RequestIdgenerator and helper to send requests and await matching responses (maintain pending map keyed by id, fulfilled when response arrives). - Parse incoming messages: discriminate between responses (
result/error) and notifications (methodw/outid).
4. Conversation Flow
- Send
initializewith client metadata. - Post
initializednotification. - Issue
newConversation(with optional overrides) and captureconversationId. - Immediately call
addConversationListener. - Send
sendUserMessagepayload containing provided text. - Track the request id of
sendUserMessageto correlate events.
5. Streaming Output Rendering
- For
codex/event/agent_messageandagent_message_delta, print to stdout (buffer deltas to form cohesive message). - Optionally colorize using
owo-colorsor similar. - Surface
agent_reasoningevents as faint/optional output behind a--show-reasoningflag. - If
exec_approval_requestorapply_patch_approval_requestarrives, log notice that approvals were requested but auto-denied (since CLI cannot interact).
6. Completion Criteria
- Monitor events for
task_completeorturn_abortedmatching this conversation. - Once received, flush output, collect final status, and exit with code 0 (or non-zero if
erroroccurred). - Ensure outstanding pending requests are dropped to avoid hanging tasks.
7. Graceful Shutdown
- After completion, send EOF to server stdin or issue
interruptConversation/archiveConversationif desired. - Await child termination with timeout; on failure, send kill signal.
8. Testing Strategy
- Unit-test JSON parsing and request builders.
- Write integration test spawning a mocked Codex server (or use real binary behind feature flag) verifying handshake + message flow.
- Add CLI smoke test using
assert_cmdif Codex binary available.
Enhancements (Later)
- Support multi-turn conversations (
run_codex_convo --repl). - Add
--planflag to render plan tool output as checklist. - Stream structured logs to file for debugging.
- Accept stdin message body when positional arg omitted.