Metadata-Version: 2.4
Name: llm-async-codex
Version: 0.1.1
Summary: ChatGPT Codex subscription provider for llm-async
License-Expression: MIT
License-File: LICENSE.md
Keywords: llm,codex,chatgpt,openai,asyncio,ai,oauth,streaming,tool calling
Author: Johanderson Mogollon
Author-email: johander1822@gmail.com
Requires-Python: >=3.10,<4.0
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Intended Audience :: Developers
Classifier: Topic :: Software Development :: Libraries
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Requires-Dist: aiosonic (>=1.0.6)
Requires-Dist: llm-async (>=0.5.2)
Project-URL: Bug Tracker, https://github.com/sonic182/llm-async-codex/issues
Project-URL: Changelog, https://github.com/sonic182/llm-async-codex/blob/master/CHANGELOG.md
Project-URL: Documentation, https://github.com/sonic182/llm-async-codex#readme
Project-URL: Homepage, https://github.com/sonic182/llm-async-codex
Project-URL: Repository, https://github.com/sonic182/llm-async-codex
Description-Content-Type: text/markdown

# llm-async-codex

ChatGPT Codex subscription provider for [`llm-async`](https://pypi.org/project/llm-async/).

```python
from llm_async_codex import CodexProvider

provider = CodexProvider.from_codex_home()
response = await provider.acomplete(
    model="gpt-5.5",
    messages=[{"role": "user", "content": "Review this repository."}],
    stream=True,
)
async for chunk in response.stream_content():
    print(chunk, end="", flush=True)
```

This reads an existing Codex CLI login from `$CODEX_HOME/auth.json` or `~/.codex/auth.json` by default (`CodexProvider.from_codex_home()`), or a `CodexCredentials` loaded from any path via `load_credentials(path)`.

## Login

If you don't already have a Codex CLI login, log in directly:

```
llm-async-codex login
llm-async-codex login --device-code   # headless/SSH, no local browser needed
llm-async-codex login --auth-file ~/.my-tool/auth.json
llm-async-codex login --verbose
```

or from Python: `await login(device_code=False, auth_path=None, verbose=False)`.

## Tool calling

Tool calling works through the normal streaming API: call `provider.acomplete(..., stream=True, tools=[...])`, drain `response.stream_content()`, then read `response.main_response.tool_calls`. Requires `llm-async>=0.5.2`.

## Limitations

- **Streaming only**: the Codex backend requires `stream=True`; non-streaming requests are rejected.
- **No stateless multi-turn**: the backend rejects `store=True` (`"Store must be set to false"`), so `previous_response_id`-based continuation (as used in some of `llm-async`'s other Responses API examples) does not work here. Resend the full conversation history (including `function_call`/`function_call_output` items) on every turn instead.

