mirror of
https://github.com/openai/codex.git
synced 2026-05-14 16:22:51 +00:00
Publish Python SDK with Codex-pinned versioning (#18996)
**note**: a large chunk of this diff comes from regenerating Python types after app-server schema changes on `main`. This is PR 3 of 3 for the Python SDK PyPI publishing split. PR #18862 refreshed the generated SDK surface, and PR #18865 made the runtime package publishable as `openai-codex-cli-bin`; this final PR makes the SDK package publishable as `openai-codex-app-server-sdk` and pins both packages to the same Codex runtime version. The key idea is that the published SDK version is the Codex runtime version. That one version now drives the SDK package version, the exact runtime dependency, the client version reported by the SDK, and the bootstrap runtime pin. This keeps release-time versioning in one lane instead of scattering checked-in literals through the package. ## What changed - Rename the SDK distribution from `codex-app-server-sdk` to `openai-codex-app-server-sdk` for conflict-free PyPI publishing. - Use `stage-sdk --codex-version ...` with one Codex version for both the SDK package version and exact `openai-codex-cli-bin` dependency. - Preserve hidden legacy `--runtime-version` / `--sdk-version` args only to reject mismatched versions during staging. - Map PEP 440 package versions back to Codex release tags for runtime setup downloads, e.g. `0.116.0a1` -> `rust-v0.116.0-alpha.1`. - Derive `codex_app_server.__version__`, the default `AppServerConfig.client_version`, and `_runtime_setup.pinned_runtime_version()` from the SDK package/project version instead of hardcoding duplicate version strings. - Carry the current generated SDK refresh from `main` so `generate-types` stays clean after recent app-server schema changes. - Update `sdk/python/uv.lock` for the renamed editable package. ## Validation - `uv run --extra dev pytest` in `sdk/python` -> 59 passed, 37 skipped. - Targeted `uv run ruff check` for the touched SDK files. - `git diff --check`. - Staged runtime with `--codex-version rust-v0.116.0-alpha.1 --platform-tag macosx_11_0_arm64`. - Staged SDK with `--codex-version rust-v0.116.0-alpha.1`. - Built runtime wheel, SDK wheel, and SDK sdist. - `twine check /tmp/codex-python-pr3-build/dist/*` -> passed. - Clean venv smoke installed `openai-codex-app-server-sdk==0.116.0a1` from local dist and pulled `openai-codex-cli-bin==0.116.0a1`. - Smoke imports passed for `Codex` and `bundled_codex_path()`.
This commit is contained in:
@@ -54,8 +54,7 @@ from .api import (
|
||||
TurnHandle,
|
||||
)
|
||||
from .retry import retry_on_overload
|
||||
|
||||
__version__ = "0.2.0"
|
||||
from ._version import __version__
|
||||
|
||||
__all__ = [
|
||||
"__version__",
|
||||
|
||||
37
sdk/python/src/codex_app_server/_version.py
Normal file
37
sdk/python/src/codex_app_server/_version.py
Normal file
@@ -0,0 +1,37 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
from importlib.metadata import PackageNotFoundError
|
||||
from importlib.metadata import version as distribution_version
|
||||
from pathlib import Path
|
||||
|
||||
DISTRIBUTION_NAME = "openai-codex-app-server-sdk"
|
||||
UNKNOWN_VERSION = "0+unknown"
|
||||
|
||||
|
||||
def package_version() -> str:
|
||||
source_version = _source_tree_project_version()
|
||||
if source_version is not None:
|
||||
return source_version
|
||||
|
||||
try:
|
||||
return distribution_version(DISTRIBUTION_NAME)
|
||||
except PackageNotFoundError:
|
||||
return UNKNOWN_VERSION
|
||||
|
||||
|
||||
def _source_tree_project_version() -> str | None:
|
||||
pyproject_path = Path(__file__).resolve().parents[2] / "pyproject.toml"
|
||||
if not pyproject_path.exists():
|
||||
return None
|
||||
|
||||
match = re.search(
|
||||
r'(?m)^version = "([^"]+)"$',
|
||||
pyproject_path.read_text(encoding="utf-8"),
|
||||
)
|
||||
if match is None:
|
||||
return None
|
||||
return match.group(1)
|
||||
|
||||
|
||||
__version__ = package_version()
|
||||
@@ -10,15 +10,18 @@ from .generated.v2_all import (
|
||||
ApprovalsReviewer,
|
||||
AskForApproval,
|
||||
ModelListResponse,
|
||||
PermissionProfile,
|
||||
Personality,
|
||||
ReasoningEffort,
|
||||
ReasoningSummary,
|
||||
SandboxMode,
|
||||
SandboxPolicy,
|
||||
ServiceTier,
|
||||
SortDirection,
|
||||
ThreadArchiveResponse,
|
||||
ThreadCompactStartResponse,
|
||||
ThreadForkParams,
|
||||
ThreadListCwdFilter,
|
||||
ThreadListParams,
|
||||
ThreadListResponse,
|
||||
ThreadReadResponse,
|
||||
@@ -26,6 +29,7 @@ from .generated.v2_all import (
|
||||
ThreadSetNameResponse,
|
||||
ThreadSortKey,
|
||||
ThreadSourceKind,
|
||||
ThreadStartSource,
|
||||
ThreadStartParams,
|
||||
Turn as AppServerTurn,
|
||||
TurnCompletedNotification,
|
||||
@@ -146,6 +150,7 @@ class Codex:
|
||||
ephemeral: bool | None = None,
|
||||
model: str | None = None,
|
||||
model_provider: str | None = None,
|
||||
permission_profile: PermissionProfile | None = None,
|
||||
personality: Personality | None = None,
|
||||
sandbox: SandboxMode | None = None,
|
||||
service_name: str | None = None,
|
||||
@@ -162,6 +167,7 @@ class Codex:
|
||||
ephemeral=ephemeral,
|
||||
model=model,
|
||||
model_provider=model_provider,
|
||||
permission_profile=permission_profile,
|
||||
personality=personality,
|
||||
sandbox=sandbox,
|
||||
service_name=service_name,
|
||||
@@ -176,13 +182,14 @@ class Codex:
|
||||
*,
|
||||
archived: bool | None = None,
|
||||
cursor: str | None = None,
|
||||
cwd: str | None = None,
|
||||
cwd: ThreadListCwdFilter | None = None,
|
||||
limit: int | None = None,
|
||||
model_providers: list[str] | None = None,
|
||||
search_term: str | None = None,
|
||||
sort_direction: SortDirection | None = None,
|
||||
sort_key: ThreadSortKey | None = None,
|
||||
source_kinds: list[ThreadSourceKind] | None = None,
|
||||
use_state_db_only: bool | None = None,
|
||||
) -> ThreadListResponse:
|
||||
params = ThreadListParams(
|
||||
archived=archived,
|
||||
@@ -194,6 +201,7 @@ class Codex:
|
||||
sort_direction=sort_direction,
|
||||
sort_key=sort_key,
|
||||
source_kinds=source_kinds,
|
||||
use_state_db_only=use_state_db_only,
|
||||
)
|
||||
return self._client.thread_list(params)
|
||||
|
||||
@@ -207,8 +215,10 @@ class Codex:
|
||||
config: JsonObject | None = None,
|
||||
cwd: str | None = None,
|
||||
developer_instructions: str | None = None,
|
||||
exclude_turns: bool | None = None,
|
||||
model: str | None = None,
|
||||
model_provider: str | None = None,
|
||||
permission_profile: PermissionProfile | None = None,
|
||||
personality: Personality | None = None,
|
||||
sandbox: SandboxMode | None = None,
|
||||
service_tier: ServiceTier | None = None,
|
||||
@@ -221,8 +231,10 @@ class Codex:
|
||||
config=config,
|
||||
cwd=cwd,
|
||||
developer_instructions=developer_instructions,
|
||||
exclude_turns=exclude_turns,
|
||||
model=model,
|
||||
model_provider=model_provider,
|
||||
permission_profile=permission_profile,
|
||||
personality=personality,
|
||||
sandbox=sandbox,
|
||||
service_tier=service_tier,
|
||||
@@ -241,8 +253,10 @@ class Codex:
|
||||
cwd: str | None = None,
|
||||
developer_instructions: str | None = None,
|
||||
ephemeral: bool | None = None,
|
||||
exclude_turns: bool | None = None,
|
||||
model: str | None = None,
|
||||
model_provider: str | None = None,
|
||||
permission_profile: PermissionProfile | None = None,
|
||||
sandbox: SandboxMode | None = None,
|
||||
service_tier: ServiceTier | None = None,
|
||||
) -> Thread:
|
||||
@@ -255,8 +269,10 @@ class Codex:
|
||||
cwd=cwd,
|
||||
developer_instructions=developer_instructions,
|
||||
ephemeral=ephemeral,
|
||||
exclude_turns=exclude_turns,
|
||||
model=model,
|
||||
model_provider=model_provider,
|
||||
permission_profile=permission_profile,
|
||||
sandbox=sandbox,
|
||||
service_tier=service_tier,
|
||||
)
|
||||
@@ -340,6 +356,7 @@ class AsyncCodex:
|
||||
ephemeral: bool | None = None,
|
||||
model: str | None = None,
|
||||
model_provider: str | None = None,
|
||||
permission_profile: PermissionProfile | None = None,
|
||||
personality: Personality | None = None,
|
||||
sandbox: SandboxMode | None = None,
|
||||
service_name: str | None = None,
|
||||
@@ -357,6 +374,7 @@ class AsyncCodex:
|
||||
ephemeral=ephemeral,
|
||||
model=model,
|
||||
model_provider=model_provider,
|
||||
permission_profile=permission_profile,
|
||||
personality=personality,
|
||||
sandbox=sandbox,
|
||||
service_name=service_name,
|
||||
@@ -371,13 +389,14 @@ class AsyncCodex:
|
||||
*,
|
||||
archived: bool | None = None,
|
||||
cursor: str | None = None,
|
||||
cwd: str | None = None,
|
||||
cwd: ThreadListCwdFilter | None = None,
|
||||
limit: int | None = None,
|
||||
model_providers: list[str] | None = None,
|
||||
search_term: str | None = None,
|
||||
sort_direction: SortDirection | None = None,
|
||||
sort_key: ThreadSortKey | None = None,
|
||||
source_kinds: list[ThreadSourceKind] | None = None,
|
||||
use_state_db_only: bool | None = None,
|
||||
) -> ThreadListResponse:
|
||||
await self._ensure_initialized()
|
||||
params = ThreadListParams(
|
||||
@@ -390,6 +409,7 @@ class AsyncCodex:
|
||||
sort_direction=sort_direction,
|
||||
sort_key=sort_key,
|
||||
source_kinds=source_kinds,
|
||||
use_state_db_only=use_state_db_only,
|
||||
)
|
||||
return await self._client.thread_list(params)
|
||||
|
||||
@@ -403,8 +423,10 @@ class AsyncCodex:
|
||||
config: JsonObject | None = None,
|
||||
cwd: str | None = None,
|
||||
developer_instructions: str | None = None,
|
||||
exclude_turns: bool | None = None,
|
||||
model: str | None = None,
|
||||
model_provider: str | None = None,
|
||||
permission_profile: PermissionProfile | None = None,
|
||||
personality: Personality | None = None,
|
||||
sandbox: SandboxMode | None = None,
|
||||
service_tier: ServiceTier | None = None,
|
||||
@@ -418,8 +440,10 @@ class AsyncCodex:
|
||||
config=config,
|
||||
cwd=cwd,
|
||||
developer_instructions=developer_instructions,
|
||||
exclude_turns=exclude_turns,
|
||||
model=model,
|
||||
model_provider=model_provider,
|
||||
permission_profile=permission_profile,
|
||||
personality=personality,
|
||||
sandbox=sandbox,
|
||||
service_tier=service_tier,
|
||||
@@ -438,8 +462,10 @@ class AsyncCodex:
|
||||
cwd: str | None = None,
|
||||
developer_instructions: str | None = None,
|
||||
ephemeral: bool | None = None,
|
||||
exclude_turns: bool | None = None,
|
||||
model: str | None = None,
|
||||
model_provider: str | None = None,
|
||||
permission_profile: PermissionProfile | None = None,
|
||||
sandbox: SandboxMode | None = None,
|
||||
service_tier: ServiceTier | None = None,
|
||||
) -> AsyncThread:
|
||||
@@ -453,8 +479,10 @@ class AsyncCodex:
|
||||
cwd=cwd,
|
||||
developer_instructions=developer_instructions,
|
||||
ephemeral=ephemeral,
|
||||
exclude_turns=exclude_turns,
|
||||
model=model,
|
||||
model_provider=model_provider,
|
||||
permission_profile=permission_profile,
|
||||
sandbox=sandbox,
|
||||
service_tier=service_tier,
|
||||
)
|
||||
@@ -491,6 +519,7 @@ class Thread:
|
||||
effort: ReasoningEffort | None = None,
|
||||
model: str | None = None,
|
||||
output_schema: JsonObject | None = None,
|
||||
permission_profile: PermissionProfile | None = None,
|
||||
personality: Personality | None = None,
|
||||
sandbox_policy: SandboxPolicy | None = None,
|
||||
service_tier: ServiceTier | None = None,
|
||||
@@ -504,6 +533,7 @@ class Thread:
|
||||
effort=effort,
|
||||
model=model,
|
||||
output_schema=output_schema,
|
||||
permission_profile=permission_profile,
|
||||
personality=personality,
|
||||
sandbox_policy=sandbox_policy,
|
||||
service_tier=service_tier,
|
||||
@@ -526,6 +556,7 @@ class Thread:
|
||||
effort: ReasoningEffort | None = None,
|
||||
model: str | None = None,
|
||||
output_schema: JsonObject | None = None,
|
||||
permission_profile: PermissionProfile | None = None,
|
||||
personality: Personality | None = None,
|
||||
sandbox_policy: SandboxPolicy | None = None,
|
||||
service_tier: ServiceTier | None = None,
|
||||
@@ -541,6 +572,7 @@ class Thread:
|
||||
effort=effort,
|
||||
model=model,
|
||||
output_schema=output_schema,
|
||||
permission_profile=permission_profile,
|
||||
personality=personality,
|
||||
sandbox_policy=sandbox_policy,
|
||||
service_tier=service_tier,
|
||||
@@ -575,6 +607,7 @@ class AsyncThread:
|
||||
effort: ReasoningEffort | None = None,
|
||||
model: str | None = None,
|
||||
output_schema: JsonObject | None = None,
|
||||
permission_profile: PermissionProfile | None = None,
|
||||
personality: Personality | None = None,
|
||||
sandbox_policy: SandboxPolicy | None = None,
|
||||
service_tier: ServiceTier | None = None,
|
||||
@@ -588,6 +621,7 @@ class AsyncThread:
|
||||
effort=effort,
|
||||
model=model,
|
||||
output_schema=output_schema,
|
||||
permission_profile=permission_profile,
|
||||
personality=personality,
|
||||
sandbox_policy=sandbox_policy,
|
||||
service_tier=service_tier,
|
||||
@@ -610,6 +644,7 @@ class AsyncThread:
|
||||
effort: ReasoningEffort | None = None,
|
||||
model: str | None = None,
|
||||
output_schema: JsonObject | None = None,
|
||||
permission_profile: PermissionProfile | None = None,
|
||||
personality: Personality | None = None,
|
||||
sandbox_policy: SandboxPolicy | None = None,
|
||||
service_tier: ServiceTier | None = None,
|
||||
@@ -626,6 +661,7 @@ class AsyncThread:
|
||||
effort=effort,
|
||||
model=model,
|
||||
output_schema=output_schema,
|
||||
permission_profile=permission_profile,
|
||||
personality=personality,
|
||||
sandbox_policy=sandbox_policy,
|
||||
service_tier=service_tier,
|
||||
|
||||
@@ -44,6 +44,7 @@ from .models import (
|
||||
UnknownNotification,
|
||||
)
|
||||
from .retry import retry_on_overload
|
||||
from ._version import __version__ as SDK_VERSION
|
||||
|
||||
ModelT = TypeVar("ModelT", bound=BaseModel)
|
||||
ApprovalHandler = Callable[[str, JsonObject | None], JsonObject]
|
||||
@@ -129,7 +130,7 @@ class AppServerConfig:
|
||||
env: dict[str, str] | None = None
|
||||
client_name: str = "codex_python_sdk"
|
||||
client_title: str = "Codex Python SDK"
|
||||
client_version: str = "0.2.0"
|
||||
client_version: str = SDK_VERSION
|
||||
experimental_api: bool = True
|
||||
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ from .v2_all import FileChangePatchUpdatedNotification
|
||||
from .v2_all import FsChangedNotification
|
||||
from .v2_all import FuzzyFileSearchSessionCompletedNotification
|
||||
from .v2_all import FuzzyFileSearchSessionUpdatedNotification
|
||||
from .v2_all import GuardianWarningNotification
|
||||
from .v2_all import HookCompletedNotification
|
||||
from .v2_all import HookStartedNotification
|
||||
from .v2_all import ItemCompletedNotification
|
||||
@@ -32,6 +33,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 ModelVerificationNotification
|
||||
from .v2_all import PlanDeltaNotification
|
||||
from .v2_all import ReasoningSummaryPartAddedNotification
|
||||
from .v2_all import ReasoningSummaryTextDeltaNotification
|
||||
@@ -41,6 +43,8 @@ from .v2_all import SkillsChangedNotification
|
||||
from .v2_all import TerminalInteractionNotification
|
||||
from .v2_all import ThreadArchivedNotification
|
||||
from .v2_all import ThreadClosedNotification
|
||||
from .v2_all import ThreadGoalClearedNotification
|
||||
from .v2_all import ThreadGoalUpdatedNotification
|
||||
from .v2_all import ThreadNameUpdatedNotification
|
||||
from .v2_all import ThreadRealtimeClosedNotification
|
||||
from .v2_all import ThreadRealtimeErrorNotification
|
||||
@@ -75,6 +79,7 @@ NOTIFICATION_MODELS: dict[str, type[BaseModel]] = {
|
||||
"fs/changed": FsChangedNotification,
|
||||
"fuzzyFileSearch/sessionCompleted": FuzzyFileSearchSessionCompletedNotification,
|
||||
"fuzzyFileSearch/sessionUpdated": FuzzyFileSearchSessionUpdatedNotification,
|
||||
"guardianWarning": GuardianWarningNotification,
|
||||
"hook/completed": HookCompletedNotification,
|
||||
"hook/started": HookStartedNotification,
|
||||
"item/agentMessage/delta": AgentMessageDeltaNotification,
|
||||
@@ -94,11 +99,14 @@ NOTIFICATION_MODELS: dict[str, type[BaseModel]] = {
|
||||
"mcpServer/oauthLogin/completed": McpServerOauthLoginCompletedNotification,
|
||||
"mcpServer/startupStatus/updated": McpServerStatusUpdatedNotification,
|
||||
"model/rerouted": ModelReroutedNotification,
|
||||
"model/verification": ModelVerificationNotification,
|
||||
"serverRequest/resolved": ServerRequestResolvedNotification,
|
||||
"skills/changed": SkillsChangedNotification,
|
||||
"thread/archived": ThreadArchivedNotification,
|
||||
"thread/closed": ThreadClosedNotification,
|
||||
"thread/compacted": ContextCompactedNotification,
|
||||
"thread/goal/cleared": ThreadGoalClearedNotification,
|
||||
"thread/goal/updated": ThreadGoalUpdatedNotification,
|
||||
"thread/name/updated": ThreadNameUpdatedNotification,
|
||||
"thread/realtime/closed": ThreadRealtimeClosedNotification,
|
||||
"thread/realtime/error": ThreadRealtimeErrorNotification,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user