Skip to content

Latest commit

 

History

History
131 lines (108 loc) · 8.88 KB

File metadata and controls

131 lines (108 loc) · 8.88 KB

Codex in Switchboard

For Codex operating Switchboard (board, notch, whiteboard, PIP, wrapps), install the shared operator plugin with npm run operator:install -- --client codex. The rest of this document covers Switchboard using Codex as a model runtime.

Switchboard can route existing wrapps through Claude Code, Codex App Server, or a local runner. The browser contract remains window.claude: this is a compatibility name, not a provider restriction. Independent native apps can also connect; see native apps and local voice.

Try Brandbrain

Install the Codex CLI and sign in using codex login. Switchboard discovers the installed runtime and asks it for its available models; model names are not hardcoded. Existing Codex authentication is reused. ChatGPT sign-in uses subscription access; API-key sign-in uses API billing.

Build and run the isolated live proof:

npm run build -w @relay/sidekick
SKIP_FRONTEND=1 node examples/brandbrain-port/build.mjs
node examples/brandbrain-port/proof/run-codex.mjs

For a release check of the packaged daemon and real WebSocket protocol:

node --test packages/sidekick/dist/backends/codex.test.js packages/sidekick/dist/backends/routing.test.js packages/sidekick/dist/storage/find.test.js
node examples/brandbrain-port/proof/run-codex-release.mjs

The release proof bundles the daemon with the Mac packager's settings, starts it on an isolated loopback port, and checks model consent, parallel apps, streaming, restart recovery, vision, and ending a conversation. It reuses Codex sign-in, makes real model calls with synthetic inputs, and imports no personal MCP servers. It leaves the installed app and normal Switchboard state alone.

The proof registers only Codex, uses a temporary state directory and synthetic brand data, and exercises Brandbrain's existing warm-session shim and the gaps route in its actual compiled app bundle. The bundle build requires the existing Brandbrain source and installed dependencies (set BRANDBRAIN_SRC if it lives elsewhere); it copies the source into an isolated build directory. It also checks legacy sonnet request translation, gated MCP execution, and revocation. It never reads your personal brand vault.

To prefer Codex in a development daemon:

RELAY_BACKEND=codex node packages/sidekick/dist/index.js

RELAY_CODEX_MODEL optionally selects an exact model advertised by the runtime. Without it, Codex's catalog default is used. RELAY_CODEX_CLI supplies an explicit executable path; RELAY_CODEX=0 disables discovery. RELAY_DIR relocates Switchboard state for an isolated test instance.

Model selection

  • Settings / command centre: models come from the daemon's provider inventory. The global defaultModel in models.json sets the suggestion for new apps, alongside the existing deny-list.
  • Connection notch: choose the models the app may access, then the model new conversations use. Mouse and keyboard approval submit the same live selection.
  • Inside an app: the shared connection chip shows the new-conversation default. Its Change action reopens consent at the notch. The extension consent panel has the same default-model choice.
  • Existing conversations: (origin, sessionId) pins the actual model, persisted in session-models.json. Changing defaults affects new conversations. A disabled, offline, or revoked pinned model produces an explicit error rather than migrating the conversation to another provider.
  • Legacy apps: an explicit user choice translates requests such as sonnet before grant validation. Existing grants are never automatically expanded. Reconnect an existing app to grant a Codex model — or pick a Codex model in the app's card in the menu-bar panel: Switchboard raises the same connect card pre-filled with the current grant plus that model, and one tap widens it (Deny changes nothing). New connects pre-select every signed-in provider's default, grouped by provider; untick to refuse.
  • Class grants (opt-in): an app may ask for a capability class instead of ids — claude_connect({ requirements: [{ class: "cloud-coding" }] }). The user still approves concrete models on the card; the providers behind them become the grant's allowed providers, and a new conversation resolves to any enabled model of that class on those providers. That keeps a grant working when a provider's catalog moves (gpt-5.5 → gpt-6-astra) or one provider is offline. Legacy scope.models grants are unchanged and never widened. claude_capabilities().modelInfo[].classes lists each model's classes.
  • Global default vs. an app's grant: if the global defaultModel is not granted to an app, that app's effective default is the first enabled model in its own grant — discovery and routing agree, and the grant is never widened. An explicit request for an ungranted model is still refused.

An app starts a new conversation by using a new sessionId, or ends one through claude_session with op: "end". Single-shot requests without a session use the current app default.

Apps discover provider features and their effective default through claude_capabilities. BYOP 1.3 adds modelInfo, defaultModel, sessionModelPinning, and the capabilitiesChanged event. The shared connection chip refreshes on these events; custom model pickers should follow the app discovery contract. Bundled SDK updates require an app rebuild.

Runtime and permissions

One supervised App Server process can host multiple independent threads. Turns for the same app session are queued; different sessions can progress independently. Thread IDs remain daemon-owned and are stored in codex-sessions.json with private file permissions. After a restart, Switchboard resumes its recorded threads. Persona or tool-schema changes create a fresh thread so removed tools and obsolete instructions are not retained as the active configuration.

Codex receives broker-discovered MCP schemas as dynamic tools. Calls return to Switchboard's Gate for authorization and execution. Inherited Codex apps, plugins, hooks, shell, browser, image-reading, and other direct execution surfaces are disabled in this runtime. User Codex configuration is not edited. Unknown approval requests are denied. Cancellation or runtime failure while a write awaits consent prevents that action from executing after approval arrives. The gate also rechecks current scope after approval, so revoking access, removing a tool, or choosing read-only mode takes effect before the pending action can execute.

Compatibility boundaries

  • Implemented against Codex CLI 0.135.0; revalidated on 0.153.4 (2026-09-07) after OpenAI's model catalog began advertising a reasoning-effort value 0.135.0 could not decode (unknown variant 'max' → every session stuck "Reconnecting"). Dynamic tools and environment selection are experimental interfaces. Revalidate on every CLI upgrade: a direct codex exec --model <m> "Reply OK" (cap it yourself — macOS has no timeout), then node --test packages/sidekick/dist/backends/codex.test.js, then node examples/brandbrain-port/proof/run-codex-release.mjs (7 live checks, isolated state), then restart the daemon (launchctl kickstart -k gui/$UID/com.relay.sidekick) so it spawns the new binary. The daemon's health check (codex login status) can report Codex online while turns cannot start.
  • Local runners currently support one-shot text completions. Warm-session requests fail explicitly instead of falling through to Claude.
  • Claude-account-only connectors and Claude's built-in WebSearch/WebFetch do not automatically become Codex tools. Configure the equivalent MCP services in Switchboard. A tool-dependent request with no usable broker tools fails explicitly. Routing pre-flights this: an agentic turn with an implicit model goes to a granted model whose provider can serve at least one of the app's granted tools; an explicit request or a pinned conversation on a provider that can't gets an explicit, provider-named error (it is never migrated). Brandbrain's knowledge-only warm path works; parity for every research, media, or computer-use workflow is not implied by the live proof.
  • Codex maintains conversation history. This does not guarantee permanent server-side prompt caching or constant latency. Usage from each turn is recorded, including cached input in total input usage.
  • App Server has no equivalent per-turn maxTokens field in the tested schema. Switchboard checks its existing budgets before calls and records actual usage afterward; maxTokens is not a hard Codex generation cap.
  • The checked-in Mac app bundle is not rebuilt or replaced by these source changes. Build/package the updated native app before expecting the new model controls in an installed copy.

Official references: App Server, authentication.