This document tracks the implementation backlog for
@codexbridge/codex-gateway.
This workstream is currently paused.
Keep this document as a historical backlog and reference. It should not be treated as an active implementation queue unless the product direction changes again.
It is the execution-oriented companion to:
docs/architecture/codexbridge-core-architecture.mddocs/todo/roadmap.md
Codex Gateway should become the protocol layer that lets Codex run on OpenAI-compatible model providers without changing bridge-side WeChat UX.
It should own:
- Responses request to Chat Completions request conversion
- Chat Completions response to Responses object conversion
- SSE and stream-event conversion
- function/tool call conversion and repair
- provider capability catalog and payload rules
- reasoning/thinking policy normalization
- usage and error normalization
- local
/v1/responsesadapter server
It should not own:
- WeChat/Telegram transports
- SendGate delivery policy or
ret:-2handling - slash commands, i18n, and user-facing chat UX
- bridge sessions, thread binding, or provider profile selection UX
- approvals, retry/reconnect, or interrupted-turn recovery state
- assistant records, automations, uploads, or artifact delivery policy
- Codex native account/session management
Primary long-lived branch for this workstream:
track/codex-gateway
Expected file ownership for this branch:
packages/codex-gateway/**src/providers/codex/config.tssrc/providers/openai_compatible/**src/providers/shared/thinking_policy.tstest/providers/codex/config.test.tstest/providers/openai_compatible/**reference/codex-gateway/**docs/architecture/codexbridge-core-architecture.mddocs/todo/codex-gateway.md
Avoid frequent edits here unless the change is truly cross-cutting:
docs/todo/roadmap.mdREADME.mdpackage.json
- Stop treating OpenRouter live smoke as an active Phase 4 blocker; defer it until credentials are available again
- Keep new provider onboarding config-first and capability-driven instead of adding one-off provider classes
- Keep package ownership strictly at protocol/gateway level
- Decide whether Phase 5 should remain internal-only or move toward publishable package form
Latest progress:
- Preset-backed provider profile exposure now iterates
OPENAI_COMPATIBLE_PROFILE_PRESET_REGISTRATIONSinstead of hardcoded per-providerpushProfile(...)calls insrc/providers/codex/config.ts - Qwen/DashScope env alias handling is covered by dedicated config tests so compatible-provider onboarding stays registration-driven
-
CODEX_COMPAT_PROFILES_JSONcan now declare multiple custom OpenAI-compatible provider profiles without adding new provider/plugin classes -
CODEX_COMPAT_PROFILES_PATHnow supports file-based custom compatible provider lists, with inline JSON taking precedence for duplicate IDs - Custom compatible provider definitions can now merge
capabilityOverrides, so provider-specific tool/multimodal/thinking/retry quirks can often stay in config instead of code - Custom compatible provider definitions can now embed
modelCatalogdirectly, so provider onboarding can stay config-first even without a separate catalog file - Custom compatible profile JSON ignores invalid entries while preserving existing built-in preset, single-profile, and legacy config paths
-
scripts/check-codex-gateway-boundary.mjsnow enforces that legacy bridge-side shim files stay pure re-exports intopackages/codex-gateway - Package public-surface tests now lock
@codexbridge/codex-gatewayto an internal-only release channel (private: true+ minimal exports/files) until the API boundary and live-provider matrix are stable - Package
tsconfignow emits intopackages/codex-gateway/dist, and public-surface tests lock that build layout to thepackage.jsonexports/files contract - OpenRouter live smoke is no longer treated as a current phase blocker; it is deferred until credentials are available again
-
codex-gatewaynow ships an internal-only standalone server launcher that can boot the local/v1/responsesadapter directly from env, without pulling in CodexBridge runtime code - The standalone launcher now supports dotenv-style env-file loading (
CODEX_GATEWAY_ENV_FILE/--env-file) so it can run without manual shell exports -
codex-proxy-inspired regression tests now lockprevious_response_idpreservation and Codex-style stream event ordering at the package server boundary - LiteLLM-inspired upstream error normalization now preserves
retry_after_msplus selected request/rate-limit headers at the package server boundary - LiteLLM-style model catalog pricing and context-window metadata are now normalized and preserved through package
/v1/modelsoutput - LiteLLM-style usage aliases such as cache, reasoning, audio, and prediction token fields are now normalized into Responses usage details at the package boundary
- LiteLLM-inspired usage normalization now associates response usage with normalized model pricing metadata to expose estimated input, output, and total cost at the package boundary
- Package
/v1/modelsoutput now includes a normalizedprotocolview that merges provider defaults with model overrides for tools, multimodal input, reasoning, compact support, structured output, and output-token limits - Package model catalogs and
/v1/modelsoutput now include a normalizedcapabilityCatalogsummary for tool calling, file/PDF input, reasoning, compact support, and provider/model-specific quirks - Package
/v1/modelsoutput now also exposes top-level adaptermetaplus per-model routing and reasoning-transport metadata, so upstream model alias rewrites and provider-specific thinking toggles are visible without replaying a live request - Model-level retry overrides now apply to live upstream retry decisions, and
/v1/modelsexposes normalized retry metadata at both top-level adaptermetaand per-modelprotocolviews - Package trace mode now emits machine-readable
request.adjustedevents for filtered fields, dropped tools, capped output-token requests, and unsupported image/file input downgrades - Package-local trace mode now exposes optional request/response/retry/stream trace hooks, and the internal standalone launcher can emit those trace events as NDJSON to stderr
- Upstream error normalization now exposes stable categories and retry hints for authentication, rate-limit, transient, unsupported-feature, invalid-request, and malformed-upstream cases
- Package contract coverage now includes provider-shaped golden fixtures for streaming tool-call deltas, Gemini-style usage payloads, and top-level rate-limit error events
-
open-responses-inspired package server coverage now locks/models,/responses, and/responses/compactas the primary Responses-first routes, while keeping/v1/*aliases for SDK compatibility -
llm-rosetta-inspired protocol-boundary rules now explicitly lockopenai-chat-compatibleto the current direct adapter path and defer Anthropic/Gemini-native targets behind a future IR gate
The package should stay as an internal package inside the CodexBridge repository first:
packages/codex-gateway/
Rules:
CodexBridge -> @codexbridge/codex-gateway@codexbridge/codex-gateway -X-> CodexBridge core/platform/runtime/store/i18n- No workspace/monorepo conversion is required yet
- Legacy CodexBridge provider paths may remain re-export shims during migration
- Phase 5 decision on 2026-05-06: keep the package internal-only for now; do not widen npm/public surface until live-provider coverage and integration contracts are stable
- Keep package-local build output aligned with
package.jsonexports/files so the internal package can still be consumed exactly as declared - Standalone server launch is allowed as an internal validation/tooling aid, but it is still not positioned as a public gateway product
- The standalone launcher may load dotenv-style env files for internal operation, but explicit process env must continue to win over file defaults
The package should be responsible for:
- Convert OpenAI Responses requests to Chat Completions requests
- Convert Chat Completions responses back to Responses objects
- Convert Chat Completions SSE chunks into Responses SSE events
- Convert tool/function calls in both non-streaming and streaming paths
- Map provider usage/token fields into Responses usage
- Map provider errors and stream read failures into stable Responses errors
- Apply provider capability rules for tools, reasoning/thinking, payload quirks, multimodal input, JSON/schema support, token caps, and unsupported feature downgrade
- Expose a small local adapter server that presents
/v1/responses,/v1/responses/compact, and/v1/models
The package must continue not to own:
- WeChat commands, SendGate, chunking, typing, or
ret:-2behavior - Bridge sessions, provider profile selection, thread binding,
/new,/open,/threads, or/status /allow,/deny,/retry,/reconnect, approval state, or interrupted-turn recovery- Assistant records, automations, uploads, attachment archival, or i18n
- Codex account/session management and native OpenAI app-server behavior
- Freeze current behavior with existing adapter tests before moving files
- Record the public surface that CodexBridge depends on: request conversion, response conversion, stream conversion, compact fallback, provider presets, capability merge, WebSocket repair primitives, and local adapter server
Frozen migration surface:
- Core converters:
responsesRequestToChatCompletions,chatCompletionsResponseToResponses,responsesRequestToCompactionResponse - Stream converters:
translateChatCompletionsSseToResponsesEvents,translateChatCompletionsSseStreamToResponsesSse - Local server:
OpenAICompatibleResponsesAdapterServer,reserveLocalPort - Capability/model catalog:
getOpenAICompatibleProviderPreset,buildOpenAICompatibleModelCatalog,buildOpenAICompatibleExternalModelCatalog, CLIProxyAPI catalog helpers - Thinking/payload policy: capability types,
mergeOpenAICompatibleProviderCapabilities,resolveOpenAICompatibleProviderCapabilitiesForModel,resolveReasoningEffortForProvider,applyThinkingPolicyToOpenAIChatRequest - WebSocket repair: transcript replacement, synthetic call ID, tool-call input repair, and event recording primitives
- Baseline tests run on 2026-05-06: adapter, adapter server, WebSocket repair, and OpenAI-compatible plugin tests
- Package root:
packages/codex-gateway - Package metadata:
packages/codex-gateway/package.json - Package source entry:
packages/codex-gateway/src/index.ts - Package README documents protocol-only ownership and bridge non-ownership
- Root scripts:
codex-gateway:typecheck,codex-gateway:build,codex-gateway:test,codex-gateway:check-boundary - Boundary script:
scripts/check-codex-gateway-boundary.mjs - Root
tsconfig.jsonincludespackages/**/*.tsso full typecheck/build sees package code - Verification run on 2026-05-06:
codex-gateway:typecheck,codex-gateway:test,codex-gateway:check-boundary,codex-gateway:build, roottypecheck, rootbuild, andgit diff --check
- Moved
src/providers/shared/thinking_policy.tsimplementation topackages/codex-gateway/src/capabilities/thinking_policy.ts - Moved
src/providers/openai_compatible/cliproxy_model_catalog.tsimplementation topackages/codex-gateway/src/capabilities/cliproxy_model_catalog.ts - Moved
src/providers/openai_compatible/capability_presets.tsimplementation topackages/codex-gateway/src/capabilities/capability_presets.ts - Replaced the old CodexBridge paths with re-export shims so existing imports continue to work
- Removed the package-side dependency on CodexBridge
ProviderModelInfoby introducing a package-local structuralOpenAICompatibleModelInfo - Added package-level capability tests for presets, external catalog import, reasoning effort resolution, and model capability overrides
- Verification run on 2026-05-06:
codex-gateway:typecheck,codex-gateway:test,codex-gateway:check-boundary,codex-gateway:build, OpenAI-compatible adapter/config/plugin tests, roottypecheck, rootbuild, andgit diff --check
- Moved
src/providers/openai_compatible/responses_adapter.tsimplementation topackages/codex-gateway/src/converters/responses_adapter.ts - Replaced the old
src/providers/openai_compatible/responses_adapter.tspath with a re-export shim so adapter server and tests keep working - Exported request conversion, response conversion, compaction fallback, and SSE translator APIs from
packages/codex-gateway/src/index.ts - Added package-level converter tests for request conversion, response conversion, and SSE conversion
- Verification run on 2026-05-06:
codex-gateway:typecheck,codex-gateway:test,codex-gateway:check-boundary,codex-gateway:build, OpenAI-compatible adapter/config/plugin tests, roottypecheck, rootbuild, andgit diff --check
- Moved
src/providers/openai_compatible/responses_adapter_server.tsimplementation topackages/codex-gateway/src/server/responses_adapter_server.ts - Replaced the old
src/providers/openai_compatible/responses_adapter_server.tspath with a re-export shim soOpenAICompatibleProviderPluginand existing tests keep working - Exported
OpenAICompatibleResponsesAdapterServer, server options, andreserveLocalPortfrompackages/codex-gateway/src/index.ts - Added package-level server tests for compact fallback, model metadata, and local port reservation
- Verification run on 2026-05-06:
codex-gateway:typecheck,codex-gateway:test,codex-gateway:check-boundary,codex-gateway:build, OpenAI-compatible adapter/server/config/plugin/WebSocket repair tests, roottypecheck, rootbuild, andgit diff --check
- Added
packages/codex-gateway/test/contracts.test.tsas the package-boundary contract suite - Covered Responses request to Chat request conversion without bridge-owned fields
- Covered non-streaming Chat response to completed Responses object conversion
- Covered function tool request conversion, tool-name shortening, and response-side name restoration
- Covered model-level tool disabling and transcript downgrade behavior
- Covered streaming text and tool-call deltas into Responses SSE events
- Covered OpenAI usage, Gemini-family
usageMetadata, and estimated usage fallback - Covered upstream stream errors and upstream read failures as
response.failed - Covered local compact fallback output
- Covered multimodal downgrade for unsupported image and file input
- Full verification run on 2026-05-06:
codex-gateway:check-boundary,codex-gateway:typecheck,codex-gateway:test,codex-gateway:build, OpenAI-compatible adapter/server/config/plugin/WebSocket repair tests, roottypecheck, rootbuild, andgit diff --check - Refactored live-provider smoke tests to load the real CodexBridge provider profiles via
loadCodexProfilesFromEnv()before starting the local Responses adapter server - Added
pnpm run test:live-openai-compatibleas the explicit gated live smoke entrypoint - Profile-based live smoke harness verification run on 2026-05-06: default test path skips safely; gated path also skips when current shell has no DeepSeek, MiniMax, Qwen/DashScope, or OpenRouter profile env
- Added
CODEXBRIDGE_TEST_ENV_FILEsupport to the test runner so gated live tests can load a service env file without printing secrets - Live profile smoke run on 2026-05-06 with
/home/ubuntu/.config/codexbridge/weixin.service.env: DeepSeek, MiniMax, and Qwen passed through real CodexBridge profiles - OpenRouter live smoke is explicitly deferred because credentials will not be provided in the near term; Phase 4 now closes with DeepSeek, MiniMax, and Qwen verified
- Decide whether to publish as
@codexbridge/codex-gateway; keep it private/internal until the API boundary is stable - Keep package metadata and package-local build output aligned so
exportsandfilespoint at real artifacts - Add an internal-only standalone launcher for the local
/v1/responsesadapter server without widening the package into a public gateway product - Let the internal standalone launcher load dotenv-style env files without depending on CodexBridge runtime env loaders
- Keep publication/promotion of the standalone launcher explicitly out of the active package backlog until product direction changes
- Use codex-proxy as the main reference for Codex Responses event handling,
previous_response_id, function-call streams, and real protocol tests - Use llm-rosetta as the reference for a future IR layer; do not add a full IR until Responses-to-Chat starts blocking Anthropic/Gemini-native support
- Use LiteLLM as the reference for provider catalogs, cost/usage metadata, retry/error taxonomy, and gateway-level operational concerns
- Treat open-responses as a Responses-first product reference, not as code to vendor into this adapter
- Codex Gateway package extraction, reference-driven hardening, and internal-only standalone tooling are no longer blocked on package-local protocol work
- The gateway package can be tested without starting WeChat or CodexBridge runtime
- The gateway package has no imports from CodexBridge core, platform runtimes, stores, slash commands, or i18n
- Legacy CodexBridge import paths still work through re-export shims during the migration window
- Adding a new OpenAI-compatible provider normally requires config/capability data, not a new provider plugin class
- Unsupported provider features produce clear downgrade/error behavior instead of silent stalls or malformed upstream payloads
- Existing CodexBridge OpenAI-compatible tests pass through the new package boundary
These items are still valid codex-gateway work, but they are not
required to consider the current package extraction complete.
They stay here because they are still package-local protocol improvements, not bridge-side WeChat product work.
- Expand the package-local provider capability catalog beyond the current presets and pricing metadata
The package now exposes a normalized
capabilityCatalogsummary for tool calling, image/file/PDF input, JSON/schema support, reasoning support, compact support, limits, and provider/model-specific quirks where the metadata is reliable enough to drive downgrade or debug behavior. - Strengthen provider error taxonomy and retry hints beyond the current normalized upstream error surface The package now distinguishes authentication failures, rate limits, transient upstream failures, unsupported-feature responses, invalid requests, and malformed provider payloads with stable machine-readable categories and retry guidance.
- Add package-local golden fixtures for real provider responses and stream events The package now keeps representative provider-shaped fixture files for streaming tool-call events, Gemini-style usage payloads, and top-level rate-limit error events so future adapter changes can be checked against stable protocol samples instead of only synthetic unit inputs.
- Extend package
/v1/modelsoutput with richer protocol-facing metadata The package now exposes a normalizedprotocolblock alongside raw model capability data so bridge/UI introspection can rely on effective adapter behavior instead of reconstructing provider defaults elsewhere. - Expose normalized adapter routing and reasoning-transport metadata in
/modelsThe package now returns top-level adaptermetaplus per-model routing and reasoning-transport details so provider/model alias rewrites and thinking toggles can be inspected directly from/modelsinstead of inferred from payload rules or live trace output. - Expose normalized retry policy metadata and honor model-level retry overrides
The package now applies model-specific
retrycapability overrides during live upstream retries and exposes the effective retry profile through/v1/modelstop-levelmeta.retryplus per-modelprotocol.retrymetadata for easier debugging and regression checks. - Add a package-local debug or trace mode for adapter transforms
The package now exposes optional request/response/retry/stream trace hooks,
including machine-readable
request.adjustedevents for downgrade/filter decisions. The internal standalone launcher can emit trace events directly to stderr as NDJSON without relying on CodexBridge runtime logging or WeChat transport reproduction.
- If publication ever becomes a goal later, decide whether to promote the standalone launcher into a supported standalone HTTP proxy binary This is a future product-direction decision, not an active protocol-package blocker.
- CodexBridge can switch OpenAI-native, DeepSeek, MiniMax, Qwen, and OpenRouter profiles without changing WeChat UX
Bridge/runtime regression coverage now proves stable WeChat-facing
/provider,/status, and/modelsUX across those profile ids. Deferred OpenRouter live smoke remains tracked separately as upstream-provider validation, not as a remaining bridge UX gap.