Skip to content

[Bug] openai-compatible: unknown provider options no longer forwarded, breaks LiteLLM allowed_openai_params passthrough (worked in v1) #53677

Description

@ajihsan

Description

OpenCode v1 (opencode-ai ≤ 1.18.x, AI-SDK based) forwarded unknown model/provider options verbatim into the outgoing request body for @ai-sdk/openai-compatible providers. OpenCode v2 (the packages/llm protocol layer) builds the request body from an explicit field list and only lowers a fixed set of known options, so provider-specific body parameters can no longer be expressed from configuration.

This breaks the LiteLLM dynamic allowlist pattern: gateways routing to deployments whose LiteLLM provider mapping doesn't list reasoning_effort require the client to send allowed_openai_params: ["reasoning_effort"] in the request body, otherwise the proxy rejects the call:

litellm.UnsupportedParamsError: tencent does not support parameters: ['reasoning_effort'], for model=glm-5.3-flashx.
If you want to use these params dynamically send allowed_openai_params=['reasoning_effort'] in your request.

The same config worked under v1 (option forwarded verbatim). Under v2 the option never reaches the wire, so any model behind such a route fails with the above HTTP 400 — and there is no config-only workaround left in v2.

Source pointers (v2)

  • packages/llm/src/protocols/openai-chat.ts — fromRequest() builds the body from explicit fields; lowerOptions() emits only store and reasoning_effort.
  • packages/llm/src/protocols/utils/openai-options.ts — options are read from the typed request.providerOptions?.openai bag; only the known keys (store, reasoningEffort, reasoningSummary, include, promptCacheKey, textVerbosity) are ever consulted.

Config like:

"glm-5.3-flashx": {
  "options": {
    "reasoningEffort": "high",
    "allowed_openai_params": ["reasoning_effort"]
  }
}

sends reasoning_effort on the wire but silently drops allowed_openai_params.

Suggested fix

Either restore verbatim forwarding of unknown option keys for openai-compatible protocols (v1 behavior), or add an explicit opt-in escape hatch (e.g. an options.extra / body bag merged into the provider body), or a documented plugin hook that can mutate the outgoing provider body. Any of the three unblocks enterprise LiteLLM gateways that rely on proxy-only body params.

Plugins

OpenCode version

2.0.1 (@opencode/cli)

Steps to reproduce

  1. Point an @ai-sdk/openai-compatible provider at a LiteLLM proxy that routes the model to a deployment whose provider mapping doesn't support reasoning_effort (e.g. tencent), with model options: { "reasoningEffort": "high", "allowed_openai_params": ["reasoning_effort"] }.
  2. Send any prompt with that model → v2 fails with litellm.UnsupportedParamsError: tencent does not support parameters: ['reasoning_effort'] (HTTP 400).
  3. The identical config under v1 sends both keys (reasoning_effort and allowed_openai_params, verified by capturing the outgoing request body against a local echo server) and the gateway returns HTTP 200.
  4. Direct curl against the same gateway with both keys in the body also returns 200 — the proxy honors the dynamic allowlist when the client actually sends it, so the failure is purely the dropped option.

Note the passthrough is functionally meaningful, not cosmetic: with allowed_openai_params accepted, reasoning_effort: low vs max measured ~2 vs ~74 reasoning tokens on the same prompt from the upstream.

Operating System

macOS 27.0.1 (arm64)

Terminal

zsh

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions