[codex] Pin Python SDK to glibc-compatible runtime (#25907)

## Summary
- pin the Python SDK runtime package to `openai-codex-cli-bin==0.136.0`
so Ubuntu/glibc installs resolve a compatible wheel
- refresh generated SDK artifacts and lock data for the runtime update
- keep newly generated client-message-id wire models internal to the
generated protocol layer

## Dependency
- merge #25906 first so the Python SDK release publishes both manylinux
and musllinux runtime wheels before publishing the package with this pin

## Validation
- ran `just fmt`
- regenerated the Python public API helpers
- validated the edited workflow YAML
- CI passed 29/29 checks
This commit is contained in:
Ahmed Ibrahim
2026-06-02 12:27:01 -07:00
committed by GitHub
Unverified
parent 9de568372d
commit bc49677ec8
9 changed files with 407 additions and 110 deletions
+3 -3
View File
@@ -34,8 +34,8 @@ jobs:
exit 1
fi
# The pinned runtime currently publishes a musllinux Linux wheel.
# Build in Alpine so release type generation installs that wheel.
# Build in a glibc Linux image so release type generation installs
# the pinned manylinux runtime wheel.
docker run --rm \
--user "$(id -u):$(id -g)" \
-e HOME=/tmp/codex-python-sdk-home \
@@ -46,7 +46,7 @@ jobs:
-v "${GITHUB_WORKSPACE}:${GITHUB_WORKSPACE}" \
-v "${RUNNER_TEMP}:${RUNNER_TEMP}" \
-w "${GITHUB_WORKSPACE}/sdk/python" \
python:3.12-alpine \
python:3.12-slim \
sh -euxc '
python -m venv /tmp/release-tools
/tmp/release-tools/bin/python -m pip install build twine uv==0.11.3
+3 -3
View File
@@ -23,15 +23,15 @@ jobs:
run: |
set -euo pipefail
# Run inside Alpine so dependency resolution exercises the pinned
# runtime wheel on the same Linux wheel family that CI installs.
# Run inside a glibc Linux image so dependency resolution exercises
# the pinned manylinux runtime wheel that users install.
docker run --rm \
--user "$(id -u):$(id -g)" \
-e HOME=/tmp/codex-python-sdk-home \
-e UV_LINK_MODE=copy \
-v "${GITHUB_WORKSPACE}:${GITHUB_WORKSPACE}" \
-w "${GITHUB_WORKSPACE}/sdk/python" \
python:3.12-alpine \
python:3.12-slim \
sh -euxc '
python -m venv /tmp/uv
/tmp/uv/bin/python -m pip install uv==0.11.3
+3 -3
View File
@@ -16,7 +16,7 @@ classifiers = [
"Intended Audience :: Developers",
"Topic :: Software Development :: Libraries :: Python Modules",
]
dependencies = ["pydantic>=2.12", "openai-codex-cli-bin==0.132.0"]
dependencies = ["pydantic>=2.12", "openai-codex-cli-bin==0.136.0"]
[project.urls]
Homepage = "https://github.com/openai/codex"
@@ -78,10 +78,10 @@ combine-as-imports = true
[tool.uv]
exclude-newer = "7 days"
exclude-newer-package = { openai-codex-cli-bin = "2026-05-20T21:00:00Z" }
exclude-newer-package = { openai-codex-cli-bin = "2026-06-01T20:00:00Z" }
index-strategy = "first-index"
[tool.uv.pip]
exclude-newer = "7 days"
exclude-newer-package = { openai-codex-cli-bin = "2026-05-20T21:00:00Z" }
exclude-newer-package = { openai-codex-cli-bin = "2026-06-01T20:00:00Z" }
index-strategy = "first-index"
+4 -2
View File
@@ -1163,7 +1163,9 @@ def generate_public_api_flat_methods() -> None:
turn_start_fields = _load_public_fields(
"openai_codex.generated.v2_all",
"TurnStartParams",
exclude={"thread_id", "input", *approval_fields},
# Keep the wire model current without exposing this app-server field
# through the ergonomic Python API yet.
exclude={"thread_id", "input", "client_user_message_id", *approval_fields},
)
turn_start_fields = _replace_public_sandbox_field(turn_start_fields, wire_name="sandbox_policy")
@@ -1267,7 +1269,7 @@ def build_parser() -> argparse.ArgumentParser:
"--platform-tag",
help=(
"Optional wheel platform tag override, for example "
"macosx_11_0_arm64 or musllinux_1_1_x86_64."
"macosx_11_0_arm64 or manylinux_2_17_x86_64."
),
)
return parser
@@ -57,6 +57,7 @@ from .v2_all import ThreadRealtimeSdpNotification
from .v2_all import ThreadRealtimeStartedNotification
from .v2_all import ThreadRealtimeTranscriptDeltaNotification
from .v2_all import ThreadRealtimeTranscriptDoneNotification
from .v2_all import ThreadSettingsUpdatedNotification
from .v2_all import ThreadStartedNotification
from .v2_all import ThreadStatusChangedNotification
from .v2_all import ThreadTokenUsageUpdatedNotification
@@ -122,6 +123,7 @@ NOTIFICATION_MODELS: dict[str, type[BaseModel]] = {
"thread/realtime/started": ThreadRealtimeStartedNotification,
"thread/realtime/transcript/delta": ThreadRealtimeTranscriptDeltaNotification,
"thread/realtime/transcript/done": ThreadRealtimeTranscriptDoneNotification,
"thread/settings/updated": ThreadSettingsUpdatedNotification,
"thread/started": ThreadStartedNotification,
"thread/status/changed": ThreadStatusChangedNotification,
"thread/tokenUsage/updated": ThreadTokenUsageUpdatedNotification,
+369 -77
View File
@@ -56,7 +56,7 @@ class ActivePermissionProfile(BaseModel):
extends: Annotated[
str | None,
Field(
description="Parent profile identifier once permissions profiles support inheritance. This is currently always `null`."
description="Parent profile identifier from the selected permissions profile's `extends` setting, when present."
),
] = None
id: Annotated[
@@ -77,6 +77,11 @@ class AddCreditsNudgeEmailStatus(Enum):
cooldown_active = "cooldown_active"
class AdditionalContextKind(Enum):
untrusted = "untrusted"
application = "application"
class AdditionalNetworkPermissions(BaseModel):
model_config = ConfigDict(
populate_by_name=True,
@@ -251,6 +256,11 @@ class AuthMode(Enum):
agent_identity = "agentIdentity"
class AutoCompactTokenLimitScope(Enum):
total = "total"
body_after_prefix = "body_after_prefix"
class AutoReviewDecisionSource(RootModel[Literal["agent"]]):
model_config = ConfigDict(
populate_by_name=True,
@@ -563,6 +573,13 @@ class CommandMigration(BaseModel):
name: str
class ComputerUseRequirements(BaseModel):
model_config = ConfigDict(
populate_by_name=True,
)
allow_locked_computer_use: Annotated[bool | None, Field(alias="allowLockedComputerUse")] = None
class MdmConfigLayerSource(BaseModel):
model_config = ConfigDict(
populate_by_name=True,
@@ -675,7 +692,7 @@ class ConfigReadParams(BaseModel):
description="Optional working directory to resolve project config layers. If specified, return the effective config as seen from that directory (i.e., including any project layers between `cwd` and the project/repo root)."
),
] = None
include_layers: Annotated[bool | None, Field(alias="includeLayers")] = False
include_layers: Annotated[bool | None, Field(alias="includeLayers")] = None
class CommandConfiguredHookHandler(BaseModel):
@@ -913,7 +930,7 @@ class FeedbackUploadParams(BaseModel):
)
classification: str
extra_log_files: Annotated[list[str] | None, Field(alias="extraLogFiles")] = None
include_logs: Annotated[bool, Field(alias="includeLogs")]
include_logs: Annotated[bool | None, Field(alias="includeLogs")] = None
reason: str | None = None
tags: dict[str, Any] | None = None
thread_id: Annotated[str | None, Field(alias="threadId")] = None
@@ -939,7 +956,7 @@ class FileChangeOutputDeltaNotification(BaseModel):
class FileSystemAccessMode(Enum):
read = "read"
write = "write"
none = "none"
deny = "deny"
class PathFileSystemPath(BaseModel):
@@ -1276,6 +1293,17 @@ class InputTextFunctionCallOutputContentItem(BaseModel):
]
class EncryptedContentFunctionCallOutputContentItem(BaseModel):
model_config = ConfigDict(
populate_by_name=True,
)
encrypted_content: str
type: Annotated[
Literal["encrypted_content"],
Field(title="EncryptedContentFunctionCallOutputContentItemType"),
]
class FuzzyFileSearchMatchType(Enum):
file = "file"
directory = "directory"
@@ -1335,7 +1363,7 @@ class GetAccountParams(BaseModel):
alias="refreshToken",
description="When `true`, requests a proactive token refresh before returning.\n\nIn managed auth mode this triggers the normal refresh-token flow. In external auth mode this flag is ignored. Clients should refresh tokens themselves and call `account/login/start` with `chatgptAuthTokens`.",
),
] = False
] = None
class GitInfo(BaseModel):
@@ -1425,6 +1453,8 @@ class HookEventName(Enum):
post_compact = "postCompact"
session_start = "sessionStart"
user_prompt_submit = "userPromptSubmit"
subagent_start = "subagentStart"
subagent_stop = "subagentStop"
stop = "stop"
@@ -1506,6 +1536,8 @@ class HooksListParams(BaseModel):
class ImageDetail(Enum):
auto = "auto"
low = "low"
high = "high"
original = "original"
@@ -1742,6 +1774,8 @@ class ManagedHooksRequirements(BaseModel):
pre_tool_use: Annotated[list[ConfiguredHookMatcherGroup], Field(alias="PreToolUse")]
session_start: Annotated[list[ConfiguredHookMatcherGroup], Field(alias="SessionStart")]
stop: Annotated[list[ConfiguredHookMatcherGroup], Field(alias="Stop")]
subagent_start: Annotated[list[ConfiguredHookMatcherGroup], Field(alias="SubagentStart")]
subagent_stop: Annotated[list[ConfiguredHookMatcherGroup], Field(alias="SubagentStop")]
user_prompt_submit: Annotated[list[ConfiguredHookMatcherGroup], Field(alias="UserPromptSubmit")]
managed_dir: Annotated[str | None, Field(alias="managedDir")] = None
windows_managed_dir: Annotated[str | None, Field(alias="windowsManagedDir")] = None
@@ -1835,6 +1869,18 @@ class McpResourceReadParams(BaseModel):
uri: str
class McpServerInfo(BaseModel):
model_config = ConfigDict(
populate_by_name=True,
)
description: str | None = None
icons: list | None = None
name: str
title: str | None = None
version: str
website_url: Annotated[str | None, Field(alias="websiteUrl")] = None
class McpServerMigration(BaseModel):
model_config = ConfigDict(
populate_by_name=True,
@@ -2142,7 +2188,7 @@ class NetworkRequirements(BaseModel):
class NetworkUnixSocketPermission(Enum):
allow = "allow"
none = "none"
deny = "deny"
class NonSteerableTurnKind(Enum):
@@ -2188,6 +2234,32 @@ class PatchChangeKind(
root: AddPatchChangeKind | DeletePatchChangeKind | UpdatePatchChangeKind
class PermissionProfileListParams(BaseModel):
model_config = ConfigDict(
populate_by_name=True,
)
cursor: Annotated[
str | None, Field(description="Opaque pagination cursor returned by a previous call.")
] = None
cwd: Annotated[
str | None,
Field(description="Optional working directory to resolve project config layers."),
] = None
limit: Annotated[
int | None, Field(description="Optional page size; defaults to the full result set.", ge=0)
] = None
class PermissionProfileSummary(BaseModel):
model_config = ConfigDict(
populate_by_name=True,
)
description: Annotated[
str | None, Field(description="Optional user-facing description for display in clients.")
] = None
id: Annotated[str, Field(description="Available permission profile identifier.")]
class Personality(Enum):
none = "none"
friendly = "friendly"
@@ -2332,6 +2404,7 @@ class PluginInterface(BaseModel):
class PluginListMarketplaceKind(Enum):
local = "local"
vertical = "vertical"
workspace_directory = "workspace-directory"
shared_with_me = "shared-with-me"
@@ -3469,6 +3542,20 @@ class SkillsConfigWriteResponse(BaseModel):
effective_enabled: Annotated[bool, Field(alias="effectiveEnabled")]
class SkillsExtraRootsSetParams(BaseModel):
model_config = ConfigDict(
populate_by_name=True,
)
extra_roots: Annotated[list[AbsolutePathBuf], Field(alias="extraRoots")]
class SkillsExtraRootsSetResponse(BaseModel):
pass
model_config = ConfigDict(
populate_by_name=True,
)
class SkillsListParams(BaseModel):
model_config = ConfigDict(
populate_by_name=True,
@@ -3624,6 +3711,20 @@ class ThreadCompactStartResponse(BaseModel):
)
class ThreadGoalClearParams(BaseModel):
model_config = ConfigDict(
populate_by_name=True,
)
thread_id: Annotated[str, Field(alias="threadId")]
class ThreadGoalClearResponse(BaseModel):
model_config = ConfigDict(
populate_by_name=True,
)
cleared: bool
class ThreadGoalClearedNotification(BaseModel):
model_config = ConfigDict(
populate_by_name=True,
@@ -3631,6 +3732,13 @@ class ThreadGoalClearedNotification(BaseModel):
thread_id: Annotated[str, Field(alias="threadId")]
class ThreadGoalGetParams(BaseModel):
model_config = ConfigDict(
populate_by_name=True,
)
thread_id: Annotated[str, Field(alias="threadId")]
class ThreadGoalStatus(Enum):
active = "active"
paused = "paused"
@@ -3749,6 +3857,7 @@ class McpToolCallThreadItem(BaseModel):
error: McpToolCallError | None = None
id: str
mcp_app_resource_uri: Annotated[str | None, Field(alias="mcpAppResourceUri")] = None
plugin_id: Annotated[str | None, Field(alias="pluginId")] = None
result: McpToolCallResult | None = None
server: str
status: McpToolCallStatus
@@ -3922,7 +4031,7 @@ class ThreadReadParams(BaseModel):
alias="includeTurns",
description="When true, include turns and their items from rollout history.",
),
] = False
] = None
thread_id: Annotated[str, Field(alias="threadId")]
@@ -4536,6 +4645,14 @@ class AccountUpdatedNotification(BaseModel):
plan_type: Annotated[PlanType | None, Field(alias="planType")] = None
class AdditionalContextEntry(BaseModel):
model_config = ConfigDict(
populate_by_name=True,
)
kind: AdditionalContextKind
value: str
class AppConfig(BaseModel):
model_config = ConfigDict(
populate_by_name=True,
@@ -4629,6 +4746,24 @@ class ThreadNameSetRequest(BaseModel):
params: ThreadSetNameParams
class ThreadGoalGetRequest(BaseModel):
model_config = ConfigDict(
populate_by_name=True,
)
id: RequestId
method: Annotated[Literal["thread/goal/get"], Field(title="Thread/goal/getRequestMethod")]
params: ThreadGoalGetParams
class ThreadGoalClearRequest(BaseModel):
model_config = ConfigDict(
populate_by_name=True,
)
id: RequestId
method: Annotated[Literal["thread/goal/clear"], Field(title="Thread/goal/clearRequestMethod")]
params: ThreadGoalClearParams
class ThreadMetadataUpdateRequest(BaseModel):
model_config = ConfigDict(
populate_by_name=True,
@@ -4730,6 +4865,17 @@ class SkillsListRequest(BaseModel):
params: SkillsListParams
class SkillsExtraRootsSetRequest(BaseModel):
model_config = ConfigDict(
populate_by_name=True,
)
id: RequestId
method: Annotated[
Literal["skills/extraRoots/set"], Field(title="Skills/extraRoots/setRequestMethod")
]
params: SkillsExtraRootsSetParams
class HooksListRequest(BaseModel):
model_config = ConfigDict(
populate_by_name=True,
@@ -4995,6 +5141,17 @@ class ExperimentalFeatureListRequest(BaseModel):
params: ExperimentalFeatureListParams
class PermissionProfileListRequest(BaseModel):
model_config = ConfigDict(
populate_by_name=True,
)
id: RequestId
method: Annotated[
Literal["permissionProfile/list"], Field(title="PermissionProfile/listRequestMethod")
]
params: PermissionProfileListParams
class ExperimentalFeatureEnablementSetRequest(BaseModel):
model_config = ConfigDict(
populate_by_name=True,
@@ -5431,16 +5588,22 @@ class ConfigRequirements(BaseModel):
model_config = ConfigDict(
populate_by_name=True,
)
allow_appshots: Annotated[bool | None, Field(alias="allowAppshots")] = None
allow_managed_hooks_only: Annotated[bool | None, Field(alias="allowManagedHooksOnly")] = None
allowed_approval_policies: Annotated[
list[AskForApproval] | None, Field(alias="allowedApprovalPolicies")
] = None
allowed_permissions: Annotated[list[str] | None, Field(alias="allowedPermissions")] = None
allowed_sandbox_modes: Annotated[
list[SandboxMode] | None, Field(alias="allowedSandboxModes")
] = None
allowed_web_search_modes: Annotated[
list[WebSearchMode] | None, Field(alias="allowedWebSearchModes")
] = None
allowed_windows_sandbox_implementations: Annotated[
list[WindowsSandboxSetupMode] | None, Field(alias="allowedWindowsSandboxImplementations")
] = None
computer_use: Annotated[ComputerUseRequirements | None, Field(alias="computerUse")] = None
enforce_residency: Annotated[ResidencyRequirement | None, Field(alias="enforceResidency")] = (
None
)
@@ -5608,13 +5771,19 @@ class InputImageFunctionCallOutputContentItem(BaseModel):
class FunctionCallOutputContentItem(
RootModel[InputTextFunctionCallOutputContentItem | InputImageFunctionCallOutputContentItem]
RootModel[
InputTextFunctionCallOutputContentItem
| InputImageFunctionCallOutputContentItem
| EncryptedContentFunctionCallOutputContentItem
]
):
model_config = ConfigDict(
populate_by_name=True,
)
root: Annotated[
InputTextFunctionCallOutputContentItem | InputImageFunctionCallOutputContentItem,
InputTextFunctionCallOutputContentItem
| InputImageFunctionCallOutputContentItem
| EncryptedContentFunctionCallOutputContentItem,
Field(
description="Responses API compatible content items that can be returned by a tool call. This is a subset of ContentItem with the types we support as function call outputs."
),
@@ -5767,6 +5936,7 @@ class ListMcpServerStatusParams(BaseModel):
int | None,
Field(description="Optional page size; defaults to a server-defined value.", ge=0),
] = None
thread_id: Annotated[str | None, Field(alias="threadId")] = None
class McpResourceReadResponse(BaseModel):
@@ -5784,6 +5954,7 @@ class McpServerStatus(BaseModel):
name: str
resource_templates: Annotated[list[ResourceTemplate], Field(alias="resourceTemplates")]
resources: list[Resource]
server_info: Annotated[McpServerInfo | None, Field(alias="serverInfo")] = None
tools: dict[str, Tool]
@@ -5817,6 +5988,13 @@ class Model(BaseModel):
] = []
availability_nux: Annotated[ModelAvailabilityNux | None, Field(alias="availabilityNux")] = None
default_reasoning_effort: Annotated[ReasoningEffort, Field(alias="defaultReasoningEffort")]
default_service_tier: Annotated[
str | None,
Field(
alias="defaultServiceTier",
description="Catalog default service tier id for this model, when one is configured.",
),
] = None
description: str
display_name: Annotated[str, Field(alias="displayName")]
hidden: bool
@@ -5859,6 +6037,20 @@ class OverriddenMetadata(BaseModel):
overriding_layer: Annotated[ConfigLayerMetadata, Field(alias="overridingLayer")]
class PermissionProfileListResponse(BaseModel):
model_config = ConfigDict(
populate_by_name=True,
)
data: list[PermissionProfileSummary]
next_cursor: Annotated[
str | None,
Field(
alias="nextCursor",
description="Opaque cursor to pass to the next call to continue after the last item. If None, there are no more items to return.",
),
] = None
class PluginSharePrincipal(BaseModel):
model_config = ConfigDict(
populate_by_name=True,
@@ -6332,6 +6524,30 @@ class ThreadGoal(BaseModel):
updated_at: Annotated[int, Field(alias="updatedAt")]
class ThreadGoalGetResponse(BaseModel):
model_config = ConfigDict(
populate_by_name=True,
)
goal: ThreadGoal | None = None
class ThreadGoalSetParams(BaseModel):
model_config = ConfigDict(
populate_by_name=True,
)
objective: str | None = None
status: ThreadGoalStatus | None = None
thread_id: Annotated[str, Field(alias="threadId")]
token_budget: Annotated[int | None, Field(alias="tokenBudget")] = None
class ThreadGoalSetResponse(BaseModel):
model_config = ConfigDict(
populate_by_name=True,
)
goal: ThreadGoal
class ThreadGoalUpdatedNotification(BaseModel):
model_config = ConfigDict(
populate_by_name=True,
@@ -6345,6 +6561,7 @@ class UserMessageThreadItem(BaseModel):
model_config = ConfigDict(
populate_by_name=True,
)
client_id: Annotated[str | None, Field(alias="clientId")] = None
content: list[UserInput]
id: str
type: Annotated[Literal["userMessage"], Field(title="UserMessageThreadItemType")]
@@ -6536,6 +6753,55 @@ class ThreadListParams(BaseModel):
] = None
class ThreadResumeInitialTurnsPageParams(BaseModel):
model_config = ConfigDict(
populate_by_name=True,
)
items_view: Annotated[
TurnItemsView | None,
Field(
alias="itemsView",
description="How much item detail to include for each returned turn; defaults to summary.",
),
] = None
limit: Annotated[int | None, Field(description="Optional turn page size.", ge=0)] = None
sort_direction: Annotated[
SortDirection | None,
Field(
alias="sortDirection",
description="Optional turn pagination direction; defaults to descending.",
),
] = None
class ThreadSettings(BaseModel):
model_config = ConfigDict(
populate_by_name=True,
)
active_permission_profile: Annotated[
ActivePermissionProfile | None, Field(alias="activePermissionProfile")
] = None
approval_policy: Annotated[AskForApproval, Field(alias="approvalPolicy")]
approvals_reviewer: Annotated[ApprovalsReviewer, Field(alias="approvalsReviewer")]
collaboration_mode: Annotated[CollaborationMode, Field(alias="collaborationMode")]
cwd: AbsolutePathBuf
effort: ReasoningEffort | None = None
model: str
model_provider: Annotated[str, Field(alias="modelProvider")]
personality: Personality | None = None
sandbox_policy: Annotated[SandboxPolicy, Field(alias="sandboxPolicy")]
service_tier: Annotated[str | None, Field(alias="serviceTier")] = None
summary: ReasoningSummary | None = None
class ThreadSettingsUpdatedNotification(BaseModel):
model_config = ConfigDict(
populate_by_name=True,
)
thread_id: Annotated[str, Field(alias="threadId")]
thread_settings: Annotated[ThreadSettings, Field(alias="threadSettings")]
class ThreadStartParams(BaseModel):
model_config = ConfigDict(
populate_by_name=True,
@@ -6648,6 +6914,7 @@ class TurnStartParams(BaseModel):
description="Override where approval requests are routed for review on this turn and subsequent turns.",
),
] = None
client_user_message_id: Annotated[str | None, Field(alias="clientUserMessageId")] = None
cwd: Annotated[
str | None,
Field(description="Override the working directory for this turn and subsequent turns."),
@@ -6696,6 +6963,7 @@ class TurnSteerParams(BaseModel):
model_config = ConfigDict(
populate_by_name=True,
)
client_user_message_id: Annotated[str | None, Field(alias="clientUserMessageId")] = None
expected_turn_id: Annotated[
str,
Field(
@@ -6803,6 +7071,15 @@ class ThreadForkRequest(BaseModel):
params: ThreadForkParams
class ThreadGoalSetRequest(BaseModel):
model_config = ConfigDict(
populate_by_name=True,
)
id: RequestId
method: Annotated[Literal["thread/goal/set"], Field(title="Thread/goal/setRequestMethod")]
params: ThreadGoalSetParams
class ThreadListRequest(BaseModel):
model_config = ConfigDict(
populate_by_name=True,
@@ -6891,6 +7168,41 @@ class ConfigValueWriteRequest(BaseModel):
params: ConfigValueWriteParams
class Config(BaseModel):
model_config = ConfigDict(
extra="allow",
populate_by_name=True,
)
analytics: AnalyticsConfig | None = None
approval_policy: AskForApproval | None = None
approvals_reviewer: Annotated[
ApprovalsReviewer | None,
Field(
description="[UNSTABLE] Optional default for where approval requests are routed for review."
),
] = None
compact_prompt: str | None = None
desktop: dict[str, Any] | None = None
developer_instructions: str | None = None
forced_chatgpt_workspace_id: ForcedChatgptWorkspaceIds | None = None
forced_login_method: ForcedLoginMethod | None = None
instructions: str | None = None
model: str | None = None
model_auto_compact_token_limit: int | None = None
model_auto_compact_token_limit_scope: AutoCompactTokenLimitScope | None = None
model_context_window: int | None = None
model_provider: str | None = None
model_reasoning_effort: ReasoningEffort | None = None
model_reasoning_summary: ReasoningSummary | None = None
model_verbosity: Verbosity | None = None
review_model: str | None = None
sandbox_mode: SandboxMode | None = None
sandbox_workspace_write: SandboxWorkspaceWrite | None = None
service_tier: str | None = None
tools: ToolsV2 | None = None
web_search: WebSearchMode | None = None
class ConfigBatchWriteParams(BaseModel):
model_config = ConfigDict(
populate_by_name=True,
@@ -6913,6 +7225,15 @@ class ConfigBatchWriteParams(BaseModel):
] = None
class ConfigReadResponse(BaseModel):
model_config = ConfigDict(
populate_by_name=True,
)
config: Config
layers: list[ConfigLayer] | None = None
origins: dict[str, ConfigLayerMetadata]
class ConfigWriteResponse(BaseModel):
model_config = ConfigDict(
populate_by_name=True,
@@ -7115,29 +7436,6 @@ class PluginSummary(BaseModel):
source: PluginSource
class ProfileV2(BaseModel):
model_config = ConfigDict(
extra="allow",
populate_by_name=True,
)
approval_policy: AskForApproval | None = None
approvals_reviewer: Annotated[
ApprovalsReviewer | None,
Field(
description="[UNSTABLE] Optional profile-level override for where approval requests are routed for review. If omitted, the enclosing config default is used."
),
] = None
chatgpt_base_url: str | None = None
model: str | None = None
model_provider: str | None = None
model_reasoning_effort: ReasoningEffort | None = None
model_reasoning_summary: ReasoningSummary | None = None
model_verbosity: Verbosity | None = None
service_tier: str | None = None
tools: ToolsV2 | None = None
web_search: WebSearchMode | None = None
class RequestPermissionProfile(BaseModel):
model_config = ConfigDict(
extra="forbid",
@@ -7229,6 +7527,16 @@ class ThreadGoalUpdatedServerNotification(BaseModel):
params: ThreadGoalUpdatedNotification
class ThreadSettingsUpdatedServerNotification(BaseModel):
model_config = ConfigDict(
populate_by_name=True,
)
method: Annotated[
Literal["thread/settings/updated"], Field(title="Thread/settings/updatedNotificationMethod")
]
params: ThreadSettingsUpdatedNotification
class ThreadTokenUsageUpdatedServerNotification(BaseModel):
model_config = ConfigDict(
populate_by_name=True,
@@ -7393,6 +7701,15 @@ class TurnStartedNotification(BaseModel):
turn: Turn
class TurnsPage(BaseModel):
model_config = ConfigDict(
populate_by_name=True,
)
backwards_cursor: Annotated[str | None, Field(alias="backwardsCursor")] = None
data: list[Turn]
next_cursor: Annotated[str | None, Field(alias="nextCursor")] = None
class PluginShareSaveRequest(BaseModel):
model_config = ConfigDict(
populate_by_name=True,
@@ -7411,51 +7728,6 @@ class ConfigBatchWriteRequest(BaseModel):
params: ConfigBatchWriteParams
class Config(BaseModel):
model_config = ConfigDict(
extra="allow",
populate_by_name=True,
)
analytics: AnalyticsConfig | None = None
approval_policy: AskForApproval | None = None
approvals_reviewer: Annotated[
ApprovalsReviewer | None,
Field(
description="[UNSTABLE] Optional default for where approval requests are routed for review."
),
] = None
compact_prompt: str | None = None
desktop: dict[str, Any] | None = None
developer_instructions: str | None = None
forced_chatgpt_workspace_id: ForcedChatgptWorkspaceIds | None = None
forced_login_method: ForcedLoginMethod | None = None
instructions: str | None = None
model: str | None = None
model_auto_compact_token_limit: int | None = None
model_context_window: int | None = None
model_provider: str | None = None
model_reasoning_effort: ReasoningEffort | None = None
model_reasoning_summary: ReasoningSummary | None = None
model_verbosity: Verbosity | None = None
profile: str | None = None
profiles: dict[str, ProfileV2] | None = {}
review_model: str | None = None
sandbox_mode: SandboxMode | None = None
sandbox_workspace_write: SandboxWorkspaceWrite | None = None
service_tier: str | None = None
tools: ToolsV2 | None = None
web_search: WebSearchMode | None = None
class ConfigReadResponse(BaseModel):
model_config = ConfigDict(
populate_by_name=True,
)
config: Config
layers: list[ConfigLayer] | None = None
origins: dict[str, ConfigLayerMetadata]
class ExternalAgentConfigDetectResponse(BaseModel):
model_config = ConfigDict(
populate_by_name=True,
@@ -7892,6 +8164,14 @@ class ThreadRollbackResponse(BaseModel):
]
class ThreadSearchResult(BaseModel):
model_config = ConfigDict(
populate_by_name=True,
)
snippet: str
thread: Thread
class ThreadStartResponse(BaseModel):
model_config = ConfigDict(
populate_by_name=True,
@@ -7960,6 +8240,9 @@ class ClientRequest(
| ThreadArchiveRequest
| ThreadUnsubscribeRequest
| ThreadNameSetRequest
| ThreadGoalSetRequest
| ThreadGoalGetRequest
| ThreadGoalClearRequest
| ThreadMetadataUpdateRequest
| ThreadUnarchiveRequest
| ThreadCompactStartRequest
@@ -7971,6 +8254,7 @@ class ClientRequest(
| ThreadReadRequest
| ThreadInjectItemsRequest
| SkillsListRequest
| SkillsExtraRootsSetRequest
| HooksListRequest
| MarketplaceAddRequest
| MarketplaceRemoveRequest
@@ -8004,6 +8288,7 @@ class ClientRequest(
| ModelListRequest
| ModelProviderCapabilitiesReadRequest
| ExperimentalFeatureListRequest
| PermissionProfileListRequest
| ExperimentalFeatureEnablementSetRequest
| McpServerOauthLoginRequest
| ConfigMcpServerReloadRequest
@@ -8043,6 +8328,9 @@ class ClientRequest(
| ThreadArchiveRequest
| ThreadUnsubscribeRequest
| ThreadNameSetRequest
| ThreadGoalSetRequest
| ThreadGoalGetRequest
| ThreadGoalClearRequest
| ThreadMetadataUpdateRequest
| ThreadUnarchiveRequest
| ThreadCompactStartRequest
@@ -8054,6 +8342,7 @@ class ClientRequest(
| ThreadReadRequest
| ThreadInjectItemsRequest
| SkillsListRequest
| SkillsExtraRootsSetRequest
| HooksListRequest
| MarketplaceAddRequest
| MarketplaceRemoveRequest
@@ -8087,6 +8376,7 @@ class ClientRequest(
| ModelListRequest
| ModelProviderCapabilitiesReadRequest
| ExperimentalFeatureListRequest
| PermissionProfileListRequest
| ExperimentalFeatureEnablementSetRequest
| McpServerOauthLoginRequest
| ConfigMcpServerReloadRequest
@@ -8158,6 +8448,7 @@ class ServerNotification(
| ThreadNameUpdatedServerNotification
| ThreadGoalUpdatedServerNotification
| ThreadGoalClearedServerNotification
| ThreadSettingsUpdatedServerNotification
| ThreadTokenUsageUpdatedServerNotification
| TurnStartedServerNotification
| HookStartedServerNotification
@@ -8227,6 +8518,7 @@ class ServerNotification(
| ThreadNameUpdatedServerNotification
| ThreadGoalUpdatedServerNotification
| ThreadGoalClearedServerNotification
| ThreadSettingsUpdatedServerNotification
| ThreadTokenUsageUpdatedServerNotification
| TurnStartedServerNotification
| HookStartedServerNotification
@@ -265,8 +265,9 @@ def test_schema_normalization_only_flattens_string_literal_oneofs(
"AuthMode",
"InputModality",
"ExperimentalFeatureStage",
"ProcessOutputStream",
"AutoCompactTokenLimitScope",
"CommandExecOutputStream",
"ProcessOutputStream",
]
@@ -357,10 +358,10 @@ def test_source_sdk_template_pins_published_runtime() -> None:
"dependencies": pyproject["project"]["dependencies"],
} == {
"sdk_template_version": "0.0.0-dev",
"runtime_pin": "0.132.0",
"runtime_pin": "0.136.0",
"dependencies": [
"pydantic>=2.12",
"openai-codex-cli-bin==0.132.0",
"openai-codex-cli-bin==0.136.0",
],
}
@@ -435,7 +436,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.132.0",
"runtime_pin": "0.136.0",
"normalized_release_version": "0.116.0a1",
"release_tag": "rust-v0.116.0-alpha.1",
}
@@ -594,11 +595,11 @@ def test_stage_runtime_release_can_pin_wheel_platform_tag(tmp_path: Path) -> Non
tmp_path / "runtime-stage",
"0.116.0a1",
package_archive,
platform_tag="musllinux_1_1_x86_64",
platform_tag="manylinux_2_17_x86_64",
)
pyproject = (staged / "pyproject.toml").read_text()
assert 'platform-tag = "musllinux_1_1_x86_64"' in pyproject
assert 'platform-tag = "manylinux_2_17_x86_64"' in pyproject
def test_stage_runtime_release_rejects_incomplete_package_layout(tmp_path: Path) -> None:
@@ -650,7 +651,7 @@ def test_stage_sdk_release_preserves_reviewed_runtime_pin(tmp_path: Path) -> Non
"version": "0.1.0b1",
"dependencies": [
"pydantic>=2.12",
"openai-codex-cli-bin==0.132.0",
"openai-codex-cli-bin==0.136.0",
],
}
assert (
@@ -687,7 +688,7 @@ def test_sdk_beta_release_can_pin_stable_runtime(tmp_path: Path) -> None:
)
runtime_stage = script.stage_python_runtime_package(
tmp_path / "runtime-stage",
"0.132.0",
"0.136.0",
package_archive,
)
@@ -700,10 +701,10 @@ def test_sdk_beta_release_can_pin_stable_runtime(tmp_path: Path) -> None:
"sdk_dependencies": sdk_pyproject["project"]["dependencies"],
} == {
"sdk_version": "0.1.0b1",
"runtime_version": "0.132.0",
"runtime_version": "0.136.0",
"sdk_dependencies": [
"pydantic>=2.12",
"openai-codex-cli-bin==0.132.0",
"openai-codex-cli-bin==0.136.0",
],
}
@@ -762,7 +763,7 @@ def test_stage_runtime_stages_package_without_type_generation(tmp_path: Path) ->
"--codex-version",
"rust-v0.116.0-alpha.1",
"--platform-tag",
"musllinux_1_1_x86_64",
"manylinux_2_17_x86_64",
]
)
@@ -793,7 +794,7 @@ def test_stage_runtime_stages_package_without_type_generation(tmp_path: Path) ->
script.run_command(args, ops)
assert calls == ["stage_runtime:0.116.0a1:musllinux_1_1_x86_64:codex-package.tar.gz"]
assert calls == ["stage_runtime:0.116.0a1:manylinux_2_17_x86_64:codex-package.tar.gz"]
def test_default_runtime_is_resolved_from_installed_runtime_package(
+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.132.0"
assert importlib.metadata.version("openai-codex-cli-bin") == "0.136.0"
env = os.environ.copy()
env.pop("CODEX_EXEC_PATH", None)
python_bin = str(Path(sys.executable).parent)
+9 -9
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-05-20T21:00:00Z"
openai-codex-cli-bin = "2026-06-01T20:00:00Z"
[[package]]
name = "annotated-types"
@@ -299,7 +299,7 @@ dev = [
[package.metadata]
requires-dist = [
{ name = "datamodel-code-generator", marker = "extra == 'dev'", specifier = "==0.31.2" },
{ name = "openai-codex-cli-bin", specifier = "==0.132.0" },
{ name = "openai-codex-cli-bin", specifier = "==0.136.0" },
{ name = "pydantic", specifier = ">=2.12" },
{ name = "pytest", marker = "extra == 'dev'", specifier = ">=8.0" },
{ name = "ruff", marker = "extra == 'dev'", specifier = ">=0.15.8" },
@@ -308,15 +308,15 @@ provides-extras = ["dev"]
[[package]]
name = "openai-codex-cli-bin"
version = "0.132.0"
version = "0.136.0"
source = { registry = "https://pypi.org/simple" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/be/a1/b92b7a1b73a83785d2e1dcd0faecd1b7f886a38cf02a30abe1c35f42f0f7/openai_codex_cli_bin-0.132.0-py3-none-macosx_10_9_x86_64.whl", hash = "sha256:1c22b51dbd679413f84f00b9d8fd4e5cf8a1c0d1c7cc8c42bcb3f9f1b33e2334", size = 89403211, upload-time = "2026-05-20T02:37:22.311Z" },
{ url = "https://files.pythonhosted.org/packages/5f/68/163272e582de55a7f460e2329281267908d75d0fbcbbbb2c6749a6329e6b/openai_codex_cli_bin-0.132.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:56217495e6635c8a5d96df820cc0da5f46cd9b6ec6f3a5f67f1607d69ef74256", size = 79058685, upload-time = "2026-05-20T02:37:27.165Z" },
{ url = "https://files.pythonhosted.org/packages/0b/18/a60c6b137e7cd3959cae16ba757f57ca5702979b0ea107a21f516ba15d98/openai_codex_cli_bin-0.132.0-py3-none-musllinux_1_1_aarch64.whl", hash = "sha256:09642e7578a3078bfccc82af4077b085d42b0022b529e4b5c645e0a0af3397a4", size = 78689038, upload-time = "2026-05-20T02:37:31.548Z" },
{ url = "https://files.pythonhosted.org/packages/f8/eb/1b184307a67c1006d59b61636bcfcea73a89aa95271f6516ed28dce554ca/openai_codex_cli_bin-0.132.0-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:85aec095f9d144d7a2d1aff39fce77b7240f42014580c35801ba74b9317aa5f7", size = 85528820, upload-time = "2026-05-20T02:37:36.559Z" },
{ url = "https://files.pythonhosted.org/packages/0e/e8/1b823a8bf7b96d1513905ad79b16a146d797f81a19a6bc350a2f95a16661/openai_codex_cli_bin-0.132.0-py3-none-win_amd64.whl", hash = "sha256:3cb5c90c55baa39bd5ddc890d2068d3e1322a57a54d1d0e623819009a205c7f5", size = 86916218, upload-time = "2026-05-20T02:37:41.886Z" },
{ url = "https://files.pythonhosted.org/packages/6b/e6/bb8634bd4f3adaea299c95d7b03105ac417e32dd6d8bc2af5dda141d6f28/openai_codex_cli_bin-0.132.0-py3-none-win_arm64.whl", hash = "sha256:74ef93d3deef7cb83c71d19fc667defe749cdab337ec331f59a23511561b6f6a", size = 79892931, upload-time = "2026-05-20T02:37:46.828Z" },
{ url = "https://files.pythonhosted.org/packages/45/2e/09764338fcb104ebcb1ebf2490d71ab4b8339b5d6f8bdce19480adad5a99/openai_codex_cli_bin-0.136.0-py3-none-macosx_10_9_x86_64.whl", hash = "sha256:9ded24a9977221f67173f49b8c3ba3a944787b7323dbd664dd8e8ae1a5efc0aa", size = 94036262, upload-time = "2026-06-01T19:28:13.291Z" },
{ url = "https://files.pythonhosted.org/packages/44/46/10dea458f8ead97b6449a1c05b65883ffe28724204c05e6169439576ee48/openai_codex_cli_bin-0.136.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:8d194688c1afe87bf85705528cbcbdb762cb378d8c58c64162402babbd795436", size = 83713829, upload-time = "2026-06-01T19:28:17.39Z" },
{ url = "https://files.pythonhosted.org/packages/7d/83/21402a805f3312196a4f4bef0b6a45d3dee301e3db3ddeee117b4b1e612b/openai_codex_cli_bin-0.136.0-py3-none-manylinux_2_17_aarch64.whl", hash = "sha256:bdbdfeeac5bb2e744bd810cb60c55313c280d0f6ff9e93699431bcfc2040c9c2", size = 82981863, upload-time = "2026-06-01T19:28:21.246Z" },
{ url = "https://files.pythonhosted.org/packages/33/79/1617e008381345391def39254404c0248a425739bd13c95d9fbe3e63d16f/openai_codex_cli_bin-0.136.0-py3-none-manylinux_2_17_x86_64.whl", hash = "sha256:37b353435f354c6d1bcc32e3b83e40ef9d1ef7294c8adedd229fbaedc82a6f74", size = 90187224, upload-time = "2026-06-01T19:28:24.89Z" },
{ url = "https://files.pythonhosted.org/packages/f4/bc/a591d4464f999e0fab6abb5ba369463eee99a82e7c298e2cff257d80b849/openai_codex_cli_bin-0.136.0-py3-none-win_amd64.whl", hash = "sha256:c91ffbb1d903970e74b65958f7d1fa548fac8abdfe9b3a098f3da7f47dbb2575", size = 91137642, upload-time = "2026-06-01T19:28:28.512Z" },
{ url = "https://files.pythonhosted.org/packages/89/f3/e8ccd644e7a87a25229022088abf4d724d3d608fcda7123f9a11515409ca/openai_codex_cli_bin-0.136.0-py3-none-win_arm64.whl", hash = "sha256:9073f7283c47ad3e585e23598ebbef554e85d280cabb637b6cb9a078c5e7086a", size = 83623904, upload-time = "2026-06-01T19:28:32.734Z" },
]
[[package]]