Prepare 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: eaa616bcbfca4258f11274e12e7eefaa551110b7
This commit is contained in:
Ahmed Ibrahim
2026-07-15 02:43:31 +00:00
committed by copyberry
parent d88db19144
commit 3f74f00295
13 changed files with 1146 additions and 194 deletions
+1 -1
View File
@@ -1,4 +1,4 @@
# OpenAI Codex Python SDK (Beta)
# OpenAI Codex Python SDK
Build Python applications that start Codex threads, run turns, stream progress,
and control workspace access.
+2 -2
View File
@@ -1,8 +1,8 @@
# OpenAI Codex Python SDK (Beta) - API Reference
# OpenAI Codex Python SDK - API Reference
Public surface of `openai_codex` for Codex workflows.
This SDK is in beta. Public APIs may change before `1.0`. Turn streams are routed by turn ID so one client can consume multiple active turns concurrently.
Turn streams are routed by turn ID so one client can consume multiple active turns concurrently.
Thread starts default to `ApprovalMode.auto_review`; turn starts accept an optional `approval_mode` override.
## Package Entry
+4 -6
View File
@@ -2,15 +2,13 @@
## Is the Python SDK stable?
`openai-codex` is a public beta. Install it with
`pip install openai-codex`; public APIs may change before `1.0`. While beta
releases are the only published SDK releases, pip selects the latest beta.
After a stable release exists, pass `--pre` to opt into newer prereleases.
`openai-codex` publishes stable releases. Install the latest one with
`pip install openai-codex`.
## Why does the SDK install a runtime package?
The SDK and runtime packages are versioned independently. Each SDK release
pins and installs one compatible runtime dependency automatically.
The SDK version tracks the corresponding Codex CLI release. Each SDK release
pins and installs its matching runtime dependency automatically.
## Thread vs turn
+3 -5
View File
@@ -1,6 +1,6 @@
# Getting Started
This guide gets a published OpenAI Codex Python SDK beta installation running
This guide gets a published OpenAI Codex Python SDK installation running
with a multi-turn thread.
## 1. Install
@@ -16,10 +16,8 @@ Requirements:
- Python `>=3.10`
- An existing Codex account session, or one of the login flows below
The SDK installs its compatible `openai-codex-cli-bin` runtime dependency
automatically. While beta releases are the only published SDK releases, this
normal install command selects the latest beta. After a stable release exists,
use `pip install --pre openai-codex` to opt into a newer prerelease.
The SDK installs its matching `openai-codex-cli-bin` runtime dependency
automatically. SDK release versions track the corresponding Codex CLI release.
## 2. Authenticate When Needed
+1 -1
View File
@@ -16,7 +16,7 @@ multimodal or structured input lists.
- Python `>=3.10`
- Install the SDK for the same Python interpreter you will use to run examples
Install the published beta:
Install the published SDK:
```bash
python -m pip install openai-codex
+4 -4
View File
@@ -12,11 +12,11 @@ license = "Apache-2.0"
authors = [{ name = "OpenAI" }]
keywords = ["codex", "sdk", "llm", "ai", "agents"]
classifiers = [
"Development Status :: 4 - Beta",
"Development Status :: 5 - Production/Stable",
"Intended Audience :: Developers",
"Topic :: Software Development :: Libraries :: Python Modules",
]
dependencies = ["pydantic>=2.12", "openai-codex-cli-bin==0.137.0a4"]
dependencies = ["pydantic>=2.12", "openai-codex-cli-bin==0.144.4"]
[project.urls]
Homepage = "https://github.com/openai/codex"
@@ -65,10 +65,10 @@ combine-as-imports = true
[tool.uv]
exclude-newer = "7 days"
exclude-newer-package = { openai-codex-cli-bin = "2026-06-03T19:00:00Z" }
exclude-newer-package = { openai-codex-cli-bin = "2026-07-15T01:00:00Z" }
index-strategy = "first-index"
[tool.uv.pip]
exclude-newer = "7 days"
exclude-newer-package = { openai-codex-cli-bin = "2026-06-03T19:00:00Z" }
exclude-newer-package = { openai-codex-cli-bin = "2026-07-15T01:00:00Z" }
index-strategy = "first-index"
+64 -2
View File
@@ -616,6 +616,8 @@ def generate_v2_all(schema_dir: Path) -> None:
cwd=sdk_root(),
)
_require_nullable_chatgpt_account_email(out_path)
_preserve_reasoning_effort_enum(out_path)
_preserve_thread_source_enum(out_path)
_normalize_generated_timestamps(out_path)
@@ -643,6 +645,66 @@ def _require_nullable_chatgpt_account_email(out_path: Path) -> None:
out_path.write_text(source[:class_start] + class_source + source[class_end:])
def _preserve_reasoning_effort_enum(out_path: Path) -> None:
"""Keep the public effort constants while accepting future wire values."""
source = out_path.read_text()
class_start = source.find("class ReasoningEffort(RootModel[str]):")
if class_start == -1:
raise RuntimeError("Generated SDK is missing the open ReasoningEffort model")
class_end = source.find("\n\nclass ", class_start)
if class_end == -1:
class_end = len(source)
class_source = source[class_start:class_end]
if "min_length=1" not in class_source:
raise RuntimeError("Generated ReasoningEffort did not preserve the non-empty constraint")
open_enum = """class ReasoningEffort(str, Enum):
none = "none"
minimal = "minimal"
low = "low"
medium = "medium"
high = "high"
xhigh = "xhigh"
@classmethod
def _missing_(cls, value: object) -> ReasoningEffort | None:
if not isinstance(value, str) or not value:
return None
member = str.__new__(cls, value)
member._name_ = value
member._value_ = value
return member
"""
out_path.write_text(source[:class_start] + open_enum + source[class_end:])
def _preserve_thread_source_enum(out_path: Path) -> None:
"""Keep the public thread-source constants while accepting future wire values."""
source = out_path.read_text()
class_start = source.find("class ThreadSource(RootModel[str]):")
if class_start == -1:
raise RuntimeError("Generated SDK is missing the open ThreadSource model")
class_end = source.find("\n\nclass ", class_start)
if class_end == -1:
class_end = len(source)
open_enum = """class ThreadSource(str, Enum):
user = "user"
subagent = "subagent"
memory_consolidation = "memory_consolidation"
@classmethod
def _missing_(cls, value: object) -> ThreadSource | None:
if not isinstance(value, str):
return None
member = str.__new__(cls, value)
member._name_ = value
member._value_ = value
return member
"""
out_path.write_text(source[:class_start] + open_enum + source[class_end:])
def _notification_specs(schema_dir: Path) -> list[tuple[str, str]]:
"""Map each server notification method to its generated payload model class."""
server_notifications = json.loads((schema_dir / "ServerNotification.json").read_text())
@@ -1217,7 +1279,7 @@ def generate_public_api_flat_methods() -> None:
thread_fork_fields = _load_public_fields(
"openai_codex.generated.v2_all",
"ThreadForkParams",
exclude={"thread_id", *approval_fields},
exclude={"thread_id", "last_turn_id", *approval_fields},
)
thread_fork_fields = _replace_public_sandbox_field(thread_fork_fields, wire_name="sandbox")
turn_start_fields = _load_public_fields(
@@ -1299,7 +1361,7 @@ def build_parser() -> argparse.ArgumentParser:
required=True,
help=(
"Python SDK release version to write into the staged package. "
"Accepts PEP 440 versions such as 0.1.0b1."
"Accepts PEP 440 versions such as 0.144.4."
),
)
@@ -17,6 +17,7 @@ from .v2_all import ContextCompactedNotification
from .v2_all import DeprecationNoticeNotification
from .v2_all import ErrorNotification
from .v2_all import ExternalAgentConfigImportCompletedNotification
from .v2_all import ExternalAgentConfigImportProgressNotification
from .v2_all import FileChangeOutputDeltaNotification
from .v2_all import FileChangePatchUpdatedNotification
from .v2_all import FsChangedNotification
@@ -33,6 +34,7 @@ from .v2_all import McpServerOauthLoginCompletedNotification
from .v2_all import McpServerStatusUpdatedNotification
from .v2_all import McpToolCallProgressNotification
from .v2_all import ModelReroutedNotification
from .v2_all import ModelSafetyBufferingUpdatedNotification
from .v2_all import ModelVerificationNotification
from .v2_all import PlanDeltaNotification
from .v2_all import ProcessExitedNotification
@@ -46,6 +48,7 @@ from .v2_all import SkillsChangedNotification
from .v2_all import TerminalInteractionNotification
from .v2_all import ThreadArchivedNotification
from .v2_all import ThreadClosedNotification
from .v2_all import ThreadDeletedNotification
from .v2_all import ThreadGoalClearedNotification
from .v2_all import ThreadGoalUpdatedNotification
from .v2_all import ThreadNameUpdatedNotification
@@ -64,6 +67,7 @@ from .v2_all import ThreadTokenUsageUpdatedNotification
from .v2_all import ThreadUnarchivedNotification
from .v2_all import TurnCompletedNotification
from .v2_all import TurnDiffUpdatedNotification
from .v2_all import TurnModerationMetadataNotification
from .v2_all import TurnPlanUpdatedNotification
from .v2_all import TurnStartedNotification
from .v2_all import WarningNotification
@@ -80,6 +84,7 @@ NOTIFICATION_MODELS: dict[str, type[BaseModel]] = {
"deprecationNotice": DeprecationNoticeNotification,
"error": ErrorNotification,
"externalAgentConfig/import/completed": ExternalAgentConfigImportCompletedNotification,
"externalAgentConfig/import/progress": ExternalAgentConfigImportProgressNotification,
"fs/changed": FsChangedNotification,
"fuzzyFileSearch/sessionCompleted": FuzzyFileSearchSessionCompletedNotification,
"fuzzyFileSearch/sessionUpdated": FuzzyFileSearchSessionUpdatedNotification,
@@ -103,6 +108,7 @@ NOTIFICATION_MODELS: dict[str, type[BaseModel]] = {
"mcpServer/oauthLogin/completed": McpServerOauthLoginCompletedNotification,
"mcpServer/startupStatus/updated": McpServerStatusUpdatedNotification,
"model/rerouted": ModelReroutedNotification,
"model/safetyBuffering/updated": ModelSafetyBufferingUpdatedNotification,
"model/verification": ModelVerificationNotification,
"process/exited": ProcessExitedNotification,
"process/outputDelta": ProcessOutputDeltaNotification,
@@ -112,6 +118,7 @@ NOTIFICATION_MODELS: dict[str, type[BaseModel]] = {
"thread/archived": ThreadArchivedNotification,
"thread/closed": ThreadClosedNotification,
"thread/compacted": ContextCompactedNotification,
"thread/deleted": ThreadDeletedNotification,
"thread/goal/cleared": ThreadGoalClearedNotification,
"thread/goal/updated": ThreadGoalUpdatedNotification,
"thread/name/updated": ThreadNameUpdatedNotification,
@@ -130,6 +137,7 @@ NOTIFICATION_MODELS: dict[str, type[BaseModel]] = {
"thread/unarchived": ThreadUnarchivedNotification,
"turn/completed": TurnCompletedNotification,
"turn/diff/updated": TurnDiffUpdatedNotification,
"turn/moderationMetadata": TurnModerationMetadataNotification,
"turn/plan/updated": TurnPlanUpdatedNotification,
"turn/started": TurnStartedNotification,
"warning": WarningNotification,
@@ -152,6 +160,7 @@ DIRECT_TURN_ID_NOTIFICATION_TYPES: tuple[type[BaseModel], ...] = (
ItemStartedNotification,
McpToolCallProgressNotification,
ModelReroutedNotification,
ModelSafetyBufferingUpdatedNotification,
ModelVerificationNotification,
PlanDeltaNotification,
ReasoningSummaryPartAddedNotification,
@@ -161,6 +170,7 @@ DIRECT_TURN_ID_NOTIFICATION_TYPES: tuple[type[BaseModel], ...] = (
ThreadGoalUpdatedNotification,
ThreadTokenUsageUpdatedNotification,
TurnDiffUpdatedNotification,
TurnModerationMetadataNotification,
TurnPlanUpdatedNotification,
)
File diff suppressed because it is too large Load Diff
@@ -373,6 +373,7 @@ def test_schema_normalization_only_flattens_string_literal_oneofs(
"ExperimentalFeatureStage",
"ProcessOutputStream",
"CommandExecOutputStream",
"ConsumeAccountRateLimitResetCreditOutcome",
"AutoCompactTokenLimitScope",
]
@@ -501,32 +502,33 @@ def test_source_sdk_template_pins_published_runtime() -> None:
"dependencies": pyproject["project"]["dependencies"],
} == {
"sdk_template_version": "0.0.0-dev",
"runtime_pin": "0.137.0a4",
"runtime_pin": "0.144.4",
"dependencies": [
"pydantic>=2.12",
"openai-codex-cli-bin==0.137.0a4",
"openai-codex-cli-bin==0.144.4",
],
}
def test_source_sdk_package_declares_beta_documentation() -> None:
"""Public package metadata should link beta docs."""
def test_source_sdk_package_declares_stable_documentation() -> None:
"""Public package metadata should link stable docs."""
pyproject = tomllib.loads((ROOT / "pyproject.toml").read_text())
readme = (ROOT / "README.md").read_text()
assert {
"description": pyproject["project"]["description"],
"is_beta": "Development Status :: 4 - Beta" in pyproject["project"]["classifiers"],
"is_stable": "Development Status :: 5 - Production/Stable"
in pyproject["project"]["classifiers"],
"license": pyproject["project"]["license"],
"documentation": pyproject["project"]["urls"]["Documentation"],
"readme_is_beta": "# OpenAI Codex Python SDK (Beta)" in readme,
"readme_is_stable": "# OpenAI Codex Python SDK\n" in readme,
"local_license_file": (ROOT / "LICENSE").exists(),
} == {
"description": "Python SDK for Codex",
"is_beta": True,
"is_stable": True,
"license": "Apache-2.0",
"documentation": "https://github.com/openai/codex/tree/main/sdk/python/docs",
"readme_is_beta": True,
"readme_is_stable": True,
"local_license_file": False,
}
@@ -558,7 +560,7 @@ def test_release_metadata_retries_without_invalid_auth(
def test_runtime_setup_reads_independent_runtime_pin_and_release_tags() -> None:
"""Runtime package pins remain independent of the SDK beta version."""
"""Runtime package pins remain independent of the SDK template version."""
runtime_setup = _load_runtime_setup_module()
pyproject = tomllib.loads((ROOT / "pyproject.toml").read_text())
@@ -573,7 +575,7 @@ def test_runtime_setup_reads_independent_runtime_pin_and_release_tags() -> None:
} == {
"package_name": "openai-codex-cli-bin",
"sdk_template_version": "0.0.0-dev",
"runtime_pin": "0.137.0a4",
"runtime_pin": "0.144.4",
"normalized_release_version": "0.116.0a1",
"release_tag": "rust-v0.116.0-alpha.1",
}
@@ -777,7 +779,7 @@ def test_stage_sdk_release_preserves_reviewed_runtime_pin(tmp_path: Path) -> Non
script = _load_update_script_module()
staged = script.stage_python_sdk_package(
tmp_path / "sdk-stage",
"0.1.0b1",
"0.144.4",
)
pyproject = tomllib.loads((staged / "pyproject.toml").read_text())
@@ -787,18 +789,18 @@ def test_stage_sdk_release_preserves_reviewed_runtime_pin(tmp_path: Path) -> Non
"dependencies": pyproject["project"]["dependencies"],
} == {
"name": "openai-codex",
"version": "0.1.0b1",
"version": "0.144.4",
"dependencies": [
"pydantic>=2.12",
"openai-codex-cli-bin==0.137.0a4",
"openai-codex-cli-bin==0.144.4",
],
}
assert (
'__version__ = "0.1.0b1"'
'__version__ = "0.144.4"'
not in (staged / "src" / "openai_codex" / "__init__.py").read_text()
)
assert (
'client_version: str = "0.1.0b1"'
'client_version: str = "0.144.4"'
not in (staged / "src" / "openai_codex" / "client.py").read_text()
)
assert not any((staged / "src" / "openai_codex").glob("bin/**"))
@@ -811,23 +813,23 @@ def test_stage_sdk_release_replaces_existing_staging_dir(tmp_path: Path) -> None
old_file.parent.mkdir(parents=True)
old_file.write_text("stale")
staged = script.stage_python_sdk_package(staging_dir, "0.1.0b1")
staged = script.stage_python_sdk_package(staging_dir, "0.144.4")
assert staged == staging_dir
assert not old_file.exists()
def test_sdk_beta_release_can_pin_stable_runtime(tmp_path: Path) -> None:
def test_sdk_release_matches_stable_runtime(tmp_path: Path) -> None:
script = _load_update_script_module()
package_archive = _write_fake_codex_package_archive(tmp_path, script)
sdk_stage = script.stage_python_sdk_package(
tmp_path / "sdk-stage",
"0.1.0b1",
"0.144.4",
)
runtime_stage = script.stage_python_runtime_package(
tmp_path / "runtime-stage",
"0.137.0a4",
"0.144.4",
package_archive,
)
@@ -839,11 +841,11 @@ def test_sdk_beta_release_can_pin_stable_runtime(tmp_path: Path) -> None:
"runtime_version": runtime_pyproject["project"]["version"],
"sdk_dependencies": sdk_pyproject["project"]["dependencies"],
} == {
"sdk_version": "0.1.0b1",
"runtime_version": "0.137.0a4",
"sdk_version": "0.144.4",
"runtime_version": "0.144.4",
"sdk_dependencies": [
"pydantic>=2.12",
"openai-codex-cli-bin==0.137.0a4",
"openai-codex-cli-bin==0.144.4",
],
}
@@ -856,7 +858,7 @@ def test_stage_sdk_runs_type_generation_before_staging(tmp_path: Path) -> None:
"stage-sdk",
str(tmp_path / "sdk-stage"),
"--sdk-version",
"0.1.0b1",
"0.144.4",
]
)
@@ -887,7 +889,7 @@ def test_stage_sdk_runs_type_generation_before_staging(tmp_path: Path) -> None:
script.run_command(args, ops)
assert calls == ["generate_types", "stage_sdk:0.1.0b1"]
assert calls == ["generate_types", "stage_sdk:0.144.4"]
def test_stage_runtime_stages_package_without_type_generation(tmp_path: Path) -> None:
@@ -7,13 +7,19 @@ from openai_codex.generated.notification_registry import notification_turn_id
from openai_codex.generated.v2_all import (
AgentMessageDeltaNotification,
ApprovalsReviewer,
ReasoningEffort,
ReasoningEffortOption,
ThreadForkParams,
ThreadListParams,
ThreadResumeResponse,
ThreadStartParams,
ThreadTokenUsageUpdatedNotification,
TurnCompletedNotification,
TurnStartParams,
WarningNotification,
)
from openai_codex.models import Notification, UnknownNotification
from openai_codex.types import ThreadSource
ROOT = Path(__file__).resolve().parents[1]
@@ -31,6 +37,56 @@ def test_generated_v2_bundle_has_single_shared_plan_type_definition() -> None:
assert source.count("class PlanType(") == 1
def test_reasoning_effort_preserves_enum_constants_and_accepts_future_values() -> None:
"""Known effort members and new runtime values should share the enum-style API."""
known_option = ReasoningEffortOption.model_validate(
{"description": "Balanced", "reasoningEffort": "medium"}
)
future_option = ReasoningEffortOption.model_validate(
{"description": "Future", "reasoningEffort": "ultra"}
)
turn_params = TurnStartParams(
thread_id="thread-1",
input=[],
effort=ReasoningEffort.medium,
)
assert {
"known_member": ReasoningEffort.medium.value,
"known_option": known_option.reasoning_effort.value,
"future_option": future_option.reasoning_effort.value,
"turn_effort": _params_dict(turn_params)["effort"],
} == {
"known_member": "medium",
"known_option": "medium",
"future_option": "ultra",
"turn_effort": "medium",
}
def test_thread_source_preserves_enum_constants_and_accepts_future_values() -> None:
"""Known thread sources and new runtime values should share the enum-style API."""
start_params = ThreadStartParams(thread_source=ThreadSource.user)
fork_params = ThreadForkParams(
thread_id="thread-1",
thread_source=ThreadSource("future_source"),
)
assert {
"known_member": ThreadSource.user.value,
"subagent_member": ThreadSource.subagent.value,
"memory_member": ThreadSource.memory_consolidation.value,
"start_source": _params_dict(start_params)["threadSource"],
"fork_source": _params_dict(fork_params)["threadSource"],
} == {
"known_member": "user",
"subagent_member": "subagent",
"memory_member": "memory_consolidation",
"start_source": "user",
"fork_source": "future_source",
}
def test_thread_resume_response_accepts_auto_review_reviewer() -> None:
"""Generated response models should keep accepting the auto review enum value."""
response = ThreadResumeResponse.model_validate(
+1 -1
View File
@@ -40,7 +40,7 @@ def test_generated_files_are_up_to_date():
# Regenerate contract artifacts via the pinned runtime package, not a local
# app-server binary from the checkout or CI environment.
assert importlib.metadata.version("openai-codex-cli-bin") == "0.137.0a4"
assert importlib.metadata.version("openai-codex-cli-bin") == "0.144.4"
env = os.environ.copy()
env.pop("CODEX_EXEC_PATH", None)
python_bin = str(Path(sys.executable).parent)
+11 -11
View File
@@ -7,7 +7,7 @@ exclude-newer = "0001-01-01T00:00:00Z" # This has no effect and is included for
exclude-newer-span = "P7D"
[options.exclude-newer-package]
openai-codex-cli-bin = "2026-06-03T19:00:00Z"
openai-codex-cli-bin = "2026-07-15T01:00:00Z"
[[package]]
name = "annotated-types"
@@ -306,7 +306,7 @@ test = [
[package.metadata]
requires-dist = [
{ name = "openai-codex-cli-bin", specifier = "==0.137.0a4" },
{ name = "openai-codex-cli-bin", specifier = "==0.144.4" },
{ name = "pydantic", specifier = ">=2.12" },
]
@@ -325,17 +325,17 @@ test = [
[[package]]
name = "openai-codex-cli-bin"
version = "0.137.0a4"
version = "0.144.4"
source = { registry = "https://pypi.org/simple" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/bd/60/af73ef1676cd477fa83ed4b889bf3b57c63c47dd87025b2cc4262793cff6/openai_codex_cli_bin-0.137.0a4-py3-none-macosx_10_9_x86_64.whl", hash = "sha256:b33c3917e0b58d527ee11a11a78ad390f7d8e6aa25577dd21665ab3c8bf5cf9a", size = 94300191, upload-time = "2026-06-03T18:44:36.312Z" },
{ url = "https://files.pythonhosted.org/packages/92/8f/d1a5f8c87176e00ef6a85798794f4530f5eb04e5a1a13468b5b3c3a361f9/openai_codex_cli_bin-0.137.0a4-py3-none-macosx_11_0_arm64.whl", hash = "sha256:3d0f0bc5becc88c61952fbfa9bd792ac9d74fa78b3a6bd40f545b612048b07eb", size = 83924479, upload-time = "2026-06-03T18:44:40.854Z" },
{ url = "https://files.pythonhosted.org/packages/3e/3c/fc00bcdc0c302208317d5eb1d0bfaab3024f351cd0121400f19baa6b19aa/openai_codex_cli_bin-0.137.0a4-py3-none-manylinux_2_17_aarch64.whl", hash = "sha256:2f1656339e2736868c4cce59f6d9e5c633879123687169b03b1137d42bf2c11a", size = 83363315, upload-time = "2026-06-03T18:44:44.851Z" },
{ url = "https://files.pythonhosted.org/packages/ec/09/39362e944ebeb12fcbfb86881fbb4dd6e806f77f7541c1f1f993bb9351a0/openai_codex_cli_bin-0.137.0a4-py3-none-manylinux_2_17_x86_64.whl", hash = "sha256:6454f838d44c56c1ed07a29b391fa412785e5dd2ffd06db0b62e62478c19bb64", size = 90611239, upload-time = "2026-06-03T18:44:49.338Z" },
{ url = "https://files.pythonhosted.org/packages/fa/38/87b1247fdfe95cddce7f7fe8331d6843cf037e14292c0f5004e23247133b/openai_codex_cli_bin-0.137.0a4-py3-none-musllinux_1_1_aarch64.whl", hash = "sha256:f5ae7401d00c65d56a75d9645d7bf87d809566a12d238e4b2a8b328a02f2316e", size = 83363315, upload-time = "2026-06-03T18:44:53.428Z" },
{ url = "https://files.pythonhosted.org/packages/fb/c4/3c693ad07e587f6b3a28128c417f2e831d81a40cdbd85c0e5f0f36aaff82/openai_codex_cli_bin-0.137.0a4-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:3dcec1e649448be498d6e7ec0e1f71dca83efa76063d90890dafb41e987069b7", size = 90611238, upload-time = "2026-06-03T18:44:57.612Z" },
{ url = "https://files.pythonhosted.org/packages/9e/26/81e037066b9b8d312a6f9e09015e452ce17630d5ab88e02a4c1d9503e4e8/openai_codex_cli_bin-0.137.0a4-py3-none-win_amd64.whl", hash = "sha256:9e13bf68e18e36bd3a0efd51213281c83e9f6ec22bdb7a45bd2e0211822733a9", size = 94744969, upload-time = "2026-06-03T18:45:02.23Z" },
{ url = "https://files.pythonhosted.org/packages/0d/a3/952bc2a5d62373a51fea161effe3b338b3417c2f6e65fe467ed91b205e2b/openai_codex_cli_bin-0.137.0a4-py3-none-win_arm64.whl", hash = "sha256:5ec4303ca2dcb5f838e0de3ca7f44050b6bcdd41d281a178c3a1420a985a515d", size = 86963504, upload-time = "2026-06-03T18:45:07.131Z" },
{ url = "https://files.pythonhosted.org/packages/79/30/7e457c007a32aa7333a78438a9f532504c3b77a1ea57e7808855712c2c0f/openai_codex_cli_bin-0.144.4-py3-none-macosx_10_9_x86_64.whl", hash = "sha256:4d587d152d5f0aa25f21ded4d08aac5150da48639b29fc3e57b2a8b413d06903", size = 126851183, upload-time = "2026-07-15T00:14:00.171Z" },
{ url = "https://files.pythonhosted.org/packages/65/eb/64c180514a2cc3e2500e486813f5a8d7f7e349342e9bebd78d99ddd9791a/openai_codex_cli_bin-0.144.4-py3-none-macosx_11_0_arm64.whl", hash = "sha256:05db505a9c7f020f58b70837a94e00d32a50086986c267bcc44ea97b573d4a05", size = 116474758, upload-time = "2026-07-15T00:14:08.177Z" },
{ url = "https://files.pythonhosted.org/packages/85/34/921ab692c7ed140941a91e39b84c6deafddb45072793f3a5f6dcbf86f59a/openai_codex_cli_bin-0.144.4-py3-none-manylinux_2_17_aarch64.whl", hash = "sha256:cd4bb31b8a477a3adba22139c8c493693fa5292ba21e86eef08ace3e96c41294", size = 119437596, upload-time = "2026-07-15T00:14:17.418Z" },
{ url = "https://files.pythonhosted.org/packages/25/62/39e630cf8b7b2e2444a5a6669235a6cd88004869a25bb7f3f629ed35638c/openai_codex_cli_bin-0.144.4-py3-none-manylinux_2_17_x86_64.whl", hash = "sha256:4106229c38f37245c3eea8d904426afd45b8bf19831765715647f5402f757c06", size = 128817757, upload-time = "2026-07-15T00:14:30.539Z" },
{ url = "https://files.pythonhosted.org/packages/23/24/318f91a95baaff845307e529d138d42a7202e6bd0e626556058eab3dead5/openai_codex_cli_bin-0.144.4-py3-none-musllinux_1_1_aarch64.whl", hash = "sha256:d2d3fada11731938e3d3e3660819d5324b7f92e825a0ed5aede63100b36ffc9a", size = 119437594, upload-time = "2026-07-15T00:14:39.327Z" },
{ url = "https://files.pythonhosted.org/packages/2e/a0/65e6fd3a6fba52639937801d9ce517b0c48026458723bb9f08eb07a1dd35/openai_codex_cli_bin-0.144.4-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:70fb62ed7755e332dd8b00ed48e22ee16df10f4a977335039e237cd330490df3", size = 128817755, upload-time = "2026-07-15T00:14:47.849Z" },
{ url = "https://files.pythonhosted.org/packages/e3/8a/3ab5fc97352e8f780d472c8dd6d7504d6a670cd7dede106d461ac1171999/openai_codex_cli_bin-0.144.4-py3-none-win_amd64.whl", hash = "sha256:56e142974467332f1f669b89f2636e06b3ada09413512abb2f24c33b4a4f59fc", size = 140595092, upload-time = "2026-07-15T00:14:58.484Z" },
{ url = "https://files.pythonhosted.org/packages/70/1a/3aa52ab8f89e0f596b6eea835e3f3494697da51917d3231f5f48f92e2bcb/openai_codex_cli_bin-0.144.4-py3-none-win_arm64.whl", hash = "sha256:2ad01058db7181323ae7c6217e560702e38c4f107595b99ab1d0abc9f184890a", size = 130665105, upload-time = "2026-07-15T00:15:08.861Z" },
]
[[package]]