Skip to content

feat: make parallel_tool_calls injection configurable for codex-api-key channels #3903

@ypq123456789

Description

@ypq123456789

Problem

The codex executor hardcodes "parallel_tool_calls": true in the request template sent to upstream APIs. This causes 400 errors on third-party OpenAI-compatible providers that strictly validate parameters and do not support this field without tools being specified.

Error from upstream:

Invalid value for 'parallel_tool_calls': 'parallel_tool_calls' is only allowed when 'tools' are specified.

Current Behavior

CPA injects parallel_tool_calls: true into every codex request regardless of whether the upstream supports it. This is hardcoded in the binary — there is no config option to disable it.

From CPA logs:

[debug] [codex_executor.go:866] request error, error status: 400, error message: Invalid value for 'parallel_tool_calls': 'parallel_tool_calls' is only allowed when 'tools' are specified.

Impact

Any third-party OpenAI-compatible API that strictly validates request parameters (e.g. evomap.ai, and likely others) cannot be used as a codex-api-key channel. The alias model mapping feature works correctly, but the injected parallel_tool_calls causes the upstream to reject the request.

Channels that are lenient about extra parameters (songsongai, zicc, etc.) work fine because they silently ignore the unsupported field.

Suggested Solutions

Any of the following would resolve this:

  1. Per-channel config option: Add a parallel-tool-calls: false field to codex-api-key entries to disable injection for specific channels
  2. Capability-based: Respect the supports_parallel_tool_calls model capability flag — if the upstream model doesn't declare support, don't inject it
  3. Global config option: A top-level disable-parallel-tool-calls flag
  4. Strip on error: If upstream returns 400 for parallel_tool_calls, retry without it

Environment

  • CPA Version: 7.1.59
  • Config: codex-api-key with alias model mapping
  • Upstream: OpenAI-compatible API (non-OpenAI provider)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    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