Skip to main content

llm-openai-codex

LLM plugin for accessing ChatGPT/Codex-backed OpenAI models through the Responses API.

Changes from the original plugin

  • Package renamed to llm-openai-codex.
  • Model prefix changed to codex/.
  • Plugin-owned auth is stored in LLM's user config directory as auth-codex.json, with borrowed fallback to ${CODEX_HOME:-~/.codex}/auth.json.
  • llm codex auth commands manage login, local or SCP import, status, refresh, and logout.
  • Explicit verbosity option maps to Responses API text.verbosity.
  • Extra Responses API options are forwarded when LLM accepts them.
  • Missing account_id values are derived from OAuth JWT claims when possible.
  • Added llm codex usage showing current Codex plan usage.
  • Registers known hidden/fallback Codex models such as gpt-5.3-codex-spark.
  • Added OpenAI's server-side web_search tool via -T WebSearch (shared with LLM's built-in OpenAI models) or -o web_search 1.
  • Streams visible reasoning summaries and round-trips encrypted reasoning between turns.
  • Tool call names stream as soon as the model starts a call, before the arguments finish generating.

Installation

Install the plugin in the same environment as LLM:

llm install llm-openai-codex

Requires LLM 0.34 or later and OpenAI Python SDK newer than 3.0.0, following LLM's httpx2 dependency stack. Installation resolves these dependencies automatically. The plugin uses the SDK's HTTP client; it does not require a separate httpx installation.

Authentication: plugin-owned or borrowed

The plugin can use ChatGPT OAuth credentials from two places, in this order:

  1. Plugin-owned auth at auth-codex.json in LLM's user config directory. This is used whenever the file exists. Create it with llm codex login, copy local Codex CLI credentials with llm codex import, or import a remote access-token snapshot over SCP.
  2. Borrowed Codex CLI auth at ${CODEX_HOME:-~/.codex}/auth.json. If plugin-owned auth does not exist, the plugin automatically uses this file; no import is required.

Choose how to set up plugin-owned auth:

# Perform a new OAuth login and save its credentials for this plugin
llm codex login [--device-code]

# Reuse an existing Codex CLI login by copying its current credentials
llm codex import

# Import an explicit local Codex auth file
llm codex import --path /path/to/auth.json

# Import a remote access-token snapshot (the trailing colon selects SCP)
llm codex import --path hostname:
llm codex import --path user@hostname:

login performs a new OAuth flow. A local import performs no login: it copies the current Codex CLI tokens into auth-codex.json, so later plugin refreshes update the plugin's copy instead of the Codex CLI file. Import creates separate storage, not a fresh OAuth authorization. It is useful when you are already logged in with Codex CLI but do not want the plugin to keep writing to its auth file. Local imports refuse to overwrite existing plugin-owned auth; run llm codex logout first if you intend to replace it.

An import target ending in : uses the system scp executable to copy the fixed remote file ~/.codex/auth.json. Arbitrary remote paths and remote CODEX_HOME discovery are not supported. The machine running LLM must have scp installed and SSH configured for the target; host-key, password, and key-passphrase prompts use the current terminal. The downloaded JSON is validated in a temporary directory before plugin auth is written, and temporary files are always removed.

SCP imports deliberately discard the remote refresh token and store only a non-refreshable snapshot (login_type: "scp"). The access token is used until its JWT expiry. If the expiry cannot be decoded, the token is sent unchanged so the backend can accept or reject it. Once a decoded expiry has passed, commands report that the SCP import must be repeated; llm codex refresh never refreshes an SCP snapshot.

Repeating an SCP import can safely replace existing plugin auth without a logout only when the existing auth has no refresh token and has a decodable, expired access-token expiry. This check happens before scp runs. Otherwise the command identifies the existing auth file and asks you to inspect it with llm codex status; remove it with llm codex logout only when replacement is intended. A failed SCP transfer or invalid download leaves the existing snapshot untouched. If plugin auth changes while the transfer is running, installation is aborted rather than overwriting the newer auth.

OAuth login, local imports, and borrowed Codex CLI auth refresh when a token nears expiry and with llm codex refresh. Refreshing rotates the refresh token. In borrowed mode this modifies the file shared with Codex CLI and can briefly disrupt a simultaneous CLI session; the plugin prints a warning. llm codex status shows the active source and refreshable: yes/no.

llm codex logout only deletes the local plugin-owned auth file, making Codex CLI auth the fallback again. It does not contact an API, revoke a token, or alter a remote machine, and routine re-import of an expired SCP snapshot does not require it.

Plugin commands

llm codex login [--device-code]  # create plugin-owned auth with OAuth
llm codex import                 # copy Codex CLI auth into plugin-owned auth
llm codex import --path PATH     # copy an explicit local auth file
llm codex import --path HOST:    # SCP HOST:~/.codex/auth.json as a snapshot
llm codex status                 # show the active source and refreshability
llm codex refresh                # refresh the active source
llm codex usage                  # show current Codex plan usage
llm codex logout                 # delete local plugin-owned auth only

Usage

List available models:

llm models -q codex

Models are discovered from the Codex API and combined with known hidden/fallback slugs. Availability depends on your plan; a listed fallback may still fail at request time. Discovery is cached for 24 hours in codex_models.json in LLM's user config directory; delete it to force a re-fetch.

codex/gpt-6-astra is included as a fallback, so it is available for selection even when the cached discovery list does not include it. Access depends on your account and the rollout; see OpenAI's Codex model documentation.

llm -m codex/gpt-6-astra "Review this code"
llm -m codex/gpt-6-astra -o reasoning_effort max "Analyze this difficult problem"

Run a prompt and optionally set Responses API verbosity:

llm -m codex/gpt-5.6-luna "Hello"
llm -m codex/gpt-5.6-terra -o verbosity low "Summarize this"

Image attachments (-a image.png) are sent at low detail to limit token use.

Fast mode and service tiers

Select Fast mode with -o service_tier fast (an alias for priority):

llm -m codex/gpt-5.5 -o service_tier fast "Review this code"

# Save Fast mode as the default for this model
llm models options set codex/gpt-5.5 service_tier priority

# Override the saved setting for one request with standard processing
llm -m codex/gpt-5.5 -o service_tier default "Explain this function"

# Remove the saved default
llm models options clear codex/gpt-5.5 service_tier

Fast mode requests faster processing of the same model at higher ChatGPT credit consumption. See OpenAI's Codex speed documentation for current availability and credit rates.

service_tier accepts auto, default, flex, scale, priority, fast, and ultrafast. The plugin sends fast as priority and forwards the other values unchanged. These values are validated locally; support depends on the Codex backend, model, and account. Unsupported tiers retain the backend's error; the plugin does not retry with another tier. When no option or saved default is set, the plugin omits service_tier, preserving the backend's default behavior. Reasoning effort is configured separately.

Reasoning

Codex models are reasoning models. Visible reasoning summaries stream to standard error while a response runs; hide them with -R/--hide-reasoning. Customize the summary detail level with -o reasoning_summary auto|concise|detailed (defaults to auto):

llm -m codex/gpt-5.6-luna -o reasoning_summary concise "Explain quantum computing"

Reasoning effort can also be adjusted with -o reasoning_effort low|medium|high|xhigh|max. Supported levels depend on the model; GPT-6 Astra supports all five.

llm -m codex/gpt-5.6-luna -o reasoning_effort high "Solve this puzzle"

Requests run stateless (store: false), so the plugin asks the API for encrypted reasoning items and echoes them back on later turns. The model keeps its chain of thought across tool calls and continued conversations (llm -c, llm chat -c).

OpenAI's server-side search (it runs on OpenAI's servers, not locally) is available as a server-side tool using the same WebSearch class as LLM's built-in OpenAI models:

llm -m codex/gpt-5.6-luna -T WebSearch "What happened in AI news today?"
llm -m codex/gpt-5.6-luna -T 'WebSearch(external_web_access=True)' "Latest stable Python release?"
llm -m codex/gpt-5.6-luna -T 'WebSearch(allowed_domains=["python.org"], search_context_size="high")' "Recent Python changes"

external_web_access requests live internet access instead of the cached index. Run llm tools -m codex/gpt-5.6-luna to see every constructor argument, including domain filters, user location, and image search. Conversations continued with llm -c restore the configured tool automatically. Searches are recorded in the conversation log as server-executed tool calls; when the final response payload carries more complete search data than the stream did, the recorded values are refreshed from it. Raw provider specifications also work, for server-side tools the plugin does not know about yet:

llm -m codex/gpt-5.6-luna -T 'ServerSideTool({"type": "web_search"})' "..."

The older option-based form is still supported and remains the way to set a per-model default:

llm -m codex/gpt-5.6-luna -o web_search 1 -o web_search_live 1 "Latest stable Python release?"
llm models options set codex/gpt-5.6-luna web_search 1

web_search_live maps to external_web_access and web_search_context_size to search_context_size. An explicit -T WebSearch tool takes precedence over the option-based form. Availability depends on the plan and model.

Development

uv run pytest
uv run llm plugins
uv run llm codex status

Releasing

  1. Finish and verify the feature/fix commits.
  2. Bump pyproject.toml and commit it separately: git add pyproject.toml && git commit -m "bump: v0.5.0".
  3. Tag and push: git tag v0.5.0 && git push origin main v0.5.0.
  4. Create the release: gh release create v0.5.0 --generate-notes.

The whole flow is version commit, tag, push, then GitHub Release. The release triggers testing and PyPI publication.

Metadata

Release files for llm-openai-codex 0.8.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for llm-openai-codex 0.8.0
File Size Uploaded
llm_openai_codex-0.8.0.tar.gz 39.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for llm-openai-codex 0.8.0
File Interpreter ABI Platform
llm_openai_codex-0.8.0-py3-none-any.whl Python 3 none any Details

Total release size: 66.6 kB

Release files / llm_openai_codex-0.8.0.tar.gz

Download URL llm_openai_codex-0.8.0.tar.gz
Size 39.9 kB
Tags Source
SHA-256 checksum
How to use checksums
4957714f88d82d926768a4bbe0f4a61ec90c3f19b5e893be0cc6d247b8521c14
BLAKE2b-256 checksum
How to use checksums
2a2be50359076c495e722284e09e394e5c048340a977fb33bd3dbcc85cbd9846
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 6, 2026.

Transparency log

Release files / llm_openai_codex-0.8.0-py3-none-any.whl

Download URL llm_openai_codex-0.8.0-py3-none-any.whl
Size 26.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
be4c941aa00d64344c41db447ea4e891a6952c89dcfdbe4e7c8f4db7448280aa
BLAKE2b-256 checksum
How to use checksums
1da86137603a90e40554dbb32d035647a2e3bcbd551b1bb209df1c75cc8a9091
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 6, 2026.

Transparency log

Release history Release notifications | RSS feed

0.10.1

2 release files

0.10.0

2 release files

0.9.0

2 release files

This release

0.8.0 This release

2 release files

0.7.0

2 release files

0.6.1

2 release files

0.5.0

2 release files

0.4.1

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.3

2 release files

0.2.2

2 release files

0.2.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page