Skip to content

fix(anthropic): preserve provider-qualified response model metadata #1117

Closed

Description

@giulioleone097

Client or integration

Codex App

Provider or upstream service

Anthropic

OpenCodex version

2.10.2

Endpoint or capability

/v1/responses streaming response model metadata and Codex catalog synchronization

Current behaviour

OpenCodex normalizes a routed Anthropic selector for the upstream request and then reuses the normalized bare ID in the Codex-facing Responses payload. A request for anthropic/claude-sonnet-5 therefore returns claude-sonnet-5. Codex cannot resolve that bare ID against the provider-qualified catalog row, so it may miss the model's long-context and auto-compaction metadata.

Expected behaviour

The Codex-facing response should retain anthropic/claude-sonnet-5. A bare legacy selector should be healed to the provider-qualified response model. Compatibility catalog aliases for existing bare selectors should remain hidden, carry the canonical context metadata, and be removed by restore.

Minimal redacted request or reproduction

curl -N http://127.0.0.1:10100/v1/responses \
  -H 'Authorization: Bearer REDACTED' \
  -H 'Content-Type: application/json' \
  -d '{"model":"anthropic/claude-sonnet-5","input":[{"role":"user","content":[{"type":"input_text","text":"reply OK"}]}],"stream":true,"store":false}'

Actual response or error

HTTP/1.1 200 OK
event: response.completed
data: {"response":{"model":"claude-sonnet-5", "status":"completed"}}

Upstream documentation

No public upstream specification requires the OpenCodex composite selector. The expected behavior is a concrete Codex client requirement: the response model must resolve to the same provider-qualified model metadata that OpenCodex writes into Codex's catalog.

Suggested mapping or implementation notes

Preserve the final Codex-facing routed selector before upstream normalization; use it in core, image-loop, and web-search-loop response bridges. For existing bare selectors, synchronize a hidden Anthropic compatibility alias with the canonical context metadata and an owner marker so restore can remove it safely.

Additional context and attachments

Live reproduction on 2.10.2 returned HTTP 200 and completed normally; only the response model identity was wrong.

Checks

  • I searched existing provider and compatibility issues.
  • The request and response were redacted.
  • The expected behaviour is based on an upstream specification or a concrete client requirement.

Activity

  1. github-actions commented on Aug 6, 2026

    @github-actions
    Contributor

    Automated translation bookkeeping — detected language: unknown.

  2. github-actions commented on Aug 6, 2026

    @github-actions
    Contributor

    Issue reopened

    The report now contains the information required by the automated check. Thanks for updating it.

  3. flyingsquirrel0419 commented on Aug 6, 2026

    @flyingsquirrel0419

    Confirmed on current dev (7af5bbac). This is a real routing/response-identity bug, not only a catalog display issue.

    applyFinalRouteRequestNormalization rewrites parsed.modelId from the final Codex-facing selector to the bare upstream Anthropic model id. The normal Responses bridge, image loop, and web-search loop then all build response.model from that rewritten value, so anthropic/claude-sonnet-5 is returned as claude-sonnet-5.

    I am preparing a focused fix that will:

    • preserve the final Codex-facing selector separately from the upstream wire model;
    • use it consistently in streaming and JSON Responses output, including image and web-search loops;
    • add hidden, marker-owned Anthropic bare-selector compatibility rows cloned from the canonical namespaced catalog metadata, with restore/removal coverage;
    • add regression tests for qualified and legacy bare selectors plus catalog sync/restore behavior.

    I will keep the change scoped to response identity and catalog compatibility; it will not alter the Anthropic upstream request model.

  4. flyingsquirrel0419 commented on Aug 6, 2026

    @flyingsquirrel0419

    Implemented in draft PR #1121 against the latest dev (bbd82e73).

    The patch now keeps the bare Anthropic model only on the upstream Messages request and emits the provider-qualified selector on all Codex-facing Responses paths (streaming, JSON, image bridge, and web-search loop). It also adds hidden marker-owned bare compatibility rows cloned from the canonical Anthropic catalog metadata and removes them safely during sync/restore.

    Validation on the rebased head:

    • focused regression and compatibility suites: 291 passed, 0 failed;
    • bun run typecheck: passed;
    • bun run privacy:scan: passed.

    The PR remains draft while GitHub CI and maintainer review run. I am keeping the issue open until the change is merged into dev.

  5. Ingwannu commented on Aug 6, 2026

    @Ingwannu
    Owner

    Maintainer triage: this is confirmed as a real response-identity bug, and the issue should stay open until a fix reaches dev.

    Contributor PR #1122 is currently the preferred implementation because it also preserves the physical routed model in request logs, but it is not mergeable yet. The current head still needs the exact streaming SSE reproduction, image/web-search bridge coverage, a dedicated nonsemantic ownership marker for generated compatibility rows, and either a narrower Anthropic-only response-identity change or cross-provider contract coverage and structure documentation. Draft #1121 remains comparison material only; neither duplicate will be merged in its current state.

    Once #1122 addresses those blockers and passes exact-head CI/review, I will re-check the final diff and close this issue only after the accepted change lands on dev.

  6. added a commit that references this issue on Aug 7, 2026
  7. Wibias commented on Aug 7, 2026

    @Wibias
    Contributor

    Closing as fixed on dev.

    #1138 now preserves the provider-qualified Anthropic model identifier for client-facing responses while still sending the bare upstream model ID to Anthropic.

    This covers the Responses bridge, image loop, and web-search path and prevents clients from losing the provider namespace when round-tripping response.model.

  8. added 2 commits that reference this issue on Sep 17, 2026
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

    providerProvider adapters, OpenAI-compat presets, upstream API quirksprovider-compatibilityProvider compatibility reportsstreamingSSE, WebSocket, terminal stream frames

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions