chatgpt.com/backend-api/codex endpoints. Existing
credentials cannot be migrated: run codex_login() again.codex_login() registers dynamically with client_id=dynamic_agent_client,
stores the client ID that OpenAI issues for the chosen account and
workspace, and reauthorizes that registration on later sign-ins. It sends a
stable ext_agent_host_id, created once per host, and uses PKCE and a nonce.
The ID token is verified against OpenAI's published keys, and sign-in fails
with the new codex_plan_scope_error when ChatGPT plan usage
(chatgpt.tokens.use.direct) is not granted. The package now imports
jose for ID token verification.http://localhost:1455/auth/callback to
http://127.0.0.1:1455/callback, as the documentation requires. Set
ELLMERCODEX_CALLBACK_PORT to use another port.credentials.json (mode 0600, atomic writes) in
tools::R_user_dir("ellmercodex", "config"), or in the directory named by
ELLMERCODEX_HOME. HTTR2_OAUTH_CACHE no longer applies. Refreshes are
serialized across R processes because refresh tokens rotate.codex_logout() gains revoke = TRUE and now revokes the refresh token
with OpenAI before deleting the local credential. It also removes the old
httr2 cache entry. To switch account or workspace, log out and sign in
again.codex_models() use the public https://api.openai.com/v1
Responses and Models endpoints with only the bearer token; the
ChatGPT-Account-Id, OpenAI-Beta, and originator headers are gone.
codex_models() keeps models with visibility: "list", and its
client_version argument is deprecated and ignored
(ELLMERCODEX_CLIENT_VERSION is no longer read).developer messages, function tools are grouped in an ellmer
namespace, and temperature, top_p, max_tokens, metadata,
previous_response_id, and the other excluded Responses arguments now fail
with codex_chat_argument_error before a request is sent.response.incomplete event now fails a Chat turn with
codex_incomplete_error instead of returning a truncated turn.codex_usage_limit_error (a codex_rate_limit_error),
codex_usage_unavailable_error (a codex_server_error),
codex_plan_ineligible_error (a codex_authentication_error), and
codex_unsupported_capability_error (a codex_malformed_request_error).
Synchronous chats now raise these package conditions, rather than httr2
errors, for HTTP failures before the stream opens.Codex generation requests no longer inherit ellmer's automatic retries, as documented in the technical design: a retried request could duplicate a generation the service already accepted.
Codex requests and turn costs are now built without five unexported ellmer helpers, reducing the private ellmer surface ahead of a CRAN submission.
chat_codex() now accepts explicitly selected models omitted from the
account catalog. The service validates those model IDs and reasoning efforts.
chat_codex() now supports ellmer 0.5.0 and later through a Model/Provider
adapter, request callbacks, and checked private Chat contracts. Provider
token counting and file management report unsupported operations before a
request; offline CI tests the minimum and latest ellmer releases (#3).Replaced the OS-keyring credential backend with httr2's encrypted OAuth
cache. Cached tokens are stored in a user-level ellmercodex cache and
refreshed without macOS Keychain prompts.
Fixed streamed reasoning summaries whose initial summary array is empty.
Reasoning deltas now initialize the first summary part and use the streamed
reasoning item identifier when it is available.
Selects the default model from the authenticated account catalog, validates reasoning effort against advertised model capabilities, and reports actionable discovery failures instead of silently using a static model.
Preserves omitted usage values as unknown, tests the actual ellmer parallel/batch boundaries, and consolidates tool execution in the version-gated compatibility architecture.
Expands the opt-in live acceptance runner and documents the remaining observed, undocumented transport risk without introducing a Codex CLI runtime dependency.
item_id and merging completed message
items instead of recording the same assistant text twice.Chat
object for interactive, single-conversation operations. The separately
exported parallel and batch helpers remain explicitly unsupported because
the subscription transport is stream-only; the package no longer presents
that limitation as a blocker to the bounded core contract.CodexProvider and
ellmer 0.4.2's own Chat lifecycle. The public Chat methods, R6 cloning,
sync/async tool loops, structured output, rich ordered content, cancellation,
history, echo, usage, cost, duration, and finish metadata now share one
compatibility seam rather than per-instance public-method patches.docs/ellmer-chat-interface.md.effort, ellmer params(), and api_args support to chat_codex().
Reasoning effort is forwarded using ellmer's Responses-compatible mapping.Chat$chat_structured(), including
repair of the terminal assistant turn into ellmer ContentJson.chat_codex(),
including fragmented Responses arguments, multiple/sequential calls,
local tool errors/rejections, streaming content, and tool-preserving
conversation history. Structured-output requests intentionally continue to
disable registered tools, matching ellmer.chat_codex() wrapper around ellmer's Chat
seam. The compatibility layer was tested against ellmer 0.4.2, buffers
streamed text, and repairs the terminal assistant turn used for multi-turn
history.