Reference

# Python SDK API Reference

Canonical interface for sync + async execution, retry/timeout control, session metadata persistence, and telemetry hooks.

## Package Exports

    from codex_local_sdk import (
        AsyncCodexLiveRun,
        CodexClientEvent,
        CodexLiveRun,
        CodexLocalClient,
        CodexThreadSession,
        CodexError,
        CodexExecFailedError,
        CodexNotInstalledError,
        CodexEvent,
        CodexExecRequest,
        CodexExecResult,
        RetryPolicy,
        SandboxMode,
        SessionStore,
        InMemorySessionStore,
        JsonFileSessionStore,
        SessionRecord,
        SessionTurnRecord,
    )

## Core Models

### CodexExecRequest

Describes `codex exec` CLI options (prompt, sandbox, model/profile, schema/output flags, images, extra args).

### RetryPolicy

Field | Type | Description
--- | --- | ---
`max_attempts` | int | Total attempts (initial + retries).
`initial_backoff_seconds` | float | Base retry delay.
`backoff_multiplier` | float | Exponential growth factor.
`max_backoff_seconds` | float | Delay cap.
`retry_on_exit_codes` | tuple[int, ...] | None | `None` retries any non-zero exit code.
`jitter_ratio` | float | Random jitter fraction applied to backoff delay.
`max_total_retry_seconds` | float | None | Caps total time spent retrying.
`retry_on_timeouts` | bool | Controls retry behavior for timeout failures.

### CodexExecResult

Command result with return code, stdout/stderr, final message, events, thread id, turn status, usage, and duration.

## Session Stores

Session stores map logical names to Codex session IDs and persist metadata/history records.

### SessionStore Interface

- `get(name)`, `set(name, session_id)`, `delete(name)`, `all()`
- `get_record(name)`, `set_record(name, record)`, `list_records()`

### SessionRecord / SessionTurnRecord

- `SessionRecord`: session id/name, counters, timestamps, and bounded turn history.
- `SessionTurnRecord`: per-turn metadata (operation, prompt/message preview, return code, status, duration).

### JsonFileSessionStore

- Schema v2 payload with automatic migration from legacy `{name: session_id}` files.
- Thread-safe + cross-process safe file locking.
- Atomic writes via temp file + `os.replace`.

## CodexLocalClient

### Constructor

    CodexLocalClient(
        codex_bin: str = "codex",
        default_cwd: str | None = None,
        default_env: dict[str, str] | None = None,
        raise_on_error: bool = True,
        retry_policy: RetryPolicy | None = None,
        session_store: SessionStore | None = None,
        event_hook: Callable[[CodexClientEvent], None] | None = None,
    )

### Execution Methods

Method | Returns | Notes
--- | --- | ---
`run(..., timeout_seconds=None)` | CodexExecResult | Sync run with retry policy.
`run_async(..., timeout_seconds=None)` | awaitable[CodexExecResult] | Async wrapper around sync behavior.
`run_prompt(..., api_key=None, timeout_seconds=None)` | CodexExecResult | Prompt convenience wrapper.
`run_prompt_async(...)` | awaitable[CodexExecResult] | Async prompt wrapper.
`run_with_schema(..., api_key=None, timeout_seconds=None)` | CodexExecResult | Schema-constrained output.
`run_with_schema_async(...)` | awaitable[CodexExecResult] | Async schema wrapper.
`start_thread(..., session_name=None, timeout_seconds=None)` | tuple[CodexThreadSession, CodexExecResult] | Starts JSON thread and optionally records named session metadata.
`start_thread_async(...)` | awaitable[tuple[CodexThreadSession, CodexExecResult]] | Async thread start.
`resume(..., session_name=None, timeout_seconds=None)` | CodexExecResult | Sync continuation.
`resume_async(...)` | awaitable[CodexExecResult] | Async continuation.
`run_live(...)` / `resume_live(...)` | CodexLiveRun | Sync live streaming with startup retry support.
`run_live_async(...)` / `resume_live_async(...)` | awaitable[AsyncCodexLiveRun] | Async live streaming with startup retry support.

### Session APIs

- `save_session`, `get_session_id`, `delete_session`, `list_sessions`
- `get_session_record`, `list_session_records`, `open_session`

## Telemetry

Pass `event_hook` to receive `CodexClientEvent` records.

    def on_event(event: CodexClientEvent) -> None:
        print(event.type, event.operation, event.attempt, event.return_code)

    client = CodexLocalClient(event_hook=on_event)

Event types include:

- `attempt.started`, `attempt.failed`, `attempt.succeeded`, `retry.scheduled`
- `live.started`, `live.startup_failed`, `live.startup_retried`, `live.event`
- `session.updated`

## Live Handles

- `CodexLiveRun`: `iter_events()`, `wait(timeout=None)`, `result()`, `terminate()`, `kill()`.
- `AsyncCodexLiveRun`: async equivalents `iter_events()`, `wait()`, and `result()`.

## CodexThreadSession

- `continue_prompt(..., timeout_seconds=None)`
- `continue_prompt_async(..., timeout_seconds=None)`
- `continue_live(...)`
- `continue_live_async(...)`
- `is_last_turn_complete` helper property

## Errors

- `CodexError` (base)
- `CodexNotInstalledError` (missing CLI)
- `CodexExecFailedError` (non-zero with `raise_on_error=True`)