feat: generic OpenAI-compatible gateway quota provider (Refs #109)#110
Open
rice-as681 wants to merge 4 commits into
Open
feat: generic OpenAI-compatible gateway quota provider (Refs #109)#110rice-as681 wants to merge 4 commits into
rice-as681 wants to merge 4 commits into
Conversation
Core fetch+map for a generic OpenAI-compatible gateway quota endpoint
(GET <baseURL><quotaPath>, Bearer): vendor-neutral {key,tokens,cost} default
shape + an openrouter preset ({data:{usage,limit,limit_remaining}}). Null-safe;
maps to a normalized {tokens, cost}. Decision-independent of the config/registry
wiring (Refs slkiser#108). 7 unit tests, all green.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Resolve a gateway's API key via the shared createProviderApiKeyResolver, keyed on its OpenCode provider id (env <ID>_API_KEY / trusted global config provider.<id>.options.apiKey / auth.json), and its base URL from an explicit override or provider.<id>.options.baseURL. Decision-independent of where the gateway list config ultimately lives (Refs slkiser#108). 7 tests; typecheck + build green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Wire the generic OpenAI-compatible gateway provider end to end (Refs slkiser#108): - Config: new experimental.quotaToast.openaiCompatibleGateways list (providerId + optional baseURL/quotaPath/label/mapping), validated and applied like other settings (types.ts, config.ts) and surfaced on the provider context (entries.ts). - Provider (src/providers/openai-compatible.ts): one provider covering N gateways — resolves each gateway's key + baseURL, polls queryGatewayQuota, maps the token bucket to a percent entry and cost to a value entry. matchesCurrentModel uses a fetch-time cache of configured provider ids (it can't see ctx.config) — flagged as design Q2 in slkiser#108. - Registry + provider-metadata: register canonical id "openai-compatible" (label, runtime ids, shape); golden metadata test updated. - README: Providers table row, provider-specific setting, and setup-notes section (neutral + openrouter mappings). Decisions made here (config location, matchesCurrentModel caching, enabledProviders canonical id) are open to maintainer feedback on slkiser#108. typecheck + 1040 tests + build all green; started from contributing/provider-template/. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Round out the provider (Refs slkiser#109): getGatewayKeyDiagnostics reports each configured gateway's key source/checked-paths, and /quota_status renders one section per gateway (provider_id, quota_path, api_key_configured/source/ checked_paths), threaded from runtimeConfig.openaiCompatibleGateways. Closes the last PR-checklist follow-up. 1042 tests + typecheck + build green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Refs #109
Summary
Adds a generic, config-driven
openai-compatibleprovider for any self-hosted /OpenAI-compatible gateway (LiteLLM, in-house/university gateways,
OpenRouter-compatible endpoints) that exposes a remaining-quota endpoint. No
vendor URL is hardcoded — the base URL is configurable — and it is bound to no
product (there is no standard quota endpoint, so it consumes a small documented
shape with an OpenRouter preset).
What changed
src/lib/openai-compatible.ts—queryGatewayQuota(GET<baseURL><quotaPath>,Bearer) → normalized
{tokens, cost}; default vendor-neutral shape(
{key, tokens:{limit,used,remaining,resets_at}, cost:{currency,limit,used,remaining}})plus an
openrouterpreset ({data:{usage,limit,limit_remaining}}).src/lib/openai-compatible-config.ts— per-gateway API key via the sharedcreateProviderApiKeyResolver(env<ID>_API_KEY/ trusted global configprovider.<id>.options.apiKey/ auth.json) + base URL (override orprovider.<id>.options.baseURL).src/providers/openai-compatible.ts— config-driven overexperimental.quotaToast.openaiCompatibleGateways; one provider, N gateways.types.ts,config.ts,entries.ts), registry +provider-metadata registration (canonical id
openai-compatible), README(Providers table row, provider-specific setting, setup-notes section).
Design decisions (open to feedback — see #109)
experimental.quotaToast.openaiCompatibleGateways.matchesCurrentModeluses a fetch-time cache of the configured provider ids,since its
(model, context)signature can't seectx.config.openai-compatibleinenabledProviders; per-gateway ids areconfig, not metadata.
Checklist
contributing/provider-template/pnpm run typecheck✓ ·pnpm test✓ (1040 passed) ·pnpm run build✓fetch mappings (neutral + openrouter) + provider wrapper
README.md)/quota_statusauth-source diagnostics for this providerTested against OpenCode 1.15.12 (config schema + plugin API).