Skip to content

Support POST /v1/responses: OpenAI's newest models cannot use function tools without it #31

Description

@mostlydev

Running cllama:v0.7.7; source read at clawdapus@v0.27.0-15-gf42af36 (cllama/).

Summary

cllama routes only POST /v1/chat/completions and POST /v1/messages. OpenAI has moved function-tool support for its newest models to /v1/responses, so a cllama-mediated agent cannot use managed tools with those models at all. This is not a niche gap — it tracks OpenAI's direction, so it widens with each release.

Evidence

Measured live against the OpenAI API, one trivial function tool, reasoning_effort: high, POST /v1/chat/completions:

Model Result
gpt-5.6-terra 400Function tools with reasoning_effort are not supported for gpt-5.6-terra in /v1/chat/completions. To use function tools, use /v1/responses or set reasoning_effort to 'none'.
gpt-5.6-luna 400 — same
gpt-5-pro 404This model is only supported in v1/responses and not in v1/chat/completions.
gpt-5 200 OK
gpt-5-mini 200 OK

Two details worth noting, because both are easy to get wrong:

  • It is not about the effort level. gpt-5.6-terra + tools returns 400 with reasoning_effort set to high, set to medium, and omitted entirely. These models always reason, so "tools + reasoning" is unconditional on chat/completions. Only the explicit reasoning_effort: "none" escape returns 200.
  • The affected set is the newest tier. gpt-5/gpt-5-mini still work the old way; the 5.6 family and gpt-5-pro do not. So the practical effect today is that cllama confines agents to the previous model generation whenever they need tools.

Current state in source

  • cllama/cmd/cllama/main.go:140-141 — only POST /v1/chat/completions and POST /v1/messages are registered
  • cllama/internal/proxy/handler.go:1402if !strings.HasPrefix(path, "/v1/chat/completions")

A request to /v1/responses therefore 404s at the mux.

Why this is a second pipeline, not a route addition

Flagging this so the work is scoped honestly rather than discovered midway. cllama's value is that all agent traffic crosses one audited path, and the following are all built around the chat/completions request/response shape:

  • Managed tool mediation (internal/proxy/toolmediation.go) — the bounded multi-round loop, duplicate-call detection, and tool_trace assembly. Responses uses a different tool-call and tool-result representation.
  • Session history normalization — the JSONL turn record, including reported_cost_usd.
  • Budget enforcement — token-usage extraction for spend accounting; the usage block differs.
  • Audit eventsrequest, response, error, tool_call, intervention.
  • Streaming — synthetic SSE re-streaming when the runner asked for a stream; Responses has its own event taxonomy.
  • Candidate/failover dispatch (dispatchCandidates) — declared model candidates and cooldown behaviour.

Each guarantee has to be re-established and re-proven for the new shape. A partial implementation that routes but does not audit would be worse than the current 404, because it would silently stop governing.

Suggested direction

  1. Register POST /v1/responses and resolve provider/candidates through the existing declared-model path, so failover and cooldown behave identically.
  2. Normalize Responses turns into the same session-history record shape, so history, cost, and claw audit stay uniform across request shapes.
  3. Port managed tool mediation to the Responses tool-call representation, preserving round limits, timeouts, duplicate policy, and tool_trace.
  4. Until it lands, consider a clear startup or per-request diagnostic when a declared model is known to be responses-only. Today the failure surfaces downstream as 502 no usable declared provider key after retries / exhausted declared model candidates, which points at credentials and sent us looking at API keys, provider pools, and egress before we found the real cause in the upstream 400.

Point 4 is cheap and independently valuable even before the main work.

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