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.
Quick start · Live dashboard · How it works · Restore Codex · Security
A real end-to-end SDK validation call captured from the dependency-free local dashboard. No mock traffic or fabricated metrics.
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_SESSIONSnow 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.
- 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_STEPSandBRIDGE_CHECKPOINT_AI_CREDITSbefore 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.
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.
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.
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.
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.
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.
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-solReopen 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.
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.
![]() |
![]() |
| Live fabric, exact SDK usage, entitlement, and request inspector | Traffic history, bounded storage, and recent calls |
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.
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
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
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.
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.
- OpenAI Responses-compatible
/v1/responsesendpoint - Official
@github/copilot-sdkbackend - 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.completedorresponse.failedevents - Assistant
commentary/final_answerphases, readable reasoning-summary events when Copilot emits them, and incremental function/custom-tool inputs auto,none,required, and named function/customtool_choicehandling- 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.failedevent 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
- 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.
GitHub's current cross-platform installation requires Node.js 22 or later:
npm install -g @github/copilot
copilot login
copilot --versionFollow 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:
- Install and start GitHub Copilot CLI
- Authenticate GitHub Copilot CLI
- How Copilot SDK authentication works
git clone https://github.com/madhavsomani/codex-copilot-relay.git
cd codex-copilot-relay
npm ciThe 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.
npm run probe -- --model gpt-5.6-solThe 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.
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-solThis command:
- Saves the complete normal Codex configuration to a protected local backup.
- Adds a managed
github_copilot_bridgecustom-provider block. - Starts the loopback relay and validates health.
- Installs a per-user Scheduled Task watchdog.
- Starts a visible Windows Terminal event stream.
- 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 = 900000The 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.
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-solOpen 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.
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-solUse 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.
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.
Use the Restore Desktop shortcut or run:
.\Disable-Codex-CopilotProxy.ps1Restore 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.
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.
-
Install/authenticate Copilot CLI, clone the repository, run
npm ci, and verify the selected model withnpm run probe -- --model MODEL_ID. -
Back up
~/.codex/config.tomlsomewhere private. -
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.
-
Update the existing top-level
modelandmodel_providervalues 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_authis 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. -
Reopen the Codex task and run the health and streaming probes shown above.
-
To stop, terminate
node server.mjsand 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.
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:
- Dashboard: http://127.0.0.1:4144/dashboard
- Health: http://127.0.0.1:4144/health
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/eventsis 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.usageevents 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.getQuotasupplieschat,completions, andpremium_interactionsentitlement 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-upgradeAlternate-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:
- GitHub Copilot SDK usage and billing metrics
- GPT-5.6 Sol public API pricing
- GPT-5.6 Luna public API pricing
- The remaining model-specific links are visible beside each rate in the dashboard.
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.
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.
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/v1The 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.
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 -NoDashboardUse 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.
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.
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.
- 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
encryptedannotation 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.
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.
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.
Created by Madhav Somani.
Codex Copilot Relay is released under the MIT License.


