Skip to content

Provider-level npm field silently ignored unless models is also configured #33888

Closed as not planned

Description

@Hxyspace

Description

Summary

When configuring a custom provider with a different npm package (e.g. switching ZAI/ZhipuAI from the default @ai-sdk/openai-compatible to @ai-sdk/anthropic), setting only provider.<id>.npm and provider.<id>.options.baseURL has no effect — opencode silently keeps using the catalog/discovery-provided npm package (e.g. @ai-sdk/openai-compatible) and sends requests in the wrong protocol. There is no warning, error, or log line indicating that provider.npm was ignored.

The user must additionally enumerate every model under provider.<id>.models: { ... } for provider.npm to take effect on those entries. Provider-level npm is only read inside the loop over provider.models, so models pre-populated by the discovery plugin keep their original npm package.

Reproduction

Configure ZAI to use Anthropic's /v1/messages endpoint:

// opencode.jsonc
{
  "provider": {
    "zai": {
      "npm": "@ai-sdk/anthropic",
      "options": {
        "baseURL": "https://open.bigmodel.cn/api/anthropic/v1"
      }
    }
  }
}

Run opencode run -m zai/glm-4.5 "hi".

Expected

provider.npm applies provider-wide; all zai models (including those from the discovery plugin) use @ai-sdk/anthropic and hit /v1/messages.

Actual

  • The npm field is silently ignored.
  • Requests go to https://open.bigmodel.cn/api/anthropic/v1/chat/completions (OpenAI path, because @ai-sdk/openai-compatible is still in use).
  • For this URL ZAI's gateway returns either:
    • HTTP 200 with body {"code":500,"msg":"404 NOT_FOUND","success":false} (business-layer 500 that the SSE parser silently swallows), or
    • HTTP 404 {"detail":"Not Found"} (when /v1 is in the path) — which surfaces as a stream error.
  • No warning is emitted that provider.npm had no effect.

Workaround

Enumerate every model:

"models": {
  "glm-4.5": {}, "glm-4.6": {}, "glm-5": {}, "glm-5.2": {}
}

Cumbersome when the provider exposes many models.

Root cause

packages/opencode/src/provider/provider.ts:1394-1414:

for (const [providerID, provider] of configProviders) {
  const existing = database[providerID]
  const parsed: Info = {
    // ...
    models: existing?.models ?? {},          // catalog/discovery models, with their own npm
  }

  for (const [modelID, model] of Object.entries(provider.models ?? {})) {  // ← only iterates user-listed models
    const apiNpm =
      model.provider?.npm ??
      provider.npm ??                          // ← only consulted inside this loop
      existingModel?.api.npm ??
      modelsDev[providerID]?.npm ??
      "@ai-sdk/openai-compatible"
    // ...
  }
}

Proposal

Either (or both):

  1. Make provider.npm provider-wide. When set, override api.npm (and optionally api.url from provider.api) for all existing.models entries that don't have an explicit per-model override.
  2. Warn when provider.npm is set but provider.models is empty (the user almost certainly intended provider-wide application and will get silently wrong behavior).

Environment

  • opencode 1.17.10
  • platform: linux
  • relevant source: packages/opencode/src/provider/provider.ts

Plugins

No response

OpenCode version

No response

Steps to reproduce

No response

Screenshot and/or share link

No response

Operating System

No response

Terminal

No response

Activity

  1. github-actions commented on Jun 25, 2026

    @github-actions
    Contributor

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

  2. github-actions commented on Aug 25, 2026

    @github-actions
    Contributor

    To stay organized issues are automatically closed after 60 days of no activity. If the issue is still relevant please open a new one.

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