Skip to content

Codex + DeepSeek fails: include field rejected in chat-translated Responses requests #532

Description

@chi-cat

Problem

When using Codex with DeepSeek through GoModel via the Responses API, requests fail with:

{
  "error": {
    "code": null,
    "message": "responses field \"include\" is only supported by native Responses providers; use an OpenAI-compatible provider or passthrough for this request",
    "param": null,
    "type": "invalid_request_error"
  }
}

Root Cause

  1. Codex requirement: Codex (0.122.0+) enforces wire_api = "responses" in its configuration and automatically adds an include field to Responses API requests.

  2. GoModel validation: When a Responses request reaches a chat-only provider (DeepSeek, Anthropic, Gemini), GoModel translates it to chat semantics. However, the validation in internal/providers/responses_adapter.go completely rejects the include field with an error:

    if len(req.Include) > 0 {
        return unsupportedResponsesChatTranslationField("include")
    }
  3. Documentation conflict: The Codex integration guide recommends using wire_api = "responses" with DeepSeek, but this configuration is actually impossible to use because Codex will always send include, triggering the error.

Reproducible Test Case

# GoModel running on localhost:8080 with DeepSeek provider
export OPENAI_API_KEY=change-me
export DEEPSEEK_API_KEY=sk-...

docker run --rm -p 8080:8080 \
  -e GOMODEL_MASTER_KEY="change-me" \
  -e DEEPSEEK_API_KEY="sk-..." \
  enterpilot/gomodel

# Codex config
[model_providers.gomodel]
name = "GoModel"
base_url = "http://localhost:8080/v1"
env_key = "OPENAI_API_KEY"
wire_api = "responses"

# This fails
codex exec -m deepseek/deepseek-v4-pro 'Reply with exactly ok'

Error: responses field "include" is only supported by native Responses providers

Solution

Instead of rejecting the include field for chat-translated providers, filter it out silently. The field has no semantic meaning in chat translation context (it's used to control response inclusion when responses are stored server-side), so it should be dropped like other non-translatable fields.

Modified logic:

  • For native Responses providers (OpenAI, xAI): forward include unchanged ✅
  • For chat-translated providers (DeepSeek, Anthropic, Gemini): filter out include during conversion ✅

This is consistent with how other provider-specific fields are handled:

  • Fields like top_logprobs, previous_response_id, conversation are also non-translatable but are rejected per spec
  • However, include is different: it's metadata about response retrieval, not model behavior, so filtering is safe

Files to modify

  • internal/providers/responses_adapter.go:
    • Remove include from validateResponsesRequestForChatTranslation() check
    • Add logic to ConvertResponsesRequestToChat() to clear req.Include before conversion

Affected users

  • Codex users trying to integrate with non-native-Responses providers (DeepSeek, Anthropic, Gemini)
  • Any client that auto-includes include fields in Responses requests

Related docs

  • Codex guide recommends DeepSeek + Responses:
    ## DeepSeek V4
    Codex sends `POST /v1/responses`. DeepSeek exposes chat completions instead of
    a native Responses API, so configure the first-class DeepSeek provider and let
    GoModel translate the request.
    ```yaml
    providers:
    deepseek:
    type: deepseek
    base_url: "https://api.deepseek.com"
    api_key: "${DEEPSEEK_API_KEY}"
    ```
    If you previously configured DeepSeek as `type: openai`, change it to
    `type: deepseek` for Codex. The generic OpenAI provider forwards `/responses`
    upstream, while the DeepSeek provider translates `/responses` to
    `/chat/completions`.
    See the [DeepSeek guide](/providers/deepseek) for the full reasoning effort
    mapping table (DeepSeek V4 only accepts `high` and `max`, so GoModel maps
    `low` and `medium` up to `high`).
    Then use the DeepSeek model name in Codex:
    ```toml
    model_provider = "gomodel"
    model = "deepseek-v4-pro"
    [model_providers.gomodel]
    name = "GoModel"
    base_url = "http://localhost:8080/v1"
    env_key = "OPENAI_API_KEY"
    wire_api = "responses"
    ```
  • Responses compatibility docs: https://github.com/ENTERPILOT/GoModel/blob/cf0a8d5c9f5c68abec886bc8ac612016898b7114/docs/advanced/responses-compatibility.mdx

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions