Skip to content

About

Unofficial localhost gateway that routes Codex model calls through the official GitHub Copilot SDK—with concurrent agents, reversible Windows setup, and live observability.

Topics

Resources

Security policy

Stars

1 star

Watchers

0 watching

Forks

Latest commit

 

History

54 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Codex Copilot Relay

Keep the Codex experience. Route model inference through your GitHub Copilot entitlement.

An unofficial, localhost-only OpenAI Responses compatibility gateway between Codex and the official GitHub Copilot SDK.

CI Node.js 22 LTS Windows 10/11 Loopback only MIT License

Quick start · Live dashboard · How it works · Restore Codex · Security

Relay Control Room showing concurrent request and response data glyphs moving through Codex, the local relay, GitHub Copilot, and a GPT model

A real end-to-end SDK validation call captured from the dependency-free local dashboard. No mock traffic or fabricated metrics.

Keep Codex. Change the inference path.

Using Claude Code? Read the complete Claude Code guide. To ask for images in the Code tab with native Codex (your OpenAI/ChatGPT allowance, not Copilot credits), see native image generation. The guide covers setup, model families, on-demand tool loading, browser and research, costs and troubleshooting.

1.3.96: optional relay features you control. A new Relay features dashboard panel switches the relay's own additions on or off, live. You can also choose them when starting the relay (Start-Relay.ps1 -EnableFeature cacheKeepWarm -DisableFeature …). Two new opt-in features:

  • Prompt-cache keep-warm. Pings a quiet long chat so Copilot's 5-minute cache does not expire. Cache rewrites were about 60% of measured Claude credits.
  • Haiku for Explore subagents.

Existing extras (answer recovery, image trimming, the encrypted-PDF note, idle slot release and Codex cost checkpoints) stay on by default and can now be switched off. Rejected requests now record a short reason. See optional relay features.

1.3.90–1.3.95:

  • No more lost answers on overlapping SDK requests. On long tool turns the Copilot SDK can have two upstream attempts in flight. The first to start streaming now owns the client stream; the other is dropped instead of failing the turn with "Server error mid-response". An answer the client already holds completely is delivered even if the SDK errors afterwards.
  • No stuck chats from SDK-only tool calls. If tool results answer exactly the tool calls the client was shown, the relay rebuilds from history instead of returning 409 Provide every outstanding tool result exactly once (which also broke /compact).
  • 128 Claude session slots by default (was 64; BRIDGE_MAX_CLAUDE_SESSIONS now accepts 2–256).
  • Session cost totals. The per-task table defaults to each session's total across all retained days, with a per-day split and search, for both Claude Code and Codex. Codex cost checkpoints count the whole session, not just today. Query every session as JSON at /dashboard/api/sessions.
  • Claude Code in the Models and AI credits panel (a key filter had dropped its rows).
  • Native image tools over HTTP MCP at http://127.0.0.1:4144/mcp (loopback only), as an alternative to the stdio adapter. See native image generation.

1.3.89: a Models and AI credits dashboard panel (current model per client, credits per model today and over 7 days), Copilot SDK 1.0.21, and seven reliability and cost fixes from the October audit. See efficiency guidelines.

1.3.81–1.3.84:

  • On-demand MCP tool loading (tool search) and context editing pass through.
  • Native PDF documents.
  • Sonnet/Haiku routing and Haiku large-prompt fixes.
  • Fail-fast on SDK stalls after a finished stream.
  • Selectable Edge/Chrome for the browser tool.

1.3.80 startup repair: permits SDK model discovery through the native request hook. Desktop Start Relay now explicitly cancels existing relay sessions and loads the latest local package. Repair and watchdog updates still wait for work to finish. Browser resume also repairs a missing opted-in skill when Desktop retained the identical connector. See verification.

1.3.78 reliability update: fixes stock Edit-default replay, split/chunked tool batches and interleaved result delivery. Explicit entitled Claude model changes rebuild at a completed tool boundary; unbound SDK inference fails before transport. See evidence, routing and peer audit. This is not a claim of full native compatibility or zero unreported usage.

Two PowerShell shortcuts, no relay EXE required: Start Relay runs Start-Relay.ps1; Stop & Restore runs Stop-Relay.ps1. Run Install-RelayDesktopControls.ps1 to install or migrate both shortcuts. The source and dependencies stay together in the installation folder. The dashboard includes an open Connect Claude Code guide and crash-recovery instructions. Existing Windows EXE builds are legacy optional developer tools; they are no longer selected by the shortcut installer.

Optional Claude browser/research setup: see browser integration. For unchanged screenshot/signed-history transport, inline screenshot instructions, test evidence and remaining limits, see Claude image compatibility. It adds pinned Playwright MCP plus a source-citing research skill, with user-approved extension access and a scoped rollback. Browser connection is separate from model routing; hosted Anthropic search and full Desktop GUI parity are not promised.

The desktop workflow is one installation folder + two shortcuts. The first terminal screen explains automatic Codex routing and Claude's one-time Gateway setup; type setup, models, status, or key. Both clients appear in the live fabric and event stream, with merged history/session views, separate durable ledgers and client-owned tool handoffs. Older controls are archived inside runtime/desktop-backups/, never published. Customer workflow and folder map.

Windows desktop controls: run powershell -NoProfile -ExecutionPolicy Bypass -File .\Start-Relay.ps1 once to install Start Relay and Stop & Restore. Both adapters share port 4144 and the existing dashboard/history. The live terminal labels Codex and Claude requests. Read two-control setup and restore for Claude's one-time supported gateway form and the restoration boundaries. The isolated node launch.mjs gateway --open mode remains a developer preview; it is not the desktop Start path. API tests are not desktop GUI certification.

Codex Copilot Relay makes GitHub Copilot look like a custom OpenAI Responses-compatible provider to Codex. The desktop app and CLI keep their normal tools, approvals, memory, child agents, streaming, and continuation loop; the relay translates model traffic to and from GitHub's official Copilot SDK.

Codex keeps owning The relay handles You gain
Tools, files, approvals, sandboxing, memory, and agent orchestration Responses protocol translation, Copilot sessions, streaming, recovery, and telemetry A reversible Copilot-backed Codex route with live local observability
  • Local by design: the server and dashboard bind only to 127.0.0.1.
  • Built for overlapping agents: each initial request receives an independent Copilot SDK session.
  • Made for long tool loops: SSE heartbeats, bounded recovery, context compaction, and a 13-hour outer-tool continuation window protect legitimate long-running work.
  • Observable without a cloud dashboard: inspect live request flow, outcomes, models, sanitized history, measured SDK usage, quota, storage, and an optional public-API benchmark.
  • Reversible on Windows: one shortcut enables or repairs the gateway; a second shortcut stops it and restores the exact original config.toml.

Important

This is not an unlimited-token route, an authentication bypass, or an official Codex/GitHub integration. Every model call uses the signed-in user's GitHub Copilot entitlement and remains subject to GitHub quota, billing, acceptable-use, and product terms.

Cost controls and Pacific accounting (1.3.36)

  • Repeated outer discovery reuses a pending SDK session only when its validated task identity, complete tool declarations, model, effort, and user/instruction/settings contract are unchanged. Changed catalogs still restart safely: SDK 1.0.11 does not expose a supported model-visible hot-schema update. Anonymous requests do not qualify for this optimization. Call details record the reuse/start reason.
  • Routine shell diagnostics are bounded to 16 KiB of UTF-8 text with an explicit middle-omission notice; instruction/document reads retain their full returned text, other tool results retain the existing 64 KiB limit, and images remain separate. This is not a limit on input context. Required instructions and verification must still be read fully; ask for narrower output when necessary.
  • Creative/editing guidance bounds a requested batch to three revision passes unless explicitly extended, then calls for a complete reviewable result rather than unrequested polishing. Explicitly authorized work and approval gates remain.
  • Per-task daily checkpoints default to 20 model steps or 500 SDK AI credits. Override with positive integer process settings BRIDGE_CHECKPOINT_STEPS and BRIDGE_CHECKPOINT_AI_CREDITS before starting the watchdog. These are advisory checkpoints, not hard budgets: the next outer boundary receives one cost/progress notice per crossed interval; active inference is never cancelled. An individual response can exceed an interval before the next checkpoint. Missing credits stay unreported; partial metering can understate cost. Model compliance is not guaranteed.
  • The task ledger uses validated task UUIDs, not shared cache keys or directories. It retains 31 Pacific dates and survives history clearing/restarts. Attribution begins with this release; older costs are not guessed or backfilled. The table distinguishes relay responses, SDK model steps, tokens, and SDK AI credits.

Unified dashboard (1.3.71+): Recent call history now includes both Codex and Claude Code, with a client filter, session names, requested/selected/actual model, applied reasoning, route, tokens and SDK AI credits. Claude's separate history panel is replaced by a client breakdown in Where calls actually go. Daily session checkpoints include both clients. Claude advisory status is displayed on the dashboard; this change does not inject checkpoint prompts into Claude. See metering, name discovery and privacy boundaries.

The relay defaults to GPT-6.1 Sol at xhigh when effort is omitted. Explicit task model and effort choices remain unchanged, including child agents. The Windows installer sets top-level model = "gpt-6.1-sol" and model_reasoning_effort = "xhigh" in Codex for the same default, preserving the original values in its protected revert backup. During an active exchange it stages the update and keeps the working route until the watchdog can safely promote it. Check /health for the effective model and version. The standard context budget, compaction, native Codex images, authentication and Remote boundaries are preserved.

Compact dashboard layout (1.3.35)

Provider routing is a slim expandable strip; its complete account counters and provider ledger remain available on expansion. Token and AI-credit charts sit directly beneath it with the existing 24-hour, 5-day and 30-day ranges. Recent call history uses the full dashboard width, retaining all 13 fields. Selected-call details appear beneath the table, with keyboard focus, direct navigation on selection, and a return link. Smaller screens retain horizontal table scrolling instead of hiding measurements. Ordinary live refreshes do not move the page to the details panel.

Reasoning visibility and efficiency (1.3.34)

Recent call history shows Intelligence · effort: applied SDK session effort, the requested level, and any continuation or capability cap in call details. It is not an intelligence score. Missing historical effort stays not recorded; only intact replay evidence can recover it. These fields survive lightweight retention.

Omitted effort now defaults to low where supported, including the generated Codex model catalog. Explicit high/xhigh/max choices are unchanged. Existing SDK continuations keep their original effort until a fresh exchange starts. Already-loaded tool-search definitions are referenced rather than copied into history again, but their full registered schemas, constraints, namespace rules, changed historical versions, and Codex approval boundaries remain intact. Per-call local character savings are recorded separately from measured SDK usage.

The supplied native image_gen.imagegen tool stays eager in large catalogs. Use that built-in Codex tool rather than discovering another image provider; no paid or browser fallback is implied by failure. Direct image generation uses Codex/OpenAI limits and may bypass this relay's ledger. The optional relay image helper is separate, enabled-only, and not included in Copilot credit totals.

Oversized instruction-field repair (1.3.29)

Copilot can reject a single instructions string over 1,048,576 characters even when the overall prompt fits the model's token window. The relay now checks this separate field limit. If necessary, older exact copies of complete skill catalogs become explicit references to their unchanged latest copy. Differing catalogs, ordinary instructions, source roles, and ordering are preserved. Genuinely unique oversized instructions fail locally with an actionable error before session creation. See the fix and verification.

Large image-history ingress repair (1.3.28)

Long Codex tasks can resend more image history than the model ever needs. The Responses reader now streams up to 512 MiB of incoming JSON, retaining a bounded image window before the existing 128 MiB assembled-body check. Older eligible images receive explicit omission markers; text, tool IDs and ordering remain unchanged. The newest image batch is never silently evicted. Original task files are untouched. See the fix, safeguards and verification.

Images-only native adapter and connection center

Keep Copilot for normal agent work and use an explicitly enabled public OpenAI connection for hosted tools, advanced search/image options and Realtime API transport. The signed-in Codex GPT Image 2 helper remains available without a Platform key. Multi-image Copilot requests use bounded, labelled overviews with exact-duplicate mapping and bounded JPEG compression. Native OpenAI search is removed. Browser/connector tools remain harness-owned. The connection cards distinguish configured Codex from recently observed traffic. The dashboard now separates Copilot, native Codex/OpenAI, and public OpenAI calls, with provider filters and observed token breakdowns. Missing usage is labelled, not invented. No automatic fallback: normal inference remains Copilot, unsupported requests do not silently change provider, and OpenAI feature quotas do not disable independent Copilot work.

Step-by-step hybrid setup and client examples covers credentials, billing, restoration, generic Responses clients and honest limits. This is hybrid compatibility, not complete native parity. Native desktop voice is currently blocked with this provider on Codex 0.153.4: call creation reaches the relay's unimplemented /v1/live, and a URL override still uses relay auth. The optional public Realtime gateway is not a fix for signed-in app voice. See the verified native voice limitation.

Quick start (Windows)

Install Node.js 22 LTS or newer and stock Codex. No custom Codex engine is needed. After cloning (or extracting the repository ZIP), npm run setup opens the read-only connection center even before dependencies or GitHub login are ready. Keep it open and use a second terminal for installation/connection commands. This is guided setup, not a one-click installer. See first run.

git clone https://github.com/madhavsomani/codex-copilot-relay.git
cd codex-copilot-relay
npm ci
node node_modules/@github/copilot/npm-loader.js login
node probe-setup-auth.mjs

Set-ExecutionPolicy -Scope Process Bypass
.\Repair-Codex-CopilotProxy.ps1 -Port 4144 -Model gpt-6.1-sol

Reopen the Codex task after the provider switch, then visit http://127.0.0.1:4144/dashboard. If the probe lists a different available GPT model, use that model ID consistently; the relay does not silently substitute another provider or model. The complete Windows setup explains authentication, verification, shortcuts, updating, and rollback.

Dashboard preview

The dashboard is served by the relay itself: no framework, analytics service, CDN, or external database is required. All displayed traffic is sanitized local telemetry.

Relay Control Room with operational KPIs, live fabric, measured model usage, and Copilot entitlement Relay analytics with traffic charts, bounded storage, and recent call history
Live fabric, exact SDK usage, entitlement, and request inspector Traffic history, bounded storage, and recent calls

How it works

Codex remains the agent runtime. It owns tasks, child agents, tools, approvals, memory, files, connectors, and sandboxing. The relay is a stateful protocol adapter plus a Windows lifecycle supervisor.

Component architecture

flowchart LR
  subgraph Codex["Codex desktop or CLI"]
    Task["Task and child agents"]
    Client["Responses client"]
    Tools["Tools, approvals, memory,<br/>sandbox and connectors"]
    Task --> Client
    Task <--> Tools
  end

  Config[("Codex config.toml")]
  Config -. "provider and base_url" .-> Client

  subgraph Relay["Node relay on 127.0.0.1:4144"]
    HTTP["HTTP router<br/>server.mjs"]
    Core["Protocol and context adapter<br/>bridge-core.mjs"]
    Exchange["Exchange registry<br/>task-owned SDK sessions"]
    Supervisor["SDK worker supervisor<br/>copilot-runtime.mjs"]
    Stream["Responses stream adapter<br/>ordered SSE and heartbeats"]
    Recorder["Sanitized recorder<br/>metrics and live events"]
    Dashboard["Embedded dashboard"]

    HTTP --> Core --> Exchange
    Exchange -- "session admission" --> Supervisor
    HTTP -. "readiness ping" .-> Supervisor
    Supervisor -. "invalidate dead generation" .-> Exchange
    Exchange --> Stream --> HTTP
    HTTP --> Recorder
    Exchange --> Recorder
    Recorder --> Dashboard
    HTTP --> Dashboard
  end

  Client -- "POST /v1/responses" --> HTTP
  HTTP -- "SSE or JSON" --> Client

  SDK["GitHub Copilot SDK<br/>local client"]
  CLI["Copilot CLI server<br/>JSON-RPC"]
  Service["GitHub Copilot service<br/>entitled GPT model"]
  Exchange <--> SDK
  Supervisor -. "own, probe, replace" .-> SDK
  SDK <--> CLI
  CLI <--> Service

  subgraph Windows["Windows lifecycle control plane"]
    Repair["Repair or Enable shortcut"]
    Watchdog["Scheduled Task watchdog"]
    Disable["Restore or Disable shortcut"]
    Runtime[("runtime/<br/>state, backup and telemetry")]

    Repair --> Watchdog
    Repair --> Runtime --> Disable
  end

  Repair -- "backup, edit and start" --> Config
  Repair -. "start relay" .-> HTTP
  Watchdog -. "/health and restart" .-> HTTP
  Recorder --> Runtime
  Disable -- "exact restore" --> Config
  Disable -. "stop" .-> Watchdog
  Disable -. "stop relay" .-> HTTP
Loading

Tool-call continuation lifecycle

sequenceDiagram
  autonumber
  participant C as Codex
  participant H as HTTP router / ResponseSink
  participant E as Exchange
  participant S as Copilot SDK session
  participant G as GitHub model

  C->>H: POST /v1/responses with input, tools and stream
  H->>E: Translate context and create Exchange
  E->>S: createSession() and send(prompt)
  S->>G: Inference request

  loop Model generation
    G-->>S: Text or tool events
    S-->>E: SDK events
    E-->>C: Responses SSE deltas and quiet-period heartbeats
  end

  alt Model requests a Codex tool
    G-->>S: external_tool.requested
    S-->>E: Tool name, arguments and call ID
    E-->>C: response.completed with function or custom call
    Note over E: Exchange remains in memory for the outer-tool window
    C->>C: Execute the tool locally with normal approvals
    C->>H: Continuation with call_id and tool output
    H->>E: Find the existing Exchange
    E->>S: handlePendingToolCall(result)
    S->>G: Resume inference
  else Model returns a final answer
    E-->>C: response.completed with assistant message
    E->>S: Disconnect session
    E->>E: Remove call and response mappings
  end
Loading

The relay translates request, response, streaming-event, and tool-call envelopes. At the OpenAI Responses protocol boundary, it is designed to be a transparent Codex provider. Codex keeps ownership of local tool execution, sandboxing, and approvals. When a model asks for a tool, the relay returns that request to Codex; Codex runs the tool locally and sends the result back through the same open exchange.

Why it exists

Codex supports custom providers that speak the OpenAI Responses protocol. The GitHub Copilot SDK is a generally available, semantically versioned SDK for building applications on top of the Copilot agent runtime. Codex Copilot Relay adapts those two interfaces locally.

The relay itself remains an unofficial, experimental compatibility layer. Neither GitHub nor OpenAI documents this exact cross-product setup, so protocol or product changes can require updates to the relay.

Features

  • OpenAI Responses-compatible /v1/responses endpoint
  • Official @github/copilot-sdk backend
  • Independent SDK session per request for overlapping Codex agents
  • Codex child-agent delegation adapter, including OpenAI-only encrypted-schema hints
  • Tool-call and tool-result continuation
  • Responses shorthand string input plus role-ordered structured input
  • Full streaming Responses lifecycle with ordered sequence numbers and terminal response.completed or response.failed events
  • Assistant commentary / final_answer phases, readable reasoning-summary events when Copilot emits them, and incremental function/custom-tool inputs
  • auto, none, required, and named function/custom tool_choice handling
  • Portable strict/deferred/output-schema tool metadata and Copilot-native lazy tool discovery for Codex declarations marked defer_loading
  • Early HTTP 400 errors for request controls the Copilot route cannot honestly honor, instead of silently ignoring them
  • Automatic recovery from empty Copilot completions with a bounded per-turn retry limit
  • Automatic recovery when a model emits only a future-tense progress update instead of taking the next available tool action
  • Separate sliding model timeout and 13-hour outer-tool result window, plus SSE heartbeats, for all-day Codex runs
  • Copilot SDK session idling disabled and automatic context compaction enabled
  • Model-advertised long-context tier selected explicitly when the authenticated Copilot model exposes it
  • Low effort by default, with explicit Sol/Terra and other available model choices honored for both parent and child tasks. Per-model catalogs preserve each backend's actual context and reasoning limits.
  • Outer Codex developer instructions, task memory, roles, reasoning effort, and tool schemas remain the source of truth; duplicate Copilot-native memory, built-ins, config discovery, and custom instructions stay disabled
  • Historical tool images travel as image attachments instead of base64 prompt text
  • Oversized historical text tool results are bounded with head and tail context preserved
  • Aggregate history is compacted against the selected model's advertised prompt token budget into a bounded, salience-aware continuity ledger that prioritizes user corrections, failures, tool inputs/results, and the latest tool chain; the legacy character ceiling is used only if no token limit is available
  • A streaming Responses reader separates the 512 MiB wire limit from the 128 MiB retained JSON limit, with a bounded historical-image window
  • Streaming failures end with a standard response.failed event instead of a silent disconnect
  • Loopback-only listener on 127.0.0.1
  • Modern loopback dashboard with a real-time dotted Codex → relay → Copilot → model network where concurrent calls keep separate colors and lanes, a six-card real-data KPI strip, a bounded live request inspector, 1,000 recent call entries, 200 on-demand sanitized detail bodies, durable lifetime mileage, and hourly/daily/model charts
  • Exact per-call Copilot SDK input, output, cache, reasoning, AI-credit, model- cost-unit, and model-call telemetry when the runtime emits assistant.usage
  • Authenticated Copilot entitlement/quota snapshots with no token, login, or account identifier exposed to the browser
  • Separately labeled OpenAI API-equivalent cost estimates from source-dated public standard text-token prices; estimates are never presented as charges
  • Visible Windows Terminal event stream
  • Watchdog recovery for both the relay and visible terminal
  • SDK-aware readiness, automatic dead-worker replacement, bounded session admission, and idle-only worker recycling
  • Two-click enable/restore workflow for Codex config.toml
  • SHA-256-verified, current-user-only full-config backup

Requirements

  • Node.js 20.19+ or 22.12+ (Node 22 LTS is recommended)
  • Git
  • A GitHub account with a Copilot plan; organization-managed accounts also need the Copilot CLI policy enabled
  • A GPT model exposed to that account by GitHub Copilot
  • Codex desktop or CLI with custom Responses-provider support

The durable shortcuts, watchdog, automatic config.toml backup, and exact restore are Windows 10/11 features. The Node relay itself can be started manually on macOS or Linux; see Manual cross-platform setup.

The Windows scripts honor CODEX_HOME. When it is set, they manage $env:CODEX_HOME\config.toml; otherwise they use $env:USERPROFILE\.codex\config.toml. The exact resolved path is recorded in the protected restore state, so disabling the relay restores the same file even if a repair process starts with a different environment later.

Windows: complete setup

1. Install and authenticate GitHub Copilot CLI

GitHub's current cross-platform installation requires Node.js 22 or later:

npm install -g @github/copilot
copilot login
copilot --version

Follow the browser device-login flow. The OAuth credential is stored by Copilot CLI in Windows Credential Manager; this project does not copy it into the relay folder. GitHub CLI authentication (gh auth login) is also supported as a lower-priority fallback.

Official references:

2. Clone and install the relay

git clone https://github.com/madhavsomani/codex-copilot-relay.git
cd codex-copilot-relay
npm ci

The official Node SDK bundles its compatible Copilot CLI runtime. Installing the global CLI above gives users the supported login command and writes the shared signed-in identity that the SDK uses.

3. Verify authentication and model access

npm run probe -- --model gpt-5.6-sol

The command prints model metadata and exits successfully when the signed-in account exposes that model. If it reports a list of other GPT models, use one of those model IDs consistently in the commands below. Windows launchers accept safe model IDs instead of maintaining a small hard-coded model allowlist, so a new SDK-exposed GPT model does not require a script update.

4. Enable the durable gateway

Open PowerShell in the cloned folder. Administrator privileges are not needed.

Set-ExecutionPolicy -Scope Process Bypass
.\Repair-Codex-CopilotProxy.ps1 -Port 4144 -Model gpt-5.6-sol

This command:

  1. Saves the complete normal Codex configuration to a protected local backup.
  2. Adds a managed github_copilot_bridge custom-provider block.
  3. Starts the loopback relay and validates health.
  4. Installs a per-user Scheduled Task watchdog.
  5. Starts a visible Windows Terminal event stream.
  6. Installs Start or Repair Codex Copilot Bridge and Restore Normal Codex (Disable Copilot Bridge) on the Desktop.

The managed provider includes these reliability controls:

request_max_retries = 0
stream_max_retries = 3
stream_idle_timeout_ms = 900000

The relay emits a valid sequenced response.in_progress SSE event every 15 seconds during quiet model work. The 15-minute Codex idle timeout is a safety net, not the normal keepalive mechanism. Bounded stream retries handle a dropped loopback stream without creating an unbounded retry loop.

5. Reopen Codex and verify routing

Close and reopen the Codex task after switching providers so the app server reloads config.toml, then run:

Invoke-RestMethod http://127.0.0.1:4144/health
npm run probe:stream -- --url http://127.0.0.1:4144/v1 --model gpt-5.6-sol
npm run probe:concurrency -- --url http://127.0.0.1:4144/v1 --count 4 --model gpt-5.6-sol

Open http://127.0.0.1:4144/dashboard to inspect sanitized local request and tool-call activity, lifetime traffic mileage, model usage, outcomes, and bounded disk use. A healthy relay reports ok: true and sdk.ok: true, reports sseHeartbeatFormat as response.in_progress, reports its telemetry policy, and accepts concurrent exchanges.

Update an existing relay checkout

The Node process loads the bridge and dashboard modules at startup. After a git pull, restart the relay to activate a newer dashboard or server build; refreshing the browser alone cannot load code that the old process never read. Every deployable runtime or dashboard change must bump the version in both package.json and package-lock.json, then start or repair the watchdog. The watchdog reads its expected version once when it starts, so arbitrary file edits and an unchanged version never deploy automatically. The Repair-Codex-CopilotProxy.ps1 script compares the running /health version with package.json. If an older healthy process still owns active tool continuations, repair completes without rolling the Codex config back: the existing relay, visible console, and dashboard remain usable. The watchdog then replaces the outdated managed process automatically after three consecutive idle checks. Repair preserves long-running work. The current desktop Start Relay shortcut instead performs an intentional restart and cancels active exchanges, just like the explicit Stop & Restore control.

The equivalent manual sequence is:

.\Stop-Codex-CopilotWatchdog.ps1
.\Stop-Codex-CopilotGatewayConsole.ps1
.\Stop-Codex-CopilotProxy.ps1 -Port 4144
.\Repair-Codex-CopilotProxy.ps1 -Port 4144 -Model gpt-5.6-sol

Use the model ID already selected for that installation. These commands keep runtime\ telemetry and the protected normal-config backup intact. Do not restart during an in-flight tool continuation or render; an in-memory exchange cannot survive a process restart.

Local-only and mobile access

Both the relay and dashboard bind to 127.0.0.1, so they are reachable only from the Windows computer running the bridge. A phone cannot open that localhost address, and ordinary mobile Chat/Work does not read the desktop Codex config.toml custom-provider setting.

If the ChatGPT mobile app shows Remote and this Windows Codex host is paired, the official Remote feature lets you steer desktop tasks while the computer stays awake, online, and running Codex. The intended configuration keeps model work on the host's Copilot relay and leaves OpenAI sign-in, pairing, and Remote transport with the desktop app. The official docs do not explicitly certify this custom provider with Remote; verify a phone-to-host task round trip on your installation.

See the iPhone Remote setup and verification guide. No Platform API key is required merely for Remote. Ordinary mobile ChatGPT conversations remain on OpenAI. This is indirect remote control, not direct mobile access to the relay or dashboard.

Do not port-forward the persistent relay: it intentionally has no bearer token in local-only mode. The source repository can be viewed from a phone after it is made public, but that alone does not route mobile ChatGPT through Copilot.

Restore normal Codex

Use the Restore Desktop shortcut or run:

.\Disable-Codex-CopilotProxy.ps1

Restore removes auto-recovery first, stops the watchdog, terminal, and relay, verifies the saved backup hash, and restores the complete pre-enable config.toml byte-for-byte.

Because restoration is exact, deliberate changes made to config.toml while the relay is enabled are replaced by the saved baseline.

The Start/Repair shortcut can enable the relay again later. Closing only the visible terminal does not disable it: the watchdog reopens the terminal and keeps the relay available. The Restore shortcut is the intentional off switch.

Manual cross-platform setup

Windows users should prefer the automated flow above. On macOS or Linux, or when you do not want the Windows watchdog, use this manual flow.

  1. Install/authenticate Copilot CLI, clone the repository, run npm ci, and verify the selected model with npm run probe -- --model MODEL_ID.

  2. Back up ~/.codex/config.toml somewhere private.

  3. Start the relay and keep that terminal open:

     BRIDGE_PORT=4144 BRIDGE_DEFAULT_MODEL=gpt-6.1-sol node server.mjs

    To make Astra the compatibility target even when an existing Codex thread still sends a persisted Sol or Terra model, start with the explicit lock:

    BRIDGE_PORT=4144 BRIDGE_DEFAULT_MODEL=gpt-6-astra BRIDGE_MODEL_ROUTING_MODE=locked-default BRIDGE_LOCKED_REASONING_EFFORT=xhigh node server.mjs

    This lock is optional for manual installations. Windows Start/Repair now uses per-request routing, so explicitly selected child models are honored. /health exposes the policy and per-model limits; dashboard records preserve requested and selected models. See agent routing.

  4. Update the existing top-level model and model_provider values in ~/.codex/config.toml, then add the provider block once:

     model = "gpt-6.1-sol"
     model_reasoning_effort = "xhigh"
    model_provider = "github_copilot_bridge"
    
    [model_providers.github_copilot_bridge]
    name = "GitHub Copilot local bridge"
    base_url = "http://127.0.0.1:4144/v1"
    wire_api = "responses"
    requires_openai_auth = true
    experimental_bearer_token = "codex-copilot-local-only"
    request_max_retries = 0
    stream_max_retries = 3
    stream_idle_timeout_ms = 900000

    Keep these two authentication settings together. Codex app-server 0.153.4 suppresses its saved ChatGPT login from the desktop authentication API when requires_openai_auth is false, which can break browser control even while websites remain logged in. The explicit bearer is a nonsecret placeholder for the loopback relay, not an OpenAI or GitHub credential. It takes precedence for model requests and prevents ChatGPT token/account headers from reaching the relay. Never enable the flag without that override. This does not authenticate or secure the relay itself.

    Validate credential separation against the installed Codex binary after upgrading Codex: npm run probe:desktop-auth -- /path/to/codex. The probe uses synthetic credentials and a local mock server, not real model calls. See desktop authentication repair.

  5. Reopen the Codex task and run the health and streaming probes shown above.

  6. To stop, terminate node server.mjs and restore the private config backup.

The provider fields are defined by Codex's official configuration schema. The manual flow has no crash watchdog and cannot restore configuration automatically.

Dashboard and health

Model labels distinguish Requested (Codex's choice), Selected (relay backend), and SDK reported (usage-event model). The current policy appears above the metrics; historical calls retain their original route. SDK AI credits are shown for lifetime relay usage, by model, and per call. They are usage units, separate from the account entitlement and dollar benchmark. See the 1.3.17 notes.

With the persistent relay running:

The Tokens & Copilot cost over time charts share a 24-hour (hourly), 5-day (default, daily), or 30-day (daily) range. Pacific (America/Los_Angeles) is the default timezone; UTC is selectable. Pacific dates are summed from retained UTC hours, including 23/25-hour DST days, never relabelled UTC-day totals. Missing retained hours are gaps or explicit partial-day subtotals. The current hour/day is partial, and usage is counted when a relay response finalizes. Tokens are input plus output; cached input is already included. Cost is only SDK-reported totalNanoAiu / 1_000_000_000 AI credits, never dollar estimates, premium-request multipliers, or account balance changes. Hover, tap, or focus a bucket for exact input/output/cache tokens and credits. Coverage is shown for each range: unreported credits remain gaps and partial telemetry is a subtotal. These durable rollups survive detailed-history clearing and relay restarts; they exclude other Copilot clients and all OpenAI-provider usage.

Recent call history shows exact per-response total/input/output tokens, cached and non-cached input, SDK-call count, and AI credits. Tokens are summed across that response's SDK calls, not divided into an average. Cached input and reasoning tokens are subsets, not additions to the total. Missing measurements say not reported; in-progress usage is partial. The separate Payload bytes column splits request and recorded response sizes. Those are structured Codex-to-relay payload sizes (history, instructions, tools, encoded images and JSON), not new text tokens or a measurement of the upstream SDK request size. Select a row for the same token breakdown, exact bytes, and retained-image count.

The dashboard is a local command center as well as a history viewer:

  • The overview starts with four source-backed operational KPIs: lifetime calls, actual completion rate, measured average latency, and resumable SDK exchanges. The active-session headline includes exchanges paused for outer Codex tools; a secondary count shows only currently streaming HTTP responses.
  • A responsive three-column control room keeps compact measured usage and Copilot entitlement on the left, the live relay fabric in the center, and the request inspector on the right. Traffic and outcome charts sit directly below the surfaces they explain, then collapse to balanced two- and one-column layouts without fixed empty rows. The 24-hour plot uses a compact viewport so its full graph remains visible in the documented 1440 x 1100 overview.
  • Exact input tokens, output tokens, and SDK model calls remain prominent. The local API is sampled on every five-second poll and after SSE activity, and the panel separately shows when durable metrics last changed. Lightweight SVG sparklines use existing hourly, daily, and retained-call telemetry. There are no fabricated seats, users, accounts, or subscription charges.
  • /dashboard/events is a loopback-only Server-Sent Events feed. Real request phases move one small upright document glyph across the continuous Codex → Local Relay → GitHub Copilot → selected GPT model route; responses return as a three-line stream glyph and tool handoffs use a bracket glyph on the compact branch. No moving words, rotating capsules, thick neon beams, or per-node blink sequence cross the diagram. Simultaneous calls keep stable colors and five collision-resistant lanes; red is reserved for failures. The dependency-free renderer uses no per-frame JavaScript, honors reduced-motion, and bounds itself to 64 visible calls and 48 transient glyphs.
  • A live request inspector shows the latest real call ID, model, phase, measured tokens, SDK model-call count, latency, route, and outer-tool count. Its newest-first event log is capped at 16 rows in memory, even when many calls stream concurrently.
  • GitHub's SDK assistant.usage events provide exact per-model input, output, cache-read, cache-write, reasoning, nano-AIU, and model-cost-unit metrics. The relay treats each event as one SDK model call, stores only safe numeric aggregates, never persists provider tracing IDs, and attributes per-model totals to the model named by the event rather than the relay fallback model.
  • GitHub's SDK account.getQuota supplies chat, completions, and premium_interactions entitlement snapshots. Refresh is fail-soft and never blocks model traffic. The SDK does not expose the user's subscription purchase price, so the dashboard does not invent one.
  • The compact Public API benchmark is the fourth measured-usage tile beside input tokens, output tokens, and SDK model calls. It multiplies live measured per-call text tokens by a source-dated static reference of OpenAI's standard public list prices. Its date is explicitly a rate-reference date, not telemetry age. Cached input, GPT-5.6 cache writes, and documented >272K long-context multipliers are applied per model call. It excludes tool charges, regional/service-tier differences, taxes, and any unmetered calls, and is explicitly hypothetical—not an OpenAI charge, a GitHub charge, savings, or a Copilot invoice.

The persistent launcher always pins telemetry to the repository's ignored runtime directory, regardless of the shell's inherited environment. Before a stopped relay starts, it creates and validates a local telemetry snapshot under runtime/telemetry-backups; the newest eight launcher-managed snapshots are retained within a 512 MiB managed-backup ceiling, keeping the configured live telemetry plus managed recovery points below 1 GiB. At least the newest valid snapshot survives even if it alone exceeds that ceiling. Manually created backup folders are never pruned. These snapshots can contain sanitized request and response bodies, so keep them local and do not commit or share them.

To create an additional recovery point without restarting the relay:

.\Backup-Codex-CopilotTelemetry.ps1 -Reason before-upgrade

Alternate-port development servers must set a separate BRIDGE_RUNTIME_DIRECTORY. Never point two running relay processes at the same telemetry directory.

Official metric and price references:

The dashboard uses two storage tiers by default:

  • The newest 200 calls retain bounded, sanitized request/replay/output detail.
  • The remaining 800 recent calls retain only small metadata records.
  • Lifetime received, replayed, completed, failed, tool, byte, and latency counters live in a separate atomic metrics file and never decrease when old detail is compacted or when Clear detailed history is used.
  • Exact token, nano-AIU, model-multiplier, SDK-call, and public-benchmark counters share that durable metrics file and survive process restart.
  • Hourly rollups cover 31 days, daily rollups cover up to 10 years, and model totals feed the dependency-free model ledger and SVG/CSS charts.
  • The dashboard API returns lightweight indexes; a detailed body is fetched only when a recent detailed row is selected.

On the first upgrade from an older relay, the call odometer is preserved. Older outcomes are labeled unmetered because their exact SDK token events no longer exist; the dashboard shows a forward-only metering coverage percentage instead of estimating old prompts from bytes. Exact token/cost mileage is durable from the version-2 metrics migration forward.

Default managed storage ceilings are 256 MiB for recent history, 16 MiB for lifetime metrics, 64 MiB for the visible event stream, 8 MiB for watchdog events, and 32 MiB each for auxiliary stdout/stderr. That is roughly 408 MiB, comfortably below the requested 1 GiB budget. Oversized detailed records are bounded first, then older bodies are downgraded to metadata before any recent metadata would need to be dropped. The persistent launcher sets these defaults; advanced manual users can override BRIDGE_HISTORY_LIMIT, BRIDGE_DETAILED_HISTORY_LIMIT, BRIDGE_HISTORY_MAX_MIB, BRIDGE_METRICS_MAX_MIB, BRIDGE_HISTORY_RECORD_MAX_KIB, and BRIDGE_EVENT_LOG_MAX_MIB within the hard server clamps.

Credential fields and common token patterns are redacted, but you should still treat runtime/ as private. The entire directory is excluded from Git.

Public pricing changes over time. pricing.mjs records the source date and model-specific official URLs used by the dashboard; update and retest that snapshot when OpenAI changes a listed rate. Copilot-side token prices and quota remain runtime SDK data and are not hard-coded as currency.

One-shot isolated launcher

The one-shot launcher does not modify the user's normal Codex configuration:

.\codex-copilot.cmd exec --ephemeral --skip-git-repo-check "Reply with exactly RELAY_OK"

It starts an authenticated temporary loopback relay, launches the bundled Codex CLI with provider overrides, and stops the relay when Codex exits.

Concurrency and tests

Each initial Responses request receives a separate Copilot SDK session, so independent Codex agents can overlap instead of sharing a single serialized session.

npm test
.\proxy-config.test.ps1
.\sdk-process-health.test.ps1
npm run probe:codex-heartbeat
npm run probe:sdk-recovery -- --model gpt-5.6-luna
npm run probe:session-churn -- --model gpt-5.6-luna --rounds 80
npm run probe:client-disconnect -- --url http://127.0.0.1:4144 --model gpt-5.6-sol
npm run probe:stream -- --url http://127.0.0.1:4144/v1
npm run probe:compatibility -- --url http://127.0.0.1:4144/v1 --model gpt-5.6-sol
npm run probe:concurrency -- --url http://127.0.0.1:4144/v1 --count 4 --model gpt-5.6-sol
npm run probe:tools-relay -- --url http://127.0.0.1:4144/v1 --steps 6 --model gpt-5.6-sol
npm run probe:deferred-tool -- --url http://127.0.0.1:4144/v1 --model gpt-5.6-sol
npm run probe:reasoning-phase -- --url http://127.0.0.1:4144/v1 --model gpt-5.6-sol
npm run probe:request-semantics -- --url http://127.0.0.1:4144/v1
npm run probe:tool-choice -- --url http://127.0.0.1:4144/v1 --model gpt-5.6-luna
npm run probe:agent-message -- --url http://127.0.0.1:4144/v1 --model gpt-5.6-luna
npm run probe:premature-recovery -- --url http://127.0.0.1:4144/v1
npm run probe:delayed-tool -- --url http://127.0.0.1:4144/v1 --delay-ms 31000
npm run probe:failure-stream -- --url http://127.0.0.1:4144/v1

The live probes consume Copilot allowance. Unit, configuration, and probe:codex-heartbeat tests do not make Copilot model calls. The heartbeat probe runs a real Codex client against a deterministic local Responses server: Codex has a 1-second idle timeout, receives no model text for 4 seconds, and must remain connected through parsed heartbeat events. Together, the probes verify ordered streaming, abandoned-client cleanup, parallel requests, a multi-turn tool chain, root/developer/memory/tool-result fidelity, progress-only recovery, deferred-tool discovery, phased output, explicit compatibility errors, local parent/child-agent message fidelity, delayed outer-tool continuation, and a well-formed terminal failure.

probe:sdk-recovery is an opt-in Windows crash test. It starts its own relay on an ephemeral loopback port, holds a tool continuation, kills only that relay's verified Copilot worker during a second streaming request, and verifies automatic replacement, dead-session cleanup, terminal SSE failure, streaming, a tool chain, and four parallel requests. It never targets the persistent relay on port 4144.

probe:session-churn starts a separate two-slot relay, holds one slow tool, and replaces the other task's history 80 times (configurable with --rounds). It must never exceed two retained SDK sessions, must resume both final tool results, and must recycle the worker only after both tasks release it. Unit tests additionally exercise 1,001 history replacements, 10,000 response lookups, and a simulated 12-hour wait. These are regression tests, not a claim of a real 12-hour soak run.

The default 13-hour outer-tool result window lets a single Codex exchange wait through a 12-hour local render, browser operation, or child-agent task. It does not create artificial follow-up turns after Codex has genuinely completed a task, and it cannot override GitHub account limits, model limits, outages, or service policy. Override it with BRIDGE_TOOL_RESULT_TIMEOUT_MS if a different local ceiling is required.

The watchdog recovers the gateway for new calls after a process or terminal failure. An in-process SDK supervisor also recovers when the Copilot CLI worker dies while the HTTP gateway remains alive. /health now pings the SDK and reports ok, sdk.state, sdk.generation, session counts, and recovery/recycle counters; an HTTP 200 alone is not a readiness check. A closed SDK connection triggers one replacement shared by concurrent callers. Interrupted streams receive a terminal response.failed event with the failure cause instead of waiting indefinitely. Only sessions belonging to the dead worker are invalidated. Session creation can retry once before any prompt is sent; prompts and tool side effects are never silently replayed. Retry or continue the interrupted Codex task after recovery.

To bound retained-session pressure, at most 64 SDK sessions (including concurrent allocations) are admitted by default. Additional new requests receive a retryable 503 while existing tool continuations are preserved. A worker is recycled after 128 created sessions or six hours, only when no sessions or allocations remain. These are pressure controls, not a guarantee against every upstream memory leak. Overrides: BRIDGE_MAX_COPILOT_SESSIONS (2-128), BRIDGE_SDK_RECYCLE_AFTER_SESSIONS (8-4096), and BRIDGE_SDK_PROBE_INTERVAL_MS (500-60000; default 10000). A slow ping marks the backend degraded; it is not by itself permission to kill healthy resumable work.

Codex can abandon a pending tool call when it compacts its history, accepts a steering message, or receives inter-agent input. Starting another SDK session without retiring that old wait used to consume a slot for the full 13-hour lease. The relay now keys sessions by Codex's thread-id / client_metadata.thread_id (with auxiliary request kinds kept separate). A fresh request from the same task retires its obsolete parked session before admission; an ordinary matching tool result continues the existing session. Active streams and other tasks' tool waits are never evicted to make room. Child agents cannot accidentally continue a parent's pending call copied into their history. Anonymous clients retain the bounded legacy behavior and should send a distinct UUID thread identity per task. Do not reuse a parent identity for concurrent child agents.

Only the latest response lookup is retained per exchange. /health exposes exchangeStates (streaming, waiting-for-tools, identified tasks, anonymous sessions), plus sdk.availableSessionSlots and sdk.canAcceptNewSessions. Backend liveness and admission capacity are separate: a healthy worker can be fully occupied by legitimate tool waits. Dashboard errors retain their actual message and code rather than displaying [object Object].

In-memory exchanges cannot survive a relay process crash, machine sleep/network loss, an upstream Copilot outage, quota exhaustion, or a model context limit. Long-running work should still produce checkpoints and durable artifacts so Codex can resume safely after any external interruption. The durable in-flight crash-resume design specifies the idempotency and crash-injection gates required before that feature can be enabled without risking duplicate local tool execution.

Recovering a pre-supervisor release after a confirmed CLI heap crash

Normal updates wait for active exchanges to finish. Old releases can retain stale exchange counts after the CLI exits with JavaScript heap out of memory. For that specific legacy failure, the following guarded recovery is available:

.\Stop-Codex-CopilotWatchdog.ps1
.\Start-Codex-CopilotProxy.ps1 -Port 4144 -Model gpt-5.6-sol -RecoverDeadBackend
.\Repair-Codex-CopilotProxy.ps1 -Port 4144 -Model gpt-5.6-sol -NoDashboard

Use your configured model in place of the example. The recovery refuses to stop the listener unless repeated checks prove that this repository owns the process, the CLI logged a fatal heap crash after startup, and no worker remains. It backs up telemetry and preserves the crash log before replacing the already-broken parent. It refuses this exception for supervised releases and live workers; do not use it as a force-update flag. The normal stop/restore shortcut remains the way to return Codex to its original provider configuration.

Since 1.3.76, Stop & Restore deliberately cancels active relay work on both adapters, disables recovery, confirms owned-process exit, and restores the protected original TOML. Click Start Relay next to load the latest local code. History, keys and backups remain intact. This manual cancellation is separate from internal Start/Repair and automatic updates, which still protect active work. Since 1.3.79, desktop Start Relay also cancels owned sessions before loading the latest local package, while retaining the managed configuration. See the two-control contract.

Since 1.3.94, Claude has 128 local session slots by default (64 since 1.3.77, 16 before), independently of Codex's 64-slot default. Tool-waiting sessions count, too; only ones idle for over 5 minutes are released when every slot is full. Developers can configure BRIDGE_MAX_CLAUDE_SESSIONS (2-256) in the launching environment. This is not a provider quota increase. See capacity and verification.

The context guard limits each historical text tool result to 64 KiB. Image count and per-image size are taken from the selected Copilot model's advertised capabilities. For gpt-5.6-sol, Copilot currently advertises one prompt image, so the relay keeps the newest image from the latest user turn first, then an outer instruction image, then older user/history images. It replaces omitted image markers with an explicit explanation instead of silently showing the model an attachment name that was not sent. When instructions, tool schemas, and accumulated history approach 90% of the selected model's advertised prompt-token limit, the relay preserves every distinct outer instruction, the latest user request, and the newest tool chain while replacing older history with a bounded continuity ledger. That ledger gives omitted user corrections and constraints priority and retains compact excerpts of tool inputs and results. Image attachments referenced only by omitted history are dropped. The selected dashboard record exposes retained/omitted entry, character, and token counts, model compatibility limits, and the terminal reports CONTEXT OK when compaction occurs.

The hard rejection remains as a last resort when fixed instructions/tool schemas or the mandatory current request and newest tool chain cannot fit under the ceiling. Raising the limit does not increase the upstream model's context window.

The relay uses a local o200k_base tokenizer as a budgeting estimate because Copilot does not expose its server-side tokenizer. A 10% reserve covers provider wrappers and tokenizer drift. The old BRIDGE_MAX_SERIALIZED_CONTEXT_CHARS limit remains an emergency fallback only for models that do not advertise a prompt-token limit; it no longer rejects a valid long-context request merely because its UTF-16 character count exceeds one million.

Independently, the Copilot instructions field is bounded to the observed 1,048,576-character maximum (reliability.maxInstructionsChars in /health). Only envelopes exceeding that cap use exact, same-role deduplication of complete standalone skill catalogs. Latest copies stay in place; older copies become explicit numbered references. Unique rules and catalogs are not truncated or moved into user text. Numeric context diagnostics include originalSystemChars, deduplicatedSkillCatalogs, deduplicatedInstructionChars and the limit. The field check runs again after image annotations. It does not increase the token window, HTTP payload limits, or the capacity for genuinely unique rules.

Codex resends its full task envelope. Drive, browser and image tools can put large base64 results in that history. Ordinary /v1/responses now streams up to 512 MiB on the wire, replaces only eligible older embedded image nodes with explicit text markers, and limits retained JSON to 128 MiB by default. The image window is at most 12 images and 32 MiB of image URL characters. It never silently evicts the newest image-bearing input item. Instructions, non-image text and tool metadata remain intact at ingress; the separate model-token compactor still applies afterward. Original Codex files are never edited.

/health reports reliability.maxRequestWireBytes, maxRequestBodyBytes and requestUploadTimeoutMs. Four uploads may be parsed concurrently; another gets 429 with a retry hint. A two-minute total upload deadline returns 408; this is only request ingestion, not the model-generation or long tool-wait deadline. Oversized current images return 400; excess text, wire bytes or retained JSON return 413. Explicit OpenAI requests are never forwarded with pruned history: a route named late after pruning is rejected. Other endpoints retain their existing strict body reader and limits.

For an unusual workload, set BRIDGE_MAX_REQUEST_BODY_BYTES and optionally BRIDGE_MAX_REQUEST_WIRE_BYTES before starting the relay. Values are clamped between 1 MiB and 512 MiB; wire capacity is never lower than retained capacity. These are payload limits, not promises of equally small process memory: parsing, serialization and later image decoding need additional bounded working space. Prefer connector calls that omit unneeded base64 media, and start a fresh Codex task if even the bounded envelope is exhausted.

Compatibility boundary

See the compatibility matrix and context-window setup for the verified feature classes, hosted-tool limits, and live regression probes.

The relay uses Copilot's standard context tier, never automatically opting into the more expensive long-context tier. Astra and Sol have a 400,000-token total window: 272,000 input plus 128,000 output. Model-specific smaller limits remain smaller. Windows enable/repair synchronizes this profile into the Codex model catalog, with automatic history compaction at 240,000 tokens for these models. SDK background compaction starts at 80% of the prompt budget (217,600 tokens). Existing in-flight exchanges retain their original settings until they finish; busy upgrades are deferred, and existing Codex tasks must reload their catalog.

The generated catalog enables Codex's client-side tool discovery with supports_search_tool = true. This capability is unrelated to hosted web search, which remains disabled through web_search = "disabled". Disabling discovery makes Codex send all connected tool definitions instead of discovering a relevant subset. Discovered tools stay loaded across rebuilds, and namespace deferral survives translation. No plugins are uninstalled and no approval policy is relaxed.

Legacy catalogs above 30 tools keep core execution tools eager and defer the remaining definitions through SDK tool search. Tools, full descriptions, schemas and Codex approval handling remain intact. The local context guard measures eager schemas and complete deferred names/descriptions, not all inactive parameter schemas. It never shortens a description merely to make a context estimate fit. Each context.prepared event separates registered, eager and deferred tool counts and labels local estimates separately from SDK-reported usage. Exact duplicate standalone skill catalogs are reduced before reaching the provider field cap; unique rules, differing snapshots and authority boundaries stay intact. SDK context usage and compaction start/complete events record numeric before/after counts and success without logging summaries. Transport history reduction is not the same as Codex history compaction: old screenshots can still arrive over the loopback connection. Compaction cannot shrink unique system/developer rules. The catalog preserves the stock Codex instruction template. Generated files stay in ignored runtime storage; original configuration values remain restorable. Native hosted search is removed. The optional native image adapter enables GPT Image 2 through the installed stock Codex engine and its existing ChatGPT sign-in. These calls use separate OpenAI/ChatGPT allowance; main conversation inference still uses Copilot. Browser and connector tools are independent. Fresh tasks must reload the configuration.

The relay preserves the Codex-side contract: system/developer instructions, role-ordered conversation history, function/custom/namespace tool declarations, tool-call continuations, reasoning effort/summary configuration, assistant phase, images within the selected model's limit, and streaming Responses lifecycle events. Codex still loads its own memory and skills and still executes every local/browser/connector tool. The Copilot SDK receives those outer instructions and declaration-only tool schemas; its own memory and built-in tools are intentionally off so they cannot conflict with the desktop harness. The sole conditional built-in is Copilot's tool_search_tool, used only to discover outer declarations deferred explicitly or by the relay's large-catalog policy. Codex's separate client-executed tool_search remains the preferred route for discovering connector tools.

Responses capability Relay status
Text input/output, streaming, usage, phases Supported
Function/custom/namespace tools and continuations Supported; execution and approval stay in Codex
Parallel independent Codex agents Supported with one Copilot SDK session per initial request
Local Codex parent/child-agent messages Supported in both directions; Codex collaboration payloads are preserved while provider-encrypted reasoning stays opaque
Reasoning effort Forwarded to Copilot; an explicit locked-default policy can pin it for all requests
Readable reasoning summary Forwarded when Copilot emits it; the provider may return reasoning usage without summary text
Context window Standard tier, at most 400k total; no automatic 1M-tier opt-in
Data-URL images Supported within the selected model's advertised image limits
Native hosted web search Removed; use harness browser/connector tools
Built-in GPT Image 2 Optional native image adapter; separate OpenAI/ChatGPT helper and image usage
Stored Responses, Conversations, other hosted tools, structured-output enforcement Rejected explicitly; not silently emulated
OpenAI prompt-cache identity, encrypted reasoning state, service tier, sampling/logprobs Provider-specific and not transferable
SDK worker crash recovery Automatic replacement and new-call recovery; interrupted in-memory exchanges require a Codex retry/continue
Durable in-flight crash resume Not yet supported; no silent replay of prompts or side effects

This is a compatibility relay, not byte-for-byte identity with OpenAI's native serving stack. Provider-side encrypted reasoning state, provider compaction, quotas, service policy, and hosted-only tools cannot be transferred between OpenAI and GitHub. The same model name can therefore still show small behavioral differences even when the visible Codex contract is preserved.

Why Codex can still ask for permission

The assistant should perform routine work already authorized by the user without asking again. The relay now reminds the model of this explicitly. A conversational question is not a command-approval dialog, and changing the shell approval policy cannot guarantee that a model will never ask a question.

The relay changes inference routing; it does not replace Codex, Windows, the browser, or connector security boundaries. With approval_policy = "never" and sandbox_mode = "danger-full-access", ordinary local shell and file work should not produce Codex command-approval prompts in a newly opened task. Existing tasks may retain the policy they loaded at creation, so reopen the task after changing config.toml.

Separate consent can still be required for Windows UAC, browser camera/location access, OAuth/login, connector authorization, publishing or sending content, purchases, destructive cloud actions, and transmission of sensitive data. A plain assistant message such as “may I proceed?” is a model clarification, not a native permission dialog. ChatGPT mobile/cloud tasks also do not inherit the desktop Codex config.toml. These boundaries remain enforced whether the model request uses the native OpenAI provider or this relay.

Security model

  • The persistent HTTP listener is hard-coded to 127.0.0.1.
  • Copilot OAuth credentials are not copied into this repository or runtime state.
  • Persistent mode intentionally has no bearer token because it is local-only.
  • Any local process running as the user may submit a request while the relay is enabled and consume Copilot allowance.
  • For child-agent compatibility, the relay removes the OpenAI-provider-specific encrypted annotation from the tool schema sent to Copilot and transports the delegation message as ordinary text on loopback. Do not expose the relay outside the local machine.
  • runtime/, node_modules/, logs, PIDs, event history, and config backups are ignored and must never be committed.
  • Node diagnostic reports, heap snapshots, and crash dumps are also ignored; they can contain environment secrets and must not be attached to public issues.
  • Disable the relay when it is not needed.

Terms and project status

The GitHub Copilot SDK is MIT-licensed and GitHub documents it as a programmable SDK for building Copilot-powered applications. SDK usage requires an entitlement unless BYOK is configured, and prompts count against the applicable Copilot quota.

Users are responsible for complying with the GitHub Terms of Service, additional product terms, and acceptable-use policies.

This project is not affiliated with, endorsed by, or supported by GitHub, Microsoft, or OpenAI. GitHub, GitHub Copilot, OpenAI, and Codex are trademarks of their respective owners.

Isolated Claude Code preview

An opt-in Messages gateway for stock Claude Code is being tested alongside the existing Codex relay. Real file tools, MCP, image reading, project skills/hooks, session resume and parallel Copilot Claude-model agents passed. It is not full native parity or a published release: hosted tools, several beta features and long-duration/cross-platform certification remain release gates. Signed-thinking tool continuations, the interactive model picker, real /compact, SDK-worker recovery and gateway restart now have scoped live proof. Auto-mode classification for parallel fixture agents also passed; permissions remain enforced by stock Claude Code.

For everyday desktop use, start with the complete Claude Code guide. See the preview setup, architecture, compatibility and rollback guide.

Failed HTTP requests now retain validated upstream retry decisions, whole-second delays and correlation IDs. Finite stock Windows/Linux retry and file-tool proofs use local fixtures; they are not paid-provider or long-duration certification. Exact token counting remains an explicit optional 501 rather than a guessed Anthropic count. See the retry contract and reproduction commands. The existing dashboard is preserved; the preview has a separate usage ledger.

The connection center also has a read-only Saved local usage panel for this checkout's canonical desktop Codex, portable Codex and Claude ledgers. It shows separate Copilot/OpenAI subtotals, reported credit coverage and stored model attribution without claiming another gateway is live. Copied histories can overlap; these are not account-wide totals. See Local usage scope and limits.

Author

Created by Madhav Somani.

License

Codex Copilot Relay is released under the MIT License.

About

Unofficial localhost gateway that routes Codex model calls through the official GitHub Copilot SDK—with concurrent agents, reversible Windows setup, and live observability.

Topics

Resources

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages