Skip to content

Add a Codex-bounded OpenAI Responses ingress behind an experimental gate #38

Description

@tiammomo

Summary

Codex CLI is a required Client/Harness, but current Codex custom Providers only speak the Responses wire API and ModelPort intentionally has no /v1/responses route. Add only the pinned-Codex subset behind a default-off experimental gate, through the typed Exchange IR and existing governance pipeline.

Actual behavior

The Dashboard correctly blocks Codex CLI and exposes no configuration because POST /v1/responses is absent. Claude Code, Qwen Code, and OpenAI SDK profiles use the existing Messages or Chat Completions ingress.

Expected behavior

A default-off, typed, fail-closed POST /v1/responses path can run a pinned Codex text turn and function-tool round trip through ModelPort with the same auth, policy, routing, quota, ledger, stream, and privacy guarantees as existing ingress. Unsupported Responses semantics remain rejected and no full-API or Tier 1 claim is made.

Steps to reproduce

Install or select a pinned Codex CLI, configure a custom Provider with base_url pointing to ModelPort /v1 and wire_api=responses, and run a synthetic prompt. Current ModelPort has no POST /v1/responses route, so the workflow cannot start; Issue #36 therefore keeps the Codex setup profile blocked.

Environment

ModelPort main at merge commit 14ea1f5; Linux x86_64; locally observed codex-cli 0.148.0-alpha.21 on 2026-08-24.

Acceptance criteria

  • Pinned content-free Codex fixtures; typed text/function request and SSE response lifecycle; fail-closed unsupported surface; parity with existing auth/policy/routing/quota/ledger/bounds; default-off flag and rollback; safe env-backed Dashboard config only when enabled; complete tests and compatibility docs.

Additional context

Product and evidence gate

The project owner requires Codex CLI alongside Claude Code, Qwen Code, and SDK
clients. Issue #36 confirmed that a safe Codex profile cannot be emitted today:
Codex custom Providers support only the Responses wire API, while ModelPort has
no POST /v1/responses ingress. The target machine currently has
codex-cli 0.148.0-alpha.21; implementation must pin and record the exact Codex
version used for acceptance.

This is a bounded exception path to the v0.1.x protocol freeze, not a general
Responses compatibility claim. It must remain disabled by default and
experimental until the acceptance evidence below is reviewed. The current
Anthropic Messages and OpenAI Chat Completions routes remain unchanged.

Official contract inputs:

Required protocol boundary

  • Add only authenticated POST /v1/responses over HTTP/SSE, behind an explicit
    server-owned experimental flag that defaults off. Do not add WebSocket,
    realtime, compact/retrieve/delete/cancel endpoints, background mode,
    conversations, hosted built-in tools, image/audio/file inputs, or generic
    pass-through.
  • Parse a typed Codex-bounded request into the existing Exchange IR. The first
    accepted surface is text instructions/messages, function tools,
    function_call and function_call_output items, tool_choice=auto, bounded
    parallel_tool_calls, stream=true, and store=false. The captured fixture
    decides which optional request fields must be accepted. Every other field or
    item kind fails before Provider egress with a stable, documented error.
  • Treat include=["reasoning.encrypted_content"], reasoning controls,
    verbosity, prompt-cache metadata, service tier, and client metadata
    explicitly: validate and preserve supported semantics, or document and
    reject them. Never fabricate encrypted reasoning, silently drop a required
    capability, forward client metadata as trusted policy, or persist prompt,
    response, tool argument/result, or raw body content.
  • Render protocol-native Responses lifecycle events with stable IDs and ordered
    sequence numbers. Text streaming covers response.created, output-item and
    content lifecycle, response.output_text.delta, and terminal
    response.completed. Function calls preserve call_id, name, complete JSON
    arguments, and the matching output causality. Pre-header failures remain
    normal HTTP errors; post-header failure/timeout/cancellation is represented
    in the Responses stream and finalized exactly once.
  • Reuse the existing authentication, model resolution, API-key/team/IP policy,
    rate/stream limits, route eligibility, retry/fallback, quota and spend
    reservation, request/attempt ledger, usage provenance, request ID,
    idempotency, timeout, body/SSE bounds, credential selection, and egress
    controls. The endpoint must not create a second routing or accounting path.

Compatibility evidence and activation

  • Add content-free, sanitized fixtures that record request field/item kinds and
    event ordering from the pinned Codex version. Do not commit Codex base
    instructions, repository context, prompts, tool arguments/results, API keys,
    authorization headers, cookies, or full request/response bodies.
  • Add an opt-in acceptance command that takes an explicit Codex binary path and
    synthetic prompt, uses a disposable config/profile and ModelPort client key,
    proves a text turn plus one function-tool round trip, and deletes its
    temporary state. It must not read or overwrite the user's ~/.codex files.
  • Only after that acceptance passes may the Dashboard change Codex CLI from
    blocked to experimental/configurable when the server reports the feature is
    enabled. The generated profile uses base_url=<gateway>/v1,
    wire_api="responses", env_key="MODELPORT_API_KEY", and never embeds the
    client key in TOML. Disabled servers continue to show the current blocked
    state and no copy action.
  • Update Architecture, API, Configuration, Compatibility, Development,
    Operations, and Tool Use evidence docs. The support matrix must continue to
    say this is experimental, exact-version evidence—not full OpenAI Responses,
    generic Codex/provider compatibility, or Tier 1 support.

Tests and rollback

  • Add parser/rendering tests for all accepted items and fields; text and
    function-call non-loss; split SSE frames; duplicate/missing/out-of-order
    terminal events; invalid JSON arguments; orphan tool outputs; unsupported
    items/fields; size, count, timeout, cancellation, and post-header errors.
  • Add route tests proving the experimental-off behavior, authentication and
    policy rejection before egress, idempotency, bounded fallback, ledger
    finalization, usage provenance, and no content persistence.
  • Add mock-backed end-to-end coverage for an OpenAI-compatible Provider and an
    Anthropic Provider where the Exchange IR can preserve the exact requested
    semantics. Unsupported Provider/model capability combinations fail closed.
  • Rollback is the experimental flag: disabling it removes the route and
    Dashboard copy action without schema rollback, deleting evidence, or changing
    the two existing ingress protocols.

Explicit non-goals

  • Full Responses API parity or a compatibility percentage.
  • Responses-over-WebSocket, Realtime, embeddings, image/audio/file inputs,
    hosted web/file/computer/code-interpreter tools, response storage/retrieval,
    conversation state, compaction, or background execution.
  • Raw JSON pass-through, bypassing the Exchange IR or governance pipeline,
    changing Provider credentials/resources, or making Codex a Provider.
  • Enabling the route by default or promoting it to Tier 1 without separate,
    dated design-partner evidence and a reviewed compatibility decision.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions