openai-codex-sdk: FileChangeItem.status Literal rejects 'in_progress' from streaming patch updates
Summary
openai-codex-sdk==0.1.11 crashes when consuming the streamed event loop on any agent-mode run that uses the patch/edit tool on a non-trivial file. The Codex CLI emits FileChangeItem payloads with status=\"in_progress\" while a patch is being applied, but the SDK's Pydantic model only allows \"completed\" or \"failed\". Pydantic raises ValidationError inside the async iterator, terminating the stream before any file changes reach the caller.
Version / environment
openai-codex-sdk==0.1.11- Python 3.12, Linux (WSL2)
- pydantic 2.x
Repro
Any agent-mode call where the model edits a file. Minimal pseudo-repro:
from openai_codex_sdk import Codex
codex = Codex()
thread = codex.start_thread({\"model\": \"gpt-5.4\", \"sandbox_mode\": \"workspace-write\", \"working_directory\": \"/tmp/scratch\"})
streamed = await thread.run_streamed(\"Create hello.py with print('hi')\")
async for event in streamed.events: # raises ValidationError on first patch update
...
Error
1 validation error for FileChangeItem
status
Input should be 'completed' or 'failed' [type=literal_error, input_value='in_progress', input_type=str]
For further information visit https://errors.pydantic.dev/2.13/v/literal_error
Root cause
openai_codex_sdk/types.py:
# line 108
PatchApplyStatus = Literal[\"completed\", \"failed\"]
# line 111
class FileChangeItem(BaseModel):
...
status: PatchApplyStatus # line 117
CommandExecutionStatus already includes intermediate states; PatchApplyStatus is the outlier.
Suggested fix
PatchApplyStatus = Literal[\"in_progress\", \"completed\", \"failed\"]
(Or whatever the canonical set of states the CLI emits for apply_patch updates is — happy to PR if the maintainers confirm the desired set.)
Workaround
Monkey-patch and rebuild the model before opening a thread:
from typing import Literal
from openai_codex_sdk import types as _t
_t.PatchApplyStatus = Literal[\"in_progress\", \"completed\", \"failed\"]
_t.FileChangeItem.model_fields[\"status\"].annotation = _t.PatchApplyStatus
_t.FileChangeItem.model_rebuild(force=True)This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗