feat(responses): loopback OpenAI Responses shim for Codex
Draft
SH
1mo ago+2831+2831+0123456789012345678901234567890123456789-1345-1345-0123456789012345678901234567890123456789
Summary
Adds a loopback OpenAI Responses API shim so Codex CLI can run against RunAnywhere models. Codex 0.145.0 removed wire_api = "chat", so a /v1/responses front door is now the only way it can reach our chat-completions gateway.
Rather than duplicate the Anthropic bridge's transport, this extracts the provider-agnostic loopback transport into a shared crate::shim module parameterized by a small Dialect trait (+ a StreamConverter). Both bridges are now thin dialects over one transport:
- Anthropic (Claude Code) —
/v1/messages, unchanged behaviour. - Responses (Codex) —
/v1/responses, new.
Each keeps its own CURRENT singleton, so starting one never tears the other down. No transport is duplicated.
What's included
src/shim.rs— shared transport (pooled + watched upstream, the streaming worker with keepalives + pre-stream status decision + incomplete-stream guard, disconnect handling, start/stop), theDialect/StreamConvertertraits, and the sharedShim/Runtime.src/anthropic/messages.rs— reduced from ~1,460 lines to ~340: just the Anthropic dialect (x-api-key/Bearer auth, its translation, its error envelope, its Claude-Desktop discovery shape,/api/hello).src/responses/translate.rs— Responses ↔ chat translation (allserde_json::Value, matching the Anthropic path): request mapping (input items, tools,call_idround-trip,max_output_tokens→max_tokens,developer→system, mirrors thestreamflag), non-streaming response, and the streaming state machine (created/in_progress → text/function_call lifecycles → completed; monotonicsequence_number; no[DONE]).src/responses/messages.rs— the Responses dialect (Bearer auth, OpenAI error envelope +/v1/models).src/commands/cmd_responses.rs— hidden dev entrypointwally __responses-serve(kept out of--help) for validation.
Validation
cargo test --lib: 393/393;cargo fmt --check+cargo clippy --libclean.- In-process e2e test drives the Anthropic dialect through the shared transport (auth → translate → upstream → Anthropic envelope), guarding the Claude path against the refactor.
- Real Codex 0.145.0 → shim → real
glm-5.3-flash: a text turn, and a tool round-trip where the model calledexec_command, Codex executed it, and the model reported the output.
Follow-ups (not blockers)
- Emit
response.reasoning_summary_text.*events (currentlyreasoning_contentis dropped; Codex works without it). - A proper
wally codexlauncher (writes~/.codex/config.toml, setsCODEX_HOME). - A real
DeclaredHarness::KCodex— a human-gated server contract change (OpenAPI +sync_from_inferenceinfra.pyregen); today it attributes asKRcli.
🤖 Generated with Claude Code
https://claude.ai/code/session_01Hm9aUP3Fvg83pJZo2mixgv
Summary by CodeRabbit
- New Features
- Added
wally codexto launch Codex with a selected local or hosted model. Additional command-line arguments are passed through, and model settings such as context window are applied when available. - Added support for the OpenAI Responses API through a local compatibility service, including request and response conversion, streaming, model discovery, and authentication.
- Added