Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 40 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,9 @@ Originally inspired by [opencode-lmstudio](https://github.com/agustif/opencode-l

OpenCode v2 uses **`plugins`** (an array of package names) and **`providers`** (a map). Configure discovery under `providers.<id>.settings.modelsDiscovery`; it runs only when `enabled` is explicitly `true`. OpenCode v1 instead uses `plugin`, `provider`, and `options` (see [OpenCode v1 quick start](#opencode-v1-quick-start)).

Add the plugin package to your OpenCode v2 `opencode.json`. OpenCode resolves
and loads the package automatically:
Add the plugin package to your OpenCode v2 `opencode.json` (or `opencode.jsonc`). OpenCode resolves and loads the package automatically:

```json
```jsonc
{
"$schema": "https://opencode.ai/config.json",
"plugins": [
Expand All @@ -43,7 +42,8 @@ and loads the package automatically:
"package": "@opencode-ai/ai/providers/openai-compatible",
"settings": {
"baseURL": "https://gateway.example.com/v1",
"apiKey": "${GATEWAY_API_KEY}",
// Optional: omit if managing credentials interactively via OpenCode '/connect'
"apiKey": "{env:GATEWAY_API_KEY}",
"modelsDiscovery": {
"enabled": true,
"modelInfoFormat": "models.dev",
Expand All @@ -63,7 +63,7 @@ and loads the package automatically:
}
```

Set `GATEWAY_API_KEY` in the environment used to start OpenCode; the `${GATEWAY_API_KEY}` placeholder is resolved by the OpenCode v2 host. Alternatively, omit `apiKey` from `opencode.json` and configure credentials interactively with OpenCode's native `/connect` command. If your endpoint needs no credential, omit `apiKey`. Use the same provider package shown above for OpenAI-compatible discovery. The provider needs a `baseURL`; the plugin fetches its models from `/v1/models` by default (relative to the URL's **origin**). For providers that expose `/models` instead, set `"endpoint": "/models"` inside `modelsDiscovery`.
Set `GATEWAY_API_KEY` in the environment used to start OpenCode; the `{env:GATEWAY_API_KEY}` placeholder is resolved by the OpenCode v2 host. Alternatively, omit `apiKey` from `opencode.json` and configure credentials interactively with OpenCode's native `/connect` command. If your endpoint needs no credential, omit `apiKey`. Use the same provider package shown above for OpenAI-compatible discovery. The provider needs a `baseURL`; the plugin fetches its models from `/v1/models` by default (relative to the URL's **origin**). For providers that expose `/models` instead, set `"endpoint": "/models"` inside `modelsDiscovery`.

### Credentials

Expand All @@ -80,7 +80,7 @@ events without requiring a restart.
See [Connect and Auth Documentation](docs/connect-and-auth.md) for credential
resolution, lifecycle handling, and security details.

`modelInfoFormat` and `smartModelName` are optional: without them, discovered names remain the model IDs and no external metadata is fetched. Supported metadata formats are `aiproxy`, `models.dev`, `bifrost`, `litellm`, `vllm`, `lmstudio`, `llama-swap`, and `omniroute`. `models.dev` fetches `https://models.dev/models.json` by default; `modelInfoEndpoint` can override the catalog URL. The `aiproxy` format composes that catalog with inline metadata from AIProxy's model list. `filterNonChat` defaults to `true`; it can filter non-chat models when the selected metadata source supplies that information. `timeoutMs` defaults to 5000 ms. Models returned by discovery are added alongside explicitly configured models.
`modelInfoFormat` and `smartModelName` are optional: without them, discovered names remain the model IDs and no external metadata is fetched. Supported metadata formats are `aiproxy`, `models.dev`, `bifrost`, `litellm`, `vllm`, `lmstudio`, `llama-swap`, `omniroute`, and `openrouter`. `models.dev` fetches `https://models.dev/models.json` by default; `modelInfoEndpoint` can override the catalog URL. The `aiproxy` format composes that catalog with inline metadata from AIProxy's model list. The `openrouter` format reads OpenRouter's inline `/v1/models` metadata without another request. `filterNonChat` defaults to `true`; it can filter non-chat models when the selected metadata source supplies that information. `timeoutMs` defaults to 5000 ms. Models returned by discovery are added alongside explicitly configured models.

For a local build, run `npm run compile` and replace the package value above with `"file:///absolute/path/to/opencode-models-discovery/dist"`. OpenCode v2 expects a **directory**, not a path to `index.js` or `server.js`. After rebuilding plugin code, run `opencode service restart` so the background service loads the new bundle. Discovery runs when the plugin initializes. The native TUI commands are `/models-discovery-refresh` and `/models-discovery-console`; the console combines Provider → model → model details browsing with cache inspection and clearing. Use `/models-discovery-console status --provider <provider-id>` to filter the browser. The OpenCode v2 agent tools `models_discovery_refresh` and `models_discovery_status` remain available for automation. Pass `rawCache: true` to `models_discovery_status` to include cached raw models and enrichment results.

Expand Down Expand Up @@ -260,7 +260,7 @@ For AIProxy's inline model-list metadata, use `modelInfoFormat: "aiproxy"`:
{
"providers": {
"aiproxy": {
"package": "aisdk:@ai-sdk/openai-compatible",
"package": "@opencode-ai/ai/providers/openai-compatible",
"settings": {
"baseURL": "https://aiproxy.example/api",
"apiKey": "{env:AIPROXY_API_KEY}",
Expand Down Expand Up @@ -303,6 +303,17 @@ For LiteLLM-compatible model info endpoints, `/v1/model/info` is used by default
}
```

For OpenRouter's inline `/v1/models` metadata, without another metadata request:

```json
{
"modelsDiscovery": {
"enabled": true,
"modelInfoFormat": "openrouter"
}
}
```

For Bifrost AI Gateway's inline `/v1/models` metadata, without another metadata request:

```json
Expand All @@ -325,6 +336,17 @@ For LM Studio 0.4.0+'s native v1 REST inventory endpoint:
}
```

For vLLM's inline `max_model_len` metadata, without another metadata request:

```json
{
"modelsDiscovery": {
"enabled": true,
"modelInfoFormat": "vllm"
}
}
```

For llama-swap's inline `/v1/models` metadata, without another metadata request:

```json
Expand All @@ -336,6 +358,17 @@ For llama-swap's inline `/v1/models` metadata, without another metadata request:
}
```

For OmniRoute's inline `/v1/models` metadata, without another metadata request:

```json
{
"modelsDiscovery": {
"enabled": true,
"modelInfoFormat": "omniroute"
}
}
```

If metadata cannot be fetched or matched safely, discovery still succeeds and the plugin leaves unknown capability fields unset rather than guessing defaults. See [model metadata enrichment](docs/configuration.md#model-metadata-enrichment) for format-specific behavior and configuration.

## Upgrade note
Expand Down
20 changes: 17 additions & 3 deletions docs/config_example/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,24 @@

This directory contains community-maintained provider configuration examples for `opencode-models-discovery`.

Examples currently use the OpenCode v1 configuration shape. OpenCode v2 support is currently in beta and uses `plugins`, `providers`, `package`, and `settings`; adapt examples using the [configuration guide](../configuration.md#opencode-v2-configuration-beta-support).
Examples use the primary OpenCode v2 configuration shape (`plugins`, `providers`, `package`, and `settings`). For legacy OpenCode v1 users, adapt examples using the [configuration migration guide](../migrate-v1-to-v2.md).

Examples may include provider declarations, non-standard `modelsDiscovery.endpoint` values, provider-level `models.includeBy` and `models.excludeBy` raw-field filters using `equals` or `match`, metadata enrichment options, and notes about provider-specific behavior. Provider-level `models.includeRegex` and `models.excludeRegex` are supported as id-only shortcuts, but examples should prefer `includeBy` and `excludeBy`.

## Self-Hosted Engines, Gateways & Metadata Enrichers

For local inference engines, self-hosted gateways, and metadata enrichment formats, see the comprehensive [Model Metadata Enrichment](../configuration.md#model-metadata-enrichment) documentation in `docs/configuration.md`. It provides configuration examples and capability mapping details for:

- **AIProxy**: [AIProxy Metadata](../configuration.md#aiproxy-metadata) (`modelInfoFormat: "aiproxy"`)
- **Bifrost**: [Bifrost Model Info](../configuration.md#bifrost-model-info) (`modelInfoFormat: "bifrost"`)
- **LiteLLM**: [LiteLLM Model Info](../configuration.md#litellm-model-info) (`modelInfoFormat: "litellm"`)
- **LM Studio**: [LM Studio Model Info](../configuration.md#lm-studio-model-info) (`modelInfoFormat: "lmstudio"`)
- **llama-swap**: [llama-swap Model Info](../configuration.md#llama-swap-model-info) (`modelInfoFormat: "llama-swap"`)
- **models.dev**: [models.dev Metadata](../configuration.md#modelsdev-metadata) (`modelInfoFormat: "models.dev"`)
- **OmniRoute**: [OmniRoute Model Info](../configuration.md#omniroute-model-info) (`modelInfoFormat: "omniroute"`)
- **OpenRouter**: [OpenRouter Model Info](../configuration.md#openrouter-model-info) (`modelInfoFormat: "openrouter"`)
- **vLLM**: [vLLM Model Info](../configuration.md#vllm-model-info) (`modelInfoFormat: "vllm"`)

## Disclaimer

This project is not affiliated with, endorsed by, or sponsored by the providers listed in these examples.
Expand All @@ -16,7 +30,7 @@ Examples are not security, legal, compliance, or purchasing advice.

Do not paste secrets into public issues or pull requests. Configure provider credentials with OpenCode `/connect` when possible, or through local private config.

## Examples
## Community Provider Examples

- [A2Agent](a2agent.md)
- [AI-ROUTER](ai-router.md)
Expand All @@ -35,7 +49,7 @@ Do not include unrelated changes in provider example PRs. In particular, do not

Each example should:

- Use provider-level `provider.<id>.options.modelsDiscovery` config for OpenCode v1. OpenCode v2 examples must use `providers.<id>.settings.modelsDiscovery`.
- Prefer the primary OpenCode v2 shape (`providers.<id>.settings.modelsDiscovery`).
- Prefer `models.includeBy` and `models.excludeBy` over `includeRegex` and `excludeRegex`.
- Avoid secrets, tokens, API keys, account IDs, or private URLs.
- Include a provider-specific disclaimer that this project is not affiliated with, endorsed by, or sponsored by that provider.
Expand Down
36 changes: 17 additions & 19 deletions docs/config_example/a2agent.md
Original file line number Diff line number Diff line change
@@ -1,40 +1,38 @@
# A2Agent Configuration Example

This example uses the OpenCode v1 configuration shape. OpenCode v2 support is currently in beta; use `plugins`, `providers`, `package`, and `settings` instead. See the [V2 configuration guide](../configuration.md#opencode-v2-configuration-beta-support).
This example uses the primary OpenCode v2 configuration shape. For legacy OpenCode v1, adapt using the [migration guide](../migrate-v1-to-v2.md).

## Disclaimer

This project is not affiliated with, endorsed by, or sponsored by
[A2Agent](https://a2agent.me/).
This project is not affiliated with, endorsed by, or sponsored by [A2Agent](https://a2agent.me/).

## Example

```json
```jsonc
{
"provider": {
"$schema": "https://opencode.ai/config.json",
"plugins": [
"opencode-models-discovery@2.0.0"
],
"providers": {
"a2agent": {
"npm": "@ai-sdk/openai-compatible",
"name": "A2Agent",
"options": {
"package": "@opencode-ai/ai/providers/openai-compatible",
"settings": {
"baseURL": "https://api.a2agent.me/v1",
// Optional: omit if managing credentials interactively via OpenCode '/connect'
"apiKey": "example_api_key",
"modelsDiscovery": {
"enabled": true
}
},
"models": {}
}
}
}
}
```

## Notes

- Configure credentials with OpenCode `/connect` when possible, or through
local private configuration.
- This uses the plugin's standard `/v1/models` discovery path, which resolves
to `https://api.a2agent.me/v1/models`.
- The example intentionally does not declare a static model list, filters,
pricing, or third-party metadata. Returned models depend on the account and
current API response.
- Verify the current API base URL, model availability, pricing, terms of
service, data handling, and regional availability before use.
- Configure credentials with OpenCode `/connect` when possible, or through local private configuration.
- This uses the plugin's standard `/v1/models` discovery path, which resolves to `https://api.a2agent.me/v1/models`.
- The example intentionally does not declare a static model list, filters, pricing, or third-party metadata. Returned models depend on the account and current API response.
- Verify the current API base URL, model availability, pricing, terms of service, data handling, and regional availability before use.
20 changes: 12 additions & 8 deletions docs/config_example/ai-router.md
Original file line number Diff line number Diff line change
@@ -1,26 +1,30 @@
# AI-ROUTER Configuration Example

This example uses the OpenCode v1 configuration shape. OpenCode v2 support is currently in beta; use `plugins`, `providers`, `package`, and `settings` instead. See the [V2 configuration guide](../configuration.md#opencode-v2-configuration-beta-support).
This example uses the primary OpenCode v2 configuration shape. For legacy OpenCode v1, adapt using the [migration guide](../migrate-v1-to-v2.md).

## Disclaimer

This project is not affiliated with, endorsed by, or sponsored by [AI-ROUTER](https://ai-router.dev/).

## Example

```json
```jsonc
{
"provider": {
"$schema": "https://opencode.ai/config.json",
"plugins": [
"opencode-models-discovery@2.0.0"
],
"providers": {
"ai-router": {
"npm": "@ai-sdk/openai-compatible",
"name": "AI-ROUTER",
"options": {
"package": "@opencode-ai/ai/providers/openai-compatible",
"settings": {
"baseURL": "https://api.ai-router.dev/v1",
// Optional: omit if managing credentials interactively via OpenCode '/connect'
"apiKey": "example_api_key",
"modelsDiscovery": {
"enabled": true
}
},
"models": {}
}
}
}
}
Expand Down
22 changes: 13 additions & 9 deletions docs/config_example/deepseek.md
Original file line number Diff line number Diff line change
@@ -1,27 +1,31 @@
# DeepSeek Configuration Example

This example uses the OpenCode v1 configuration shape. OpenCode v2 support is currently in beta; use `plugins`, `providers`, `package`, and `settings` instead. See the [V2 configuration guide](../configuration.md#opencode-v2-configuration-beta-support).
This example uses the primary OpenCode v2 configuration shape. For legacy OpenCode v1, adapt using the [migration guide](../migrate-v1-to-v2.md).

## Disclaimer

This project is not affiliated with, endorsed by, or sponsored by DeepSeek.

## Example

```json
```jsonc
{
"provider": {
"$schema": "https://opencode.ai/config.json",
"plugins": [
"opencode-models-discovery@2.0.0"
],
"providers": {
"deepseek": {
"npm": "@ai-sdk/openai-compatible",
"name": "DeepSeek",
"options": {
"package": "@opencode-ai/ai/providers/openai-compatible",
"settings": {
"baseURL": "https://api.deepseek.com/",
// Optional: omit if managing credentials interactively via OpenCode '/connect'
"apiKey": "example_api_key",
"modelsDiscovery": {
"endpoint": "/models",
"endpoint": "/models", // DeepSeek uses /models instead of /v1/models
"modelInfoFormat": "models.dev"
}
},
"models": {}
}
}
}
}
Expand Down
Loading
Loading