[5/8] Rename Python SDK package to openai-codex (#21905)

## Why

The SDK should publish under the reserved public distribution name
`openai-codex`, and its import module should match that name in the
Python style. Since package names can contain hyphens but import modules
cannot, the public import path becomes `openai_codex`.

Keeping the rename separate from the public API surface change makes the
naming change easy to review and avoids mixing it with API curation.

## What

- Rename the SDK distribution from `openai-codex-app-server-sdk` to
`openai-codex`.
- Rename the import package from `codex_app_server` to `openai_codex`.
- Keep the runtime wheel as the separate `openai-codex-cli-bin`
dependency.
- Update docs, examples, notebooks, artifact scripts, lockfile metadata,
and tests for the new distribution/module names.

## 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. This PR `[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

- Updated package metadata and public API tests to assert the
distribution and import names.

Co-authored-by: Codex <noreply@openai.com>
This commit is contained in:
Ahmed Ibrahim
2026-05-12 00:59:25 +03:00
committed by GitHub
parent b4bc02439f
commit f1b84fac63
63 changed files with 152 additions and 152 deletions

View File

@@ -1,6 +1,6 @@
# Codex CLI Runtime for Python SDK # Codex CLI Runtime for Python SDK
Platform-specific runtime package consumed by the published `openai-codex-app-server-sdk`. Platform-specific runtime package consumed by the published `openai-codex`.
This package is staged during release so the SDK can pin an exact Codex CLI This package is staged during release so the SDK can pin an exact Codex CLI
version without checking platform binaries into the repo. version without checking platform binaries into the repo.

View File

@@ -1,4 +1,4 @@
# Codex App Server Python SDK (Experimental) # OpenAI Codex Python SDK (Experimental)
Experimental Python SDK for `codex app-server` JSON-RPC v2 over stdio, with a small default surface optimized for real scripts and apps. Experimental Python SDK for `codex app-server` JSON-RPC v2 over stdio, with a small default surface optimized for real scripts and apps.
@@ -6,7 +6,7 @@ The generated wire-model layer is sourced from the pinned `openai-codex-cli-bin`
runtime package and exposed as Pydantic models with snake_case Python fields runtime package and exposed as Pydantic models with snake_case Python fields
that serialize back to the app-servers camelCase wire format. that serialize back to the app-servers camelCase wire format.
The package root exports the ergonomic client API; public app-server value and The package root exports the ergonomic client API; public app-server value and
event types live in `codex_app_server.types`. event types live in `openai_codex.types`.
## Install ## Install
@@ -25,7 +25,7 @@ automatically.
## Quickstart ## Quickstart
```python ```python
from codex_app_server import Codex from openai_codex import Codex
with Codex() as codex: with Codex() as codex:
thread = codex.thread_start(model="gpt-5") thread = codex.thread_start(model="gpt-5")
@@ -76,7 +76,7 @@ uv sync
python scripts/update_sdk_artifacts.py generate-types python scripts/update_sdk_artifacts.py generate-types
python scripts/update_sdk_artifacts.py \ python scripts/update_sdk_artifacts.py \
stage-sdk \ stage-sdk \
/tmp/codex-python-release/openai-codex-app-server-sdk \ /tmp/codex-python-release/openai-codex \
--codex-version <codex-release-tag-or-pep440-version> --codex-version <codex-release-tag-or-pep440-version>
python scripts/update_sdk_artifacts.py \ python scripts/update_sdk_artifacts.py \
stage-runtime \ stage-runtime \
@@ -94,13 +94,13 @@ matrix is `macosx_11_0_arm64`, `macosx_10_9_x86_64`,
This supports the CI release flow: This supports the CI release flow:
- run `generate-types` before packaging - run `generate-types` before packaging
- stage `openai-codex-app-server-sdk` once with an exact `openai-codex-cli-bin==...` dependency - stage `openai-codex` once with an exact `openai-codex-cli-bin==...` dependency
- stage `openai-codex-cli-bin` on each supported platform runner with the same pinned runtime version - stage `openai-codex-cli-bin` on each supported platform runner with the same pinned runtime version
- build and publish `openai-codex-cli-bin` as platform wheels only through PyPI trusted publishing; do not publish an sdist - build and publish `openai-codex-cli-bin` as platform wheels only through PyPI trusted publishing; do not publish an sdist
## Compatibility and versioning ## Compatibility and versioning
- Package: `openai-codex-app-server-sdk` - Package: `openai-codex`
- Runtime package: `openai-codex-cli-bin` - Runtime package: `openai-codex-cli-bin`
- Python: `>=3.10` - Python: `>=3.10`
- Target protocol: Codex `app-server` JSON-RPC v2 - Target protocol: Codex `app-server` JSON-RPC v2

View File

@@ -18,7 +18,7 @@ import zipfile
from pathlib import Path from pathlib import Path
PACKAGE_NAME = "openai-codex-cli-bin" PACKAGE_NAME = "openai-codex-cli-bin"
SDK_PACKAGE_NAME = "openai-codex-app-server-sdk" SDK_PACKAGE_NAME = "openai-codex"
REPO_SLUG = "openai/codex" REPO_SLUG = "openai/codex"

View File

@@ -1,13 +1,13 @@
# Codex App Server SDK — API Reference # OpenAI Codex SDK — API Reference
Public surface of `codex_app_server` for app-server v2. Public surface of `openai_codex` for app-server v2.
This SDK surface is experimental. Turn streams are routed by turn ID so one client can consume multiple active turns concurrently. This SDK surface is experimental. Turn streams are routed by turn ID so one client can consume multiple active turns concurrently.
## Package Entry ## Package Entry
```python ```python
from codex_app_server import ( from openai_codex import (
Codex, Codex,
AsyncCodex, AsyncCodex,
RunResult, RunResult,
@@ -23,7 +23,7 @@ from codex_app_server import (
SkillInput, SkillInput,
MentionInput, MentionInput,
) )
from codex_app_server.types import ( from openai_codex.types import (
InitializeResponse, InitializeResponse,
ThreadItem, ThreadItem,
ThreadTokenUsage, ThreadTokenUsage,
@@ -31,9 +31,9 @@ from codex_app_server.types import (
) )
``` ```
- Version: `codex_app_server.__version__` - Version: `openai_codex.__version__`
- Requires Python >= 3.10 - Requires Python >= 3.10
- Public app-server value and event types live in `codex_app_server.types` - Public app-server value and event types live in `openai_codex.types`
## Codex (sync) ## Codex (sync)
@@ -136,7 +136,7 @@ Use `turn(...)` when you need low-level turn control (`stream()`, `steer()`,
- `steer(input: Input) -> TurnSteerResponse` - `steer(input: Input) -> TurnSteerResponse`
- `interrupt() -> TurnInterruptResponse` - `interrupt() -> TurnInterruptResponse`
- `stream() -> Iterator[Notification]` - `stream() -> Iterator[Notification]`
- `run() -> codex_app_server.types.Turn` - `run() -> openai_codex.types.Turn`
Behavior notes: Behavior notes:
@@ -148,7 +148,7 @@ Behavior notes:
- `steer(input: Input) -> Awaitable[TurnSteerResponse]` - `steer(input: Input) -> Awaitable[TurnSteerResponse]`
- `interrupt() -> Awaitable[TurnInterruptResponse]` - `interrupt() -> Awaitable[TurnInterruptResponse]`
- `stream() -> AsyncIterator[Notification]` - `stream() -> AsyncIterator[Notification]`
- `run() -> Awaitable[codex_app_server.types.Turn]` - `run() -> Awaitable[openai_codex.types.Turn]`
Behavior notes: Behavior notes:
@@ -173,7 +173,7 @@ Input = list[InputItem] | InputItem
The SDK wrappers return and accept public app-server models wherever possible: The SDK wrappers return and accept public app-server models wherever possible:
```python ```python
from codex_app_server.types import ( from openai_codex.types import (
AskForApproval, AskForApproval,
ThreadReadResponse, ThreadReadResponse,
Turn, Turn,
@@ -184,7 +184,7 @@ from codex_app_server.types import (
## Retry + errors ## Retry + errors
```python ```python
from codex_app_server import ( from openai_codex import (
retry_on_overload, retry_on_overload,
JsonRpcError, JsonRpcError,
MethodNotFoundError, MethodNotFoundError,
@@ -200,7 +200,7 @@ from codex_app_server import (
## Example ## Example
```python ```python
from codex_app_server import Codex from openai_codex import Codex
with Codex() as codex: with Codex() as codex:
thread = codex.thread_start(model="gpt-5.4", config={"model_reasoning_effort": "high"}) thread = codex.thread_start(model="gpt-5.4", config={"model_reasoning_effort": "high"})

View File

@@ -8,7 +8,7 @@
## `run()` vs `stream()` ## `run()` vs `stream()`
- `TurnHandle.run()` / `AsyncTurnHandle.run()` is the easiest path. It consumes events until completion and returns the public app-server `Turn` model from `codex_app_server.types`. - `TurnHandle.run()` / `AsyncTurnHandle.run()` is the easiest path. It consumes events until completion and returns the public app-server `Turn` model from `openai_codex.types`.
- `TurnHandle.stream()` / `AsyncTurnHandle.stream()` yields raw notifications (`Notification`) so you can react event-by-event. - `TurnHandle.stream()` / `AsyncTurnHandle.stream()` yields raw notifications (`Notification`) so you can react event-by-event.
Choose `run()` for most apps. Choose `stream()` for progress UIs, custom timeout logic, or custom parsing. Choose `run()` for most apps. Choose `stream()` for progress UIs, custom timeout logic, or custom parsing.
@@ -68,7 +68,7 @@ cd sdk/python
python scripts/update_sdk_artifacts.py generate-types python scripts/update_sdk_artifacts.py generate-types
python scripts/update_sdk_artifacts.py \ python scripts/update_sdk_artifacts.py \
stage-sdk \ stage-sdk \
/tmp/codex-python-release/openai-codex-app-server-sdk \ /tmp/codex-python-release/openai-codex \
--codex-version <codex-release-tag-or-pep440-version> --codex-version <codex-release-tag-or-pep440-version>
python scripts/update_sdk_artifacts.py \ python scripts/update_sdk_artifacts.py \
stage-runtime \ stage-runtime \

View File

@@ -24,7 +24,7 @@ Requirements:
## 2) Run your first turn (sync) ## 2) Run your first turn (sync)
```python ```python
from codex_app_server import Codex from openai_codex import Codex
with Codex() as codex: with Codex() as codex:
server = codex.metadata.serverInfo server = codex.metadata.serverInfo
@@ -50,7 +50,7 @@ What happened:
## 3) Continue the same thread (multi-turn) ## 3) Continue the same thread (multi-turn)
```python ```python
from codex_app_server import Codex from openai_codex import Codex
with Codex() as codex: with Codex() as codex:
thread = codex.thread_start(model="gpt-5.4", config={"model_reasoning_effort": "high"}) thread = codex.thread_start(model="gpt-5.4", config={"model_reasoning_effort": "high"})
@@ -69,7 +69,7 @@ initializes lazily, and context entry makes startup/shutdown explicit.
```python ```python
import asyncio import asyncio
from codex_app_server import AsyncCodex from openai_codex import AsyncCodex
async def main() -> None: async def main() -> None:
@@ -85,7 +85,7 @@ asyncio.run(main())
## 5) Resume an existing thread ## 5) Resume an existing thread
```python ```python
from codex_app_server import Codex from openai_codex import Codex
THREAD_ID = "thr_123" # replace with a real id THREAD_ID = "thr_123" # replace with a real id
@@ -101,7 +101,7 @@ The convenience wrappers live at the package root. Public app-server value and
event types live under: event types live under:
```python ```python
from codex_app_server.types import ThreadReadResponse, Turn, TurnStatus from openai_codex.types import ThreadReadResponse, Turn, TurnStatus
``` ```
## 7) Next stops ## 7) Next stops

View File

@@ -15,7 +15,7 @@ ensure_local_sdk_src()
import asyncio import asyncio
from codex_app_server import AsyncCodex from openai_codex import AsyncCodex
async def main() -> None: async def main() -> None:

View File

@@ -13,7 +13,7 @@ from _bootstrap import (
ensure_local_sdk_src() ensure_local_sdk_src()
from codex_app_server import Codex from openai_codex import Codex
with Codex(config=runtime_config()) as codex: with Codex(config=runtime_config()) as codex:
print("Server:", server_label(codex.metadata)) print("Server:", server_label(codex.metadata))

View File

@@ -16,7 +16,7 @@ ensure_local_sdk_src()
import asyncio import asyncio
from codex_app_server import AsyncCodex, TextInput from openai_codex import AsyncCodex, TextInput
async def main() -> None: async def main() -> None:

View File

@@ -14,7 +14,7 @@ from _bootstrap import (
ensure_local_sdk_src() ensure_local_sdk_src()
from codex_app_server import Codex, TextInput from openai_codex import Codex, TextInput
with Codex(config=runtime_config()) as codex: with Codex(config=runtime_config()) as codex:
thread = codex.thread_start(model="gpt-5.4", config={"model_reasoning_effort": "high"}) thread = codex.thread_start(model="gpt-5.4", config={"model_reasoning_effort": "high"})

View File

@@ -16,7 +16,7 @@ ensure_local_sdk_src()
import asyncio import asyncio
from codex_app_server import AsyncCodex, TextInput from openai_codex import AsyncCodex, TextInput
async def main() -> None: async def main() -> None:

View File

@@ -14,7 +14,7 @@ from _bootstrap import (
ensure_local_sdk_src() ensure_local_sdk_src()
from codex_app_server import Codex, TextInput from openai_codex import Codex, TextInput
with Codex(config=runtime_config()) as codex: with Codex(config=runtime_config()) as codex:
thread = codex.thread_start(model="gpt-5.4", config={"model_reasoning_effort": "high"}) thread = codex.thread_start(model="gpt-5.4", config={"model_reasoning_effort": "high"})

View File

@@ -11,7 +11,7 @@ ensure_local_sdk_src()
import asyncio import asyncio
from codex_app_server import AsyncCodex from openai_codex import AsyncCodex
async def main() -> None: async def main() -> None:

View File

@@ -9,7 +9,7 @@ from _bootstrap import ensure_local_sdk_src, runtime_config, server_label
ensure_local_sdk_src() ensure_local_sdk_src()
from codex_app_server import Codex from openai_codex import Codex
with Codex(config=runtime_config()) as codex: with Codex(config=runtime_config()) as codex:
print("server:", server_label(codex.metadata)) print("server:", server_label(codex.metadata))

View File

@@ -11,7 +11,7 @@ ensure_local_sdk_src()
import asyncio import asyncio
from codex_app_server import AsyncCodex, TextInput from openai_codex import AsyncCodex, TextInput
async def main() -> None: async def main() -> None:

View File

@@ -9,7 +9,7 @@ from _bootstrap import assistant_text_from_turn, ensure_local_sdk_src, find_turn
ensure_local_sdk_src() ensure_local_sdk_src()
from codex_app_server import Codex, TextInput from openai_codex import Codex, TextInput
with Codex(config=runtime_config()) as codex: with Codex(config=runtime_config()) as codex:
# Create an initial thread and turn so we have a real thread to resume. # Create an initial thread and turn so we have a real thread to resume.

View File

@@ -11,7 +11,7 @@ ensure_local_sdk_src()
import asyncio import asyncio
from codex_app_server import AsyncCodex, TextInput from openai_codex import AsyncCodex, TextInput
async def main() -> None: async def main() -> None:

View File

@@ -9,7 +9,7 @@ from _bootstrap import ensure_local_sdk_src, runtime_config
ensure_local_sdk_src() ensure_local_sdk_src()
from codex_app_server import Codex, TextInput from openai_codex import Codex, TextInput
with Codex(config=runtime_config()) as codex: with Codex(config=runtime_config()) as codex:

View File

@@ -16,7 +16,7 @@ ensure_local_sdk_src()
import asyncio import asyncio
from codex_app_server import AsyncCodex, ImageInput, TextInput from openai_codex import AsyncCodex, ImageInput, TextInput
REMOTE_IMAGE_URL = "https://raw.githubusercontent.com/github/explore/main/topics/python/python.png" REMOTE_IMAGE_URL = "https://raw.githubusercontent.com/github/explore/main/topics/python/python.png"

View File

@@ -14,7 +14,7 @@ from _bootstrap import (
ensure_local_sdk_src() ensure_local_sdk_src()
from codex_app_server import Codex, ImageInput, TextInput from openai_codex import Codex, ImageInput, TextInput
REMOTE_IMAGE_URL = "https://raw.githubusercontent.com/github/explore/main/topics/python/python.png" REMOTE_IMAGE_URL = "https://raw.githubusercontent.com/github/explore/main/topics/python/python.png"

View File

@@ -17,7 +17,7 @@ ensure_local_sdk_src()
import asyncio import asyncio
from codex_app_server import AsyncCodex, LocalImageInput, TextInput from openai_codex import AsyncCodex, LocalImageInput, TextInput
async def main() -> None: async def main() -> None:

View File

@@ -15,7 +15,7 @@ from _bootstrap import (
ensure_local_sdk_src() ensure_local_sdk_src()
from codex_app_server import Codex, LocalImageInput, TextInput from openai_codex import Codex, LocalImageInput, TextInput
with temporary_sample_image_path() as image_path: with temporary_sample_image_path() as image_path:
with Codex(config=runtime_config()) as codex: with Codex(config=runtime_config()) as codex:

View File

@@ -15,7 +15,7 @@ from _bootstrap import (
ensure_local_sdk_src() ensure_local_sdk_src()
from codex_app_server import Codex, TextInput from openai_codex import Codex, TextInput
with Codex(config=runtime_config()) as codex: with Codex(config=runtime_config()) as codex:
print("Server:", server_label(codex.metadata)) print("Server:", server_label(codex.metadata))

View File

@@ -19,14 +19,14 @@ import random
from collections.abc import Awaitable, Callable from collections.abc import Awaitable, Callable
from typing import TypeVar from typing import TypeVar
from codex_app_server import ( from openai_codex import (
AsyncCodex, AsyncCodex,
JsonRpcError, JsonRpcError,
ServerBusyError, ServerBusyError,
TextInput, TextInput,
is_retryable_error, is_retryable_error,
) )
from codex_app_server.types import TurnStatus from openai_codex.types import TurnStatus
ResultT = TypeVar("ResultT") ResultT = TypeVar("ResultT")

View File

@@ -14,14 +14,14 @@ from _bootstrap import (
ensure_local_sdk_src() ensure_local_sdk_src()
from codex_app_server import ( from openai_codex import (
Codex, Codex,
JsonRpcError, JsonRpcError,
ServerBusyError, ServerBusyError,
TextInput, TextInput,
retry_on_overload, retry_on_overload,
) )
from codex_app_server.types import TurnStatus from openai_codex.types import TurnStatus
with Codex(config=runtime_config()) as codex: with Codex(config=runtime_config()) as codex:
thread = codex.thread_start(model="gpt-5.4", config={"model_reasoning_effort": "high"}) thread = codex.thread_start(model="gpt-5.4", config={"model_reasoning_effort": "high"})

View File

@@ -11,11 +11,11 @@ ensure_local_sdk_src()
import asyncio import asyncio
from codex_app_server import ( from openai_codex import (
AsyncCodex, AsyncCodex,
TextInput, TextInput,
) )
from codex_app_server.types import ( from openai_codex.types import (
ThreadTokenUsageUpdatedNotification, ThreadTokenUsageUpdatedNotification,
TurnCompletedNotification, TurnCompletedNotification,
) )

View File

@@ -9,11 +9,11 @@ from _bootstrap import ensure_local_sdk_src, runtime_config
ensure_local_sdk_src() ensure_local_sdk_src()
from codex_app_server import ( from openai_codex import (
Codex, Codex,
TextInput, TextInput,
) )
from codex_app_server.types import ( from openai_codex.types import (
ThreadTokenUsageUpdatedNotification, ThreadTokenUsageUpdatedNotification,
TurnCompletedNotification, TurnCompletedNotification,
) )

View File

@@ -17,11 +17,11 @@ ensure_local_sdk_src()
import asyncio import asyncio
from codex_app_server import ( from openai_codex import (
AsyncCodex, AsyncCodex,
TextInput, TextInput,
) )
from codex_app_server.types import ( from openai_codex.types import (
AskForApproval, AskForApproval,
Personality, Personality,
ReasoningSummary, ReasoningSummary,

View File

@@ -15,11 +15,11 @@ from _bootstrap import (
ensure_local_sdk_src() ensure_local_sdk_src()
from codex_app_server import ( from openai_codex import (
Codex, Codex,
TextInput, TextInput,
) )
from codex_app_server.types import ( from openai_codex.types import (
AskForApproval, AskForApproval,
Personality, Personality,
ReasoningSummary, ReasoningSummary,

View File

@@ -11,11 +11,11 @@ ensure_local_sdk_src()
import asyncio import asyncio
from codex_app_server import ( from openai_codex import (
AsyncCodex, AsyncCodex,
TextInput, TextInput,
) )
from codex_app_server.types import ( from openai_codex.types import (
AskForApproval, AskForApproval,
Personality, Personality,
ReasoningEffort, ReasoningEffort,

View File

@@ -9,11 +9,11 @@ from _bootstrap import assistant_text_from_turn, ensure_local_sdk_src, find_turn
ensure_local_sdk_src() ensure_local_sdk_src()
from codex_app_server import ( from openai_codex import (
Codex, Codex,
TextInput, TextInput,
) )
from codex_app_server.types import ( from openai_codex.types import (
AskForApproval, AskForApproval,
Personality, Personality,
ReasoningEffort, ReasoningEffort,

View File

@@ -15,7 +15,7 @@ ensure_local_sdk_src()
import asyncio import asyncio
from codex_app_server import AsyncCodex, TextInput from openai_codex import AsyncCodex, TextInput
async def main() -> None: async def main() -> None:

View File

@@ -13,7 +13,7 @@ from _bootstrap import (
ensure_local_sdk_src() ensure_local_sdk_src()
from codex_app_server import Codex, TextInput from openai_codex import Codex, TextInput
with Codex(config=runtime_config()) as codex: with Codex(config=runtime_config()) as codex:
thread = codex.thread_start(model="gpt-5.4", config={"model_reasoning_effort": "high"}) thread = codex.thread_start(model="gpt-5.4", config={"model_reasoning_effort": "high"})

View File

@@ -5,8 +5,8 @@ Each example folder contains runnable versions:
- `sync.py` (public sync surface: `Codex`) - `sync.py` (public sync surface: `Codex`)
- `async.py` (public async surface: `AsyncCodex`) - `async.py` (public async surface: `AsyncCodex`)
All examples intentionally use only public SDK exports from `codex_app_server` All examples intentionally use only public SDK exports from `openai_codex`
and `codex_app_server.types`. and `openai_codex.types`.
## Prerequisites ## Prerequisites

View File

@@ -35,7 +35,7 @@ def ensure_local_sdk_src() -> Path:
"""Add sdk/python/src to sys.path so examples run without installing the package.""" """Add sdk/python/src to sys.path so examples run without installing the package."""
sdk_python_dir = _SDK_PYTHON_DIR sdk_python_dir = _SDK_PYTHON_DIR
src_dir = sdk_python_dir / "src" src_dir = sdk_python_dir / "src"
package_dir = src_dir / "codex_app_server" package_dir = src_dir / "openai_codex"
if not package_dir.exists(): if not package_dir.exists():
raise RuntimeError(f"Could not locate local SDK package at {package_dir}") raise RuntimeError(f"Could not locate local SDK package at {package_dir}")
@@ -49,7 +49,7 @@ def ensure_local_sdk_src() -> Path:
def runtime_config(): def runtime_config():
"""Return an example-friendly AppServerConfig for repo-source SDK usage.""" """Return an example-friendly AppServerConfig for repo-source SDK usage."""
from codex_app_server import AppServerConfig from openai_codex import AppServerConfig
ensure_runtime_package_installed(sys.executable, _SDK_PYTHON_DIR) ensure_runtime_package_installed(sys.executable, _SDK_PYTHON_DIR)
return AppServerConfig() return AppServerConfig()

View File

@@ -6,7 +6,7 @@
"source": [ "source": [
"# Codex Python SDK Walkthrough\n", "# Codex Python SDK Walkthrough\n",
"\n", "\n",
"Public SDK surface only (`codex_app_server` root exports)." "Public SDK surface only (`openai_codex` root exports)."
] ]
}, },
{ {
@@ -32,7 +32,7 @@
"\n", "\n",
"\n", "\n",
"def _is_sdk_python_dir(path: Path) -> bool:\n", "def _is_sdk_python_dir(path: Path) -> bool:\n",
" return (path / 'pyproject.toml').exists() and (path / 'src' / 'codex_app_server').exists()\n", " return (path / 'pyproject.toml').exists() and (path / 'src' / 'openai_codex').exists()\n",
"\n", "\n",
"\n", "\n",
"def _iter_home_fallback_candidates(home: Path):\n", "def _iter_home_fallback_candidates(home: Path):\n",
@@ -114,7 +114,7 @@
"\n", "\n",
"# Force fresh imports after SDK upgrades in the same notebook kernel.\n", "# Force fresh imports after SDK upgrades in the same notebook kernel.\n",
"for module_name in list(sys.modules):\n", "for module_name in list(sys.modules):\n",
" if module_name == 'codex_app_server' or module_name.startswith('codex_app_server.'):\n", " if module_name == 'openai_codex' or module_name.startswith('openai_codex.'):\n",
" sys.modules.pop(module_name, None)\n", " sys.modules.pop(module_name, None)\n",
"\n", "\n",
"print('Kernel:', sys.executable)\n", "print('Kernel:', sys.executable)\n",
@@ -130,7 +130,7 @@
"source": [ "source": [
"# Cell 2: imports (public only)\n", "# Cell 2: imports (public only)\n",
"from _bootstrap import assistant_text_from_turn, find_turn_by_id, server_label\n", "from _bootstrap import assistant_text_from_turn, find_turn_by_id, server_label\n",
"from codex_app_server import (\n", "from openai_codex import (\n",
" AsyncCodex,\n", " AsyncCodex,\n",
" Codex,\n", " Codex,\n",
" ImageInput,\n", " ImageInput,\n",
@@ -245,7 +245,7 @@
"source": [ "source": [
"# Cell 5b: one turn with most optional turn params\n", "# Cell 5b: one turn with most optional turn params\n",
"from pathlib import Path\n", "from pathlib import Path\n",
"from codex_app_server import (\n", "from openai_codex import (\n",
" AskForApproval,\n", " AskForApproval,\n",
" Personality,\n", " Personality,\n",
" ReasoningEffort,\n", " ReasoningEffort,\n",
@@ -295,7 +295,7 @@
"source": [ "source": [
"# Cell 5c: choose highest model + highest supported reasoning, then run turns\n", "# Cell 5c: choose highest model + highest supported reasoning, then run turns\n",
"from pathlib import Path\n", "from pathlib import Path\n",
"from codex_app_server import (\n", "from openai_codex import (\n",
" AskForApproval,\n", " AskForApproval,\n",
" Personality,\n", " Personality,\n",
" ReasoningEffort,\n", " ReasoningEffort,\n",

View File

@@ -3,13 +3,13 @@ requires = ["hatchling>=1.24.0"]
build-backend = "hatchling.build" build-backend = "hatchling.build"
[project] [project]
name = "openai-codex-app-server-sdk" name = "openai-codex"
version = "0.131.0a4" version = "0.131.0a4"
description = "Python SDK for Codex app-server v2" description = "Python SDK for Codex app-server v2"
readme = "README.md" readme = "README.md"
requires-python = ">=3.10" requires-python = ">=3.10"
license = { text = "Apache-2.0" } license = { text = "Apache-2.0" }
authors = [{ name = "OpenClaw Assistant" }] authors = [{ name = "OpenAI" }]
keywords = ["codex", "json-rpc", "sdk", "llm", "app-server"] keywords = ["codex", "json-rpc", "sdk", "llm", "app-server"]
classifiers = [ classifiers = [
"Development Status :: 4 - Beta", "Development Status :: 4 - Beta",
@@ -42,14 +42,14 @@ exclude = [
] ]
[tool.hatch.build.targets.wheel] [tool.hatch.build.targets.wheel]
packages = ["src/codex_app_server"] packages = ["src/openai_codex"]
include = [ include = [
"src/codex_app_server/py.typed", "src/openai_codex/py.typed",
] ]
[tool.hatch.build.targets.sdist] [tool.hatch.build.targets.sdist]
include = [ include = [
"src/codex_app_server/**", "src/openai_codex/**",
"README.md", "README.md",
"CHANGELOG.md", "CHANGELOG.md",
"CONTRIBUTING.md", "CONTRIBUTING.md",

View File

@@ -18,7 +18,7 @@ from dataclasses import dataclass
from pathlib import Path from pathlib import Path
from typing import Any, Callable, Sequence, get_args, get_origin from typing import Any, Callable, Sequence, get_args, get_origin
SDK_DISTRIBUTION_NAME = "openai-codex-app-server-sdk" SDK_DISTRIBUTION_NAME = "openai-codex"
RUNTIME_DISTRIBUTION_NAME = "openai-codex-cli-bin" RUNTIME_DISTRIBUTION_NAME = "openai-codex-cli-bin"
@@ -250,7 +250,7 @@ def _rewrite_sdk_runtime_dependency(pyproject_text: str, runtime_version: str) -
def stage_python_sdk_package(staging_dir: Path, codex_version: str) -> Path: def stage_python_sdk_package(staging_dir: Path, codex_version: str) -> Path:
package_version = normalize_codex_version(codex_version) package_version = normalize_codex_version(codex_version)
_copy_package_tree(sdk_root(), staging_dir) _copy_package_tree(sdk_root(), staging_dir)
sdk_bin_dir = staging_dir / "src" / "codex_app_server" / "bin" sdk_bin_dir = staging_dir / "src" / "openai_codex" / "bin"
if sdk_bin_dir.exists(): if sdk_bin_dir.exists():
shutil.rmtree(sdk_bin_dir) shutil.rmtree(sdk_bin_dir)
@@ -572,7 +572,7 @@ def _normalized_schema_bundle_text(schema_dir: Path) -> str:
def generate_v2_all(schema_dir: Path) -> None: def generate_v2_all(schema_dir: Path) -> None:
"""Regenerate the Pydantic v2 protocol model module from runtime schemas.""" """Regenerate the Pydantic v2 protocol model module from runtime schemas."""
out_path = sdk_root() / "src" / "codex_app_server" / "generated" / "v2_all.py" out_path = sdk_root() / "src" / "openai_codex" / "generated" / "v2_all.py"
out_dir = out_path.parent out_dir = out_path.parent
old_package_dir = out_dir / "v2_all" old_package_dir = out_dir / "v2_all"
if old_package_dir.exists(): if old_package_dir.exists():
@@ -624,7 +624,7 @@ def _notification_specs(schema_dir: Path) -> list[tuple[str, str]]:
) )
one_of = server_notifications.get("oneOf", []) one_of = server_notifications.get("oneOf", [])
generated_source = ( generated_source = (
sdk_root() / "src" / "codex_app_server" / "generated" / "v2_all.py" sdk_root() / "src" / "openai_codex" / "generated" / "v2_all.py"
).read_text() ).read_text()
specs: list[tuple[str, str]] = [] specs: list[tuple[str, str]] = []
@@ -702,7 +702,7 @@ def generate_notification_registry(schema_dir: Path) -> None:
out = ( out = (
sdk_root() sdk_root()
/ "src" / "src"
/ "codex_app_server" / "openai_codex"
/ "generated" / "generated"
/ "notification_registry.py" / "notification_registry.py"
) )
@@ -834,7 +834,7 @@ def _load_public_fields(
) -> list[PublicFieldSpec]: ) -> list[PublicFieldSpec]:
"""Load generated model fields used to render the ergonomic public methods.""" """Load generated model fields used to render the ergonomic public methods."""
exclude = exclude or set() exclude = exclude or set()
if module_name == "codex_app_server.generated.v2_all": if module_name == "openai_codex.generated.v2_all":
module = _load_generated_v2_all_module() module = _load_generated_v2_all_module()
else: else:
module = importlib.import_module(module_name) module = importlib.import_module(module_name)
@@ -861,9 +861,9 @@ def _load_public_fields(
def _load_generated_v2_all_module() -> types.ModuleType: def _load_generated_v2_all_module() -> types.ModuleType:
"""Import the freshly generated v2_all module without importing package init.""" """Import the freshly generated v2_all module without importing package init."""
module_name = "_codex_app_server_generated_v2_all_for_artifacts" module_name = "_openai_codex_generated_v2_all_for_artifacts"
sys.modules.pop(module_name, None) sys.modules.pop(module_name, None)
module_path = sdk_root() / "src" / "codex_app_server" / "generated" / "v2_all.py" module_path = sdk_root() / "src" / "openai_codex" / "generated" / "v2_all.py"
spec = importlib.util.spec_from_file_location(module_name, module_path) spec = importlib.util.spec_from_file_location(module_name, module_path)
if spec is None or spec.loader is None: if spec is None or spec.loader is None:
raise RuntimeError(f"Failed to load generated module from {module_path}") raise RuntimeError(f"Failed to load generated module from {module_path}")
@@ -1084,7 +1084,7 @@ def _render_async_thread_block(
def generate_public_api_flat_methods() -> None: def generate_public_api_flat_methods() -> None:
"""Regenerate the public convenience methods from generated protocol models.""" """Regenerate the public convenience methods from generated protocol models."""
src_dir = sdk_root() / "src" src_dir = sdk_root() / "src"
public_api_path = src_dir / "codex_app_server" / "api.py" public_api_path = src_dir / "openai_codex" / "api.py"
if not public_api_path.exists(): if not public_api_path.exists():
# PR2 can run codegen before the ergonomic public API layer is added. # PR2 can run codegen before the ergonomic public API layer is added.
return return
@@ -1093,25 +1093,25 @@ def generate_public_api_flat_methods() -> None:
sys.path.insert(0, src_dir_str) sys.path.insert(0, src_dir_str)
thread_start_fields = _load_public_fields( thread_start_fields = _load_public_fields(
"codex_app_server.generated.v2_all", "openai_codex.generated.v2_all",
"ThreadStartParams", "ThreadStartParams",
) )
thread_list_fields = _load_public_fields( thread_list_fields = _load_public_fields(
"codex_app_server.generated.v2_all", "openai_codex.generated.v2_all",
"ThreadListParams", "ThreadListParams",
) )
thread_resume_fields = _load_public_fields( thread_resume_fields = _load_public_fields(
"codex_app_server.generated.v2_all", "openai_codex.generated.v2_all",
"ThreadResumeParams", "ThreadResumeParams",
exclude={"thread_id"}, exclude={"thread_id"},
) )
thread_fork_fields = _load_public_fields( thread_fork_fields = _load_public_fields(
"codex_app_server.generated.v2_all", "openai_codex.generated.v2_all",
"ThreadForkParams", "ThreadForkParams",
exclude={"thread_id"}, exclude={"thread_id"},
) )
turn_start_fields = _load_public_fields( turn_start_fields = _load_public_fields(
"codex_app_server.generated.v2_all", "openai_codex.generated.v2_all",
"TurnStartParams", "TurnStartParams",
exclude={"thread_id", "input"}, exclude={"thread_id", "input"},
) )

View File

@@ -5,7 +5,7 @@ from importlib.metadata import PackageNotFoundError
from importlib.metadata import version as distribution_version from importlib.metadata import version as distribution_version
from pathlib import Path from pathlib import Path
DISTRIBUTION_NAME = "openai-codex-app-server-sdk" DISTRIBUTION_NAME = "openai-codex"
UNKNOWN_VERSION = "0+unknown" UNKNOWN_VERSION = "0+unknown"

View File

@@ -12,5 +12,5 @@ if src_str in sys.path:
sys.path.insert(0, src_str) sys.path.insert(0, src_str)
for module_name in list(sys.modules): for module_name in list(sys.modules):
if module_name == "codex_app_server" or module_name.startswith("codex_app_server."): if module_name == "openai_codex" or module_name.startswith("openai_codex."):
sys.modules.pop(module_name) sys.modules.pop(module_name)

View File

@@ -172,12 +172,12 @@ def test_examples_readme_points_to_runtime_version_source_of_truth() -> None:
def test_runtime_distribution_name_is_consistent() -> None: def test_runtime_distribution_name_is_consistent() -> None:
script = _load_update_script_module() script = _load_update_script_module()
runtime_setup = _load_runtime_setup_module() runtime_setup = _load_runtime_setup_module()
from codex_app_server import client as client_module from openai_codex import client as client_module
from codex_app_server import _version from openai_codex import _version
assert script.SDK_DISTRIBUTION_NAME == "openai-codex-app-server-sdk" assert script.SDK_DISTRIBUTION_NAME == "openai-codex"
assert runtime_setup.SDK_PACKAGE_NAME == "openai-codex-app-server-sdk" assert runtime_setup.SDK_PACKAGE_NAME == "openai-codex"
assert _version.DISTRIBUTION_NAME == "openai-codex-app-server-sdk" assert _version.DISTRIBUTION_NAME == "openai-codex"
assert script.RUNTIME_DISTRIBUTION_NAME == "openai-codex-cli-bin" assert script.RUNTIME_DISTRIBUTION_NAME == "openai-codex-cli-bin"
assert runtime_setup.PACKAGE_NAME == "openai-codex-cli-bin" assert runtime_setup.PACKAGE_NAME == "openai-codex-cli-bin"
assert client_module.RUNTIME_PKG_NAME == "openai-codex-cli-bin" assert client_module.RUNTIME_PKG_NAME == "openai-codex-cli-bin"
@@ -457,18 +457,18 @@ def test_stage_sdk_release_injects_exact_runtime_pin(tmp_path: Path) -> None:
) )
pyproject = (staged / "pyproject.toml").read_text() pyproject = (staged / "pyproject.toml").read_text()
assert 'name = "openai-codex-app-server-sdk"' in pyproject assert 'name = "openai-codex"' in pyproject
assert 'version = "0.116.0a1"' in pyproject assert 'version = "0.116.0a1"' in pyproject
assert '"openai-codex-cli-bin==0.116.0a1"' in pyproject assert '"openai-codex-cli-bin==0.116.0a1"' in pyproject
assert ( assert (
'__version__ = "0.116.0a1"' '__version__ = "0.116.0a1"'
not in (staged / "src" / "codex_app_server" / "__init__.py").read_text() not in (staged / "src" / "openai_codex" / "__init__.py").read_text()
) )
assert ( assert (
'client_version: str = "0.116.0a1"' 'client_version: str = "0.116.0a1"'
not in (staged / "src" / "codex_app_server" / "client.py").read_text() not in (staged / "src" / "openai_codex" / "client.py").read_text()
) )
assert not any((staged / "src" / "codex_app_server").glob("bin/**")) assert not any((staged / "src" / "openai_codex").glob("bin/**"))
def test_stage_sdk_release_replaces_existing_staging_dir(tmp_path: Path) -> None: def test_stage_sdk_release_replaces_existing_staging_dir(tmp_path: Path) -> None:
@@ -637,7 +637,7 @@ def test_stage_runtime_stages_binary_without_type_generation(tmp_path: Path) ->
def test_default_runtime_is_resolved_from_installed_runtime_package( def test_default_runtime_is_resolved_from_installed_runtime_package(
tmp_path: Path, tmp_path: Path,
) -> None: ) -> None:
from codex_app_server import client as client_module from openai_codex import client as client_module
fake_binary = tmp_path / ("codex.exe" if client_module.os.name == "nt" else "codex") fake_binary = tmp_path / ("codex.exe" if client_module.os.name == "nt" else "codex")
fake_binary.write_text("") fake_binary.write_text("")
@@ -652,7 +652,7 @@ def test_default_runtime_is_resolved_from_installed_runtime_package(
def test_explicit_codex_bin_override_takes_priority(tmp_path: Path) -> None: def test_explicit_codex_bin_override_takes_priority(tmp_path: Path) -> None:
from codex_app_server import client as client_module from openai_codex import client as client_module
explicit_binary = tmp_path / ( explicit_binary = tmp_path / (
"custom-codex.exe" if client_module.os.name == "nt" else "custom-codex" "custom-codex.exe" if client_module.os.name == "nt" else "custom-codex"
@@ -670,7 +670,7 @@ def test_explicit_codex_bin_override_takes_priority(tmp_path: Path) -> None:
def test_missing_runtime_package_requires_explicit_codex_bin() -> None: def test_missing_runtime_package_requires_explicit_codex_bin() -> None:
from codex_app_server import client as client_module from openai_codex import client as client_module
ops = client_module.CodexBinResolverOps( ops = client_module.CodexBinResolverOps(
installed_codex_path=lambda: (_ for _ in ()).throw( installed_codex_path=lambda: (_ for _ in ()).throw(
@@ -684,7 +684,7 @@ def test_missing_runtime_package_requires_explicit_codex_bin() -> None:
def test_broken_runtime_package_does_not_fall_back() -> None: def test_broken_runtime_package_does_not_fall_back() -> None:
from codex_app_server import client as client_module from openai_codex import client as client_module
ops = client_module.CodexBinResolverOps( ops = client_module.CodexBinResolverOps(
installed_codex_path=lambda: (_ for _ in ()).throw( installed_codex_path=lambda: (_ for _ in ()).throw(

View File

@@ -4,12 +4,12 @@ import asyncio
import time import time
from types import SimpleNamespace from types import SimpleNamespace
from codex_app_server.async_client import AsyncAppServerClient from openai_codex.async_client import AsyncAppServerClient
from codex_app_server.generated.v2_all import ( from openai_codex.generated.v2_all import (
AgentMessageDeltaNotification, AgentMessageDeltaNotification,
TurnCompletedNotification, TurnCompletedNotification,
) )
from codex_app_server.models import Notification, UnknownNotification from openai_codex.models import Notification, UnknownNotification
def test_async_client_allows_concurrent_transport_calls() -> None: def test_async_client_allows_concurrent_transport_calls() -> None:

View File

@@ -3,9 +3,9 @@ from __future__ import annotations
from pathlib import Path from pathlib import Path
from typing import Any from typing import Any
from codex_app_server.client import AppServerClient, _params_dict from openai_codex.client import AppServerClient, _params_dict
from codex_app_server.generated.notification_registry import notification_turn_id from openai_codex.generated.notification_registry import notification_turn_id
from codex_app_server.generated.v2_all import ( from openai_codex.generated.v2_all import (
AgentMessageDeltaNotification, AgentMessageDeltaNotification,
ApprovalsReviewer, ApprovalsReviewer,
ThreadListParams, ThreadListParams,
@@ -14,7 +14,7 @@ from codex_app_server.generated.v2_all import (
TurnCompletedNotification, TurnCompletedNotification,
WarningNotification, WarningNotification,
) )
from codex_app_server.models import Notification, UnknownNotification from openai_codex.models import Notification, UnknownNotification
ROOT = Path(__file__).resolve().parents[1] ROOT = Path(__file__).resolve().parents[1]
@@ -45,7 +45,7 @@ def test_generated_params_models_are_snake_case_and_dump_by_alias() -> None:
def test_generated_v2_bundle_has_single_shared_plan_type_definition() -> None: def test_generated_v2_bundle_has_single_shared_plan_type_definition() -> None:
source = (ROOT / "src" / "codex_app_server" / "generated" / "v2_all.py").read_text() source = (ROOT / "src" / "openai_codex" / "generated" / "v2_all.py").read_text()
assert source.count("class PlanType(") == 1 assert source.count("class PlanType(") == 1

View File

@@ -8,9 +8,9 @@ from pathlib import Path
ROOT = Path(__file__).resolve().parents[1] ROOT = Path(__file__).resolve().parents[1]
GENERATED_TARGETS = [ GENERATED_TARGETS = [
Path("src/codex_app_server/generated/notification_registry.py"), Path("src/openai_codex/generated/notification_registry.py"),
Path("src/codex_app_server/generated/v2_all.py"), Path("src/openai_codex/generated/v2_all.py"),
Path("src/codex_app_server/api.py"), Path("src/openai_codex/api.py"),
] ]

View File

@@ -7,9 +7,9 @@ from types import SimpleNamespace
import pytest import pytest
import codex_app_server.api as public_api_module import openai_codex.api as public_api_module
from codex_app_server.client import AppServerClient from openai_codex.client import AppServerClient
from codex_app_server.generated.v2_all import ( from openai_codex.generated.v2_all import (
AgentMessageDeltaNotification, AgentMessageDeltaNotification,
ItemCompletedNotification, ItemCompletedNotification,
MessagePhase, MessagePhase,
@@ -17,8 +17,8 @@ from codex_app_server.generated.v2_all import (
TurnCompletedNotification, TurnCompletedNotification,
TurnStatus, TurnStatus,
) )
from codex_app_server.models import InitializeResponse, Notification from openai_codex.models import InitializeResponse, Notification
from codex_app_server.api import ( from openai_codex.api import (
AsyncCodex, AsyncCodex,
AsyncThread, AsyncThread,
AsyncTurnHandle, AsyncTurnHandle,

View File

@@ -6,9 +6,9 @@ import tomllib
from pathlib import Path from pathlib import Path
from typing import Any from typing import Any
import codex_app_server import openai_codex
import codex_app_server.types as public_types import openai_codex.types as public_types
from codex_app_server import ( from openai_codex import (
AppServerConfig, AppServerConfig,
AsyncCodex, AsyncCodex,
AsyncThread, AsyncThread,
@@ -16,7 +16,7 @@ from codex_app_server import (
RunResult, RunResult,
Thread, Thread,
) )
from codex_app_server.types import InitializeResponse from openai_codex.types import InitializeResponse
EXPECTED_ROOT_EXPORTS = [ EXPECTED_ROOT_EXPORTS = [
"__version__", "__version__",
@@ -122,32 +122,32 @@ def test_package_and_default_client_versions_follow_project_version() -> None:
pyproject_path = Path(__file__).resolve().parents[1] / "pyproject.toml" pyproject_path = Path(__file__).resolve().parents[1] / "pyproject.toml"
pyproject = tomllib.loads(pyproject_path.read_text()) pyproject = tomllib.loads(pyproject_path.read_text())
assert codex_app_server.__version__ == pyproject["project"]["version"] assert openai_codex.__version__ == pyproject["project"]["version"]
assert AppServerConfig().client_version == codex_app_server.__version__ assert AppServerConfig().client_version == openai_codex.__version__
def test_package_includes_py_typed_marker() -> None: def test_package_includes_py_typed_marker() -> None:
"""The wheel should advertise that inline type information is available.""" """The wheel should advertise that inline type information is available."""
marker = resources.files("codex_app_server").joinpath("py.typed") marker = resources.files("openai_codex").joinpath("py.typed")
assert marker.is_file() assert marker.is_file()
def test_package_root_exports_only_public_api() -> None: def test_package_root_exports_only_public_api() -> None:
"""The package root should expose the supported SDK surface, not internals.""" """The package root should expose the supported SDK surface, not internals."""
assert codex_app_server.__all__ == EXPECTED_ROOT_EXPORTS assert openai_codex.__all__ == EXPECTED_ROOT_EXPORTS
assert { assert {
name: hasattr(codex_app_server, name) for name in EXPECTED_ROOT_EXPORTS name: hasattr(openai_codex, name) for name in EXPECTED_ROOT_EXPORTS
} == {name: True for name in EXPECTED_ROOT_EXPORTS} } == {name: True for name in EXPECTED_ROOT_EXPORTS}
assert { assert {
"AppServerClient": hasattr(codex_app_server, "AppServerClient"), "AppServerClient": hasattr(openai_codex, "AppServerClient"),
"AsyncAppServerClient": hasattr(codex_app_server, "AsyncAppServerClient"), "AsyncAppServerClient": hasattr(openai_codex, "AsyncAppServerClient"),
"InitializeResponse": hasattr(codex_app_server, "InitializeResponse"), "InitializeResponse": hasattr(openai_codex, "InitializeResponse"),
"ThreadStartParams": hasattr(codex_app_server, "ThreadStartParams"), "ThreadStartParams": hasattr(openai_codex, "ThreadStartParams"),
"TurnStartParams": hasattr(codex_app_server, "TurnStartParams"), "TurnStartParams": hasattr(openai_codex, "TurnStartParams"),
"TurnCompletedNotification": hasattr( "TurnCompletedNotification": hasattr(
codex_app_server, "TurnCompletedNotification" openai_codex, "TurnCompletedNotification"
), ),
"TurnStatus": hasattr(codex_app_server, "TurnStatus"), "TurnStatus": hasattr(openai_codex, "TurnStatus"),
} == { } == {
"AppServerClient": False, "AppServerClient": False,
"AsyncAppServerClient": False, "AsyncAppServerClient": False,
@@ -162,7 +162,7 @@ def test_package_root_exports_only_public_api() -> None:
def test_package_star_import_matches_public_api() -> None: def test_package_star_import_matches_public_api() -> None:
"""Star imports should follow the same explicit public API list.""" """Star imports should follow the same explicit public API list."""
namespace: dict[str, object] = {} namespace: dict[str, object] = {}
exec("from codex_app_server import *", namespace) exec("from openai_codex import *", namespace)
exported = set(namespace) - {"__builtins__"} exported = set(namespace) - {"__builtins__"}
assert exported == set(EXPECTED_ROOT_EXPORTS) assert exported == set(EXPECTED_ROOT_EXPORTS)
@@ -179,7 +179,7 @@ def test_types_module_exports_curated_public_types() -> None:
def test_types_star_import_matches_public_types() -> None: def test_types_star_import_matches_public_types() -> None:
"""Star imports from the type module should match its explicit export list.""" """Star imports from the type module should match its explicit export list."""
namespace: dict[str, object] = {} namespace: dict[str, object] = {}
exec("from codex_app_server.types import *", namespace) exec("from openai_codex.types import *", namespace)
exported = set(namespace) - {"__builtins__"} exported = set(namespace) - {"__builtins__"}
assert exported == set(EXPECTED_TYPES_EXPORTS) assert exported == set(EXPECTED_TYPES_EXPORTS)
@@ -189,11 +189,11 @@ def test_examples_use_public_import_surfaces() -> None:
"""Examples should teach users the public root and type-module imports only.""" """Examples should teach users the public root and type-module imports only."""
examples_root = Path(__file__).resolve().parents[1] / "examples" examples_root = Path(__file__).resolve().parents[1] / "examples"
private_import_markers = [ private_import_markers = [
"codex_app_server.api", "openai_codex.api",
"codex_app_server.client", "openai_codex.client",
"codex_app_server.generated", "openai_codex.generated",
"codex_app_server.models", "openai_codex.models",
"codex_app_server.retry", "openai_codex.retry",
] ]
offenders = { offenders = {

View File

@@ -205,7 +205,7 @@ def test_real_initialize_and_model_list(runtime_env: PreparedRuntimeEnv) -> None
textwrap.dedent( textwrap.dedent(
""" """
import json import json
from codex_app_server import Codex from openai_codex import Codex
with Codex() as codex: with Codex() as codex:
models = codex.models(include_hidden=True) models = codex.models(include_hidden=True)
@@ -234,7 +234,7 @@ def test_real_thread_and_turn_start_smoke(runtime_env: PreparedRuntimeEnv) -> No
textwrap.dedent( textwrap.dedent(
""" """
import json import json
from codex_app_server import Codex, TextInput from openai_codex import Codex, TextInput
with Codex() as codex: with Codex() as codex:
thread = codex.thread_start( thread = codex.thread_start(
@@ -271,7 +271,7 @@ def test_real_thread_run_convenience_smoke(runtime_env: PreparedRuntimeEnv) -> N
textwrap.dedent( textwrap.dedent(
""" """
import json import json
from codex_app_server import Codex from openai_codex import Codex
with Codex() as codex: with Codex() as codex:
thread = codex.thread_start( thread = codex.thread_start(
@@ -304,7 +304,7 @@ def test_real_async_thread_turn_usage_and_ids_smoke(
""" """
import asyncio import asyncio
import json import json
from codex_app_server import AsyncCodex, TextInput from openai_codex import AsyncCodex, TextInput
async def main(): async def main():
async with AsyncCodex() as codex: async with AsyncCodex() as codex:
@@ -347,7 +347,7 @@ def test_real_async_thread_run_convenience_smoke(
""" """
import asyncio import asyncio
import json import json
from codex_app_server import AsyncCodex from openai_codex import AsyncCodex
async def main(): async def main():
async with AsyncCodex() as codex: async with AsyncCodex() as codex:
@@ -436,7 +436,7 @@ def test_real_streaming_smoke_turn_completed(runtime_env: PreparedRuntimeEnv) ->
textwrap.dedent( textwrap.dedent(
""" """
import json import json
from codex_app_server import Codex, TextInput from openai_codex import Codex, TextInput
with Codex() as codex: with Codex() as codex:
thread = codex.thread_start( thread = codex.thread_start(
@@ -469,7 +469,7 @@ def test_real_turn_interrupt_smoke(runtime_env: PreparedRuntimeEnv) -> None:
textwrap.dedent( textwrap.dedent(
""" """
import json import json
from codex_app_server import Codex, TextInput from openai_codex import Codex, TextInput
with Codex() as codex: with Codex() as codex:
thread = codex.thread_start( thread = codex.thread_start(

2
sdk/python/uv.lock generated
View File

@@ -281,7 +281,7 @@ wheels = [
] ]
[[package]] [[package]]
name = "openai-codex-app-server-sdk" name = "openai-codex"
version = "0.131.0a4" version = "0.131.0a4"
source = { editable = "." } source = { editable = "." }
dependencies = [ dependencies = [