Files
codex/codex-rs/docs/agent_runtime_baseline.md
jimmyfraiture 0d340b1bec P5
2025-09-29 12:03:57 +01:00

78 lines
5.3 KiB
Markdown

# Agent Runtime Baseline
Codex currently exposes its agent runtime from the `codex-core` crate. The runtime is organised around three cooperating interfaces located in `core/src`:
- `Codex` (`core/src/codex.rs`) is the public façade that hosts use. It owns the submission/event queues and spawns the asynchronous runtime.
- `Session` (`core/src/codex.rs`) encapsulates conversation-scoped state and orchestrates task lifecycles once a session has been configured.
- `SessionTask` (`core/src/tasks/mod.rs`) is the trait implemented by the concrete task runners (`RegularTask`, `ReviewTask`, `CompactTask`).
The refactor tracked in `../agent_refactor.md` will extract these responsibilities into a dedicated `codex-agent` crate; this document captures the current layout before the extraction begins.
## `Codex`
`Codex` is the high-level queue API that front-ends interact with:
- `spawn` initialises the runtime with a `Config`, `AuthManager`, and `InitialHistory` and returns a `CodexSpawnOk` containing the queue endpoints and generated `ConversationId`.
- `submit` wraps an `Op` in a `Submission`, generates a unique id, and pushes it onto the bounded submission channel (`SUBMISSION_CHANNEL_CAPACITY = 64`).
- `next_event` pulls the next `Event` from the unbounded event receiver, propagating `CodexErr::InternalAgentDied` if the channel is closed.
Upon spawning, `Codex` constructs a `ConfigureSession` payload that gathers CLI-derived configuration (model details, approvals, sandbox policy, notify hooks, `cwd`) and uses `prepare_session_bootstrap` to assemble rollout/MCP/sandbox services before delegating to `Session::new`. The CLI now also constructs the initial `ModelClient`/`ToolsConfig` pair and wraps them in a `TurnContext` `Arc`, hands over the host-built `SessionServices`, and kicks off the background `submission_loop` task that drives the agent.
## `Session`
`Session` bundles the pieces required to handle a configured conversation:
- Identifiers: `conversation_id` (originating from `InitialHistory`) and an internal `next_internal_sub_id` counter for action-specific ids.
- Communication: the `tx_event` sender used to emit `Event` messages back to the host.
- State holders: a `Mutex<SessionState>` for persistent session data and a `Mutex<Option<ActiveTurn>>` tracking the currently running tasks.
- Services: `SessionServices` (now defined in `codex-agent`) packages dependencies that are currently hard-wired to CLI types—`ExecSessionManager`, `UnifiedExecSessionManager`, `RolloutRecorder`, `McpConnectionManager`, etc.
`Session::new` now expects those services to be prepared by the host: `prepare_session_bootstrap` initialises rollout recording, MCP connections, default shell discovery, and history metadata in parallel before handing the assembled pieces to `Session::new`, which emits the initial `SessionConfigured` event and records any startup warnings so they can be surfaced after configuration.
Operationally, `Session` is responsible for:
- Translating incoming `Submission`s into task invocations via `run_task`, `run_turn`, and helper functions in `core/src/codex.rs` and `core/src/tasks`.
- Managing approvals and sandbox execution by calling into `sandbox::plan_*` helpers and dispatching events (`ExecApprovalRequestEvent`, `ApplyPatchApprovalRequestEvent`, etc.).
- Recording rollout items and forwarding MCP tool call updates.
- Tracking and cancelling running work when new input arrives or when approvals are rejected.
## `SessionTask`
Tasks implement the asynchronous work units that execute within a session. The trait lives in `core/src/tasks/mod.rs`:
```rust
#[async_trait]
pub(crate) trait SessionTask: Send + Sync + 'static {
fn kind(&self) -> TaskKind;
async fn run(
self: Arc<Self>,
session: Arc<SessionTaskContext>,
ctx: Arc<TurnContext>,
sub_id: String,
input: Vec<InputItem>,
) -> Option<String>;
async fn abort(&self, session: Arc<SessionTaskContext>, sub_id: &str) { ... }
}
```
`SessionTaskContext` is a thin wrapper that hands tasks a clone of the `Session`, giving them access to helpers such as `send_event`, `plan_exec`, and `run_with_plan`. `Session::spawn_task` ensures only one task runs at a time by:
1. Calling `abort_all_tasks` to cancel the current `ActiveTurn`.
2. Wrapping the concrete task in `Arc<dyn SessionTask>`.
3. Spawning a Tokio task that awaits `run` and then reports completion through `Session::on_task_finished`.
`RunningTask`, `ActiveTurn`, and `TurnAbortReason` (from `core/src/state`) coordinate cancellation semantics and surface `TurnAborted`/`TaskComplete` events consistently.
Today the concrete implementations are:
- `RegularTask` (`core/src/tasks/regular.rs`) for the standard Codex workflow.
- `ReviewTask` (`core/src/tasks/review.rs`) used during review mode.
- `CompactTask` (`core/src/tasks/compact.rs`) which emits summarised history.
Each uses shared utilities in `core/src/codex.rs` (e.g., `run_task`, `exit_review_mode`, sandbox planners) and relies on the CLI-flavoured services packaged in `SessionServices`.
## Next Steps
With this baseline documented, the next implementation steps are described in `../agent_refactor.md`. As we move work into the new `codex-agent` crate we should revisit this document to ensure the captured interfaces stay accurate and to outline any newly introduced abstractions (`AgentRuntime`, `AgentConfig`, service traits, etc.).