ChatGPT OAuth sign-in screen, reachable via /auth -> openai_codex.
Mirrors the MCP loopback flow in mcp_auth from the user's POV: a modal
shows progress, surfaces the authorize URL inline (so headless / SSH users
can copy it when the browser launch fails), and dismisses once the OAuth
callback completes. The OAuth primitives themselves (PKCE, callback HTTP
server, token exchange, refresh, atomic file write) are delegated to
langchain_openai.chatgpt_oauth via the
deepagents_code.integrations.openai_codex adapter.
Security notes:
notify never include
the access token, refresh token, or ID token.Get the glyph set for the current charset mode.
Check whether the terminal is in ASCII charset mode.
Convenience wrapper so widgets can branch on charset without importing
both _detect_charset_mode and CharsetMode.
Reset module-level caches so the next call recomputes from scratch.
Intended for tests and for the /reload command.
Open the URL from a Rich link style on click, if present.
Rich Style(link=...) embeds OSC 8 terminal hyperlinks, but Textual's
mouse capture intercepts normal clicks before the terminal can act on them.
By handling the Textual click event directly we open the URL with a single
click, matching the behavior of links in the Markdown widget.
URLs that fail the safety check (e.g. containing hidden Unicode or homograph domains) are blocked and not opened; the event bubbles and a warning is logged and displayed as a Textual notification.
On success the event is stopped so it does not bubble further. On failure (e.g. no browser available in a headless environment) the error is logged at debug level and the event bubbles normally.
Open the ChatGPT account page in the user's browser.
Used by /auth to let signed-in users jump to chatgpt.com (e.g., to
change account, manage billing).
Run the ChatGPT OAuth Authorization Code Flow with PKCE inline.
Dismissal value:
True: a token was saved (caller should refresh provider lists /
retry the operation that needed the credential).False: the user cancelled, or the flow failed irrecoverably.The flow lives in a worker so the modal stays responsive to the cancel
keybinding while _wait_for_oauth_callback blocks for up to 5 minutes;
pressing Esc sets the worker's cancel_event, which frees the loopback
port within one poll interval rather than holding it until the timeout.
Outcome of the CodexSignedInScreen quick-action overlay.
Encoded as an enum (mirroring AuthResult) rather than bare strings so a
typo in either the producing action_* method or the consuming dispatch
is a type error, not a silent no-op.
Quick-action overlay shown when openai_codex is already signed in.
Dismissal values:
CodexSignedInAction.SIGN_OUT: delete the stored token.CodexSignedInAction.REAUTH: open the OAuth flow again.None: close without changes.LangChain brand colors and semantic constants for the app.
Single source of truth for color values used in Python code (Rich markup,
Content.styled, Content.from_markup). CSS-side styling should reference
Textual CSS variables: built-in variables
($primary, $background, $text-muted, $error-muted, etc.) are set via
register_theme() in DeepAgentsApp.__init__, while the few app-specific
variables ($mode-bash, $mode-command, $mode-incognito, $skill,
$skill-hover, $tool, $tool-hover) are backed by these constants via
App.get_theme_variable_defaults().
Code that needs custom CSS variable values should call
get_css_variable_defaults(dark=...). For the full semantic color palette, look
up the ThemeColors instance via get_registry().
Users can define custom themes in ~/.deepagents/config.toml under
[themes.<name>] sections. Each new theme section must include label (str);
dark (bool) defaults to False if omitted (set to True for dark themes).
Color fields are optional and fall back to the built-in dark/light palette based
on the dark flag. Sections whose name matches a built-in theme override its
colors without replacing it. See _load_user_themes() for details.
ChatGPT OAuth integration for the openai_codex model provider.
Thin orchestration layer over langchain_openai.chatgpt_oauth. Reuses the
upstream PKCE/token primitives directly (_generate_pkce_pair,
_build_authorize_url, _CallbackHandler, _post_form,
_token_from_response, _FileChatGPTOAuthTokenProvider) so this module only
adds:
login_chatgpt
uses print(), which is invisible inside a Textual app),_wait_for_oauth_callback), and/auth to read sign-in status, expiry, and the linked account
without re-implementing token parsing.The browser-loopback flow mirrors the MCP one in mcp_auth from the user's
POV — PKCE + state CSRF + browser launch with a manual-URL fallback — but
the callback server here is upstream's single-threaded polling
http.server.HTTPServer (reused via _CallbackHandler), not the
ThreadingHTTPServer that mcp_auth runs itself. The OAuth-specific parts
(token exchange, refresh, file storage with 0600 perms) are delegated to
upstream.
The OAuth primitives are reused from langchain-openai>=1.3.1, which is
the first release to ship langchain_openai.chatgpt_oauth. This module
deliberately reaches into upstream-internal (_-prefixed) helpers; their
stability is an upstream concern, so pin the minimum langchain-openai
version when bumping and re-check the imported names against the release.