codex-sdk-python 0.104.0__tar.gz → 0.105.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {codex_sdk_python-0.104.0 → codex_sdk_python-0.105.0}/PKG-INFO +108 -23
- {codex_sdk_python-0.104.0 → codex_sdk_python-0.105.0}/README.md +107 -22
- {codex_sdk_python-0.104.0 → codex_sdk_python-0.105.0}/pyproject.toml +2 -2
- {codex_sdk_python-0.104.0 → codex_sdk_python-0.105.0}/src/codex_sdk/__init__.py +1 -1
- codex_sdk_python-0.105.0/src/codex_sdk/integrations/pydantic_ai_model.py +1228 -0
- codex_sdk_python-0.104.0/src/codex_sdk/integrations/pydantic_ai_model.py +0 -655
- {codex_sdk_python-0.104.0 → codex_sdk_python-0.105.0}/src/codex_sdk/abort.py +0 -0
- {codex_sdk_python-0.104.0 → codex_sdk_python-0.105.0}/src/codex_sdk/app_server.py +0 -0
- {codex_sdk_python-0.104.0 → codex_sdk_python-0.105.0}/src/codex_sdk/codex.py +0 -0
- {codex_sdk_python-0.104.0 → codex_sdk_python-0.105.0}/src/codex_sdk/config_overrides.py +0 -0
- {codex_sdk_python-0.104.0 → codex_sdk_python-0.105.0}/src/codex_sdk/events.py +0 -0
- {codex_sdk_python-0.104.0 → codex_sdk_python-0.105.0}/src/codex_sdk/exceptions.py +0 -0
- {codex_sdk_python-0.104.0 → codex_sdk_python-0.105.0}/src/codex_sdk/exec.py +0 -0
- {codex_sdk_python-0.104.0 → codex_sdk_python-0.105.0}/src/codex_sdk/hooks.py +0 -0
- {codex_sdk_python-0.104.0 → codex_sdk_python-0.105.0}/src/codex_sdk/integrations/__init__.py +0 -0
- {codex_sdk_python-0.104.0 → codex_sdk_python-0.105.0}/src/codex_sdk/integrations/pydantic_ai.py +0 -0
- {codex_sdk_python-0.104.0 → codex_sdk_python-0.105.0}/src/codex_sdk/items.py +0 -0
- {codex_sdk_python-0.104.0 → codex_sdk_python-0.105.0}/src/codex_sdk/options.py +0 -0
- {codex_sdk_python-0.104.0 → codex_sdk_python-0.105.0}/src/codex_sdk/telemetry.py +0 -0
- {codex_sdk_python-0.104.0 → codex_sdk_python-0.105.0}/src/codex_sdk/thread.py +0 -0
- {codex_sdk_python-0.104.0 → codex_sdk_python-0.105.0}/src/codex_sdk/tool_envelope.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: codex-sdk-python
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.105.0
|
|
4
4
|
Summary: Python SDK for the Codex CLI agent with async threads, streaming events, and structured outputs
|
|
5
5
|
Keywords: codex,sdk,python,api,cli,agent,async,streaming
|
|
6
6
|
Author: Vectorfy Co
|
|
@@ -44,7 +44,7 @@ Embed the Codex agent in Python workflows. This SDK wraps the bundled `codex` CL
|
|
|
44
44
|
<td><strong>Lifecycle</strong></td>
|
|
45
45
|
<td>
|
|
46
46
|
<a href="#ci-cd"><img src="https://img.shields.io/badge/CI%2FCD-Active-16a34a?style=flat&logo=githubactions&logoColor=white" alt="CI/CD badge" /></a>
|
|
47
|
-
<img src="https://img.shields.io/badge/Release-0.
|
|
47
|
+
<img src="https://img.shields.io/badge/Release-0.105.0-6b7280?style=flat&logo=pypi&logoColor=white" alt="Release 0.105.0 badge" />
|
|
48
48
|
<a href="#license"><img src="https://img.shields.io/badge/License-Apache--2.0-0f766e?style=flat&logo=apache&logoColor=white" alt="License badge" /></a>
|
|
49
49
|
</td>
|
|
50
50
|
</tr>
|
|
@@ -73,7 +73,7 @@ Embed the Codex agent in Python workflows. This SDK wraps the bundled `codex` CL
|
|
|
73
73
|
</div>
|
|
74
74
|
|
|
75
75
|
- Runtime dependency-free: uses only the Python standard library.
|
|
76
|
-
- Codex CLI binaries
|
|
76
|
+
- Codex CLI binaries can be sourced either from the vendored `src/codex_sdk/vendor/` tree (when present) or from a system-installed `codex` binary (`codex_path_override` supported).
|
|
77
77
|
- Async-first API with sync helpers, streaming events, and structured output.
|
|
78
78
|
- Python 3.8/3.9 support is deprecated and will be removed in a future release; use Python 3.10+.
|
|
79
79
|
|
|
@@ -168,6 +168,8 @@ python examples/app_server_turn_session.py
|
|
|
168
168
|
python examples/config_overrides.py
|
|
169
169
|
python examples/hooks_streaming.py
|
|
170
170
|
python examples/notify_hook.py
|
|
171
|
+
python examples/pydantic_ai_run_compat.py
|
|
172
|
+
python examples/pydantic_ai_run_stream_compat.py
|
|
171
173
|
```
|
|
172
174
|
|
|
173
175
|
<a id="features"></a>
|
|
@@ -185,6 +187,15 @@ python examples/notify_hook.py
|
|
|
185
187
|
|  | Cancel running turns via `AbortController` and `AbortSignal`. |
|
|
186
188
|
|  | Optional spans if Logfire is installed and initialized. |
|
|
187
189
|
|
|
190
|
+
### Execution surfaces and transports
|
|
191
|
+
|
|
192
|
+
| Surface | Primary transport | Typical use |
|
|
193
|
+
| ------- | ----------------- | ----------- |
|
|
194
|
+
| `Codex` + `Thread` | `codex exec --experimental-json` (JSONL over stdio) | Conversational turns, streaming item events, structured output (`run_json` / `run_pydantic`). |
|
|
195
|
+
| `AppServerClient` | `codex app-server` (JSON-RPC over stdio) | Full app-server protocol: thread management, turn sessions, approvals, account/config/skills APIs. |
|
|
196
|
+
| `CodexModel` (PydanticAI provider) | `codex app-server` (JSON-RPC over stdio) | Tool-call planning + text generation through app-server turn sessions with incremental stream events. |
|
|
197
|
+
| `codex_handoff_tool` (PydanticAI tool) | `Thread.run(...)` on top of `codex exec` | Delegate repository-aware tasks from another model to Codex. |
|
|
198
|
+
|
|
188
199
|
<a id="configuration"></a>
|
|
189
200
|
## 
|
|
190
201
|
|
|
@@ -312,6 +323,10 @@ For richer integrations (thread fork, requirements, explicit skill input), use t
|
|
|
312
323
|
protocol. The client handles the initialize/initialized handshake and gives you access to
|
|
313
324
|
JSON-RPC notifications.
|
|
314
325
|
|
|
326
|
+
`AppServerClient` starts `codex app-server` and multiplexes notifications + server-initiated
|
|
327
|
+
requests (for example approval requests in `turn_session(...)`) on top of the same stdio
|
|
328
|
+
connection.
|
|
329
|
+
|
|
315
330
|
```python
|
|
316
331
|
import asyncio
|
|
317
332
|
from codex_sdk import AppServerClient, AppServerOptions
|
|
@@ -427,6 +442,11 @@ If you are working from source and the vendor directory is missing, run
|
|
|
427
442
|
`python scripts/setup_binary.py` to fetch and assemble the platform `@openai/codex`
|
|
428
443
|
artifacts into `src/codex_sdk/vendor/`.
|
|
429
444
|
|
|
445
|
+
`scripts/setup_binary.py` behavior:
|
|
446
|
+
- Resolves `CODEX_NPM_VERSION` when set; otherwise resolves latest `@openai/codex`.
|
|
447
|
+
- Tries legacy `@openai/codex-sdk` package first, then falls back to per-target `@openai/codex@<version>-<suffix>` artifacts.
|
|
448
|
+
- Rebuilds `src/codex_sdk/vendor/` for all supported targets and validates current-platform binary presence.
|
|
449
|
+
|
|
430
450
|
<a id="auth"></a>
|
|
431
451
|
## 
|
|
432
452
|
|
|
@@ -633,6 +653,8 @@ Example scripts under `examples/`:
|
|
|
633
653
|
- `notify_hook.py`: notify script for CLI callbacks.
|
|
634
654
|
- `pydantic_ai_model_provider.py`: Codex as a PydanticAI model provider.
|
|
635
655
|
- `pydantic_ai_handoff.py`: Codex as a PydanticAI tool.
|
|
656
|
+
- `pydantic_ai_run_compat.py`: minimal compatibility harness for `Agent.run(...)`.
|
|
657
|
+
- `pydantic_ai_run_stream_compat.py`: minimal compatibility harness for `Agent.run_stream(...)`.
|
|
636
658
|
|
|
637
659
|
<a id="sandbox"></a>
|
|
638
660
|
## 
|
|
@@ -655,6 +677,9 @@ Additional controls:
|
|
|
655
677
|
|
|
656
678
|
This SDK offers two ways to integrate with PydanticAI:
|
|
657
679
|
|
|
680
|
+
Note: starting in `0.105.0`, `CodexModel` is app-server-only and no longer supports
|
|
681
|
+
the legacy `CodexModel(codex=...)` fallback path.
|
|
682
|
+
|
|
658
683
|
### 1) Codex as a PydanticAI model provider
|
|
659
684
|
|
|
660
685
|
Use `CodexModel` to delegate tool-call planning and text generation to Codex, while PydanticAI executes tools and validates outputs.
|
|
@@ -682,11 +707,20 @@ print(result.output)
|
|
|
682
707
|
```
|
|
683
708
|
|
|
684
709
|
How it works:
|
|
710
|
+
- `CodexModel` keeps a persistent app-server session and starts/reuses threads based on
|
|
711
|
+
`thread_reuse_mode` (`"run"` by default, `"always"` optional).
|
|
685
712
|
- `CodexModel` builds a JSON schema envelope with `tool_calls` and `final`.
|
|
686
713
|
- Codex emits tool calls as JSON strings; PydanticAI runs them.
|
|
687
714
|
- If `allow_text_output` is true, Codex can place final text in `final`.
|
|
688
|
-
- Streaming APIs
|
|
689
|
-
|
|
715
|
+
- Streaming APIs emit incremental events while app-server turn notifications arrive.
|
|
716
|
+
|
|
717
|
+
Provider options:
|
|
718
|
+
- `performance_profile`: `"balanced"` (default) or `"max"`.
|
|
719
|
+
- `thread_reuse_mode`: `"run"` (default) or `"always"`.
|
|
720
|
+
|
|
721
|
+
Lifecycle:
|
|
722
|
+
- `CodexModel` owns an app-server client by default; call `await model.close()` in
|
|
723
|
+
long-lived processes to release resources.
|
|
690
724
|
|
|
691
725
|
Safety defaults (you can override with your own `ThreadOptions`):
|
|
692
726
|
- `sandbox_mode="read-only"`
|
|
@@ -749,38 +783,49 @@ If `logfire` is installed and initialized, the SDK emits spans:
|
|
|
749
783
|
If Logfire is missing or not initialized, the span context manager is a no-op.
|
|
750
784
|
|
|
751
785
|
<a id="architecture"></a>
|
|
752
|
-
<a id="acheature"></a>
|
|
753
786
|
## 
|
|
754
787
|
|
|
755
|
-
### System components
|
|
788
|
+
### System components and transport paths
|
|
756
789
|
|
|
757
790
|
```mermaid
|
|
758
791
|
flowchart LR
|
|
759
792
|
subgraph App[Your Python App]
|
|
760
793
|
U[User Code]
|
|
761
|
-
T[Thread API]
|
|
794
|
+
T[Codex + Thread API]
|
|
795
|
+
A[AppServerClient API]
|
|
796
|
+
PM[PydanticAI CodexModel]
|
|
797
|
+
PH[PydanticAI codex_handoff_tool]
|
|
762
798
|
end
|
|
763
799
|
|
|
764
800
|
subgraph SDK[Codex SDK]
|
|
765
801
|
C[Codex]
|
|
766
802
|
E[CodexExec]
|
|
767
|
-
P[Event Parser]
|
|
803
|
+
P[Thread Event Parser]
|
|
804
|
+
R[JSON-RPC Client]
|
|
768
805
|
end
|
|
769
806
|
|
|
770
|
-
subgraph CLI[
|
|
807
|
+
subgraph CLI[Codex CLI]
|
|
771
808
|
X["codex exec --experimental-json"]
|
|
809
|
+
S["codex app-server"]
|
|
772
810
|
end
|
|
773
811
|
|
|
774
812
|
FS[(Filesystem)]
|
|
775
813
|
NET[(Network)]
|
|
776
814
|
|
|
777
815
|
U --> T --> C --> E --> X
|
|
816
|
+
U --> A --> R --> S
|
|
817
|
+
U --> PM --> R
|
|
818
|
+
U --> PH --> C
|
|
778
819
|
X -->|JSONL events| P --> T
|
|
820
|
+
S -->|JSON-RPC messages| R --> A
|
|
821
|
+
S -->|JSON-RPC messages| R --> PM
|
|
779
822
|
X --> FS
|
|
780
823
|
X --> NET
|
|
824
|
+
S --> FS
|
|
825
|
+
S --> NET
|
|
781
826
|
```
|
|
782
827
|
|
|
783
|
-
###
|
|
828
|
+
### Thread API streaming lifecycle (`codex exec`)
|
|
784
829
|
|
|
785
830
|
```mermaid
|
|
786
831
|
sequenceDiagram
|
|
@@ -803,21 +848,41 @@ sequenceDiagram
|
|
|
803
848
|
Thread-->>Dev: turn.completed / turn.failed
|
|
804
849
|
```
|
|
805
850
|
|
|
806
|
-
###
|
|
851
|
+
### App-server lifecycle (`codex app-server`)
|
|
852
|
+
|
|
853
|
+
```mermaid
|
|
854
|
+
sequenceDiagram
|
|
855
|
+
participant Dev as Developer
|
|
856
|
+
participant App as AppServerClient
|
|
857
|
+
participant CLI as codex app-server
|
|
858
|
+
|
|
859
|
+
Dev->>App: start()
|
|
860
|
+
App->>CLI: spawn process
|
|
861
|
+
App->>CLI: initialize
|
|
862
|
+
CLI-->>App: initialize result
|
|
863
|
+
App->>CLI: initialized (notification)
|
|
864
|
+
Dev->>App: turn_session(thread_id, input)
|
|
865
|
+
App->>CLI: turn/start
|
|
866
|
+
CLI-->>App: thread/turn/item notifications
|
|
867
|
+
CLI-->>App: request (approval needed)
|
|
868
|
+
App-->>CLI: response (approve/reject)
|
|
869
|
+
CLI-->>App: turn completed notification
|
|
870
|
+
App-->>Dev: final turn payload
|
|
871
|
+
```
|
|
872
|
+
|
|
873
|
+
### PydanticAI model-provider loop (current implementation)
|
|
807
874
|
|
|
808
875
|
```mermaid
|
|
809
876
|
sequenceDiagram
|
|
810
877
|
participant Agent as PydanticAI Agent
|
|
811
878
|
participant Model as CodexModel
|
|
812
|
-
participant
|
|
813
|
-
participant CLI as codex exec
|
|
879
|
+
participant App as Codex app-server
|
|
814
880
|
participant Tools as User Tools
|
|
815
881
|
|
|
816
882
|
Agent->>Model: request(messages, tools)
|
|
817
|
-
Model->>
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
SDK-->>Model: ParsedTurn
|
|
883
|
+
Model->>App: thread/start (if needed)
|
|
884
|
+
Model->>App: turn/session(input + output_schema envelope)
|
|
885
|
+
App-->>Model: item/updated + turn/completed notifications
|
|
821
886
|
alt tool_calls present
|
|
822
887
|
Model-->>Agent: ToolCallPart(s)
|
|
823
888
|
Agent->>Tools: execute tool(s)
|
|
@@ -833,12 +898,18 @@ sequenceDiagram
|
|
|
833
898
|
flowchart LR
|
|
834
899
|
Agent[PydanticAI Agent] --> Tool[codex_handoff_tool]
|
|
835
900
|
Tool --> SDK[Codex SDK Thread]
|
|
836
|
-
SDK --> CLI[
|
|
901
|
+
SDK --> CLI[codex exec]
|
|
837
902
|
CLI --> SDK
|
|
838
903
|
SDK --> Tool
|
|
839
904
|
Tool --> Agent
|
|
840
905
|
```
|
|
841
906
|
|
|
907
|
+
### Streaming semantics summary
|
|
908
|
+
|
|
909
|
+
- `Thread.run_streamed()` and `Thread.run_streamed_events()` stream incremental `ThreadEvent` values as JSONL lines arrive from `codex exec`.
|
|
910
|
+
- `AppServerClient.notifications()` streams incremental JSON-RPC notifications from `codex app-server`.
|
|
911
|
+
- `CodexModel.request_stream(...)` emits incremental events from app-server turn notifications, with compatibility handling for current and legacy PydanticAI stream interfaces.
|
|
912
|
+
|
|
842
913
|
<a id="testing"></a>
|
|
843
914
|
## 
|
|
844
915
|
|
|
@@ -847,9 +918,12 @@ This repo uses unit tests with mocked CLI processes to keep the test suite fast
|
|
|
847
918
|
Test focus areas:
|
|
848
919
|
- `tests/test_exec.py`: CLI invocation, environment handling, config flags, abort behavior.
|
|
849
920
|
- `tests/test_thread.py`: parsing, streaming, JSON schema, Pydantic validation, input normalization.
|
|
921
|
+
- `tests/test_app_server.py` and `tests/test_app_server_session.py`: JSON-RPC lifecycle, method wrappers, turn-session approvals/notifications.
|
|
850
922
|
- `tests/test_codex.py`: resume helpers and option wiring.
|
|
923
|
+
- `tests/test_config_overrides.py`: `--config` serialization and merge behavior.
|
|
851
924
|
- `tests/test_abort.py`: abort signal semantics.
|
|
852
925
|
- `tests/test_telemetry.py`: Logfire span behavior.
|
|
926
|
+
- `tests/test_tool_envelope.py`: tool envelope parsing and schema normalization helpers.
|
|
853
927
|
- `tests/test_pydantic_ai_*`: PydanticAI model provider and handoff integration.
|
|
854
928
|
|
|
855
929
|
### Run tests
|
|
@@ -891,10 +965,21 @@ uv run mypy src
|
|
|
891
965
|
## 
|
|
892
966
|
|
|
893
967
|
This repository includes GitHub Actions workflows under `.github/workflows/`.
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
`
|
|
897
|
-
|
|
968
|
+
|
|
969
|
+
Current workflows:
|
|
970
|
+
- `ci.yml`: lint (`black`, `isort`, `flake8`), type-check (`mypy`), and tests (`pytest --cov=codex_sdk`) on Python 3.10/3.11/3.12.
|
|
971
|
+
- `release.yml`: extracts release notes from `CHANGELOG_SDK.md` and creates a GitHub Release for `vX.Y.Z`.
|
|
972
|
+
- `publish.yml`: builds (`uv build --no-sources`) and publishes to PyPI on release publish (or successful release workflow).
|
|
973
|
+
- `docs-deploy.yml`: optional docs deployment (gated by `DOCS_DEPLOY_ENABLED`).
|
|
974
|
+
- `uv-lock-update.yml`: scheduled weekly lockfile refresh PR.
|
|
975
|
+
|
|
976
|
+
`ci.yml` test jobs install Node.js and run:
|
|
977
|
+
|
|
978
|
+
```bash
|
|
979
|
+
python scripts/setup_binary.py
|
|
980
|
+
```
|
|
981
|
+
|
|
982
|
+
before `pytest`, so test runs do not depend on committed vendor binary updates.
|
|
898
983
|
|
|
899
984
|
<a id="operations"></a>
|
|
900
985
|
## 
|
|
@@ -8,7 +8,7 @@ Embed the Codex agent in Python workflows. This SDK wraps the bundled `codex` CL
|
|
|
8
8
|
<td><strong>Lifecycle</strong></td>
|
|
9
9
|
<td>
|
|
10
10
|
<a href="#ci-cd"><img src="https://img.shields.io/badge/CI%2FCD-Active-16a34a?style=flat&logo=githubactions&logoColor=white" alt="CI/CD badge" /></a>
|
|
11
|
-
<img src="https://img.shields.io/badge/Release-0.
|
|
11
|
+
<img src="https://img.shields.io/badge/Release-0.105.0-6b7280?style=flat&logo=pypi&logoColor=white" alt="Release 0.105.0 badge" />
|
|
12
12
|
<a href="#license"><img src="https://img.shields.io/badge/License-Apache--2.0-0f766e?style=flat&logo=apache&logoColor=white" alt="License badge" /></a>
|
|
13
13
|
</td>
|
|
14
14
|
</tr>
|
|
@@ -37,7 +37,7 @@ Embed the Codex agent in Python workflows. This SDK wraps the bundled `codex` CL
|
|
|
37
37
|
</div>
|
|
38
38
|
|
|
39
39
|
- Runtime dependency-free: uses only the Python standard library.
|
|
40
|
-
- Codex CLI binaries
|
|
40
|
+
- Codex CLI binaries can be sourced either from the vendored `src/codex_sdk/vendor/` tree (when present) or from a system-installed `codex` binary (`codex_path_override` supported).
|
|
41
41
|
- Async-first API with sync helpers, streaming events, and structured output.
|
|
42
42
|
- Python 3.8/3.9 support is deprecated and will be removed in a future release; use Python 3.10+.
|
|
43
43
|
|
|
@@ -132,6 +132,8 @@ python examples/app_server_turn_session.py
|
|
|
132
132
|
python examples/config_overrides.py
|
|
133
133
|
python examples/hooks_streaming.py
|
|
134
134
|
python examples/notify_hook.py
|
|
135
|
+
python examples/pydantic_ai_run_compat.py
|
|
136
|
+
python examples/pydantic_ai_run_stream_compat.py
|
|
135
137
|
```
|
|
136
138
|
|
|
137
139
|
<a id="features"></a>
|
|
@@ -149,6 +151,15 @@ python examples/notify_hook.py
|
|
|
149
151
|
|  | Cancel running turns via `AbortController` and `AbortSignal`. |
|
|
150
152
|
|  | Optional spans if Logfire is installed and initialized. |
|
|
151
153
|
|
|
154
|
+
### Execution surfaces and transports
|
|
155
|
+
|
|
156
|
+
| Surface | Primary transport | Typical use |
|
|
157
|
+
| ------- | ----------------- | ----------- |
|
|
158
|
+
| `Codex` + `Thread` | `codex exec --experimental-json` (JSONL over stdio) | Conversational turns, streaming item events, structured output (`run_json` / `run_pydantic`). |
|
|
159
|
+
| `AppServerClient` | `codex app-server` (JSON-RPC over stdio) | Full app-server protocol: thread management, turn sessions, approvals, account/config/skills APIs. |
|
|
160
|
+
| `CodexModel` (PydanticAI provider) | `codex app-server` (JSON-RPC over stdio) | Tool-call planning + text generation through app-server turn sessions with incremental stream events. |
|
|
161
|
+
| `codex_handoff_tool` (PydanticAI tool) | `Thread.run(...)` on top of `codex exec` | Delegate repository-aware tasks from another model to Codex. |
|
|
162
|
+
|
|
152
163
|
<a id="configuration"></a>
|
|
153
164
|
## 
|
|
154
165
|
|
|
@@ -276,6 +287,10 @@ For richer integrations (thread fork, requirements, explicit skill input), use t
|
|
|
276
287
|
protocol. The client handles the initialize/initialized handshake and gives you access to
|
|
277
288
|
JSON-RPC notifications.
|
|
278
289
|
|
|
290
|
+
`AppServerClient` starts `codex app-server` and multiplexes notifications + server-initiated
|
|
291
|
+
requests (for example approval requests in `turn_session(...)`) on top of the same stdio
|
|
292
|
+
connection.
|
|
293
|
+
|
|
279
294
|
```python
|
|
280
295
|
import asyncio
|
|
281
296
|
from codex_sdk import AppServerClient, AppServerOptions
|
|
@@ -391,6 +406,11 @@ If you are working from source and the vendor directory is missing, run
|
|
|
391
406
|
`python scripts/setup_binary.py` to fetch and assemble the platform `@openai/codex`
|
|
392
407
|
artifacts into `src/codex_sdk/vendor/`.
|
|
393
408
|
|
|
409
|
+
`scripts/setup_binary.py` behavior:
|
|
410
|
+
- Resolves `CODEX_NPM_VERSION` when set; otherwise resolves latest `@openai/codex`.
|
|
411
|
+
- Tries legacy `@openai/codex-sdk` package first, then falls back to per-target `@openai/codex@<version>-<suffix>` artifacts.
|
|
412
|
+
- Rebuilds `src/codex_sdk/vendor/` for all supported targets and validates current-platform binary presence.
|
|
413
|
+
|
|
394
414
|
<a id="auth"></a>
|
|
395
415
|
## 
|
|
396
416
|
|
|
@@ -597,6 +617,8 @@ Example scripts under `examples/`:
|
|
|
597
617
|
- `notify_hook.py`: notify script for CLI callbacks.
|
|
598
618
|
- `pydantic_ai_model_provider.py`: Codex as a PydanticAI model provider.
|
|
599
619
|
- `pydantic_ai_handoff.py`: Codex as a PydanticAI tool.
|
|
620
|
+
- `pydantic_ai_run_compat.py`: minimal compatibility harness for `Agent.run(...)`.
|
|
621
|
+
- `pydantic_ai_run_stream_compat.py`: minimal compatibility harness for `Agent.run_stream(...)`.
|
|
600
622
|
|
|
601
623
|
<a id="sandbox"></a>
|
|
602
624
|
## 
|
|
@@ -619,6 +641,9 @@ Additional controls:
|
|
|
619
641
|
|
|
620
642
|
This SDK offers two ways to integrate with PydanticAI:
|
|
621
643
|
|
|
644
|
+
Note: starting in `0.105.0`, `CodexModel` is app-server-only and no longer supports
|
|
645
|
+
the legacy `CodexModel(codex=...)` fallback path.
|
|
646
|
+
|
|
622
647
|
### 1) Codex as a PydanticAI model provider
|
|
623
648
|
|
|
624
649
|
Use `CodexModel` to delegate tool-call planning and text generation to Codex, while PydanticAI executes tools and validates outputs.
|
|
@@ -646,11 +671,20 @@ print(result.output)
|
|
|
646
671
|
```
|
|
647
672
|
|
|
648
673
|
How it works:
|
|
674
|
+
- `CodexModel` keeps a persistent app-server session and starts/reuses threads based on
|
|
675
|
+
`thread_reuse_mode` (`"run"` by default, `"always"` optional).
|
|
649
676
|
- `CodexModel` builds a JSON schema envelope with `tool_calls` and `final`.
|
|
650
677
|
- Codex emits tool calls as JSON strings; PydanticAI runs them.
|
|
651
678
|
- If `allow_text_output` is true, Codex can place final text in `final`.
|
|
652
|
-
- Streaming APIs
|
|
653
|
-
|
|
679
|
+
- Streaming APIs emit incremental events while app-server turn notifications arrive.
|
|
680
|
+
|
|
681
|
+
Provider options:
|
|
682
|
+
- `performance_profile`: `"balanced"` (default) or `"max"`.
|
|
683
|
+
- `thread_reuse_mode`: `"run"` (default) or `"always"`.
|
|
684
|
+
|
|
685
|
+
Lifecycle:
|
|
686
|
+
- `CodexModel` owns an app-server client by default; call `await model.close()` in
|
|
687
|
+
long-lived processes to release resources.
|
|
654
688
|
|
|
655
689
|
Safety defaults (you can override with your own `ThreadOptions`):
|
|
656
690
|
- `sandbox_mode="read-only"`
|
|
@@ -713,38 +747,49 @@ If `logfire` is installed and initialized, the SDK emits spans:
|
|
|
713
747
|
If Logfire is missing or not initialized, the span context manager is a no-op.
|
|
714
748
|
|
|
715
749
|
<a id="architecture"></a>
|
|
716
|
-
<a id="acheature"></a>
|
|
717
750
|
## 
|
|
718
751
|
|
|
719
|
-
### System components
|
|
752
|
+
### System components and transport paths
|
|
720
753
|
|
|
721
754
|
```mermaid
|
|
722
755
|
flowchart LR
|
|
723
756
|
subgraph App[Your Python App]
|
|
724
757
|
U[User Code]
|
|
725
|
-
T[Thread API]
|
|
758
|
+
T[Codex + Thread API]
|
|
759
|
+
A[AppServerClient API]
|
|
760
|
+
PM[PydanticAI CodexModel]
|
|
761
|
+
PH[PydanticAI codex_handoff_tool]
|
|
726
762
|
end
|
|
727
763
|
|
|
728
764
|
subgraph SDK[Codex SDK]
|
|
729
765
|
C[Codex]
|
|
730
766
|
E[CodexExec]
|
|
731
|
-
P[Event Parser]
|
|
767
|
+
P[Thread Event Parser]
|
|
768
|
+
R[JSON-RPC Client]
|
|
732
769
|
end
|
|
733
770
|
|
|
734
|
-
subgraph CLI[
|
|
771
|
+
subgraph CLI[Codex CLI]
|
|
735
772
|
X["codex exec --experimental-json"]
|
|
773
|
+
S["codex app-server"]
|
|
736
774
|
end
|
|
737
775
|
|
|
738
776
|
FS[(Filesystem)]
|
|
739
777
|
NET[(Network)]
|
|
740
778
|
|
|
741
779
|
U --> T --> C --> E --> X
|
|
780
|
+
U --> A --> R --> S
|
|
781
|
+
U --> PM --> R
|
|
782
|
+
U --> PH --> C
|
|
742
783
|
X -->|JSONL events| P --> T
|
|
784
|
+
S -->|JSON-RPC messages| R --> A
|
|
785
|
+
S -->|JSON-RPC messages| R --> PM
|
|
743
786
|
X --> FS
|
|
744
787
|
X --> NET
|
|
788
|
+
S --> FS
|
|
789
|
+
S --> NET
|
|
745
790
|
```
|
|
746
791
|
|
|
747
|
-
###
|
|
792
|
+
### Thread API streaming lifecycle (`codex exec`)
|
|
748
793
|
|
|
749
794
|
```mermaid
|
|
750
795
|
sequenceDiagram
|
|
@@ -767,21 +812,41 @@ sequenceDiagram
|
|
|
767
812
|
Thread-->>Dev: turn.completed / turn.failed
|
|
768
813
|
```
|
|
769
814
|
|
|
770
|
-
###
|
|
815
|
+
### App-server lifecycle (`codex app-server`)
|
|
816
|
+
|
|
817
|
+
```mermaid
|
|
818
|
+
sequenceDiagram
|
|
819
|
+
participant Dev as Developer
|
|
820
|
+
participant App as AppServerClient
|
|
821
|
+
participant CLI as codex app-server
|
|
822
|
+
|
|
823
|
+
Dev->>App: start()
|
|
824
|
+
App->>CLI: spawn process
|
|
825
|
+
App->>CLI: initialize
|
|
826
|
+
CLI-->>App: initialize result
|
|
827
|
+
App->>CLI: initialized (notification)
|
|
828
|
+
Dev->>App: turn_session(thread_id, input)
|
|
829
|
+
App->>CLI: turn/start
|
|
830
|
+
CLI-->>App: thread/turn/item notifications
|
|
831
|
+
CLI-->>App: request (approval needed)
|
|
832
|
+
App-->>CLI: response (approve/reject)
|
|
833
|
+
CLI-->>App: turn completed notification
|
|
834
|
+
App-->>Dev: final turn payload
|
|
835
|
+
```
|
|
836
|
+
|
|
837
|
+
### PydanticAI model-provider loop (current implementation)
|
|
771
838
|
|
|
772
839
|
```mermaid
|
|
773
840
|
sequenceDiagram
|
|
774
841
|
participant Agent as PydanticAI Agent
|
|
775
842
|
participant Model as CodexModel
|
|
776
|
-
participant
|
|
777
|
-
participant CLI as codex exec
|
|
843
|
+
participant App as Codex app-server
|
|
778
844
|
participant Tools as User Tools
|
|
779
845
|
|
|
780
846
|
Agent->>Model: request(messages, tools)
|
|
781
|
-
Model->>
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
SDK-->>Model: ParsedTurn
|
|
847
|
+
Model->>App: thread/start (if needed)
|
|
848
|
+
Model->>App: turn/session(input + output_schema envelope)
|
|
849
|
+
App-->>Model: item/updated + turn/completed notifications
|
|
785
850
|
alt tool_calls present
|
|
786
851
|
Model-->>Agent: ToolCallPart(s)
|
|
787
852
|
Agent->>Tools: execute tool(s)
|
|
@@ -797,12 +862,18 @@ sequenceDiagram
|
|
|
797
862
|
flowchart LR
|
|
798
863
|
Agent[PydanticAI Agent] --> Tool[codex_handoff_tool]
|
|
799
864
|
Tool --> SDK[Codex SDK Thread]
|
|
800
|
-
SDK --> CLI[
|
|
865
|
+
SDK --> CLI[codex exec]
|
|
801
866
|
CLI --> SDK
|
|
802
867
|
SDK --> Tool
|
|
803
868
|
Tool --> Agent
|
|
804
869
|
```
|
|
805
870
|
|
|
871
|
+
### Streaming semantics summary
|
|
872
|
+
|
|
873
|
+
- `Thread.run_streamed()` and `Thread.run_streamed_events()` stream incremental `ThreadEvent` values as JSONL lines arrive from `codex exec`.
|
|
874
|
+
- `AppServerClient.notifications()` streams incremental JSON-RPC notifications from `codex app-server`.
|
|
875
|
+
- `CodexModel.request_stream(...)` emits incremental events from app-server turn notifications, with compatibility handling for current and legacy PydanticAI stream interfaces.
|
|
876
|
+
|
|
806
877
|
<a id="testing"></a>
|
|
807
878
|
## 
|
|
808
879
|
|
|
@@ -811,9 +882,12 @@ This repo uses unit tests with mocked CLI processes to keep the test suite fast
|
|
|
811
882
|
Test focus areas:
|
|
812
883
|
- `tests/test_exec.py`: CLI invocation, environment handling, config flags, abort behavior.
|
|
813
884
|
- `tests/test_thread.py`: parsing, streaming, JSON schema, Pydantic validation, input normalization.
|
|
885
|
+
- `tests/test_app_server.py` and `tests/test_app_server_session.py`: JSON-RPC lifecycle, method wrappers, turn-session approvals/notifications.
|
|
814
886
|
- `tests/test_codex.py`: resume helpers and option wiring.
|
|
887
|
+
- `tests/test_config_overrides.py`: `--config` serialization and merge behavior.
|
|
815
888
|
- `tests/test_abort.py`: abort signal semantics.
|
|
816
889
|
- `tests/test_telemetry.py`: Logfire span behavior.
|
|
890
|
+
- `tests/test_tool_envelope.py`: tool envelope parsing and schema normalization helpers.
|
|
817
891
|
- `tests/test_pydantic_ai_*`: PydanticAI model provider and handoff integration.
|
|
818
892
|
|
|
819
893
|
### Run tests
|
|
@@ -855,10 +929,21 @@ uv run mypy src
|
|
|
855
929
|
## 
|
|
856
930
|
|
|
857
931
|
This repository includes GitHub Actions workflows under `.github/workflows/`.
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
`
|
|
861
|
-
|
|
932
|
+
|
|
933
|
+
Current workflows:
|
|
934
|
+
- `ci.yml`: lint (`black`, `isort`, `flake8`), type-check (`mypy`), and tests (`pytest --cov=codex_sdk`) on Python 3.10/3.11/3.12.
|
|
935
|
+
- `release.yml`: extracts release notes from `CHANGELOG_SDK.md` and creates a GitHub Release for `vX.Y.Z`.
|
|
936
|
+
- `publish.yml`: builds (`uv build --no-sources`) and publishes to PyPI on release publish (or successful release workflow).
|
|
937
|
+
- `docs-deploy.yml`: optional docs deployment (gated by `DOCS_DEPLOY_ENABLED`).
|
|
938
|
+
- `uv-lock-update.yml`: scheduled weekly lockfile refresh PR.
|
|
939
|
+
|
|
940
|
+
`ci.yml` test jobs install Node.js and run:
|
|
941
|
+
|
|
942
|
+
```bash
|
|
943
|
+
python scripts/setup_binary.py
|
|
944
|
+
```
|
|
945
|
+
|
|
946
|
+
before `pytest`, so test runs do not depend on committed vendor binary updates.
|
|
862
947
|
|
|
863
948
|
<a id="operations"></a>
|
|
864
949
|
## 
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
[build-system]
|
|
2
|
-
requires = ["uv_build>=0.9.21,<0.
|
|
2
|
+
requires = ["uv_build>=0.9.21,<0.10.0"]
|
|
3
3
|
build-backend = "uv_build"
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "codex-sdk-python"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.105.0"
|
|
8
8
|
description = "Python SDK for the Codex CLI agent with async threads, streaming events, and structured outputs"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = {text = "Apache-2.0"}
|