WikifitaGitHub live67e8de5
pesquisa · openai-research/chatgpt-desktop-architecture

ChatGPT Desktop — Hybrid Architecture and Mode Hierarchy

RE of the desktop app — Swift shell + Chromium renderer + embedded Codex app-server, the three conversation surfaces and their transports

Baixar raw

ChatGPT Desktop — Hybrid Architecture and Mode Hierarchy

Part of openai-research.

Binary composition

/Applications/ChatGPT.app — bundle id com.openai.codex (the desktop app is the Codex app).

LayerTechnologyRole
ShellNative Swift (SDK macosx15.5, Sparkle updater, provisionprofile)Window, menu, macOS integration
Codex Framework.frameworkRenamed Electron (Chromium 151.0.7922.170 — Chromium locale.pak in the bundle)UI runtime ("Codex Framework" is branding of the Electron framework, not Rust)
Resources/app.asar (271MB)Electron (.vite/build/main-*.js main + /webview/ Vite renderer, 7609 files)The whole app UI — works offline
Resources/codexRust — compiled Codex app-server (Mach-O arm64, 220MB, 3669 rustc/cargo strings; same base as the codex-rs open source, desktop build)App-server: auth/keychain, threads, realtime, HTTP to the codex backend (models polling ~3min, responses, images/generations) carrying x-oai-attestation; NOTE (2026-08-27): X-OAI-IS not observed in flow A / A1 / the manual runs (0 occurrences in the captured main headers of those flows); flow B: unknown (not executed) — the rust client request headers of any flow were never captured. The earlier "chain" claim came from the web-flow/vendor analysis

~/.codex/ is the desktop app's CODEX_HOME (auth.json, models_cache.json, logs_2.sqlite with codex_http_client Rust logs, bundled plugins). Electron ↔ app-server communication: stdio JSON-RPC (app_server.request{rpc.transport="stdio"}).

ChatGPT Desktop ≠ Codex CLI: distinct products. The desktop embeds the Codex app-server (same codebase as the codex-rs open source, own binary and protocol) — it does not depend on the Codex CLI being installed, and the desktop binary has code the open source does not (e.g. the DeviceCheck attestation integration — x-oai-attestation; the public codex-rs has the AttestationProvider trait, the desktop supplies the Apple implementation). X-OAI-IS: not observed in the executed flows (A/A1/manual; 0 hits in the captured main headers); unknown for flow B (not executed); rust request headers never captured. The ~/workdir/codex source is a reference for the shared protocol, not the absolute source of the closed binary.

Mode hierarchy

MODO CHATGPT
├─ submodo work → chatgpt.com/backend-api + handoff tool (Codex quota, /compact)
└─ submodo chat → chatgpt.com/backend-api (chat quota, no compact)  ← RESEARCH FOCUS
MODO CODEX     → app-server direct → /backend-api/codex

Submode marking in the payload (/f/conversation)

The body builder is r3r() in the renderer. Chat vs Work is not a mode boolean:

  • The distinguishing mechanism is local_function_signatures — the handoff tool with the server-provided description that is always offered in the ChatGPT mode
  • conversation_mode: {kind: 'gizmo_interaction', gizmo_id} + gizmo_id = Projects
  • conversation_execution_target — execution target (tpp/local tasks)

Renderer → network transport

  1. Renderer calls the typed API client (safeGet/safePost, OpenAPI paths — 163 mapped)
  2. Transport Hp sends via IPC (fetch-response events) — the renderer never fetches directly
  3. Control headers renderer→main: X-OpenAI-Attach-Auth: 1 (main injects Authorization: Bearer + ChatGPT-Account-Id from the app-server), X-OpenAI-Attach-Integrity-State: 1 (main resolves the session integrity marker — see the oai_is field of the OAuth refresh; NOT observed as an X-OAI-IS request header in the real f/* traffic), X-OpenAI-Attach-Desktop-Surface, X-OpenAI-Attach-DeviceCheck-Token (DeviceCheck)
  4. Main cleans the User-Agent (excludedUserAgentProducts: ['Electron', app name])
  5. Client defaults: OAI-Language: en, originator: Codex Desktop, oai-did (persisted device uuid)

Authenticated webviews (the only exception)

Webviews that render site pages (checkout /purchase/*, workspace settings, Sites) use SR()/OR() in the main: clear cookies, POST /api/auth/link-session with {auth_token, expires_in} + x-i-am-a-browser: true (see auth-and-link-session), then set routing cookies (_account, _account_residency_region, _account_is_fedramp). The chat does not use this path.

Plugin primary runtime (on-demand download)

The app downloads a bundled "primary runtime" on demand: GET persistent.oaistatic.com/codex-primary-runtime/<version>/codex-primary-runtime-darwin-arm64-<version>.tar.xz with UA codex-primary-runtime-installer (main process). Version 26.826.11250 (newer than the app 26.820.60940 — the runtime tracks its own release line). Extracts into ~/.codex/plugins/cache/openai-primary-runtime/{template-creator,spreadsheets,pdf,presentations,documents}/26.826.11250/ — the plugin runtime surfaces (docs, sheets, PDF, slides, template creator) used by the agent mode.

Cross-references