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.