Skip to content

About

OpenCode plugin that auto-syncs models for an OpenAI-compatible provider.

Topics

Resources

Stars

4 stars

Watchers

0 watching

Forks

Repository files navigation

opencode-auto-provider-models

NOT an official project by the OpenCode team. No affiliation.

English | 简体中文

Local plugin for opencode that auto-syncs the model list for an existing custom provider.

Useful when:

  • you already configured a custom provider in opencode.jsonc
  • the provider exposes an OpenAI-compatible API
  • the service supports GET /models
  • you do not want to manually maintain provider.<name>.models whenever models change

Behavior

The plugin runs once when opencode starts:

  1. Read the target provider's baseURL
  2. Request ${baseURL}/models
  3. Inject the returned models into provider.<name>.models
  4. Preserve existing local model entries; if a model already exists locally, the local entry wins

If the remote request fails, the plugin only prints a warning and does not block opencode startup.

Files

  • index.js: 同时支持 OpenCode v1 和 v2 的插件实现
  • enrichment.js: 可选的模型增强逻辑(从 models.dev 补全缺失字段)

Installation

Install the package in your opencode project:

# From GitHub Packages (requires ~/.npmrc scoped registry):
#   @guochen-thlg:registry=https://npm.pkg.github.com
npm install @guochen-thlg/opencode-auto-provider-models
bun install @guochen-thlg/opencode-auto-provider-models

# Or directly from GitHub (no registry setup needed):
npm install guochen-thlg/opencode-auto-provider-models
bun install guochen-thlg/opencode-auto-provider-models

Then add the plugin to your opencode.jsonc.

OpenCode v2

OpenCode v2 使用不同的插件 API。插件通过 plugins 数组加载:

{
  "$schema": "https://opencode.ai/config.json",
  "plugins": [
    {
      "package": "@guochen-thlg/opencode-auto-provider-models",
      "options": {
        "provider": "custom-provider"
      }
    }
  ]
}

With a local checkout:

{
  "plugins": [
    {
      "package": "./index.js",
      "options": {
        "provider": "custom-provider"
      }
    }
  ]
}

插件会读取 provider 的 settings.baseURL,通过 ctx.provider.transform 注入模型,使用 v2 原生的模型格式(capabilities.tools、capabilities.input、capabilities.output、limit、family)。

Configuration

Single provider

{
  "$schema": "https://opencode.ai/config.json",
  "plugin": [
    [
      "@guochen-thlg/opencode-auto-provider-models",
      {
        "provider": "custom-provider"
      }
    ]
  ]
}

Multiple providers

Pass an array to provider:

{
  "plugin": [
    [
      "@guochen-thlg/opencode-auto-provider-models",
      {
        "provider": ["custom-provider1", "custom-provider2"]
      }
    ]
  ]
}

Each entry can also be an object for per-provider overrides (e.g. a different apiKeyEnv):

{
  "plugin": [
    [
      "@guochen-thlg/opencode-auto-provider-models",
      {
        "provider": [
          "custom-provider1",
          {
            "id": "custom-provider2",
            "apiKeyEnv": "CUSTOM_PROVIDER2_API_KEY"
          }
        ]
      }
    ]
  ]
}

Filter models

If you only want to sync part of the remote model list:

{
  "plugin": [
    [
      "@guochen-thlg/opencode-auto-provider-models",
      {
        "provider": "custom-provider1",
        "include": ["gpt-5.4", "gpt-5.4-mini", "glm-5"]
      }
    ]
  ]
}

include and exclude work with multiple providers too:

{
  "plugin": [
    [
      "@guochen-thlg/opencode-auto-provider-models",
      {
        "provider": ["custom-provider1", "custom-provider2"],
        "exclude": ["internal-test-model"]
      }
    ]
  ]
}

API key

If the provider's options.apiKey is not the final key to use, you can explicitly point the plugin to an environment variable:

{
  "plugin": [
    [
      "@guochen-thlg/opencode-auto-provider-models",
      {
        "provider": "custom-provider1",
        "apiKeyEnv": "CUSTOM_PROVIDER1_API_KEY"
      }
    ]
  ]
}

Startup performance

The plugin sends an HTTP request to ${baseURL}/models for each provider on every startup. Two options help control this:

{
  "plugin": [
    [
      "@guochen-thlg/opencode-auto-provider-models",
      {
        "provider": "custom-provider",
        "timeout": 5000,
        "cacheTTL": 300000
      }
    ]
  ]
}
Option Default Description
timeout 5000 Max wait (ms) for the /models response. Prevents a slow or hung provider from blocking startup.
cacheTTL 0 How long (ms) to reuse the last fetched model list without re-requesting. Set to 300000 (5 min) to skip the request on most restarts. 0 disables caching.
refreshInterval 3600000 Interval (ms) for re-fetching the model list, defaulting to once per hour. Reload is triggered only when the list actually changes; a failed refresh keeps the previous list. Set to 0 to disable. Applies to the OpenCode v2 plugin only (v1 syncs once at startup).

Model enrichment (optional)

The plugin can fetch supplemental metadata from https://models.dev/models.json and fill in missing fields for each model entry. This is optional and disabled by default.

Priority: when the remote /models payload already declares non-default modalities (e.g. image input), the remote declaration wins; enrich only fills in values when the remote reports the default plain-text modality, so stale models.dev data cannot override real remote capabilities.

To enable it:

{
  "plugin": [
    [
      "@guochen-thlg/opencode-auto-provider-models",
      {
        "provider": "custom-provider",
        "enrich": true
      }
    ]
  ]
}

When enabled, the plugin:

  1. Requests https://models.dev/models.json at startup
  2. Matches model IDs from the remote provider against the enrichment data (exact match -> suffix match -> tail match)
  3. For matched models, fills in missing fields: name, description, family, reasoning, attachment, tool_call, structured_output, temperature, knowledge, open_weights, release_date, last_updated, modalities, limit

If the models.dev request fails, the plugin only logs a warning and proceeds with normal model sync.

Remote Response Shape

The plugin reads the standard OpenAI-compatible format:

{
  "object": "list",
  "data": [
    {
      "id": "gpt-5.4",
      "object": "model"
    }
  ]
}

If the remote endpoint also returns the following fields, the plugin maps them when possible:

  • name
  • input_modalities
  • output_modalities
  • modalities.input
  • modalities.output
  • context_window
  • max_output_tokens

Notes

  • Sync happens at startup, not as a hot reload during runtime
  • Restart opencode after changing its config or upgrading the plugin package
  • The plugin only injects the model list into runtime config and does not write back to opencode.jsonc

Release

Direct commits to main are not allowed. Releases always go through dev -> PR -> main.

Cutting a new version

Run on the dev branch:

# patch: 0.3.1 -> 0.3.2 | minor: 0.3.1 -> 0.4.0 | major: 0.3.1 -> 1.0.0
npm run release patch

The script verifies you are on dev with a clean working tree, runs the full test suite, syncs with the remote dev, bumps the version and commits it, then opens a dev -> main PR and prints the link.

Auto-publish after merge

When the PR is merged into main, the CI workflow (publish-github-packages.yml) will:

  1. Read version from package.json and skip if that version is already published
  2. Run npm test as a publish gate
  3. Create tag v<version> and a GitHub Release (release notes are generated automatically)
  4. Publish the package to GitHub Packages

No manual steps are needed after merging — just verify on the Releases page.

Update CHANGELOG before releasing

The version bump script does not write changelog entries. Add the new version section at the top of CHANGELOG.md before releasing.

About

OpenCode plugin that auto-syncs models for an OpenAI-compatible provider.

Topics

Resources

Stars

4 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages