oauth-codex 2.0.0__tar.gz → 2.0.2__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.
- {oauth_codex-2.0.0 → oauth_codex-2.0.2}/PKG-INFO +22 -22
- oauth_codex-2.0.2/README.md +89 -0
- {oauth_codex-2.0.0 → oauth_codex-2.0.2}/pyproject.toml +1 -1
- {oauth_codex-2.0.0 → oauth_codex-2.0.2}/src/oauth_codex/_client.py +5 -12
- {oauth_codex-2.0.0 → oauth_codex-2.0.2}/src/oauth_codex/_engine.py +372 -49
- {oauth_codex-2.0.0 → oauth_codex-2.0.2}/src/oauth_codex/_version.py +1 -1
- {oauth_codex-2.0.0 → oauth_codex-2.0.2}/src/oauth_codex/core_types.py +1 -1
- {oauth_codex-2.0.0 → oauth_codex-2.0.2}/src/oauth_codex/tooling.py +36 -11
- {oauth_codex-2.0.0 → oauth_codex-2.0.2}/src/oauth_codex.egg-info/PKG-INFO +22 -22
- {oauth_codex-2.0.0 → oauth_codex-2.0.2}/src/oauth_codex.egg-info/SOURCES.txt +1 -0
- oauth_codex-2.0.2/tests/test_engine_stream_and_continuity.py +170 -0
- {oauth_codex-2.0.0 → oauth_codex-2.0.2}/tests/test_generate_sync.py +27 -0
- oauth_codex-2.0.0/README.md +0 -89
- {oauth_codex-2.0.0 → oauth_codex-2.0.2}/setup.cfg +0 -0
- {oauth_codex-2.0.0 → oauth_codex-2.0.2}/src/oauth_codex/__init__.py +0 -0
- {oauth_codex-2.0.0 → oauth_codex-2.0.2}/src/oauth_codex/_base_client.py +0 -0
- {oauth_codex-2.0.0 → oauth_codex-2.0.2}/src/oauth_codex/_exceptions.py +0 -0
- {oauth_codex-2.0.0 → oauth_codex-2.0.2}/src/oauth_codex/_models.py +0 -0
- {oauth_codex-2.0.0 → oauth_codex-2.0.2}/src/oauth_codex/_module_client.py +0 -0
- {oauth_codex-2.0.0 → oauth_codex-2.0.2}/src/oauth_codex/_resource.py +0 -0
- {oauth_codex-2.0.0 → oauth_codex-2.0.2}/src/oauth_codex/_types.py +0 -0
- {oauth_codex-2.0.0 → oauth_codex-2.0.2}/src/oauth_codex/auth/__init__.py +0 -0
- {oauth_codex-2.0.0 → oauth_codex-2.0.2}/src/oauth_codex/auth/config.py +0 -0
- {oauth_codex-2.0.0 → oauth_codex-2.0.2}/src/oauth_codex/auth/pkce.py +0 -0
- {oauth_codex-2.0.0 → oauth_codex-2.0.2}/src/oauth_codex/auth/store.py +0 -0
- {oauth_codex-2.0.0 → oauth_codex-2.0.2}/src/oauth_codex/auth/token_manager.py +0 -0
- {oauth_codex-2.0.0 → oauth_codex-2.0.2}/src/oauth_codex/compat_store.py +0 -0
- {oauth_codex-2.0.0 → oauth_codex-2.0.2}/src/oauth_codex/errors.py +0 -0
- {oauth_codex-2.0.0 → oauth_codex-2.0.2}/src/oauth_codex/py.typed +0 -0
- {oauth_codex-2.0.0 → oauth_codex-2.0.2}/src/oauth_codex/resources/__init__.py +0 -0
- {oauth_codex-2.0.0 → oauth_codex-2.0.2}/src/oauth_codex/resources/_wrappers.py +0 -0
- {oauth_codex-2.0.0 → oauth_codex-2.0.2}/src/oauth_codex/resources/files.py +0 -0
- {oauth_codex-2.0.0 → oauth_codex-2.0.2}/src/oauth_codex/resources/models.py +0 -0
- {oauth_codex-2.0.0 → oauth_codex-2.0.2}/src/oauth_codex/resources/responses/__init__.py +0 -0
- {oauth_codex-2.0.0 → oauth_codex-2.0.2}/src/oauth_codex/resources/responses/_helpers.py +0 -0
- {oauth_codex-2.0.0 → oauth_codex-2.0.2}/src/oauth_codex/resources/responses/input_tokens.py +0 -0
- {oauth_codex-2.0.0 → oauth_codex-2.0.2}/src/oauth_codex/resources/responses/responses.py +0 -0
- {oauth_codex-2.0.0 → oauth_codex-2.0.2}/src/oauth_codex/resources/vector_stores/__init__.py +0 -0
- {oauth_codex-2.0.0 → oauth_codex-2.0.2}/src/oauth_codex/resources/vector_stores/file_batches.py +0 -0
- {oauth_codex-2.0.0 → oauth_codex-2.0.2}/src/oauth_codex/resources/vector_stores/files.py +0 -0
- {oauth_codex-2.0.0 → oauth_codex-2.0.2}/src/oauth_codex/resources/vector_stores/vector_stores.py +0 -0
- {oauth_codex-2.0.0 → oauth_codex-2.0.2}/src/oauth_codex/store.py +0 -0
- {oauth_codex-2.0.0 → oauth_codex-2.0.2}/src/oauth_codex/types/__init__.py +0 -0
- {oauth_codex-2.0.0 → oauth_codex-2.0.2}/src/oauth_codex/types/file_deleted.py +0 -0
- {oauth_codex-2.0.0 → oauth_codex-2.0.2}/src/oauth_codex/types/file_object.py +0 -0
- {oauth_codex-2.0.0 → oauth_codex-2.0.2}/src/oauth_codex/types/responses/__init__.py +0 -0
- {oauth_codex-2.0.0 → oauth_codex-2.0.2}/src/oauth_codex/types/responses/input_token_count_response.py +0 -0
- {oauth_codex-2.0.0 → oauth_codex-2.0.2}/src/oauth_codex/types/responses/response.py +0 -0
- {oauth_codex-2.0.0 → oauth_codex-2.0.2}/src/oauth_codex/types/responses/response_stream_event.py +0 -0
- {oauth_codex-2.0.0 → oauth_codex-2.0.2}/src/oauth_codex/types/shared/__init__.py +0 -0
- {oauth_codex-2.0.0 → oauth_codex-2.0.2}/src/oauth_codex/types/shared/model_capabilities.py +0 -0
- {oauth_codex-2.0.0 → oauth_codex-2.0.2}/src/oauth_codex/types/shared/usage.py +0 -0
- {oauth_codex-2.0.0 → oauth_codex-2.0.2}/src/oauth_codex/types/vector_stores/__init__.py +0 -0
- {oauth_codex-2.0.0 → oauth_codex-2.0.2}/src/oauth_codex/types/vector_stores/vector_store.py +0 -0
- {oauth_codex-2.0.0 → oauth_codex-2.0.2}/src/oauth_codex/types/vector_stores/vector_store_deleted.py +0 -0
- {oauth_codex-2.0.0 → oauth_codex-2.0.2}/src/oauth_codex/types/vector_stores/vector_store_file.py +0 -0
- {oauth_codex-2.0.0 → oauth_codex-2.0.2}/src/oauth_codex/types/vector_stores/vector_store_file_batch.py +0 -0
- {oauth_codex-2.0.0 → oauth_codex-2.0.2}/src/oauth_codex/types/vector_stores/vector_store_search_response.py +0 -0
- {oauth_codex-2.0.0 → oauth_codex-2.0.2}/src/oauth_codex/version.py +0 -0
- {oauth_codex-2.0.0 → oauth_codex-2.0.2}/src/oauth_codex.egg-info/dependency_links.txt +0 -0
- {oauth_codex-2.0.0 → oauth_codex-2.0.2}/src/oauth_codex.egg-info/requires.txt +0 -0
- {oauth_codex-2.0.0 → oauth_codex-2.0.2}/src/oauth_codex.egg-info/top_level.txt +0 -0
- {oauth_codex-2.0.0 → oauth_codex-2.0.2}/tests/test_generate_async.py +0 -0
- {oauth_codex-2.0.0 → oauth_codex-2.0.2}/tests/test_public_surface.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: oauth-codex
|
|
3
|
-
Version: 2.0.
|
|
3
|
+
Version: 2.0.2
|
|
4
4
|
Summary: Codex OAuth-based Python SDK with a single Client and generate-first API
|
|
5
5
|
Author: Codex
|
|
6
6
|
Requires-Python: >=3.11
|
|
@@ -16,22 +16,22 @@ Requires-Dist: pytest-asyncio>=0.23.0; extra == "dev"
|
|
|
16
16
|
|
|
17
17
|
# oauth-codex
|
|
18
18
|
|
|
19
|
-
OAuth PKCE
|
|
19
|
+
OAuth PKCE-based Python SDK for the Codex backend.
|
|
20
20
|
|
|
21
|
-
##
|
|
21
|
+
## Key Changes (v2)
|
|
22
22
|
|
|
23
|
-
-
|
|
24
|
-
-
|
|
25
|
-
-
|
|
26
|
-
-
|
|
23
|
+
- The public API now exposes a single `Client`.
|
|
24
|
+
- The default workflow is centered around `generate`.
|
|
25
|
+
- Async support is provided on the same class via `agenerate` and `astream`.
|
|
26
|
+
- Supports text generation, image input analysis, automatic function-calling execution, and `reasoning_effort`.
|
|
27
27
|
|
|
28
|
-
##
|
|
28
|
+
## Installation
|
|
29
29
|
|
|
30
30
|
```bash
|
|
31
31
|
pip install oauth-codex
|
|
32
32
|
```
|
|
33
33
|
|
|
34
|
-
##
|
|
34
|
+
## Quick Start
|
|
35
35
|
|
|
36
36
|
```python
|
|
37
37
|
from oauth_codex import Client
|
|
@@ -41,30 +41,30 @@ text = client.generate("hello")
|
|
|
41
41
|
print(text)
|
|
42
42
|
```
|
|
43
43
|
|
|
44
|
-
##
|
|
44
|
+
## Image Input
|
|
45
45
|
|
|
46
46
|
```python
|
|
47
47
|
text = client.generate(
|
|
48
|
-
"
|
|
48
|
+
"Describe this image",
|
|
49
49
|
images=["https://example.com/cat.png", "./local-photo.jpg"],
|
|
50
50
|
)
|
|
51
51
|
print(text)
|
|
52
52
|
```
|
|
53
53
|
|
|
54
|
-
## Function Calling (
|
|
54
|
+
## Function Calling (Automatic Loop)
|
|
55
55
|
|
|
56
56
|
```python
|
|
57
57
|
def add(a: int, b: int) -> dict:
|
|
58
58
|
return {"sum": a + b}
|
|
59
59
|
|
|
60
60
|
text = client.generate(
|
|
61
|
-
"2+3
|
|
61
|
+
"Calculate 2+3",
|
|
62
62
|
tools=[add],
|
|
63
63
|
)
|
|
64
64
|
print(text)
|
|
65
65
|
```
|
|
66
66
|
|
|
67
|
-
|
|
67
|
+
If a tool raises an exception, the SDK forwards it to the model as `{\"error\": ...}` and continues the loop.
|
|
68
68
|
|
|
69
69
|
## Async
|
|
70
70
|
|
|
@@ -82,22 +82,22 @@ async def main() -> None:
|
|
|
82
82
|
asyncio.run(main())
|
|
83
83
|
```
|
|
84
84
|
|
|
85
|
-
##
|
|
85
|
+
## Breaking Changes in v2.0
|
|
86
86
|
|
|
87
|
-
-
|
|
88
|
-
-
|
|
87
|
+
- Removed: `AsyncOAuthCodexClient`, module-level proxies, `client.responses/files/vector_stores/models`, `oauth_codex.compat`
|
|
88
|
+
- Single entry points: `Client.generate/stream/agenerate/astream`
|
|
89
89
|
|
|
90
|
-
##
|
|
90
|
+
## Documentation
|
|
91
91
|
|
|
92
|
-
-
|
|
93
|
-
-
|
|
92
|
+
- English index: [`docs/en/index.md`](docs/en/index.md)
|
|
93
|
+
- Korean index: [`docs/ko/index.md`](docs/ko/index.md)
|
|
94
94
|
|
|
95
|
-
##
|
|
95
|
+
## Development
|
|
96
96
|
|
|
97
97
|
```bash
|
|
98
98
|
pytest -q
|
|
99
99
|
```
|
|
100
100
|
|
|
101
|
-
##
|
|
101
|
+
## Changelog
|
|
102
102
|
|
|
103
103
|
- [`CHANGELOG.md`](CHANGELOG.md)
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
[English](README.md) | [한국어](README.ko.md)
|
|
2
|
+
|
|
3
|
+
# oauth-codex
|
|
4
|
+
|
|
5
|
+
OAuth PKCE-based Python SDK for the Codex backend.
|
|
6
|
+
|
|
7
|
+
## Key Changes (v2)
|
|
8
|
+
|
|
9
|
+
- The public API now exposes a single `Client`.
|
|
10
|
+
- The default workflow is centered around `generate`.
|
|
11
|
+
- Async support is provided on the same class via `agenerate` and `astream`.
|
|
12
|
+
- Supports text generation, image input analysis, automatic function-calling execution, and `reasoning_effort`.
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
pip install oauth-codex
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Quick Start
|
|
21
|
+
|
|
22
|
+
```python
|
|
23
|
+
from oauth_codex import Client
|
|
24
|
+
|
|
25
|
+
client = Client()
|
|
26
|
+
text = client.generate("hello")
|
|
27
|
+
print(text)
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Image Input
|
|
31
|
+
|
|
32
|
+
```python
|
|
33
|
+
text = client.generate(
|
|
34
|
+
"Describe this image",
|
|
35
|
+
images=["https://example.com/cat.png", "./local-photo.jpg"],
|
|
36
|
+
)
|
|
37
|
+
print(text)
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Function Calling (Automatic Loop)
|
|
41
|
+
|
|
42
|
+
```python
|
|
43
|
+
def add(a: int, b: int) -> dict:
|
|
44
|
+
return {"sum": a + b}
|
|
45
|
+
|
|
46
|
+
text = client.generate(
|
|
47
|
+
"Calculate 2+3",
|
|
48
|
+
tools=[add],
|
|
49
|
+
)
|
|
50
|
+
print(text)
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
If a tool raises an exception, the SDK forwards it to the model as `{\"error\": ...}` and continues the loop.
|
|
54
|
+
|
|
55
|
+
## Async
|
|
56
|
+
|
|
57
|
+
```python
|
|
58
|
+
import asyncio
|
|
59
|
+
from oauth_codex import Client
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
async def main() -> None:
|
|
63
|
+
client = Client()
|
|
64
|
+
text = await client.agenerate("hello async")
|
|
65
|
+
print(text)
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
asyncio.run(main())
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Breaking Changes in v2.0
|
|
72
|
+
|
|
73
|
+
- Removed: `AsyncOAuthCodexClient`, module-level proxies, `client.responses/files/vector_stores/models`, `oauth_codex.compat`
|
|
74
|
+
- Single entry points: `Client.generate/stream/agenerate/astream`
|
|
75
|
+
|
|
76
|
+
## Documentation
|
|
77
|
+
|
|
78
|
+
- English index: [`docs/en/index.md`](docs/en/index.md)
|
|
79
|
+
- Korean index: [`docs/ko/index.md`](docs/ko/index.md)
|
|
80
|
+
|
|
81
|
+
## Development
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
pytest -q
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Changelog
|
|
88
|
+
|
|
89
|
+
- [`CHANGELOG.md`](CHANGELOG.md)
|
|
@@ -20,7 +20,7 @@ from .core_types import (
|
|
|
20
20
|
ToolResult,
|
|
21
21
|
)
|
|
22
22
|
from .store import FallbackTokenStore
|
|
23
|
-
from .tooling import callable_to_tool_schema
|
|
23
|
+
from .tooling import callable_to_tool_schema, normalize_tool_output
|
|
24
24
|
|
|
25
25
|
DEFAULT_MODEL = "gpt-5.3-codex"
|
|
26
26
|
DEFAULT_MAX_TOOL_ROUNDS = 8
|
|
@@ -364,7 +364,7 @@ class OAuthCodexClient(SyncAPIClient):
|
|
|
364
364
|
) -> list[ToolResult]:
|
|
365
365
|
results: list[ToolResult] = []
|
|
366
366
|
for call in tool_calls:
|
|
367
|
-
output:
|
|
367
|
+
output: dict[str, Any]
|
|
368
368
|
tool = tools_by_name.get(call.name)
|
|
369
369
|
if tool is None:
|
|
370
370
|
output = {"error": f"tool not found: {call.name}"}
|
|
@@ -387,7 +387,7 @@ class OAuthCodexClient(SyncAPIClient):
|
|
|
387
387
|
) -> list[ToolResult]:
|
|
388
388
|
results: list[ToolResult] = []
|
|
389
389
|
for call in tool_calls:
|
|
390
|
-
output:
|
|
390
|
+
output: dict[str, Any]
|
|
391
391
|
tool = tools_by_name.get(call.name)
|
|
392
392
|
if tool is None:
|
|
393
393
|
output = {"error": f"tool not found: {call.name}"}
|
|
@@ -411,15 +411,8 @@ class OAuthCodexClient(SyncAPIClient):
|
|
|
411
411
|
raise TypeError("tool arguments must be a JSON object")
|
|
412
412
|
return parsed
|
|
413
413
|
|
|
414
|
-
def _normalize_tool_output(self, output: Any) ->
|
|
415
|
-
|
|
416
|
-
return output
|
|
417
|
-
if isinstance(output, str):
|
|
418
|
-
return output
|
|
419
|
-
try:
|
|
420
|
-
return json.dumps(output, ensure_ascii=True)
|
|
421
|
-
except TypeError:
|
|
422
|
-
return str(output)
|
|
414
|
+
def _normalize_tool_output(self, output: Any) -> dict[str, Any]:
|
|
415
|
+
return normalize_tool_output(output)
|
|
423
416
|
|
|
424
417
|
|
|
425
418
|
Client = OAuthCodexClient
|