Skip to content

Responses → Chat Completions rejects additional_tools, breaking Codex tools-on-demand and approval review #521

Description

@yyyr-p

Codex requests routed from /responses to a /chat/completions upstream fail as soon as the input history contains a tools-on-demand additional_tools item. This also breaks automatic approval review: the reviewer request fails before an approval decision can be made.

Observed error:

Automatic approval review failed: {"type":"error","status":400,"error":{"type":"invalid_request_error","code":"invalid_request_error","message":"Invalid input item type 'additional_tools'."}}

Reproduction

Configure a model whose Responses requests are translated to a Chat Completions upstream, then send this minimal body to the Responses endpoint:

{
  "model": "<configured-chat-completions-model>",
  "input": [
    { "role": "user", "content": "Use lookup if needed." },
    {
      "type": "additional_tools",
      "role": "developer",
      "tools": [
        { "type": "function", "name": "lookup", "parameters": { "type": "object", "properties": {} } }
      ]
    }
  ]
}

Expected: the supported function tool is available to the Chat Completions model and the request proceeds.

Actual: Floway returns Invalid input item type 'additional_tools'.

Cause

The protocol models additional_tools, but the Responses → Chat Completions request translator does not consume it before processing conversation items. It reaches the unsupported-item branch and throws. This is still present in upstream main at 14f0b7725da737a96a82d2e9daf8cd10dc0583e1:

Proposed temporary fix

Before tool validation and message conversion:

  1. Append tools from every additional_tools input item to the request-level tools, preserving the initial tools and declaration order.
  2. Remove those declaration items from the conversation input.
  3. Pass the combined tools through the existing validation and tool translation, including custom-tool wrapping and response mapping.

This deliberately trades cache reuse for compatibility. Promoting newly introduced tools to the request-level tool list changes the prompt prefix and can cause cache misses, increasing latency and, on providers with cached-input pricing, cost. It also exposes the combined tool set at request scope rather than preserving the original point of introduction. This is a temporary compatibility fallback, not a complete implementation of deferred-tool semantics.

A native Responses route remains useful when the upstream supports the needed semantics. Chat Completions compatibility is still needed for existing inference deployments; the motivating discussion included a modified SGLang deployment for older GPUs whose available interface was Chat Completions. That is deployment context, not a claim about current upstream SGLang support.

Reference implementation and validation

The minimal fallback is implemented in the yyyr-p fork:

yyyr-p@bbf0623

  • Six added regression cases fail against the pre-fix implementation and pass with the fix.
  • Coverage includes absent/null/empty initial tools, multiple additions, existing-tool preservation, custom-tool mapping, uninterrupted tool-call history, source immutability, and validation of hoisted tools.
  • All 587 translation tests passed on that fork revision; lint, installer checks, and the web build also passed.
  • The full repository was not green: seven unrelated tests also failed on the pre-fix baseline, and an existing Web type error remained.

Longer-term discussion

Related: #17, which tracks the broader hosted/deferred-tool translation gap.

One alternative discussed was a stable dispatcher tool: keep its declaration fixed, represent dynamically available tool definitions in conversation context, and translate dispatcher calls/results to the original tools. This may preserve more prefix-cache reuse, but requires a deliberate protocol bridge and evaluation of tool selection, argument schemas, names, custom tools, and history round-tripping. It has not been implemented or validated by the temporary fix above.

The immediate request is to unblock supported tools carried by additional_tools on the Chat Completions translation path, with the cache tradeoff made explicit. Full tool_search/namespace/deferred-tool support can remain a separate design discussion under #17.

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

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions