Codex Runtime
Codex Runtime is the repository for a Rust wrapper around the local codex app-server—the stdio JSON-RPC backend spawned by the codex CLI binary.
Current identity:
- repository and package name:
codex-runtime - Rust import path:
codex_runtime
It exposes six layers so you can start simple and reach deeper only when needed:
| Layer | Entry point | When to use |
|---|---|---|
| 1 | quick_run, quick_run_with_profile |
One prompt, disposable session |
| 2 | Workflow, WorkflowConfig |
Repeated runs in one working directory |
| 3 | runtime::{Client, Session} |
Explicit session lifecycle, resume, interrupt |
| 4 | automation::{spawn, AutomationSpec} |
Schedule repeated turns on one prepared Session |
| 5 | AppServer |
Direct JSON-RPC with typed helpers and server-request loop |
| 6 | runtime::Runtime or raw JSON-RPC |
Full control, live events, experimental access |
Install
Requires: codex CLI >= 0.104.0 installed and available on $PATH.
Published crate dependency:
[]
= "0.4.0"
= { = "1", = ["macros", "rt-multi-thread"] }
Local workspace dependency:
[]
= { = "crates/codex-runtime" }
Safe Defaults
All entry points share the same safe defaults unless explicitly overridden:
| Setting | Default |
|---|---|
| approval | never |
| sandbox | read-only |
| effort | medium |
| timeout | 120s |
| privileged escalation | false (requires explicit opt-in) |
High-Level API
quick_run
use quick_run;
async
Workflow
use ;
async
Low-Level Typed API
Client and Session
use ;
async
automation::spawn
use ;
use ;
use ;
async
Contract:
- automation reuses one prepared
Session; it does not create or resume sessions for you - scheduling uses absolute
SystemTimebounds plus one fixedDuration everymust be greater than zero- only one turn is in flight at a time
- missed ticks collapse into one next eligible run
- any
PromptRunErrorstops the runner and recordslast_error - V1 does not provide cron parsing or restart persistence
AppServer
use CommandExecParams;
use AppServer;
use json;
async
Defaults And Contracts
- High-level builders stay minimal and do not mirror every upstream field.
- When you need more control, use
RunProfile,SessionConfig,ClientConfig, orRuntimeConfig. - Use
AppServertyped helpers for stable low-level parity. - Use raw JSON-RPC for experimental or custom methods.
Public Modules
| Module | Role |
|---|---|
codex_runtime |
Root: quick_run, Workflow, WorkflowConfig, AppServer, rpc_methods, HookMatcher, FilteredPreHook, FilteredPostHook, ShellCommandHook |
codex_runtime::automation |
Optional session-scoped recurring prompt runner above one prepared Session |
codex_runtime::runtime |
Low-level runtime: Client, Session, Runtime, typed models, errors |
codex_runtime::plugin |
Hook extension point: PreHook, PostHook, HookContext, HookPatch |
codex_runtime::web |
Optional HTTP adapter bridging runtime sessions to SSE/REST web services |
codex_runtime::artifact |
Optional artifact tracking domain built on top of the runtime |
Important runtime submodules available for direct use when re-exports are not enough:
runtime::api, runtime::approvals, runtime::client, runtime::core,
runtime::errors, runtime::events, runtime::hooks, runtime::metrics,
runtime::rpc, runtime::rpc_contract, runtime::sink, runtime::state,
runtime::transport, runtime::turn_output
Optional Modules
codex_runtime::web
Primary entry points:
WebAdapter::spawn(runtime, config)orspawn_with_adapter(...)create_session(...),create_turn(...),close_session(...)subscribe_session_events(...),subscribe_session_approvals(...)post_approval(...)new_session_id(),serialize_sse_envelope(...)
Contract:
- one
WebAdapterbridges runtime threads into tenant/session-scoped web sessions - approval replies flow back through
post_approval(...); callers do not mutate runtime approval state directly
codex_runtime::artifact
Primary entry points:
ArtifactSessionManager::new(runtime, store)ornew_with_adapter(...)open(artifact_id)— load or create one artifact-backed runtime threadrun_task(spec)— execute one typed artifact taskFsArtifactStore::new(root)— filesystem-backed store- pure helpers:
compute_revision(...),validate_doc_patch(...),apply_doc_patch(...)
Contract:
- the module keeps artifact state in an
ArtifactStoreand delegates runtime turns through an adapter - compatibility is gated by
PluginContractVersionbefore artifact tasks run
Hooks
Hooks let you intercept and mutate prompt calls at defined lifecycle phases without forking the call path.
use Arc;
use ;
;
let config = new
.with_global_pre_hook;
Hook phases:
- run/session/turn:
PreRun,PostRun,PreSessionStart,PostSessionStart,PreTurn,PostTurn - tool loop:
PreToolUse,PostToolUse
Hook actions:
HookAction::NoopHookAction::Mutate(HookPatch)HookAction::Block(BlockReason)for pre-hooks
Ergonomic builders:
- global hooks:
with_global_pre_hook,with_global_post_hook,with_global_pre_tool_use_hook - run-scoped hooks:
with_run_pre_hook,with_run_post_hook - shell adapters:
with_shell_pre_hook,with_shell_post_hook,with_shell_pre_hook_timeout
Path note:
HookMatcher,FilteredPreHook,FilteredPostHook, andShellCommandHookare also re-exported at the crate root ascodex_runtime::...
Important contract:
- pre-tool-use hooks fire on approval-gated tool/file-change requests, not every successful write
- privileged write sandboxes still require explicit opt-in via
allow_privileged_escalation() - tool-use hooks do not replace sandbox/approval policy; they sit on top of it
Documentation
- docs/README.md: active documentation index
- API_REFERENCE.md: full public API surface, typed payload contracts, validation and security rules
- CRATE_RENAME_AUDIT.md: rename verification status and remaining caveats
- TEST_TREE.md: test layer structure and live-gate boundary
- BACKLOG.md: non-blocking follow-up improvements
- CHANGELOG.md: release history
Quality Gates
Deterministic release gates:
Release preflight:
Opt-in real-server preflight:
CODEX_RUNTIME_REAL_SERVER_APPROVED=1 \
CODEX_RUNTIME_RELEASE_INCLUDE_REAL_SERVER=1 \
Design Boundaries
- High-level APIs stay small on purpose.
- Stable non-experimental upstream fields go to typed APIs first.
- Experimental fields stay raw until the protocol is stable and testable.
requestUserInputand dynamic tool-call live coverage remain outside the deterministic release boundary.- Hook support exists, but live hook coverage is narrower than core prompt/session flows.
License
MIT