Pre-flight checks
OpenCode version reviewed
1.15.12
Problem statement
Every provider hardcodes its vendor's balance/quota URL in src/lib/<vendor>.ts, and createProviderApiKeyResolver reads only an API key, not a base URL. So self-hosted / OpenAI-compatible gateways (LiteLLM proxies, in-house or university gateways, Vertex/Apigee fronts, OpenRouter-compatible endpoints) can't be supported, even though users already configure them as ordinary OpenAI-compatible providers for chat.
There's no standard remaining-quota endpoint, so each such gateway publishes its own small JSON but the plugin currently has no way to point at one.
Proposed change
A single, config-driven generic provider (openai-compatible) that polls a configurable quota endpoint and maps a small JSON shape into the normalized entries. One provider covers any number of gateways:
"experimental": {
"quotaToast": {
"openaiCompatibleGateways": [
{ "providerId": "my-gateway", "quotaPath": "/quota" }
// baseURL inherited from provider.<id>.options.baseURL; apiKey via the existing resolver
]
}
}
Key resolved via the existing createProviderApiKeyResolver (env / trusted global config / auth.json), keyed on providerId.
GET <baseURL><quotaPath> (Bearer) → a default vendor-neutral shape:
{
key,
tokens: {
limit,
used,
remaining,
resets_at
},
cost: {
currency,
limit,
used,
remaining
}
}
with a built-in openrouter preset mapping (data:{usage,limit,limit_remaining}) so OpenRouter-style endpoints work too.
Token bucket → percent entry; cost → value entries. Bound to no product.
I'd start from contributing/provider-template/ and follow the existing resolver/result-helper patterns.
Alternatives considered
- Hardcode OpenRouter (add an
openrouter.ts): narrower (one product) and binds to a product API rather than the open OpenAI-compatible class.
- Read a marker off
provider.<id>.options instead of plugin config: avoids new plugin-config surface, but risks OpenCode rejecting unknown options keys and couples to the chat provider block.
Acceptance criteria
Pre-flight checks
OpenCode version reviewed
1.15.12
Problem statement
Every provider hardcodes its vendor's balance/quota URL in
src/lib/<vendor>.ts, andcreateProviderApiKeyResolverreads only an API key, not a base URL. So self-hosted / OpenAI-compatible gateways (LiteLLM proxies, in-house or university gateways, Vertex/Apigee fronts, OpenRouter-compatible endpoints) can't be supported, even though users already configure them as ordinary OpenAI-compatible providers for chat.There's no standard remaining-quota endpoint, so each such gateway publishes its own small JSON but the plugin currently has no way to point at one.
Proposed change
A single, config-driven generic provider (openai-compatible) that polls a configurable quota endpoint and maps a small JSON shape into the normalized entries. One provider covers any number of gateways:
Key resolved via the existing
createProviderApiKeyResolver(env / trusted global config / auth.json), keyed onproviderId.GET <baseURL><quotaPath>(Bearer) → a default vendor-neutral shape:with a built-in openrouter preset mapping (
data:{usage,limit,limit_remaining}) so OpenRouter-style endpoints work too.Token bucket → percent entry; cost → value entries. Bound to no product.
I'd start from contributing/provider-template/ and follow the existing resolver/result-helper patterns.
Alternatives considered
openrouter.ts): narrower (one product) and binds to a product API rather than the open OpenAI-compatible class.provider.<id>.optionsinstead of plugin config: avoids new plugin-config surface, but risks OpenCode rejecting unknown options keys and couples to the chat provider block.Acceptance criteria
openai-compatibleprovider registered; config-driven gateways list validated like other settings.pnpm run typecheck && pnpm test && pnpm run buildgreen; started fromcontributing/provider-template/./quota_statusreports the provider's key source.