codex-backend-sdk 0.5.2__tar.gz → 0.5.4__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_backend_sdk-0.5.2 → codex_backend_sdk-0.5.4}/CHANGELOG.md +25 -1
- {codex_backend_sdk-0.5.2 → codex_backend_sdk-0.5.4}/PKG-INFO +39 -24
- {codex_backend_sdk-0.5.2 → codex_backend_sdk-0.5.4}/README.md +34 -19
- {codex_backend_sdk-0.5.2 → codex_backend_sdk-0.5.4}/codex_backend_sdk/__init__.py +9 -1
- {codex_backend_sdk-0.5.2 → codex_backend_sdk-0.5.4}/codex_backend_sdk/_client.py +3 -2
- {codex_backend_sdk-0.5.2 → codex_backend_sdk-0.5.4}/codex_backend_sdk/_models.py +26 -0
- {codex_backend_sdk-0.5.2 → codex_backend_sdk-0.5.4}/codex_backend_sdk/_transport.py +21 -1
- {codex_backend_sdk-0.5.2 → codex_backend_sdk-0.5.4}/codex_backend_sdk/codex_client.py +8 -0
- {codex_backend_sdk-0.5.2 → codex_backend_sdk-0.5.4}/codex_backend_sdk/resources/chatgpt_plugins.py +101 -19
- {codex_backend_sdk-0.5.2 → codex_backend_sdk-0.5.4}/codex_backend_sdk/resources/codex.py +213 -23
- codex_backend_sdk-0.5.4/codex_backend_sdk/resources/realtime.py +437 -0
- {codex_backend_sdk-0.5.2 → codex_backend_sdk-0.5.4}/docs/api-reference.md +25 -1
- {codex_backend_sdk-0.5.2 → codex_backend_sdk-0.5.4}/docs/backend-api.md +27 -13
- {codex_backend_sdk-0.5.2 → codex_backend_sdk-0.5.4}/docs/desktop-endpoint-inventory.md +53 -7
- {codex_backend_sdk-0.5.2 → codex_backend_sdk-0.5.4}/docs/endpoint-coverage.md +19 -8
- {codex_backend_sdk-0.5.2 → codex_backend_sdk-0.5.4}/docs/openai-compatibility.md +9 -2
- {codex_backend_sdk-0.5.2 → codex_backend_sdk-0.5.4}/pyproject.toml +5 -5
- {codex_backend_sdk-0.5.2 → codex_backend_sdk-0.5.4}/tests/conftest.py +2 -1
- {codex_backend_sdk-0.5.2 → codex_backend_sdk-0.5.4}/tests/test_basic.py +5 -2
- {codex_backend_sdk-0.5.2 → codex_backend_sdk-0.5.4}/tests/test_chatgpt_plugins.py +59 -13
- {codex_backend_sdk-0.5.2 → codex_backend_sdk-0.5.4}/tests/test_client_retry.py +19 -2
- {codex_backend_sdk-0.5.2 → codex_backend_sdk-0.5.4}/tests/test_codex_resources.py +148 -22
- {codex_backend_sdk-0.5.2 → codex_backend_sdk-0.5.4}/tests/test_openai_compatibility.py +36 -18
- {codex_backend_sdk-0.5.2 → codex_backend_sdk-0.5.4}/tests/test_realtime_resource.py +72 -0
- {codex_backend_sdk-0.5.2 → codex_backend_sdk-0.5.4}/uv.lock +80 -28
- codex_backend_sdk-0.5.2/codex_backend_sdk/resources/realtime.py +0 -171
- {codex_backend_sdk-0.5.2 → codex_backend_sdk-0.5.4}/.gitignore +0 -0
- {codex_backend_sdk-0.5.2 → codex_backend_sdk-0.5.4}/LICENSE +0 -0
- {codex_backend_sdk-0.5.2 → codex_backend_sdk-0.5.4}/codex_backend_sdk/_streaming.py +0 -0
- {codex_backend_sdk-0.5.2 → codex_backend_sdk-0.5.4}/codex_backend_sdk/_utils.py +0 -0
- {codex_backend_sdk-0.5.2 → codex_backend_sdk-0.5.4}/codex_backend_sdk/oauth.py +0 -0
- {codex_backend_sdk-0.5.2 → codex_backend_sdk-0.5.4}/codex_backend_sdk/pkce.py +0 -0
- {codex_backend_sdk-0.5.2 → codex_backend_sdk-0.5.4}/codex_backend_sdk/resources/__init__.py +0 -0
- {codex_backend_sdk-0.5.2 → codex_backend_sdk-0.5.4}/codex_backend_sdk/resources/_responses_payloads.py +0 -0
- {codex_backend_sdk-0.5.2 → codex_backend_sdk-0.5.4}/codex_backend_sdk/resources/chatgpt.py +0 -0
- {codex_backend_sdk-0.5.2 → codex_backend_sdk-0.5.4}/codex_backend_sdk/resources/chatgpt_apps.py +0 -0
- {codex_backend_sdk-0.5.2 → codex_backend_sdk-0.5.4}/codex_backend_sdk/resources/chatgpt_connectors.py +0 -0
- {codex_backend_sdk-0.5.2 → codex_backend_sdk-0.5.4}/codex_backend_sdk/resources/chatgpt_plugin_bundles.py +0 -0
- {codex_backend_sdk-0.5.2 → codex_backend_sdk-0.5.4}/codex_backend_sdk/resources/chatgpt_plugin_shares.py +0 -0
- {codex_backend_sdk-0.5.2 → codex_backend_sdk-0.5.4}/codex_backend_sdk/resources/chatgpt_writing_blocks.py +0 -0
- {codex_backend_sdk-0.5.2 → codex_backend_sdk-0.5.4}/codex_backend_sdk/resources/codex_web_search.py +0 -0
- {codex_backend_sdk-0.5.2 → codex_backend_sdk-0.5.4}/codex_backend_sdk/resources/files.py +0 -0
- {codex_backend_sdk-0.5.2 → codex_backend_sdk-0.5.4}/codex_backend_sdk/resources/images.py +0 -0
- {codex_backend_sdk-0.5.2 → codex_backend_sdk-0.5.4}/codex_backend_sdk/resources/models.py +0 -0
- {codex_backend_sdk-0.5.2 → codex_backend_sdk-0.5.4}/codex_backend_sdk/resources/openai_oauth.py +0 -0
- {codex_backend_sdk-0.5.2 → codex_backend_sdk-0.5.4}/codex_backend_sdk/resources/remote_control.py +0 -0
- {codex_backend_sdk-0.5.2 → codex_backend_sdk-0.5.4}/codex_backend_sdk/resources/responses.py +0 -0
- {codex_backend_sdk-0.5.2 → codex_backend_sdk-0.5.4}/codex_backend_sdk/resources/responses_websocket.py +0 -0
- {codex_backend_sdk-0.5.2 → codex_backend_sdk-0.5.4}/codex_backend_sdk/resources/worktree_snapshots.py +0 -0
- {codex_backend_sdk-0.5.2 → codex_backend_sdk-0.5.4}/codex_backend_sdk/storage.py +0 -0
- {codex_backend_sdk-0.5.2 → codex_backend_sdk-0.5.4}/examples/agent.py +0 -0
- {codex_backend_sdk-0.5.2 → codex_backend_sdk-0.5.4}/tests/test_account_info.py +0 -0
- {codex_backend_sdk-0.5.2 → codex_backend_sdk-0.5.4}/tests/test_chatgpt_apps.py +0 -0
- {codex_backend_sdk-0.5.2 → codex_backend_sdk-0.5.4}/tests/test_chatgpt_connectors.py +0 -0
- {codex_backend_sdk-0.5.2 → codex_backend_sdk-0.5.4}/tests/test_chatgpt_plugin_bundles.py +0 -0
- {codex_backend_sdk-0.5.2 → codex_backend_sdk-0.5.4}/tests/test_chatgpt_plugin_shares.py +0 -0
- {codex_backend_sdk-0.5.2 → codex_backend_sdk-0.5.4}/tests/test_chatgpt_projects_gizmos.py +0 -0
- {codex_backend_sdk-0.5.2 → codex_backend_sdk-0.5.4}/tests/test_chatgpt_resources.py +0 -0
- {codex_backend_sdk-0.5.2 → codex_backend_sdk-0.5.4}/tests/test_chatgpt_search_files.py +0 -0
- {codex_backend_sdk-0.5.2 → codex_backend_sdk-0.5.4}/tests/test_chatgpt_writing_blocks.py +0 -0
- {codex_backend_sdk-0.5.2 → codex_backend_sdk-0.5.4}/tests/test_codex_web_search.py +0 -0
- {codex_backend_sdk-0.5.2 → codex_backend_sdk-0.5.4}/tests/test_conversation.py +0 -0
- {codex_backend_sdk-0.5.2 → codex_backend_sdk-0.5.4}/tests/test_files_resource.py +0 -0
- {codex_backend_sdk-0.5.2 → codex_backend_sdk-0.5.4}/tests/test_hosted_mcp.py +0 -0
- {codex_backend_sdk-0.5.2 → codex_backend_sdk-0.5.4}/tests/test_images.py +0 -0
- {codex_backend_sdk-0.5.2 → codex_backend_sdk-0.5.4}/tests/test_oauth.py +0 -0
- {codex_backend_sdk-0.5.2 → codex_backend_sdk-0.5.4}/tests/test_openai_oauth_resources.py +0 -0
- {codex_backend_sdk-0.5.2 → codex_backend_sdk-0.5.4}/tests/test_prompt_cache_usage.py +0 -0
- {codex_backend_sdk-0.5.2 → codex_backend_sdk-0.5.4}/tests/test_reasoning.py +0 -0
- {codex_backend_sdk-0.5.2 → codex_backend_sdk-0.5.4}/tests/test_remote_control_resource.py +0 -0
- {codex_backend_sdk-0.5.2 → codex_backend_sdk-0.5.4}/tests/test_responses_resource.py +0 -0
- {codex_backend_sdk-0.5.2 → codex_backend_sdk-0.5.4}/tests/test_responses_websocket.py +0 -0
- {codex_backend_sdk-0.5.2 → codex_backend_sdk-0.5.4}/tests/test_structured_output.py +0 -0
- {codex_backend_sdk-0.5.2 → codex_backend_sdk-0.5.4}/tests/test_tools.py +0 -0
- {codex_backend_sdk-0.5.2 → codex_backend_sdk-0.5.4}/tests/test_worktree_snapshots.py +0 -0
|
@@ -2,7 +2,31 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## [0.5.4] - 2026-09-24
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
- Preserve a bounded backend response body in raised HTTP errors so callers can
|
|
9
|
+
diagnose rejected requests without reconstructing the transport call.
|
|
10
|
+
|
|
11
|
+
## [0.5.3] - 2026-09-18
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
- Added the OpenAI-shaped `client.live.create(...)` and
|
|
15
|
+
`client.live.sideband.connect(...)` surfaces over the existing Codex OAuth
|
|
16
|
+
Realtime v3 transport, including the public response shape and lazy
|
|
17
|
+
sideband context-manager idiom.
|
|
18
|
+
- Added current Codex workspace usage, task-usage, turn-estimate, plugin/skill
|
|
19
|
+
analytics, and reset-credit history resources discovered by the refreshed
|
|
20
|
+
source scan.
|
|
21
|
+
- Added the current Desktop plugin home feed and explicit plugin/skill
|
|
22
|
+
enable-disable mutations.
|
|
23
|
+
|
|
24
|
+
### Changed
|
|
25
|
+
- Updated the compatibility baseline to `openai-python` 3.16.1 while retaining
|
|
26
|
+
the additive low-level `client.realtime` API.
|
|
27
|
+
- Reconciled the endpoint inventory with the refreshed Codex and official
|
|
28
|
+
Desktop checkouts, and tightened validation of plugin catalog responses and
|
|
29
|
+
pagination state.
|
|
6
30
|
|
|
7
31
|
## [0.5.1] - 2026-08-14
|
|
8
32
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: codex-backend-sdk
|
|
3
|
-
Version: 0.5.
|
|
3
|
+
Version: 0.5.4
|
|
4
4
|
Summary: Unofficial Python SDK for the ChatGPT Codex backend API
|
|
5
5
|
License: MIT
|
|
6
6
|
License-File: LICENSE
|
|
@@ -19,12 +19,12 @@ Requires-Dist: pydantic>=2.0
|
|
|
19
19
|
Requires-Dist: requests>=2.28
|
|
20
20
|
Requires-Dist: websocket-client>=1.8
|
|
21
21
|
Provides-Extra: dev
|
|
22
|
-
Requires-Dist: openai<
|
|
23
|
-
Requires-Dist: openai>=
|
|
22
|
+
Requires-Dist: openai<3.0,>=1.0; (python_version < '3.10') and extra == 'dev'
|
|
23
|
+
Requires-Dist: openai>=3.16.1; (python_version >= '3.10') and extra == 'dev'
|
|
24
24
|
Requires-Dist: pytest>=7.0; extra == 'dev'
|
|
25
25
|
Provides-Extra: openai
|
|
26
|
-
Requires-Dist: openai<
|
|
27
|
-
Requires-Dist: openai>=
|
|
26
|
+
Requires-Dist: openai<3.0,>=1.0; (python_version < '3.10') and extra == 'openai'
|
|
27
|
+
Requires-Dist: openai>=3.16.1; (python_version >= '3.10') and extra == 'openai'
|
|
28
28
|
Description-Content-Type: text/markdown
|
|
29
29
|
|
|
30
30
|
# codex-backend-sdk
|
|
@@ -65,7 +65,7 @@ from codex_backend_sdk import OpenAI
|
|
|
65
65
|
client = OpenAI().authenticate()
|
|
66
66
|
|
|
67
67
|
response = client.responses.create(
|
|
68
|
-
model="gpt-5.
|
|
68
|
+
model="gpt-5.5",
|
|
69
69
|
input="Explain quicksort in one paragraph.",
|
|
70
70
|
)
|
|
71
71
|
|
|
@@ -89,7 +89,8 @@ client.files # upload files for Apps/MCP parameters
|
|
|
89
89
|
client.images # Codex-backed image generation and editing
|
|
90
90
|
client.audio # ChatGPT-backed transcription
|
|
91
91
|
client.embeddings # OpenAI embeddings endpoint through OAuth
|
|
92
|
-
client.
|
|
92
|
+
client.live # OpenAI-shaped GPT-Live creation and sideband attachment
|
|
93
|
+
client.realtime # additive low-level Codex Realtime v3 transport
|
|
93
94
|
```
|
|
94
95
|
|
|
95
96
|
These resources follow `openai-python` conventions where the backend overlaps
|
|
@@ -142,7 +143,7 @@ dictionaries or raw streams when imposing a stable model would be misleading.
|
|
|
142
143
|
|
|
143
144
|
```python
|
|
144
145
|
response = client.responses.create(
|
|
145
|
-
model="gpt-5.
|
|
146
|
+
model="gpt-5.5",
|
|
146
147
|
instructions="Be concise.",
|
|
147
148
|
input="Summarize the CAP theorem.",
|
|
148
149
|
reasoning={"effort": "medium", "summary": "auto"},
|
|
@@ -173,7 +174,7 @@ connection reusable across sequential turns:
|
|
|
173
174
|
|
|
174
175
|
```python
|
|
175
176
|
with client.responses.websocket.connect() as ws:
|
|
176
|
-
for event in ws.create({"model": "gpt-5.
|
|
177
|
+
for event in ws.create({"model": "gpt-5.5", "input": "Say hello."}):
|
|
177
178
|
if event.get("type") == "response.output_text.delta":
|
|
178
179
|
print(event.get("delta", ""), end="")
|
|
179
180
|
```
|
|
@@ -197,7 +198,7 @@ print(client.responses.create(input=history).output_text)
|
|
|
197
198
|
|
|
198
199
|
```python
|
|
199
200
|
compacted = client.responses.compact(
|
|
200
|
-
model="gpt-5.
|
|
201
|
+
model="gpt-5.5",
|
|
201
202
|
instructions="Preserve task-critical decisions and unresolved work.",
|
|
202
203
|
input=history,
|
|
203
204
|
)
|
|
@@ -268,7 +269,7 @@ print(result.output_parsed)
|
|
|
268
269
|
for model in client.models.list():
|
|
269
270
|
print(model.id, model.context_window, model.supported_reasoning_levels)
|
|
270
271
|
|
|
271
|
-
model = client.models.retrieve("gpt-5.
|
|
272
|
+
model = client.models.retrieve("gpt-5.5")
|
|
272
273
|
```
|
|
273
274
|
|
|
274
275
|
### Upload a file
|
|
@@ -340,6 +341,10 @@ sports, and time commands. See the API reference for command validation.
|
|
|
340
341
|
quota = client.codex.usage()
|
|
341
342
|
daily = client.codex.usage_details.daily_token_breakdown()
|
|
342
343
|
credits = client.codex.usage_details.credit_events()
|
|
344
|
+
plugin_metrics = client.codex.usage_details.plugin_usage_metrics(
|
|
345
|
+
start_date="2026-09-01",
|
|
346
|
+
end_date="2026-09-18",
|
|
347
|
+
)
|
|
343
348
|
|
|
344
349
|
print(quota.get("rate_limit", {}).get("primary_window"))
|
|
345
350
|
```
|
|
@@ -443,6 +448,7 @@ tool annotations and own user confirmation; the SDK never auto-invokes tools.
|
|
|
443
448
|
plugins = client.chatgpt.plugins.list_all(scope="GLOBAL")
|
|
444
449
|
installed = client.chatgpt.plugins.installed_all()
|
|
445
450
|
suggested = client.chatgpt.plugins.suggested()
|
|
451
|
+
home = client.chatgpt.plugins.home()
|
|
446
452
|
skill = client.chatgpt.plugins.skill("plugins~...", "skill-name")
|
|
447
453
|
|
|
448
454
|
checkout = client.chatgpt.plugins.bundles.extract_plugin(
|
|
@@ -491,33 +497,42 @@ return a typed in-memory object, bytes, `BytesIO`, a data URI, or a file path.
|
|
|
491
497
|
### Realtime voice
|
|
492
498
|
|
|
493
499
|
```python
|
|
494
|
-
|
|
495
|
-
sdp=offer_sdp,
|
|
500
|
+
live = client.live.create(
|
|
496
501
|
session={
|
|
497
502
|
"model": "gpt-live-1-codex",
|
|
498
503
|
"instructions": "Speak naturally and stay concise.",
|
|
504
|
+
"delegation": {"type": "client"},
|
|
499
505
|
},
|
|
506
|
+
transport={"type": "webrtc", "sdp": offer_sdp},
|
|
500
507
|
)
|
|
501
|
-
|
|
508
|
+
apply_remote_sdp(live.transport.sdp)
|
|
509
|
+
|
|
510
|
+
with client.live.sideband.connect(session_id=live.session.id) as sideband:
|
|
511
|
+
for event in sideband:
|
|
512
|
+
print(event.type)
|
|
502
513
|
```
|
|
503
514
|
|
|
504
515
|
Live probes confirmed `gpt-live-1-codex` and
|
|
505
516
|
`gpt-live-1-boulder-alpha`. They are Codex Realtime v3 snapshots, not aliases
|
|
506
|
-
for the public `gpt-
|
|
507
|
-
|
|
517
|
+
for the public `gpt-live-1` model. `client.live` follows the current
|
|
518
|
+
`openai-python` creation, response, and sideband idioms while adapting them to
|
|
519
|
+
the ChatGPT OAuth call transport.
|
|
520
|
+
|
|
521
|
+
The earlier low-level surface remains available for backend-specific code:
|
|
508
522
|
|
|
509
523
|
```python
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
524
|
+
answer = client.realtime.calls.create_v3(
|
|
525
|
+
sdp=offer_sdp,
|
|
526
|
+
session={"model": "gpt-live-1-codex"},
|
|
513
527
|
)
|
|
514
|
-
sideband.
|
|
515
|
-
|
|
516
|
-
sideband.close()
|
|
528
|
+
with client.realtime.sideband.connect(call_id=answer.call_id) as sideband:
|
|
529
|
+
sideband.send({"type": "session.close"})
|
|
517
530
|
```
|
|
518
531
|
|
|
519
|
-
The
|
|
520
|
-
|
|
532
|
+
The OAuth backend's event dialect is still experimental and is exposed
|
|
533
|
+
forward-compatibly through `LiveEvent` rather than rewritten into invented
|
|
534
|
+
public fields. The public primary `client.live.connect()` WebSocket is not
|
|
535
|
+
available through ChatGPT OAuth; use WebRTC plus the attached sideband.
|
|
521
536
|
|
|
522
537
|
### Embeddings
|
|
523
538
|
|
|
@@ -36,7 +36,7 @@ from codex_backend_sdk import OpenAI
|
|
|
36
36
|
client = OpenAI().authenticate()
|
|
37
37
|
|
|
38
38
|
response = client.responses.create(
|
|
39
|
-
model="gpt-5.
|
|
39
|
+
model="gpt-5.5",
|
|
40
40
|
input="Explain quicksort in one paragraph.",
|
|
41
41
|
)
|
|
42
42
|
|
|
@@ -60,7 +60,8 @@ client.files # upload files for Apps/MCP parameters
|
|
|
60
60
|
client.images # Codex-backed image generation and editing
|
|
61
61
|
client.audio # ChatGPT-backed transcription
|
|
62
62
|
client.embeddings # OpenAI embeddings endpoint through OAuth
|
|
63
|
-
client.
|
|
63
|
+
client.live # OpenAI-shaped GPT-Live creation and sideband attachment
|
|
64
|
+
client.realtime # additive low-level Codex Realtime v3 transport
|
|
64
65
|
```
|
|
65
66
|
|
|
66
67
|
These resources follow `openai-python` conventions where the backend overlaps
|
|
@@ -113,7 +114,7 @@ dictionaries or raw streams when imposing a stable model would be misleading.
|
|
|
113
114
|
|
|
114
115
|
```python
|
|
115
116
|
response = client.responses.create(
|
|
116
|
-
model="gpt-5.
|
|
117
|
+
model="gpt-5.5",
|
|
117
118
|
instructions="Be concise.",
|
|
118
119
|
input="Summarize the CAP theorem.",
|
|
119
120
|
reasoning={"effort": "medium", "summary": "auto"},
|
|
@@ -144,7 +145,7 @@ connection reusable across sequential turns:
|
|
|
144
145
|
|
|
145
146
|
```python
|
|
146
147
|
with client.responses.websocket.connect() as ws:
|
|
147
|
-
for event in ws.create({"model": "gpt-5.
|
|
148
|
+
for event in ws.create({"model": "gpt-5.5", "input": "Say hello."}):
|
|
148
149
|
if event.get("type") == "response.output_text.delta":
|
|
149
150
|
print(event.get("delta", ""), end="")
|
|
150
151
|
```
|
|
@@ -168,7 +169,7 @@ print(client.responses.create(input=history).output_text)
|
|
|
168
169
|
|
|
169
170
|
```python
|
|
170
171
|
compacted = client.responses.compact(
|
|
171
|
-
model="gpt-5.
|
|
172
|
+
model="gpt-5.5",
|
|
172
173
|
instructions="Preserve task-critical decisions and unresolved work.",
|
|
173
174
|
input=history,
|
|
174
175
|
)
|
|
@@ -239,7 +240,7 @@ print(result.output_parsed)
|
|
|
239
240
|
for model in client.models.list():
|
|
240
241
|
print(model.id, model.context_window, model.supported_reasoning_levels)
|
|
241
242
|
|
|
242
|
-
model = client.models.retrieve("gpt-5.
|
|
243
|
+
model = client.models.retrieve("gpt-5.5")
|
|
243
244
|
```
|
|
244
245
|
|
|
245
246
|
### Upload a file
|
|
@@ -311,6 +312,10 @@ sports, and time commands. See the API reference for command validation.
|
|
|
311
312
|
quota = client.codex.usage()
|
|
312
313
|
daily = client.codex.usage_details.daily_token_breakdown()
|
|
313
314
|
credits = client.codex.usage_details.credit_events()
|
|
315
|
+
plugin_metrics = client.codex.usage_details.plugin_usage_metrics(
|
|
316
|
+
start_date="2026-09-01",
|
|
317
|
+
end_date="2026-09-18",
|
|
318
|
+
)
|
|
314
319
|
|
|
315
320
|
print(quota.get("rate_limit", {}).get("primary_window"))
|
|
316
321
|
```
|
|
@@ -414,6 +419,7 @@ tool annotations and own user confirmation; the SDK never auto-invokes tools.
|
|
|
414
419
|
plugins = client.chatgpt.plugins.list_all(scope="GLOBAL")
|
|
415
420
|
installed = client.chatgpt.plugins.installed_all()
|
|
416
421
|
suggested = client.chatgpt.plugins.suggested()
|
|
422
|
+
home = client.chatgpt.plugins.home()
|
|
417
423
|
skill = client.chatgpt.plugins.skill("plugins~...", "skill-name")
|
|
418
424
|
|
|
419
425
|
checkout = client.chatgpt.plugins.bundles.extract_plugin(
|
|
@@ -462,33 +468,42 @@ return a typed in-memory object, bytes, `BytesIO`, a data URI, or a file path.
|
|
|
462
468
|
### Realtime voice
|
|
463
469
|
|
|
464
470
|
```python
|
|
465
|
-
|
|
466
|
-
sdp=offer_sdp,
|
|
471
|
+
live = client.live.create(
|
|
467
472
|
session={
|
|
468
473
|
"model": "gpt-live-1-codex",
|
|
469
474
|
"instructions": "Speak naturally and stay concise.",
|
|
475
|
+
"delegation": {"type": "client"},
|
|
470
476
|
},
|
|
477
|
+
transport={"type": "webrtc", "sdp": offer_sdp},
|
|
471
478
|
)
|
|
472
|
-
|
|
479
|
+
apply_remote_sdp(live.transport.sdp)
|
|
480
|
+
|
|
481
|
+
with client.live.sideband.connect(session_id=live.session.id) as sideband:
|
|
482
|
+
for event in sideband:
|
|
483
|
+
print(event.type)
|
|
473
484
|
```
|
|
474
485
|
|
|
475
486
|
Live probes confirmed `gpt-live-1-codex` and
|
|
476
487
|
`gpt-live-1-boulder-alpha`. They are Codex Realtime v3 snapshots, not aliases
|
|
477
|
-
for the public `gpt-
|
|
478
|
-
|
|
488
|
+
for the public `gpt-live-1` model. `client.live` follows the current
|
|
489
|
+
`openai-python` creation, response, and sideband idioms while adapting them to
|
|
490
|
+
the ChatGPT OAuth call transport.
|
|
491
|
+
|
|
492
|
+
The earlier low-level surface remains available for backend-specific code:
|
|
479
493
|
|
|
480
494
|
```python
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
495
|
+
answer = client.realtime.calls.create_v3(
|
|
496
|
+
sdp=offer_sdp,
|
|
497
|
+
session={"model": "gpt-live-1-codex"},
|
|
484
498
|
)
|
|
485
|
-
sideband.
|
|
486
|
-
|
|
487
|
-
sideband.close()
|
|
499
|
+
with client.realtime.sideband.connect(call_id=answer.call_id) as sideband:
|
|
500
|
+
sideband.send({"type": "session.close"})
|
|
488
501
|
```
|
|
489
502
|
|
|
490
|
-
The
|
|
491
|
-
|
|
503
|
+
The OAuth backend's event dialect is still experimental and is exposed
|
|
504
|
+
forward-compatibly through `LiveEvent` rather than rewritten into invented
|
|
505
|
+
public fields. The public primary `client.live.connect()` WebSocket is not
|
|
506
|
+
available through ChatGPT OAuth; use WebRTC plus the attached sideband.
|
|
492
507
|
|
|
493
508
|
### Embeddings
|
|
494
509
|
|
|
@@ -17,7 +17,7 @@ Quickstart:
|
|
|
17
17
|
print(response.output_text)
|
|
18
18
|
"""
|
|
19
19
|
|
|
20
|
-
__version__ = "0.5.
|
|
20
|
+
__version__ = "0.5.3"
|
|
21
21
|
|
|
22
22
|
from .oauth import (
|
|
23
23
|
DeviceCode,
|
|
@@ -57,6 +57,10 @@ from .codex_client import (
|
|
|
57
57
|
Image,
|
|
58
58
|
ImageResponse,
|
|
59
59
|
ImagesResponse,
|
|
60
|
+
LiveCreateResponse,
|
|
61
|
+
LiveEvent,
|
|
62
|
+
LiveSession,
|
|
63
|
+
LiveTransport,
|
|
60
64
|
RateLimitResetCredit,
|
|
61
65
|
RateLimitResetCredits,
|
|
62
66
|
ConsumeRateLimitResetCreditResponse,
|
|
@@ -102,6 +106,10 @@ __all__ = [
|
|
|
102
106
|
"Image",
|
|
103
107
|
"ImageResponse",
|
|
104
108
|
"ImagesResponse",
|
|
109
|
+
"LiveCreateResponse",
|
|
110
|
+
"LiveEvent",
|
|
111
|
+
"LiveSession",
|
|
112
|
+
"LiveTransport",
|
|
105
113
|
"RateLimitResetCredit",
|
|
106
114
|
"RateLimitResetCredits",
|
|
107
115
|
"ConsumeRateLimitResetCreditResponse",
|
|
@@ -30,7 +30,7 @@ class CodexClient:
|
|
|
30
30
|
self,
|
|
31
31
|
*,
|
|
32
32
|
store: Optional[TokenStore] = None,
|
|
33
|
-
model: str = "gpt-5.
|
|
33
|
+
model: str = "gpt-5.5",
|
|
34
34
|
instructions: Optional[str] = None,
|
|
35
35
|
timeout: float = 120,
|
|
36
36
|
max_retries: int = 2,
|
|
@@ -44,7 +44,7 @@ class CodexClient:
|
|
|
44
44
|
from .resources.openai_oauth import Audio, Embeddings
|
|
45
45
|
from .resources.files import Files
|
|
46
46
|
from .resources.images import Images
|
|
47
|
-
from .resources.realtime import Realtime
|
|
47
|
+
from .resources.realtime import Live, Realtime
|
|
48
48
|
from .resources.responses import Responses
|
|
49
49
|
|
|
50
50
|
self._store = store
|
|
@@ -66,6 +66,7 @@ class CodexClient:
|
|
|
66
66
|
self.responses = Responses(self)
|
|
67
67
|
self.models = Models(self)
|
|
68
68
|
self.realtime = Realtime(self)
|
|
69
|
+
self.live = Live(self)
|
|
69
70
|
self.embeddings = Embeddings(self)
|
|
70
71
|
self.audio = Audio(self)
|
|
71
72
|
self.images = Images(self)
|
|
@@ -435,6 +435,32 @@ class RealtimeCallResponse(BinaryResponseContent):
|
|
|
435
435
|
)
|
|
436
436
|
|
|
437
437
|
|
|
438
|
+
class LiveSession(CodexBaseModel):
|
|
439
|
+
"""Resolved Live session identity returned by the OAuth adapter."""
|
|
440
|
+
|
|
441
|
+
id: str
|
|
442
|
+
|
|
443
|
+
|
|
444
|
+
class LiveTransport(CodexBaseModel):
|
|
445
|
+
"""WebRTC answer using the public OpenAI Live response shape."""
|
|
446
|
+
|
|
447
|
+
type: Literal["webrtc"] = "webrtc"
|
|
448
|
+
sdp: str
|
|
449
|
+
|
|
450
|
+
|
|
451
|
+
class LiveCreateResponse(CodexBaseModel):
|
|
452
|
+
"""OpenAI-compatible view of a Codex OAuth Realtime call response."""
|
|
453
|
+
|
|
454
|
+
session: LiveSession
|
|
455
|
+
transport: LiveTransport
|
|
456
|
+
|
|
457
|
+
|
|
458
|
+
class LiveEvent(CodexBaseModel):
|
|
459
|
+
"""Forward-compatible Live sideband event with attribute access."""
|
|
460
|
+
|
|
461
|
+
type: str
|
|
462
|
+
|
|
463
|
+
|
|
438
464
|
def _is_uuid(value: str) -> bool:
|
|
439
465
|
if len(value) != 36:
|
|
440
466
|
return False
|
|
@@ -8,6 +8,26 @@ from typing import Any
|
|
|
8
8
|
import requests
|
|
9
9
|
|
|
10
10
|
|
|
11
|
+
_MAX_ERROR_DETAIL_CHARS = 4_000
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def raise_for_status_with_detail(response: requests.Response) -> None:
|
|
15
|
+
"""Raise the usual HTTPError while retaining a bounded backend error body."""
|
|
16
|
+
try:
|
|
17
|
+
response.raise_for_status()
|
|
18
|
+
except requests.HTTPError as error:
|
|
19
|
+
detail = response.text.strip()
|
|
20
|
+
if not detail:
|
|
21
|
+
raise
|
|
22
|
+
if len(detail) > _MAX_ERROR_DETAIL_CHARS:
|
|
23
|
+
detail = detail[:_MAX_ERROR_DETAIL_CHARS] + "..."
|
|
24
|
+
raise requests.HTTPError(
|
|
25
|
+
f"{error}. Backend response: {detail}",
|
|
26
|
+
response=response,
|
|
27
|
+
request=error.request,
|
|
28
|
+
) from error
|
|
29
|
+
|
|
30
|
+
|
|
11
31
|
def request_with_retries(
|
|
12
32
|
session: requests.Session,
|
|
13
33
|
method: str,
|
|
@@ -26,7 +46,7 @@ def request_with_retries(
|
|
|
26
46
|
if should_retry_response(response, attempt, max_retries=max_retries):
|
|
27
47
|
sleep_before_retry(response, attempt, retry_base_delay=retry_base_delay)
|
|
28
48
|
continue
|
|
29
|
-
response
|
|
49
|
+
raise_for_status_with_detail(response)
|
|
30
50
|
return response
|
|
31
51
|
except (requests.Timeout, requests.ConnectionError) as exc:
|
|
32
52
|
last_error = exc
|
|
@@ -18,6 +18,10 @@ from ._models import (
|
|
|
18
18
|
ImageData,
|
|
19
19
|
ImageResponse,
|
|
20
20
|
ImagesResponse,
|
|
21
|
+
LiveCreateResponse,
|
|
22
|
+
LiveEvent,
|
|
23
|
+
LiveSession,
|
|
24
|
+
LiveTransport,
|
|
21
25
|
Model,
|
|
22
26
|
MemorySummarizeOutput,
|
|
23
27
|
MemorySummarizeResponse,
|
|
@@ -55,6 +59,10 @@ __all__ = [
|
|
|
55
59
|
"ImageData",
|
|
56
60
|
"ImageResponse",
|
|
57
61
|
"ImagesResponse",
|
|
62
|
+
"LiveCreateResponse",
|
|
63
|
+
"LiveEvent",
|
|
64
|
+
"LiveSession",
|
|
65
|
+
"LiveTransport",
|
|
58
66
|
"CompactedResponse",
|
|
59
67
|
"MemorySummarizeOutput",
|
|
60
68
|
"MemorySummarizeResponse",
|