feat: configurable base_url for all LLM providers#24
Closed
ricorna wants to merge 1 commit intospacedriveapp:mainfrom
Closed
feat: configurable base_url for all LLM providers#24ricorna wants to merge 1 commit intospacedriveapp:mainfrom
ricorna wants to merge 1 commit intospacedriveapp:mainfrom
Conversation
Deduplicate per-provider API call methods (call_openai, call_zhipu, call_groq, etc.) into two generic methods — call_openai_compatible and call_anthropic_compatible — parameterized by provider ID, display name, and endpoint URL. Add configurable base_url support for all providers: each provider can now have its endpoint overridden via TOML config (e.g. zhipu_base_url), env vars (e.g. ZHIPU_BASE_URL), or the env: reference syntax. The frontend gains an EndpointSelector component with preset and custom URL options, and the GET /providers response now includes any configured base_url overrides. Also: expand is_needs_setup to check all provider env vars, fix isConfigured for hyphenated provider IDs, clean up delete_provider to remove orphaned base_url entries, fix empty env vars (VAR="") being treated as configured providers.
This was referenced Feb 18, 2026
Contributor
Author
|
built this out when i realized that adding coding providers would mean and even increasing number of permutations that requires forking to add or change. This give ultimate flexibility out of the box (in theory if a provider made a new subscription product and endpoint tomorrow, this would allow a user to add that right away, custom), and lets maintainers add known defaults as they go. |
3 tasks
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.
Motivation
LLM providers increasingly offer multiple API surfaces — different endpoints, different formats, sometimes different credentials — for the same underlying models:
api.z.ai/api/paas/v4) vs Coding Plan (api.z.ai/api/coding/paas/v4) — same key, different billing pathapi.moonshot.ai/v1) vs Kimi Coding Plan (api.kimi.com/coding/v1) — same key, entirely different domainapi.minimax.io) vs China mainland (api.minimaxi.com), OpenAI-compatible (/v1) vs Anthropic-compatible (/anthropic), standard API key vs Coding Plan key (sk-cp-prefix) — different keys, different domains, different API formatsCurrently every provider hardcodes its URL. Users on alternate plans, behind proxies, or in different regions must fork the code to change an endpoint.
Huge thanks to @ZerGo0 for the research in #13 identifying the Z.ai, Kimi, and MiniMax coding plan endpoints and the need for this feature. This PR takes a complementary approach — making the base URL a configurable property of each existing provider rather than creating separate provider entries per endpoint variant. One provider = one API key field = one identity. The URL is a deployment choice, not a provider identity.
This also lays groundwork for future extensibility: custom provider instances, proxy routing, and arbitrary OpenAI/Anthropic-compatible endpoints can all be configured without code changes.
Changes
Backend
call_*methods into 2 generic helpers (call_openai_compatible,call_anthropic_compatible), removing ~260 lines of duplicationbase_url(Option<String>) for every provider inLlmConfig{PROVIDER}_BASE_URL(e.g.,ZHIPU_BASE_URL,OPENAI_BASE_URL)zhipu_base_url = "..."in[llm]sectionenv:VAR_NAMEindirection works for base URLs, consistent with API keysdelete_providercleans upbase_urlalongside the keyGET /providersreturnsbase_urlsmap so the frontend can display current stateFrontend
EndpointSelectorcomponent with declarative presets per provider + custom URL fallbackENDPOINT_PRESETSBug fixes discovered during refactor
opencode-zenvsopencode_zenkey mismatch in frontendisConfigured— was always returningfalseis_needs_setuponly checked 3 of 12 providers — users with only Groq/Together/etc. configured were stuck in setup modeBreaking Changes
None. All existing config, env vars, and defaults are preserved. Providers without a
base_urlconfigured behave identically to before.How to Test
Verified
Tested end-to-end with a Z.ai Coding Plan subscription. Set
ZHIPU_BASE_URLto the Coding Plan endpoint — chat completions return successfully. Without the override, the same key against the general endpoint returns 429 "Insufficient balance" (no pay-per-token credits loaded). With the Coding Plan endpoint, the subscription billing kicks in and requests succeed. This is exactly the user experience thebase_urlfeature is designed to solve: same key, different endpoint, works without touching code.Diff stats
Net reduction of 23 lines while adding the feature.