feat: add OpenAI Codex (ChatGPT subscription) OAuth chat provider#1733
Open
FFFFFFpy wants to merge 3 commits into
Open
feat: add OpenAI Codex (ChatGPT subscription) OAuth chat provider#1733FFFFFFpy wants to merge 3 commits into
FFFFFFpy wants to merge 3 commits into
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
PR Body (paste into the GitHub PR description)
Description
Adds a new chat model provider,
openai-codex, that authenticates against anOpenAI ChatGPT / Codex subscription via OAuth (PKCE) instead of an API key,
and talks to the Codex Responses backend (
chatgpt.com/backend-api/codex).This lets operators back the interactive Q&A and article-summary chat slots with
a ChatGPT subscription rather than per-token API billing.
It does not touch the embedding/rerank path — the Codex subscription only
exposes chat, so those slots keep using existing providers.
Design
The Codex Responses protocol is not OpenAI chat-completions compatible (different
request/response shape, SSE event stream, stateless
store:false), so thisfollows the existing
AnthropicChatprecedent: a standaloneCodexChatimplementation dispatched in
NewRemoteChat, rather than aproviderAdapteroverride (the adapter interface has no response-translation hook). All new logic
is isolated in new files; shared-code changes are minimal:
internal/models/chat/codex.go—CodexChat, implements theChatinterfaceinternal/models/chat/codex_oauth.go— token store: load / refresh (rotationwrite-back) / cache /
account_idextraction, concurrency-safe (RWMutex)internal/models/chat/codex_login.go— PKCE + authorize URL + code exchangeinternal/models/chat/codex_responses.go— request translation + Responses SSE parseinternal/handler/codex_auth.go— OAuth start / complete / status endpoints (Admin-gated)internal/models/chat/chat.gointernal/models/provider/openai_codex.go(+ enum,DetectProvider)docker-compose.ymlvolume,.env.exampleAuth model (OpenClaw-style)
dedicated ChatGPT account, and pastes the
localhost:1455callback URL back(the Codex CLI public client only whitelists that redirect URI).
/data/weknora/codex_auth.json, on a private volume,0600), owned andrefreshed exclusively by WeKnora. Refresh tokens rotate and are written back.
.env.example): use a separate account anddo not log the same account in from another client, or refresh-token rotation
will log them out of each other.
Type of Change
Related Issue
Fixes #
Testing
internal/models/chat/codex_test.goandinternal/models/provider/provider_test.go, covering:%20space encoding, not+)0600shouldRefreshtiming (exp skew / max-age)output_index)DetectProvidermapping forchatgpt.com/backend-api/codexgo test ./internal/models/chat/ ./internal/models/provider/dedicated account and verified the interactive agent chat path only —
streaming and non-streaming Q&A, token usage recorded on both.
Checklist
make fmt && make lint && make testpass locallydocs/, Swagger annotations on the3 new
/models/codex/oauth/*handlers, etc.)Screenshots / Recordings
Known limitations / untested paths
The following are unverified against the live Codex backend and may need
follow-up before relying on them (each has a concrete reason it might differ from
the interactive chat path that was tested):
(
opts.Format→ Responsestext.format, json_object / json_schema), which isonly covered by unit tests, not against the real backend.
Chat(). Two specifics to watch: (1)max_output_tokensis intentionally notsent (the Codex Responses backend rejects it), so any output-length cap the wiki
pipeline sets is silently dropped; (2) long synthesis calls may approach
defaultChatTimeout.opts.Thinking(true→ medium,false→ low). Batch slots that enable thinking will spend more of thesubscription's rate budget.
interactive use; bulk summary/wiki ingest can hit them. Throttling on the
WeKnora side is not part of this PR.
Scoping suggestion: this PR can be treated as interactive-chat support, with
summary/wiki validation as a follow-up — or held until those paths are tested,
per maintainer preference.
Compliance / scope note for maintainers
This provider authenticates a ChatGPT/Codex subscription via OAuth, reusing
the Codex CLI public client id, and routes requests to the Codex Responses
backend. OpenAI sanctions subscription OAuth in personal coding-assistant
tools (Codex CLI, OpenClaw); using it to back a self-hosted service is a
grayer area under OpenAI's terms. The feature is therefore strictly opt-in:
it is a separate, non-default provider, requires an explicit operator login with
a dedicated account, ships with the deployment caveats above, and changes nothing
for existing API-key providers. Flagging this so maintainers can decide on
inclusion and whether to attach a usage disclaimer in the docs.