Skip to content

providers: custom openai-compatible providers hang or send to undefined/chat/completions #36834

Closed

Description

@saiqulhaq-hh

Summary

V2 next (opencode2 v0.0.0-next-15363) fails to start a chat completion for any
custom openai-compatible provider that the equivalent V1 config can use. The
session hangs with no error and only emits after timeout, and the documented
aisdk:@ai-sdk/openai-compatible package path is the only working shape — but
settings.baseURL is silently ignored when the V1-style options.baseURL is
used, producing a request to undefined/chat/completions. A V1 provider block
that worked for the same OpenAI-compatible gateway is rejected by V2.

Environment

  • opencode version: opencode2 v0.0.0-next-15363
  • OS: Linux 7.0.10-arch1-1 (linux x64)
  • Terminal: tmux (TERM=tmux-256color, COLORTERM=truecolor)
  • Shell: /usr/bin/bash
  • Install/channel: next
  • Active plugins: ~/.config/opencode/plugins/gk-hooks.js

Reproduction

  1. Use this V1 config that works on V1 with an OpenAI-compatible gateway
    exposing a custom acme/acme-m3 model:

    {
      "$schema": "https://opencode.ai/config.json",
      "provider": {
        "acme": {
          "npm": "@ai-sdk/openai-compatible",
          "name": "Acme Gateway",
          "options": { "baseURL": "https://gateway.example.com/v1" },
          "models": {
            "acme-m3": { "name": "Acme M3" }
          }
        }
      }
    }
  2. Translate to the V2 shape per
    https://v2.opencode.ai/providers.md#provider-packages:

    {
      "$schema": "https://opencode.ai/config.json",
      "providers": {
        "acme": {
          "name": "Acme Gateway",
          "env": ["ACME_API_KEY"],
          "package": "aisdk:@ai-sdk/openai-compatible",
          "settings": { "baseURL": "https://gateway.example.com/v1" },
          "models": {
            "acme-m3": {
              "name": "Acme M3",
              "capabilities": { "tools": true, "input": ["text"], "output": ["text"] },
              "limit": { "context": 200000, "output": 32000 }
            }
          }
        }
      }
    }
  3. Run any request:

    opencode2 api post /api/generate \
      --data '{"model":{"providerID":"acme","id":"acme-m3"},"prompt":"ping"}'

Expected Behavior

  • Either the V1 provider / options shape is accepted and translated, or
    V2 returns a clear migration error.
  • The V2 config above sends the request to
    https://gateway.example.com/v1/chat/completions and returns a normal
    model response (the endpoint is reachable, GET /v1/models returns the
    model catalog, and curl with the same Bearer token works).

Actual Behavior

  • First error reported by opencode2 api post /api/generate:

    Unsupported package for acme/acme-m3: @opencode-ai/llm/providers/openai-compatible
    

    The V2 docs say the native package is the recommended path, but the runtime
    refuses it. Switching to aisdk:@ai-sdk/openai-compatible is required but
    undocumented as the only working choice.

  • After switching to aisdk:@ai-sdk/openai-compatible, the request hangs and
    the TUI never produces a response. A test against the same V2 build using
    the openai-compatible V2 native package fails with a parse error:

    "undefined/chat/completions" cannot be parsed as a URL.
    

    settings.baseURL is being dropped, so the package sends to undefined.

  • Disabling reasoning via a none variant
    (settings: { reasoningEffort: "none" }) makes it worse — the upstream
    gateway rejects both reasoning_effort and thinking with
    UnsupportedParamsError: openai does not support parameters: ['reasoning_effort', 'thinking'], because OpenCode V2 still sends them
    even when the provider/model doesn't declare reasoning support.

Additional Context

  • The same gateway endpoint responds fine to a direct curl against
    https://gateway.example.com/v1/chat/completions with the API key.
  • V1 (opencode-ai v0.x) ran this provider block end-to-end without hangs.
  • Workarounds attempted in V2:
    • package: "@opencode-ai/llm/providers/openai-compatible" (native) →
      rejected as "Unsupported package".
    • package: "aisdk:@ai-sdk/openai-compatible" + settings.baseURL →
      hangs / sends to undefined depending on which field is present.
    • options.baseURL (V1 spelling) → ignored entirely.
    • Adding a none variant with reasoningEffort: none → upstream rejects
      the unsupported parameters and returns 400.
  • Likely root causes: (1) the V2 native openai-compatible package
    (@opencode-ai/llm/providers/openai-compatible) is documented but
    unregistered / unsupported at runtime; (2) settings.baseURL is not
    forwarded to the aisdk:@ai-sdk/openai-compatible provider, and the
    error surface for missing config is a silent hang or a confusing
    "undefined/chat/completions" parse error instead of a clear validation
    message; (3) reasoning-related fields are not stripped or detected
    per-provider.
  • A real opencode.json (with the key redacted) is sufficient to reproduce
    using any OpenAI-compatible gateway and a custom model name.

Activity

  1. github-actions commented on Jul 14, 2026

    @github-actions
    Contributor

    This issue might be a duplicate of or related to existing issues. Please check:

  2. opencode-agent commented on Jul 17, 2026

    @opencode-agent
    Contributor

    The reported V2 undefined/chat/completions / unsupported native OpenAI-compatible package path is resolved on the latest v2 branch. settings.baseURL now reaches the native openai-compatible-chat route, bearer auth is preserved, and the built-in @opencode-ai/ai/providers/openai-compatible entrypoint is registered. Focused session model-resolution and OpenAI-compatible Chat route tests pass. Any provider-specific reasoning-option incompatibility should be tracked separately.

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

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions