@@ -4,9 +4,14 @@ Python SDK for Codex with bundled `codex` binaries inside platform wheels.
44
55This package exposes two supported APIs:
66
7- - ` Codex ` : a simple, local, CLI-backed interface built on ` codex exec `
7+ - ` Codex ` : a simple, local convenience interface backed by a private stdio app-server session
88- ` AppServerClient ` : a richer app-server client for thread management, streaming events, approvals, and typed protocol access
99
10+ Canonical import paths:
11+
12+ - use ` from codex import ... ` for the high-level ` Codex ` facade
13+ - use ` from codex.app_server import ... ` for the raw app-server client and app-server option types
14+
1015## Install
1116
1217``` bash
@@ -19,7 +24,9 @@ pip install codex-python
1924
2025Use ` Codex ` when you want the smallest surface area for local automation:
2126
22- - one process per run
27+ - one private local app-server session per ` Codex ` instance
28+ - stateless ` run*() ` convenience (fresh internal thread per call)
29+ - stateful thread workflows when needed via ` start_thread() ` / ` resume_thread() `
2330- simple request/response usage
2431- optional streaming over the exec event stream
2532- structured output via ` TurnOptions(output_schema=...) `
@@ -40,18 +47,16 @@ Use `AppServerClient` when you want a deeper integration:
4047from codex import Codex
4148
4249client = Codex()
43- thread = client.start_thread()
44-
45- summary = thread.run_text(" Diagnose the failing tests and propose a fix" )
50+ summary = client.run_text(" Diagnose the failing tests and propose a fix" )
4651print (summary)
4752```
4853
49- More exec-based examples: [ docs/exec_api.md] ( docs/exec_api.md )
54+ More ` Codex ` examples: [ docs/exec_api.md] ( docs/exec_api.md )
5055
5156## Quickstart: ` AppServerClient `
5257
5358``` python
54- from codex import AppServerClient, AppServerClientInfo, AppServerInitializeOptions
59+ from codex.app_server import AppServerClient, AppServerClientInfo, AppServerInitializeOptions
5560
5661initialize_options = AppServerInitializeOptions(
5762 client_info = AppServerClientInfo(
@@ -68,6 +73,7 @@ with AppServerClient.connect_stdio(initialize_options=initialize_options) as cli
6873```
6974
7075More app-server examples: [ docs/app_server.md] ( docs/app_server.md )
76+ For websocket transport, install the optional extra: ` pip install "codex-python[websocket]" ` .
7177
7278## Structured output
7379
@@ -84,8 +90,7 @@ schema = {
8490}
8591
8692client = Codex()
87- thread = client.start_thread()
88- payload = thread.run_json(" Summarize repository status" , TurnOptions(output_schema = schema))
93+ payload = client.run_json(" Summarize repository status" , TurnOptions(output_schema = schema))
8994print (payload[" summary" ])
9095```
9196
@@ -94,7 +99,7 @@ print(payload["summary"])
9499``` python
95100from pydantic import BaseModel
96101
97- from codex import AppServerClient
102+ from codex.app_server import AppServerClient, AppServerTurnOptions
98103
99104
100105class Summary (BaseModel ):
@@ -112,31 +117,35 @@ with AppServerClient.connect_stdio() as client:
112117
113118` run_model() ` uses ` Summary ` both as the validation model and, by default, as the output schema sent
114119to Codex. If you want JSON back without validation, you can also pass the model class directly to
115- ` outputSchema ` , for example ` thread.run_json(..., outputSchema =Summary) ` .
120+ ` output_schema ` , for example ` thread.run_json(..., AppServerTurnOptions(output_schema =Summary) ) ` .
116121
117122## Streaming
118123
119- ### Exec stream
124+ ### ` Codex ` stream
120125
121126``` python
122127from codex import Codex
123128from codex.protocol import types as protocol
124129
125130client = Codex()
126- thread = client.start_thread()
127-
128- stream = thread.run(" Investigate this bug" )
131+ stream = client.run(" Investigate this bug" )
129132for event in stream:
130- if isinstance (event, protocol.AgentMessageDeltaEventMsg ):
131- print (event.delta, end = " " , flush = True )
133+ if isinstance (event, protocol.ItemAgentMessageDeltaNotification ):
134+ print (event.params. delta, end = " " , flush = True )
132135
133136print ()
134137```
135138
139+ ` Codex.run*() ` starts a fresh internal thread for each call. Use
140+ ` start_thread() ` or ` resume_thread() ` when you want later runs to share context.
141+
142+ High-level ` Codex ` helpers raise ` ThreadRunError ` on failed or interrupted terminal turns and
143+ preserve the final turn metadata on the exception for debugging and UI handling.
144+
136145### App-server stream
137146
138147``` python
139- from codex import AppServerClient
148+ from codex.app_server import AppServerClient
140149from codex.protocol import types as protocol
141150
142151with AppServerClient.connect_stdio() as client:
@@ -150,12 +159,13 @@ with AppServerClient.connect_stdio() as client:
150159 print ()
151160```
152161
153- Advanced app-server usage: [ docs/app_server_advanced.md] ( docs/app_server_advanced.md )
162+ Advanced app-server usage, including typed stable RPC domains such as ` client.models ` and the raw ` client.rpc ` fallback : [ docs/app_server_advanced.md] ( docs/app_server_advanced.md )
154163
155164## Examples
156165
157166- [ examples/basic_conversation.py] ( examples/basic_conversation.py ) : minimal ` Codex ` flow
158167- [ examples/app_server_conversation.py] ( examples/app_server_conversation.py ) : minimal app-server flow
168+ - [ examples/app_server_websocket_conversation.py] ( examples/app_server_websocket_conversation.py ) : minimal websocket app-server flow
159169- [ examples/app_server_stream_events.py] ( examples/app_server_stream_events.py ) : protocol-native app-server streaming
160170- [ examples/app_server_tool_handler.py] ( examples/app_server_tool_handler.py ) : typed app-server request handling
161171
@@ -171,7 +181,7 @@ If the bundled binary is not present, for example in a source checkout, the SDK
171181You can override the executable path with:
172182
173183- ` CodexOptions(codex_path_override=...) `
174- - ` AppServerProcessOptions(codex_path_override=...) `
184+ - ` codex.app_server. AppServerProcessOptions(codex_path_override=...)`
175185
176186## Development
177187
0 commit comments