π Authentication plugin for OpenCode to connect to OmniRoute API.
/connect Command - No manual configuration needed/v1/models endpointomniroute provider via plugin hookscx/gpt-5.5 β codex/gpt-5.5)gpt-5.5-xhigh β gpt-5.5) for lookupnpm install opencode-omniroute-auth
{
"plugin": [
"opencode-omniroute-auth"
]
}
Simply run the /connect command in OpenCode:
/connect omniroute
The plugin will prompt you for your API key.
The plugin automatically:
/v1/modelsNo manual configuration file editing required!
Once connected, OpenCode will automatically use OmniRoute for AI requests:
# The plugin is now active and ready to use
# All AI requests will be routed through OmniRoute
By default, the plugin refreshes the model list whenever provider options are reloaded (refreshOnList: true).
You can disable refreshes by setting provider.omniroute.options.refreshOnList to false and clear the cache programmatically:
import { clearModelCache } from 'opencode-omniroute-auth/runtime';
clearModelCache();
While the plugin works out-of-the-box with /connect, you can also configure it manually in your OpenCode config:
{
"plugin": [
"opencode-omniroute-auth"
],
"provider": {
"omniroute": {
"options": {
"baseURL": "http://localhost:20128/v1",
"apiMode": "chat",
"refreshOnList": true,
"modelCacheTtl": 300000
}
}
}
}
Use /connect omniroute to store your API key in ~/.local/share/opencode/auth.json.
| Option | Type | Required | Description |
|---|---|---|---|
plugin | string[] | No | npm plugin packages to load (use opencode-omniroute-auth when installed from npm) |
provider.omniroute.options.baseURL | string | No | OmniRoute API base URL (default: http://localhost:20128/v1) |
provider.omniroute.options.apiMode | 'chat' | 'responses' | No | Provider API mode (default: chat) |
provider.omniroute.options.modelCacheTtl | number | No | Model cache TTL in milliseconds (default: 5 minutes) |
provider.omniroute.options.refreshOnList | boolean | No | Whether to refresh models when provider options load (default: true) |
provider.omniroute.options.modelsDev | object | No | Enrich model metadata from models.dev on refresh (default: enabled) |
provider.omniroute.options.modelMetadata | object | array | No | Override/add metadata for custom/virtual models (works well in opencode.js) |
OmniRoute may not expose model context/output limits in /v1/models. When enabled, this plugin attempts to
enrich contextWindow and maxTokens by matching your OmniRoute models against models.dev.
You can disable enrichment or override defaults:
{
provider: {
omniroute: {
options: {
modelsDev: {
enabled: true,
url: 'https://models.dev/api.json',
timeoutMs: 1000,
cacheTtl: 86400000,
providerAliases: {
cx: 'openai',
},
},
},
},
},
}
For custom/virtual models (or when matching is imperfect), you can provide metadata overrides.
In opencode.js you can use RegExp matchers:
{
provider: {
omniroute: {
options: {
modelMetadata: [
{ match: /gpt-5\.3-codex$/i, contextWindow: 200000, maxTokens: 8192 },
{ match: 'omniroute/virtual/my-custom-model', addIfMissing: true, contextWindow: 50000 },
],
},
},
},
}
In JSON configs, use an object keyed by model id:
{
"provider": {
"omniroute": {
"options": {
"modelMetadata": {
"virtual/my-custom-model": { "contextWindow": 50000, "maxTokens": 2048 }
}
}
}
}
}
OmniRoute supports "combo models" - virtual models that route to multiple underlying models with fallback strategies. This plugin automatically detects combo models and calculates their capabilities using a lowest common denominator approach:
This ensures safe operation by never exceeding the capabilities of any single model in the combo.
How it works:
/api/combos endpointmodels.devExample: The "Designer" combo might route to:
kmc/kimi-k2.5 (context: 256000, tools: yes)cx/gpt-5.1-codex-mini (context: 204800, tools: yes)gemini/models/gemini-3-flash-preview (context: 1048576, tools: yes)Calculated capabilities:
Note: Some underlying models may not be found in models.dev (e.g., custom models). In such cases, they are excluded from capability calculation, and a warning is logged.
The plugin supports two provider API modes:
chat (default) - best compatibility with existing OpenAI-compatible chat workflows.responses - enables Responses API mode when your OmniRoute/OpenCode setup supports it.Example:
{
"provider": {
"omniroute": {
"options": {
"apiMode": "responses"
}
}
}
}
If an unsupported value is provided, the plugin falls back to chat.
This plugin automatically fetches available models from OmniRoute's /v1/models endpoint. This ensures you always have access to the latest models without manual configuration.
/v1/modelsrefreshOnList: true)refreshOnList is disabled, models are cached for 5 minutes (configurable via modelCacheTtl)When the /v1/models endpoint is unavailable, the plugin provides these fallback models:
gpt-4o - GPT-4o model with full capabilitiesgpt-4o-mini - Fast and cost-effectiveclaude-3-5-sonnet - Claude 3.5 Sonnetllama-3-1-405b - Llama 3.1 405Bimport type {
OmniRouteApiMode,
OmniRouteConfig,
OmniRouteModel,
OmniRouteModelMetadataConfig,
OmniRouteModelsDevConfig,
} from "opencode-omniroute-auth";
interface OmniRouteConfig {
baseUrl: string;
apiKey: string;
apiMode: OmniRouteApiMode;
defaultModels?: OmniRouteModel[];
modelCacheTtl?: number;
refreshOnList?: boolean;
modelsDev?: OmniRouteModelsDevConfig;
modelMetadata?: OmniRouteModelMetadataConfig;
}
type OmniRouteApiMode = 'chat' | 'responses';
interface OmniRouteModel {
id: string;
name: string;
description?: string;
contextWindow?: number;
maxTokens?: number;
supportsStreaming?: boolean;
supportsVision?: boolean;
supportsTools?: boolean;
supportsTemperature?: boolean;
supportsReasoning?: boolean;
supportsAttachment?: boolean;
// OmniRoute native fields (normalized automatically)
context_length?: number;
max_input_tokens?: number;
max_output_tokens?: number;
capabilities?: {
vision?: boolean;
tool_calling?: boolean;
reasoning?: boolean;
thinking?: boolean;
attachment?: boolean;
temperature?: boolean;
};
pricing?: {
input?: number;
output?: number;
};
}
import {
fetchModels,
clearModelCache,
refreshModels,
// Combo model utilities
clearComboCache,
fetchComboData,
resolveUnderlyingModels,
calculateModelCapabilities,
} from 'opencode-omniroute-auth/runtime';
// Fetch models manually (with automatic normalization and enrichment)
const models = await fetchModels(config, apiKey);
// Clear model cache (also clears combo cache)
clearModelCache();
// Force refresh models
const freshModels = await refreshModels(config, apiKey);
// Combo model utilities
const combos = await fetchComboData(config);
const underlyingModels = await resolveUnderlyingModels('Designer', config);
const capabilities = await calculateModelCapabilities(model, config, modelsDevIndex);
# Install dependencies
npm install
# Build
npm run build
# Watch mode
npm run dev
# Clean
npm run clean
If you see "Connection failed" when running /connect omniroute:
provider.omniroute.options.baseURL points to your OmniRoute endpointsk- and is validIf models aren't loading:
/v1/models endpoint is accessibleprovider.omniroute.options.baseURL points to your OmniRoute endpoint/connect omniroute to refresh your API keyclearModelCache() from opencode-omniroute-auth/runtimeIf the plugin loads only through a local shim (for example from .opencode/plugins) but not from npm in opencode.json:
opencode-omniroute-auth@1.0.1 or newer"plugin": ["opencode-omniroute-auth"]~/.cache/opencode/node_modulesIf needed, clear and reinstall plugin dependencies, then restart OpenCode.
MIT
Contributions are welcome! Please feel free to submit a Pull Request.
For support, please open an issue on GitHub or contact OmniRoute support.
TypeScript
54.9%
JavaScript
45.1%
π Authentication plugin for OpenCode to connect to OmniRoute API.
/connect Command - No manual configuration needed/v1/models endpointomniroute provider via plugin hookscx/gpt-5.5 β codex/gpt-5.5)gpt-5.5-xhigh β gpt-5.5) for lookupnpm install opencode-omniroute-auth
{
"plugin": [
"opencode-omniroute-auth"
]
}
Simply run the /connect command in OpenCode:
/connect omniroute
The plugin will prompt you for your API key.
The plugin automatically:
/v1/modelsNo manual configuration file editing required!
Once connected, OpenCode will automatically use OmniRoute for AI requests:
# The plugin is now active and ready to use
# All AI requests will be routed through OmniRoute
By default, the plugin refreshes the model list whenever provider options are reloaded (refreshOnList: true).
You can disable refreshes by setting provider.omniroute.options.refreshOnList to false and clear the cache programmatically:
import { clearModelCache } from 'opencode-omniroute-auth/runtime';
clearModelCache();
While the plugin works out-of-the-box with /connect, you can also configure it manually in your OpenCode config:
{
"plugin": [
"opencode-omniroute-auth"
],
"provider": {
"omniroute": {
"options": {
"baseURL": "http://localhost:20128/v1",
"apiMode": "chat",
"refreshOnList": true,
"modelCacheTtl": 300000
}
}
}
}
Use /connect omniroute to store your API key in ~/.local/share/opencode/auth.json.
| Option | Type | Required | Description |
|---|---|---|---|
plugin | string[] | No | npm plugin packages to load (use opencode-omniroute-auth when installed from npm) |
provider.omniroute.options.baseURL | string | No | OmniRoute API base URL (default: http://localhost:20128/v1) |
provider.omniroute.options.apiMode | 'chat' | 'responses' | No | Provider API mode (default: chat) |
provider.omniroute.options.modelCacheTtl | number | No | Model cache TTL in milliseconds (default: 5 minutes) |
provider.omniroute.options.refreshOnList | boolean | No | Whether to refresh models when provider options load (default: true) |
provider.omniroute.options.modelsDev | object | No | Enrich model metadata from models.dev on refresh (default: enabled) |
provider.omniroute.options.modelMetadata | object | array | No | Override/add metadata for custom/virtual models (works well in opencode.js) |
OmniRoute may not expose model context/output limits in /v1/models. When enabled, this plugin attempts to
enrich contextWindow and maxTokens by matching your OmniRoute models against models.dev.
You can disable enrichment or override defaults:
{
provider: {
omniroute: {
options: {
modelsDev: {
enabled: true,
url: 'https://models.dev/api.json',
timeoutMs: 1000,
cacheTtl: 86400000,
providerAliases: {
cx: 'openai',
},
},
},
},
},
}
For custom/virtual models (or when matching is imperfect), you can provide metadata overrides.
In opencode.js you can use RegExp matchers:
{
provider: {
omniroute: {
options: {
modelMetadata: [
{ match: /gpt-5\.3-codex$/i, contextWindow: 200000, maxTokens: 8192 },
{ match: 'omniroute/virtual/my-custom-model', addIfMissing: true, contextWindow: 50000 },
],
},
},
},
}
In JSON configs, use an object keyed by model id:
{
"provider": {
"omniroute": {
"options": {
"modelMetadata": {
"virtual/my-custom-model": { "contextWindow": 50000, "maxTokens": 2048 }
}
}
}
}
}
OmniRoute supports "combo models" - virtual models that route to multiple underlying models with fallback strategies. This plugin automatically detects combo models and calculates their capabilities using a lowest common denominator approach:
This ensures safe operation by never exceeding the capabilities of any single model in the combo.
How it works:
/api/combos endpointmodels.devExample: The "Designer" combo might route to:
kmc/kimi-k2.5 (context: 256000, tools: yes)cx/gpt-5.1-codex-mini (context: 204800, tools: yes)gemini/models/gemini-3-flash-preview (context: 1048576, tools: yes)Calculated capabilities:
Note: Some underlying models may not be found in models.dev (e.g., custom models). In such cases, they are excluded from capability calculation, and a warning is logged.
The plugin supports two provider API modes:
chat (default) - best compatibility with existing OpenAI-compatible chat workflows.responses - enables Responses API mode when your OmniRoute/OpenCode setup supports it.Example:
{
"provider": {
"omniroute": {
"options": {
"apiMode": "responses"
}
}
}
}
If an unsupported value is provided, the plugin falls back to chat.
This plugin automatically fetches available models from OmniRoute's /v1/models endpoint. This ensures you always have access to the latest models without manual configuration.
/v1/modelsrefreshOnList: true)refreshOnList is disabled, models are cached for 5 minutes (configurable via modelCacheTtl)When the /v1/models endpoint is unavailable, the plugin provides these fallback models:
gpt-4o - GPT-4o model with full capabilitiesgpt-4o-mini - Fast and cost-effectiveclaude-3-5-sonnet - Claude 3.5 Sonnetllama-3-1-405b - Llama 3.1 405Bimport type {
OmniRouteApiMode,
OmniRouteConfig,
OmniRouteModel,
OmniRouteModelMetadataConfig,
OmniRouteModelsDevConfig,
} from "opencode-omniroute-auth";
interface OmniRouteConfig {
baseUrl: string;
apiKey: string;
apiMode: OmniRouteApiMode;
defaultModels?: OmniRouteModel[];
modelCacheTtl?: number;
refreshOnList?: boolean;
modelsDev?: OmniRouteModelsDevConfig;
modelMetadata?: OmniRouteModelMetadataConfig;
}
type OmniRouteApiMode = 'chat' | 'responses';
interface OmniRouteModel {
id: string;
name: string;
description?: string;
contextWindow?: number;
maxTokens?: number;
supportsStreaming?: boolean;
supportsVision?: boolean;
supportsTools?: boolean;
supportsTemperature?: boolean;
supportsReasoning?: boolean;
supportsAttachment?: boolean;
// OmniRoute native fields (normalized automatically)
context_length?: number;
max_input_tokens?: number;
max_output_tokens?: number;
capabilities?: {
vision?: boolean;
tool_calling?: boolean;
reasoning?: boolean;
thinking?: boolean;
attachment?: boolean;
temperature?: boolean;
};
pricing?: {
input?: number;
output?: number;
};
}
import {
fetchModels,
clearModelCache,
refreshModels,
// Combo model utilities
clearComboCache,
fetchComboData,
resolveUnderlyingModels,
calculateModelCapabilities,
} from 'opencode-omniroute-auth/runtime';
// Fetch models manually (with automatic normalization and enrichment)
const models = await fetchModels(config, apiKey);
// Clear model cache (also clears combo cache)
clearModelCache();
// Force refresh models
const freshModels = await refreshModels(config, apiKey);
// Combo model utilities
const combos = await fetchComboData(config);
const underlyingModels = await resolveUnderlyingModels('Designer', config);
const capabilities = await calculateModelCapabilities(model, config, modelsDevIndex);
# Install dependencies
npm install
# Build
npm run build
# Watch mode
npm run dev
# Clean
npm run clean
If you see "Connection failed" when running /connect omniroute:
provider.omniroute.options.baseURL points to your OmniRoute endpointsk- and is validIf models aren't loading:
/v1/models endpoint is accessibleprovider.omniroute.options.baseURL points to your OmniRoute endpoint/connect omniroute to refresh your API keyclearModelCache() from opencode-omniroute-auth/runtimeIf the plugin loads only through a local shim (for example from .opencode/plugins) but not from npm in opencode.json:
opencode-omniroute-auth@1.0.1 or newer"plugin": ["opencode-omniroute-auth"]~/.cache/opencode/node_modulesIf needed, clear and reinstall plugin dependencies, then restart OpenCode.
MIT
Contributions are welcome! Please feel free to submit a Pull Request.
For support, please open an issue on GitHub or contact OmniRoute support.
TypeScript
54.9%
JavaScript
45.1%