Skip to content

Define and test the bounded Codex Responses request contract #39

Description

@tiammomo

Summary

Create the typed, fail-closed request-contract foundation for the experimental Codex Responses ingress proposed in #38, without exposing a runtime route.

Actual behavior

ModelPort has no Responses protocol identity or typed Codex request contract. Converting a Responses body directly into a Chat Completions request would lose source protocol, path, fingerprint, and ledger evidence.

Expected behavior

A versioned content-free fixture and typed parser normalize the pinned Codex request subset into the existing Exchange IR while retaining Responses identity and rejecting semantics ModelPort cannot preserve.

Acceptance criteria

  • Content-free fixture covers the pinned official Codex request-builder fields; accepted requests require stream=true and store=false; unsupported fields fail closed; input ordering and function-call causality are tested; protocol/path/fingerprint evidence remains Responses-native; documentation explicitly says no HTTP route is enabled.

Additional context

Context

This is the first implementation slice of #38. ModelPort currently exposes OpenAI Chat Completions and Anthropic Messages, while Codex custom providers use the OpenAI Responses wire API. Before an experimental route or an SSE adapter is added, ModelPort needs a versioned, testable ingress contract that preserves the original client protocol in its exchange evidence.

The contract is intentionally not a claim of full OpenAI Responses compatibility. It is pinned to the request shape emitted by the officially documented Codex custom-provider flow and the locally verified codex-cli 0.148.0-alpha.21 request builder.

Scope

  • Add a content-free, versioned Codex request-shape fixture. It may contain field names, types, and synthetic values, but no prompts, credentials, model outputs, or user metadata.
  • Add typed Rust request types for the bounded Codex Responses subset.
  • Reject unknown or unsupported top-level fields and unsupported nested semantics rather than silently discarding them.
  • Require the invariants needed by the planned experimental ingress (stream: true, store: false).
  • Normalize text/message items, function calls, and function-call outputs into the existing typed exchange IR while preserving their original order and tool-call causality.
  • Preserve openai-responses, /v1/responses, the raw typed source, and the Responses request fingerprint in protocol/path/ledger evidence.
  • Add focused unit and contract tests for accepted shapes, rejection cases, ordering, causality, route/path/protocol identity, and content-free fixtures.
  • Document the exact supported/unsupported field semantics and the fact that no Responses HTTP route is enabled by this issue.

Non-goals

  • Registering POST /v1/responses.
  • Translating provider output into Responses SSE events.
  • Enabling the experimental runtime flag or changing Dashboard/Codex setup status.
  • Claiming general Responses API, WebSocket, Realtime, background, image, audio, file, hosted-tool, or remote-MCP compatibility.
  • Persisting or forwarding Codex client metadata.

Design constraints

  • The existing Exchange IR remains the provider-neutral policy/routing boundary.
  • A Responses request must not be relabeled as Chat Completions merely because the same downstream provider renderer can eventually serve it.
  • Optional fields are accepted only when their semantics can be preserved or when a documented, safe no-op is part of this bounded contract. Otherwise the parser fails closed.
  • Runtime route and response-stream work remain follow-up slices of Add a Codex-bounded OpenAI Responses ingress behind an experimental gate #38.

References

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