# Python Parity Status — 2025-10-17
## Overview
- Reviewed the vendored `codex/` repository, including the shared Rust event schema (`codex/codex-rs/exec/src/exec_events.rs`) and TypeScript SDK (`codex/sdk/typescript/src/thread.ts`, `threadOptions.ts`). The Python SDK (`openai/codex`) is **not** vendored here, but it drives the same codex-rs protocol and features documented upstream.
- Cross-checked the current Elixir implementation (`lib/codex/**/*.ex`) and tests to determine which Python capabilities are still missing. Recent work (e.g. attachment TTL registry) is already reflected below.
- Goal: enumerate every known Python feature we lack so follow-up tasks can be planned without rediscovery.
## Update (2025-12-14)
As of `codex_sdk` `0.3.0`, the SDK supports both exec JSONL (`codex exec --experimental-json`) **and** app-server JSON-RPC over stdio (`codex app-server`). For current parity tracking and protocol mappings, see `docs/20251214/multi_transport_refactor/README.md`.
## Gap Inventory
| Area | Python capability (evidence) | Elixir status (evidence) | Gap & Next Steps |
|------|------------------------------|---------------------------|------------------|
| **Event & Item Coverage** | `ThreadEvent` covers `item.started`, `item.updated`, command executions, file changes, MCP tool calls, web search, todo list, etc. (`codex/codex-rs/exec/src/exec_events.rs:1`) | ✅ All item variants now deserialize into typed structs via `Codex.Items`, and the turn pipeline preserves the richer data (`lib/codex/items.ex`, `lib/codex/events.ex`, `test/codex/events_test.exs:38`). | Maintain parity as codex-rs adds new item types (add tests/structs on schema updates). |
| **Structured Output** | Python/TypeScript write JSON schemas to disk and pass them to the binary (`createOutputSchemaFile` / `outputSchema` in `codex/sdk/typescript/src/thread.ts:33`) | ✅ Schemas are persisted, decoded responses populate `Items.AgentMessage.parsed`, and helpers expose the parsed payload (`lib/codex/thread.ex:360`, `lib/codex/turn/result.ex:28`, `test/codex/thread_test.exs:107`). | Track edge cases (nested structs, large payloads) and extend helpers once schema builders land. |
| **Per-turn Tool Bridging** | Python feeds tool outputs/failures back into codex-rs so continuation turns consume them (see tool harness in `codex/codex-rs/core/tests/suite/tool_harness.rs`) | 🟡 The SDK can buffer tool outputs/failures internally, but neither exec JSONL nor app-server v2 currently exposes a supported external-client mechanism to inject tool results back into the agent loop. | Prefer hosting tools via MCP or wait for an upstream protocol surface that supports tool result injection. Keep exec transport honest and avoid undocumented flags. |
| **Thread Options: sandbox, working dir, Git checks** | Python exposes sandbox/workdir/git toggles plus per-run model overrides (`codex` CLI flags and config) | ✅ Thread-level exec options are exposed via `Codex.Thread.Options` and forwarded to `codex exec` (`sandbox`, `working_directory`, `additional_directories`, `skip_git_repo_check`, etc.). | Track upstream CLI flags for drift; app-server uses the v2 thread/turn params instead of CLI flags. |
| **MCP Tool Surfacing** | Event schema includes `McpToolCall` items and Rust core differentiates MCP call lifecycles (`codex/codex-rs/exec/src/exec_events.rs:60`) | `Codex.MCP.Client` exists but nothing in the turn pipeline inspects MCP-specific items or dispatches to external transports (`lib/codex/mcp/client.ex:1`, `lib/codex/thread.ex:245`) | Add item parsing plus orchestration so MCP tool calls flow through approvals/registries just like Python’s MCP support. |
| **File Upload APIs** | Python client offers staging **and** upload helpers for the HTTP file endpoints (`docs/design/attachments-files.md:24` describes parity goal) | Elixir exposes `stage/2`, `attach/2`, TTL cleanup, but no file upload helper to a remote API. | If needed, implement upload helpers against the OpenAI Files API and document how they relate (or don’t) to `codex exec` (which only supports `--image` attachments). |
| **Temporary Attachment Helpers** | Python provides RAII-style helpers for ephemeral files (referenced in design doc `docs/design/attachments-files.md:26`) | Elixir missing {@literal Codex.Files.temporary/1} or similar API | Implement helper returning disposable attachment structs and cover via unit tests. |
| **Structured Logging / Telemetry Parity** | Python emits structured logs alongside telemetry (see roadmap `docs/20251018/codex-sdk-completion/module-implementation.md:54`) | Elixir telemetry exists for threads/tools/approvals/attachments, but logging output hasn’t been aligned with Python formats (`lib/codex/telemetry.ex:1`) | Add logger helpers / formatting utilities so CLI-integrated apps see the same log payloads Python produces. |
| **Binary Lifecycle Mix Tasks** | Python packaging bundles the codex binary; parity plan calls for install/verify tasks (`docs/20251018/codex-sdk-completion/integration-readiness.md:5`) | Only `mix codex.verify` is wired; no installer/build task yet (`mix.exs:12`) | Provide `mix codex.install` (Rust build/download), document usage, and integrate with CI. |
## Observations & Open Questions
- Python source is external, so parity tracking relies on codex-rs schemas, TypeScript SDK behavior, and harvested fixtures. Any hidden Python-only helpers (async APIs, context managers) need confirmation once the repo is available locally.
- Event schema evolves quickly; re-check `codex/codex-rs` on each update so we don’t miss new item types or fields.
Update this status doc whenever we land a missing feature or discover additional Python-only capabilities.