Ahmed Ibrahim
90d · built 2026-07-24
90-day totals
- Commits
- 77
- Grow
- 7.1
- Maintenance
- 12.8
- Fixes
- 0.2
- Total ETV
- 20
Where this dev ranks
Percentile against the global top-100 leaderboard (all-time totals).
- By commits
- Top 40 %
- By Growth share
- Top 35 %
30-day trajectory
Last 30 days vs. the 30 days before. Up arrows on Growth and ETV mean improvement; up arrow on Fixes share means more time on fixes (worse).
↓-68.8 %
vs 32 prior
↑+6.1 pp
recent vs prior
↑+2.9 pp
recent vs prior
Daily performance
Daily ETV, stacked by Growth, Maintenance and Fixes.
Work-mix over time
Share of Growth / Maintenance / Fixes over a rolling 7-day window. Reads as 'where is effort flowing right now'.
Repository spread
Where this developer's commits land. Concentrated work (top1 > 80%) vs polymath spread (top1 < 30%).
Most impactful commits
Top 20 by ETV in the 90-day window.
- 1.6ETVSplit MCP connection modules (#19725) ## Why The MCP connection manager module had grown to mix orchestration, RMCP client startup, elicitation handling, Codex Apps cache and naming behavior, tool qualification and filtering, and runtime data. The previous stacked PRs split these responsibilities incrementally; this PR collapses that work into one self-contained refactor on latest main. ## What changed - Move McpConnectionManager into connection_manager.rs. - Move RMCP client lifecycle, startup, and uncached tool listing into rmcp_client.rs. - Move elicitation request tracking and policy handling into elicitation.rs. - Move Codex Apps cache, key, filtering, and naming helpers into codex_apps.rs. - Rename the tool-name helper module to tools.rs and move ToolInfo, tool filtering, schema masking, and qualification there. - Move runtime and sandbox shared types into runtime.rs. - Preserve latest main PermissionProfile-based MCP elicitation auto-approval behavior. ## Verification - just fmt - cargo check -p codex-mcp - cargo check -p codex-mcp --tests - cargo check -p codex-core --------- Co-authored-by: Codex <noreply@openai.com>github.com-openai-codex · 0bda8161 · 2026-04-26
- 1.5ETV[codex] Support model-defined reasoning efforts (#26444) ## Summary - accept non-empty model-defined reasoning effort values while preserving built-in effort behavior - propagate the non-Copy effort type through core, app-server, TUI, telemetry, and persistence call sites - preserve string wire encoding and expose an open-string schema for clients - update model selection and shortcut behavior for model-advertised effort values ## Root cause `ReasoningEffort` gained a string-backed custom variant, so it could no longer implement `Copy` or rely on derived closed-enum serialization. Existing consumers still moved effort values from shared references and assumed a fixed built-in value set. ## Validation - `just fmt` - Local tests and compilation were not run per request; relying on CI.github.com-openai-codex · 8ac304c2 · 2026-06-04
- 1.3ETV[codex] Generalize service tier slash commands (#21745) ## Why `/fast` was wired as a one-off slash command even though model metadata now exposes service tiers as catalog data. That meant adding another tier, such as a slower/cheaper tier, would require more hardcoded TUI plumbing instead of letting the model catalog drive the available commands. This change makes service-tier commands data-driven: each advertised `service_tiers` entry becomes a `/name` command using the catalog description, while the request path sends the tier `id` only when the selected model supports it. ## What Changed - Removed the hardcoded `/fast` slash-command variant and introduced dynamic service-tier command items in the composer and command popup. - Added toggle behavior for service-tier commands: invoking `/name` selects that tier, and invoking it again clears the selection. - Preserved the existing Fast-mode keybinding/status affordances by resolving the current model tier whose name is `fast`, while still sending the tier request value such as `priority`. - Persisted service-tier selections as raw request strings so non-fast tiers can round-trip through config. - Updated the Bedrock catalog entry to advertise fast support through `service_tiers` with `id: "priority"` and `name: "fast"`. - Added defensive filtering in core so unsupported selected service tiers are omitted from `/responses` requests. ## Validation - Added/updated coverage for dynamic service-tier slash command lookup, popup descriptions, composer dispatch, TUI fast toggling, and unsupported-tier omission in core request construction. - Local tests were not run per request. --------- Co-authored-by: Codex <noreply@openai.com>github.com-openai-codex · 7c0e54bf · 2026-05-08
- 1.3ETV[7/8] Add Python SDK app-server integration harness (#22014) ## Why The SDK had behavioral tests that replaced SDK client internals. Those tests could catch wrapper mistakes, but they did not prove the pinned app-server runtime, generated notification models, request routing, and sync/async public clients worked together. This PR adds deterministic integration coverage that starts the pinned `codex app-server` process and mocks only the upstream Responses HTTP boundary. ## What - Add `AppServerHarness` and `MockResponsesServer` helpers for isolated `CODEX_HOME`, mock-provider config, queued SSE responses, and captured `/v1/responses` requests. - Add shared helpers for SSE construction, stream assertions, approval-policy inspection, and image fixtures. - Split integration coverage into focused modules for run behavior, inputs, streaming, turn controls, approvals, and thread lifecycle. - Cover sync and async `Thread.run`, `TurnHandle.stream`, interleaved streams, approval-mode persistence, lifecycle helpers, final-answer phase handling, image inputs, loaded skill input injection, steering, interruption, listing, history reads, run overrides, and token usage mapping. - Replace public-wrapper tests that duplicated integration-test behavior with lower-level client tests only where direct client behavior is the thing under test. ## Stack 1. #21891 `[1/8]` Pin Python SDK runtime dependency 2. #21893 `[2/8]` Generate Python SDK types from pinned runtime 3. #21895 `[3/8]` Run Python SDK tests in CI 4. #21896 `[4/8]` Define Python SDK public API surface 5. #21905 `[5/8]` Rename Python SDK package to `openai-codex` 6. #21910 `[6/8]` Add high-level Python SDK approval mode 7. This PR `[7/8]` Add Python SDK app-server integration harness 8. #22021 `[8/8]` Add Python SDK Ruff formatting ## Verification - Added pinned app-server integration tests under `sdk/python/tests/test_app_server_*.py` and `test_real_app_server_integration.py`. --------- Co-authored-by: Codex <noreply@openai.com>github.com-openai-codex · 3e10e09e · 2026-05-11
- 0.8ETVRoute Python SDK turn notifications by ID (#21778) ## Why The Python SDK previously protected the stdio transport with a single active turn-consumer guard. That avoided competing reads from stdout, but it also meant one `Codex`/`AsyncCodex` client could not stream multiple active turns at the same time. Notifications could also arrive before the caller received a `TurnHandle` and registered for streaming, so the SDK needed an explicit routing layer instead of letting individual API calls read directly from the shared transport. ## What Changed - Added a private `MessageRouter` that owns per-request response queues, per-turn notification queues, pending turn-notification replay, and global notification delivery behind a single stdout reader thread. - Generated typed notification routing metadata so turn IDs come from known payload shapes instead of router-side attribute guessing, with explicit fallback handling for unknown notification payloads. - Updated sync and async turn streaming so `TurnHandle.stream()`/`run()` and `stream_text()` consume only notifications for their own turn ID, while `AsyncAppServerClient` no longer serializes all transport calls behind one async lock. - Cleared pending turn-notification buffers when unregistered turns complete so never-consumed turn handles do not leave stale queues behind. - Removed the internal stream-until helper now that turn completion waiting can register directly with routed turn notifications. - Updated Python SDK docs and focused tests for concurrent transport calls, interleaved turn routing, buffered early notifications, unknown notification routing, async delegation, and routed turn completion behavior. ## Validation - `uv run --extra dev ruff format scripts/update_sdk_artifacts.py src/codex_app_server/_message_router.py src/codex_app_server/client.py src/codex_app_server/generated/notification_registry.py tests/test_client_rpc_methods.py tests/test_public_api_runtime_behavior.py tests/test_async_client_behavior.py` - `uv run --extra dev ruff check scripts/update_sdk_artifacts.py src/codex_app_server/_message_router.py src/codex_app_server/client.py src/codex_app_server/generated/notification_registry.py tests/test_client_rpc_methods.py tests/test_public_api_runtime_behavior.py tests/test_async_client_behavior.py` - `uv run --extra dev pytest tests/test_client_rpc_methods.py tests/test_public_api_runtime_behavior.py tests/test_async_client_behavior.py` - `git diff --check` --------- Co-authored-by: Codex <noreply@openai.com>github.com-openai-codex · ebe75bb6 · 2026-05-09
- 0.7ETVsdk/python: add first-class login support (#23093) ## Why The Python SDK can already create threads and run turns, but authentication still has to be arranged outside the SDK. App-server already exposes account login, account inspection, logout, and `account/login/completed` notifications, so SDK users currently have to work around a missing public client layer for a core setup step. This change makes authentication a normal SDK workflow while preserving the backend flow shape: API-key login completes immediately, and interactive ChatGPT flows return live handles that complete later through app-server notifications. ## What changed - Added public sync and async auth methods on `Codex` / `AsyncCodex`: - `login_api_key(...)` - `login_chatgpt()` - `login_chatgpt_device_code()` - `account(...)` - `logout()` - Added public browser-login and device-code handle types with attempt-local `wait()` and `cancel()` helpers. Cancellation stays on the handle instead of a root-level SDK method. - Extended the Python app-server client and notification router so login completion events are routed by `login_id` without consuming unrelated global notifications. - Kept login request/handle logic in a focused internal `_login.py` module so `api.py` remains the public facade instead of absorbing more auth plumbing. - Exported the new handle types plus curated account/login response types from the SDK surfaces. - Updated SDK docs, added sync/async login walkthrough examples, and added a notebook login walkthrough cell. ## Verification Added SDK coverage for: - API-key login, account readback, and logout through the app-server harness in both sync and async clients. - Browser login cancellation plus `handle.wait()` completion through the real app-server boundary used by the Python SDK harness. - Waiter routing that stays scoped across replaced interactive login attempts, plus async handle cancellation coverage. - Login notification demuxing, replay of early completion events, and async client delegation. - Public export/signature assertions. - Real integration-suite smoke coverage for the new examples and notebook login cell.github.com-openai-codex · 4c897723 · 2026-05-17
- 0.7ETV2- Use string service tiers in session protocol (#20971) ## Summary - break service tier session/op/app-server protocol fields from the closed enum to string tier ids - send the service tier string directly through model requests, prewarm, compaction, memories, and TUI/app-server turn starts - regenerate app-server protocol JSON/TypeScript schemas, removing the standalone ServiceTier TS enum ## Verification - just fmt - cargo check -p codex-core -p codex-app-server -p codex-tui - just write-app-server-schema --------- Co-authored-by: Codex <noreply@openai.com>github.com-openai-codex · be1d3cff · 2026-05-06
- 0.6ETVTrack deferred tool namespaces in world state (#35063) ## What changed - Add the disabled-by-default `deferred_tool_world_state` feature, which exposes deferred tool namespaces and their descriptions to the model in a `<tools>` world-state section. - Emit added and removed namespace updates as tool availability changes, bound the rendered context size, and persist nonempty state across thread resumes. - Omit empty tool state while retaining deferred tool discovery through `tool_search`. ## Testing - Cover initial, unchanged, removed, recovered, empty, and resumed namespace state, along with description truncation and rendered-size limits. GitOrigin-RevId: 867e599666dc3569eb0789ba78aaa40254253a6fgithub.com-openai-codex · 1d4b58f3 · 2026-07-24
- 0.6ETV[codex] Add turn profiling analytics (#26484) ## Summary Add flat profiling fields to `codex_turn_event` so analytics can explain where turn wall-clock time is spent without changing tool execution behavior. The profile reports: - time before the first sampling request - sampling time across all attempts and follow-ups - overhead between sampling requests - time blocked in the post-sampling tool drain - time after the final sampling request - sampling request and retry counts ## Implementation - Extend the existing turn timing state with constant-memory phase accounting and one RAII phase guard. - Observe sampling and the existing post-sampling drain only at turn orchestration boundaries. - Keep tool runtime, tool futures, response item handling, and turn lifecycle values unchanged. - Add the profiling fields directly to the existing analytics turn event without changing app-server protocol or rollout persistence. - Use the existing turn `status` to distinguish completed, failed, and interrupted profiles. Exact sampling/tool overlap is intentionally omitted because measuring tool completion accurately would require hooks in the tool execution path. ## Validation - Add app-server end-to-end coverage for a single-sampling turn with no blocking tool work. - Add app-server end-to-end coverage for `request_user_input` blocking followed by a second sampling request. - CI is running on the PR; tests were not executed locally per repository guidance.github.com-openai-codex · 8d72fb6d · 2026-06-05
- 0.6ETV[6/8] Add high-level Python SDK approval mode (#21910) ## Why The high-level SDK should expose the approval behavior it actually supports instead of leaking generated app-server routing fields. New work should have two clear choices: default auto review, or explicitly deny escalated permission requests. Existing threads and subsequent turns should preserve their current approval behavior unless the caller passes an override. ## What - Add the public `ApprovalMode` enum with `auto_review` and `deny_all`. - Default new thread creation to `ApprovalMode.auto_review`. - Preserve existing approval settings by default for resume, fork, run, and turn helpers. - Remove raw `approval_policy` / `approvals_reviewer` kwargs from high-level SDK wrappers. - Update generated wrapper output, docs, examples, notebooks, and tests for the high-level approval mode API. ## Stack 1. #21891 `[1/8]` Pin Python SDK runtime dependency 2. #21893 `[2/8]` Generate Python SDK types from pinned runtime 3. #21895 `[3/8]` Run Python SDK tests in CI 4. #21896 `[4/8]` Define Python SDK public API surface 5. #21905 `[5/8]` Rename Python SDK package to `openai-codex` 6. This PR `[6/8]` Add high-level Python SDK approval mode 7. #22014 `[7/8]` Add Python SDK app-server integration harness 8. #22021 `[8/8]` Add Python SDK Ruff formatting ## Verification - Added approval-mode mapping/default tests for new threads, existing threads, forks, resumes, and subsequent turns. --------- Co-authored-by: Codex <noreply@openai.com>github.com-openai-codex · 2b90c370 · 2026-05-11
- 0.5ETVAllow ChatGPT-hosted MCP servers to use session auth (#29733) ## Why ChatGPT session authentication was inferred from the reserved Codex Apps server name. That couples credential routing to Codex Apps-specific behavior and prevents other MCP endpoints hosted by ChatGPT from explicitly using the current session. The opt-in also needs a clear security boundary: an arbitrary MCP configuration must not be able to redirect ChatGPT credentials to another origin. ## What changed - Add `use_chatgpt_auth` to HTTP MCP server configuration, defaulting to `false`. - Honor the setting only when the parsed server URL has the same HTTP(S) origin as the configured `chatgpt_base_url`; otherwise remove the capability before startup. - Resolve bearer tokens and static or environment-backed authorization headers before selecting authentication, with configured authorization taking precedence over ChatGPT session auth. - Enable the setting for the built-in Codex Apps and hosted plugin runtime endpoints while keeping Codex Apps caching and tool normalization scoped to the reserved server. - Persist the setting through MCP config rewrite paths and expose it in the generated config schema. - Load the current login state for `codex mcp list` so reported auth status matches runtime behavior. ## Verification Core integration coverage exercises the complete streamable HTTP MCP startup path and verifies that: - a same-origin opted-in server receives the current ChatGPT access token; - an explicitly configured authorization header takes precedence; - a different-origin server completes MCP initialization and tool listing without receiving any ChatGPT authorization header.github.com-openai-codex · 4c0706e2 · 2026-06-25
- 0.5ETV[2/4] Add private Python goal operations (#27111) ## Why The Python SDK must treat the runtime's initial goal turn and its continuations as one logical operation. That requires a private lifecycle engine before the public API can return the existing turn handle and result types. ## What - start goals by composing the existing clear/set goal RPCs - enforce persisted, idle threads and a bounded startup handshake - coalesce continuation notifications under a stable logical turn ID - aggregate items, usage, timing, and terminal status - support rollover-aware steering, interruption, cancellation, and cleanup - provide equivalent sync and async internals This is the second PR in the stack and intentionally adds no public API. ## Test plan - online CI, including the Python SDK suite - behavioral coverage is added in the following two stack PRsgithub.com-openai-codex · 9316acf9 · 2026-06-09
- 0.4ETV[1/4] Add Python goal routing foundation (#27110) ## Why Goal continuation turns are emitted by the existing runtime as separate physical turns. The Python SDK needs private thread-scoped routing before it can present those notifications as one logical operation, without changing ordinary turn routing or the app-server protocol. ## What - add private goal operation state and thread-scoped notification routing - add internal wrappers for the existing `thread/goal/clear` and `thread/goal/set` RPCs - include existing goal notifications in the SDK notification union - preserve ordinary turn-ID routing unchanged - add focused routing coverage This PR does not expose a public goal API. It is the first PR in the Python goal operations stack. ## Test plan - online CI, including the Python SDK suite - focused typed-notification routing coveragegithub.com-openai-codex · 5a0f9134 · 2026-06-09
- 0.4ETV[codex] Add model tool mode selector (#25031) ## Why Some models need to select their code-execution behavior through model catalog metadata. Models without that metadata must continue to follow the existing `CodeMode` and `CodeModeOnly` feature flags, including when a newer server sends an enum value this client does not recognize. ## What changed - add optional `ModelInfo.tool_mode` metadata with `direct`, `code_mode`, and `code_mode_only` - treat omitted and unknown wire values as `None` - resolve `None` from the existing feature flags - carry the resolved `ToolMode` directly on `TurnContext`, outside `Config` - use the resolved value for turn creation, model switches, review turns, tool planning, and code execution ## Coverage - add protocol coverage for omitted, known, and unknown enum values - add focused coverage for flag fallback and explicit metadata overriding feature flags - add core integration coverage that fetches remote model metadata through `/v1/models` and verifies the outbound `/responses` tools for explicit `direct` and `code_mode_only` selectors ## Stack - followed by #25032github.com-openai-codex · 5577a9e1 · 2026-05-29
- 0.4ETV[codex] Harden overflow auto-compaction recovery (#22141) ## Why Dogfooder feedback exposed two correctness gaps in normal-loop overflow recovery: 1. a sampling request that hit `ContextWindowExceeded` could keep re-entering auto-compaction indefinitely if the compacted retry still did not fit, and 2. local compact-history rebuilds flattened user messages down to text, so an overflowing `[image, "what is this?"]` turn could be retried without the image after compaction. That means recovery could either fail to terminate cleanly or proceed with a materially weakened version of the user request. ## What changed - Move normal-loop `ContextWindowExceeded` handling into the sampling retry loop, so successful rescue compaction consumes the provider retry budget instead of creating an unbounded outer-turn loop. - Keep compacted user-history rebuilds structured: `collect_user_messages` now carries user `UserInput` content rather than flattened strings, and `build_compacted_history` reconstructs full user messages from that structured representation. - Preserve image inputs while retaining the existing text-budget truncation behavior for compacted user history. - Preserve existing compaction-task failure handling and client-session reset behavior while bounding repeated overflow retries. - Add focused regression coverage for: - recovery after a normal-loop overflow, - retry-budget exhaustion after repeated overflow, - local recovery preserving image + text input, - remote recovery preserving image + text input, - remote compaction v2 preserving image + text input, and - compaction failure still terminating cleanly. The main behavior changes are in `codex-rs/core/src/session/turn.rs` and `codex-rs/core/src/compact.rs`. ## Verification - Not run locally; relying on PR CI for this update. --------- Co-authored-by: Codex <noreply@openai.com>github.com-openai-codex · 15e79f3c · 2026-05-11
- 0.4ETV[2/8] Generate Python SDK types from pinned runtime (#21893) ## Why Once the SDK declares its runtime package, generated Python artifacts should come from that pinned runtime rather than whatever app-server schema happens to be in the current checkout. That keeps the generated API and model surface aligned with the runtime users install. ## What - Teach `scripts/update_sdk_artifacts.py generate-types` to invoke the pinned runtime package for schema generation. - Regenerate `v2_all.py`, `notification_registry.py`, and generated public wrapper methods from that schema. - Add freshness coverage so regenerating from the pinned runtime must leave checked-in artifacts unchanged. ## Stack 1. #21891 `[1/8]` Pin Python SDK runtime dependency 2. This PR `[2/8]` Generate Python SDK types from pinned runtime 3. #21895 `[3/8]` Run Python SDK tests in CI 4. #21896 `[4/8]` Define Python SDK public API surface 5. #21905 `[5/8]` Rename Python SDK package to `openai-codex` 6. #21910 `[6/8]` Add high-level Python SDK approval mode 7. #22014 `[7/8]` Add Python SDK app-server integration harness 8. #22021 `[8/8]` Add Python SDK Ruff formatting ## Verification - Added `test_generated_files_are_up_to_date` for pinned-runtime generation drift. - Added generator-structure tests for schema annotation and notification metadata generation. --------- Co-authored-by: Codex <noreply@openai.com>github.com-openai-codex · 6a4653ef · 2026-05-11
- 0.4ETVPrepare Python SDK 0.144.4 stable release (#33213) ## What changed - Mark `openai-codex` as stable and align its versioned runtime dependency with Codex CLI `0.144.4`. - Regenerate the Python protocol models and notification registry from that runtime, exposing the latest requests, responses, notifications, and schema fields. - Keep `ReasoningEffort` and `ThreadSource` as enum-style APIs while accepting unknown future wire values, and omit `last_turn_id` from the flat `thread_fork` helper. ## Testing - Cover stable SDK/runtime version matching, forward-compatible enum parsing, and generated client method signatures. GitOrigin-RevId: eaa616bcbfca4258f11274e12e7eefaa551110b7github.com-openai-codex · 3f74f002 · 2026-07-15
- 0.4ETVPreserve user input when MCP startup is interrupted (#34839) ## Why Interrupting a turn while MCP tools were still starting could abort before the submitted user input was recorded in conversation history. ## What changed - Build and retain the MCP tool list and tool router as part of each step snapshot, using the turn cancellation token during tool discovery. - Record turn hooks and submitted input when cancellation occurs during startup prewarming, pre-sampling compaction, or first-step capture. - Reuse the captured router for sampling, compaction, and prompt debugging so advertised and executable tools share the same request-scoped view. ## Testing Add coverage that interrupts each affected MCP startup phase and verifies that the user prompt remains in history before the turn-aborted marker. GitOrigin-RevId: 6e96c6814357a55545d69b580e28f35933cfadf7github.com-openai-codex · d7e8f4c3 · 2026-07-22
- 0.3ETV[codex] Compact when comp_hash changes (#27520) ## Summary - snapshot `comp_hash` into `TurnContext` when the turn is created and use that snapshot as the downstream source of truth - persist the turn hash in rollout context and recover it into previous-turn settings during resume and fork replay - compact existing history with the previous model only when both adjacent turns provide hashes and the values differ - record `comp_hash_changed` as the compaction reason - cover ordinary transitions, resume, and missing-hash compatibility with end-to-end tests ## Why History produced under one compaction-compatible model configuration may not be safe to carry directly into another. Compacting at the turn boundary converts that history before context updates and the new user message are added. Persisting the turn snapshot in `TurnContextItem` makes the same protection work after resuming a rollout. A missing hash is not treated as evidence of incompatibility. `None → Some`, `Some → None`, and `None → None` do not trigger compaction; only `Some(previous) → Some(current)` with unequal values does. ## Stack - depends on #27532 - #27532 is based directly on `main` ## Testing - `just test -p codex-core pre_sampling_compact_` — 6 passed - `just test -p codex-core turn_context_item_uses_turn_context_comp_hash_snapshot` — passed - `just fix -p codex-core -p codex-protocol -p codex-analytics -p codex-models-manager`github.com-openai-codex · ba4925b3 · 2026-06-11
- 0.3ETV[codex] Add friendly Python SDK sandbox presets (#24772) ## Why The Python SDK currently exposes sandbox selection differently depending on where it is used: thread lifecycle methods accept `SandboxMode`, while turns accept the lower-level `SandboxPolicy` shape. For the common case of choosing an access level, that leaks app-server wire details into otherwise straightforward SDK usage. This makes the common path explicit and discoverable: callers choose a named sandbox preset once, using the same keyword on threads and turns. The preset name `workspace_write` also makes the granted capability clear at the callsite. ## What changed - Added a root-level `Sandbox` enum with documented presets: - `Sandbox.read_only`: read files without allowing writes. - `Sandbox.workspace_write`: the normal default for projects with a recorded trust decision; read files and write inside the workspace and configured writable roots. - `Sandbox.full_access`: run without filesystem access restrictions. - Documented that omitting `sandbox=` delegates to app-server's configured default, while explicit turn overrides remain sticky for subsequent turns. - Updated sync and async thread lifecycle and turn APIs to consistently accept `sandbox=Sandbox...`, translating to the existing app-server thread and turn representations internally. - Updated the public API artifact generator so regenerated SDK wrappers retain the friendly enum shape. - Replaced low-level policy construction in Python docs, examples, and the walkthrough notebook with the preset API. - Added focused coverage for root exports, method signatures, preset-to-wire mapping, and rejection of raw string sandbox inputs. ## API impact High-level turn calls now use `sandbox=` instead of `sandbox_policy=`: ```python from openai_codex import Codex, Sandbox with Codex() as codex: thread = codex.thread_start(sandbox=Sandbox.workspace_write) result = thread.run("Review the diff only.", sandbox=Sandbox.read_only) ``` `thread_start(...)` already defaults to `ApprovalMode.auto_review`, so normal writable usage is concise: ```python with Codex() as codex: thread = codex.thread_start(sandbox=Sandbox.workspace_write) thread.run("Update the files in this workspace.") ``` With that combination, edits inside `cwd` and configured writable roots run within the workspace-write sandbox. Operations that require approval, such as edits outside those roots, are routed through auto review. When `sandbox=` is omitted, app-server resolves its configured default. A sandbox supplied to `run(...)` or `turn(...)` applies to that turn and subsequent turns. ## Test coverage - `sdk/python/tests/test_public_api_signatures.py` covers the public export and parameter names, including the default approval mode. - `sdk/python/tests/test_public_api_runtime_behavior.py` covers preset mappings to the existing wire types and raw string rejection.github.com-openai-codex · b1cbf622 · 2026-05-27