diff --git a/src/api/providers/fetchers/modelEndpointCache.ts b/src/api/providers/fetchers/modelEndpointCache.ts index 256ae84048..50e822323b 100644 --- a/src/api/providers/fetchers/modelEndpointCache.ts +++ b/src/api/providers/fetchers/modelEndpointCache.ts @@ -34,10 +34,16 @@ export const getModelEndpoints = async ({ router, modelId, endpoint, + // kilocode_change start + baseUrl, + // kilocode_change end }: { router: RouterName modelId?: string endpoint?: string + // kilocode_change start + baseUrl?: string + // kilocode_change end }): Promise => { // OpenRouter is the only provider that supports model endpoints, but you // can see how we'd extend this to other providers in the future. @@ -53,7 +59,14 @@ export const getModelEndpoints = async ({ return modelProviders } - modelProviders = await getOpenRouterModelEndpoints(modelId) + modelProviders = await getOpenRouterModelEndpoints( + modelId, + // kilocode_change start + { + openRouterBaseUrl: baseUrl, + }, + // kilocode_change end + ) if (Object.keys(modelProviders).length > 0) { // console.log(`[getModelProviders] API fetch for ${key} -> ${Object.keys(modelProviders).length}`) diff --git a/src/api/providers/openrouter.ts b/src/api/providers/openrouter.ts index 3ae29555e5..9cab361b01 100644 --- a/src/api/providers/openrouter.ts +++ b/src/api/providers/openrouter.ts @@ -281,11 +281,17 @@ export class OpenRouterHandler extends BaseProvider implements SingleCompletionH public async fetchModel() { const [models, endpoints] = await Promise.all([ - getModels({ provider: "openrouter" }), + getModels({ + provider: "openrouter", + baseUrl: this.options.openRouterBaseUrl, // kilocode_change + }), getModelEndpoints({ router: "openrouter", modelId: this.options.openRouterModelId, endpoint: this.options.openRouterSpecificProvider, + // kilocode_change start + baseUrl: this.options.openRouterBaseUrl, + // kilocode_change end }), ]) diff --git a/src/core/webview/webviewMessageHandler.ts b/src/core/webview/webviewMessageHandler.ts index 30d3f9bc06..3c621617eb 100644 --- a/src/core/webview/webviewMessageHandler.ts +++ b/src/core/webview/webviewMessageHandler.ts @@ -811,8 +811,17 @@ export const webviewMessageHandler = async ( } // kilocode_change start: openrouter auth, kilocode provider - const openRouterApiKey = apiConfiguration.openRouterApiKey || message?.values?.openRouterApiKey - const openRouterBaseUrl = apiConfiguration.openRouterBaseUrl || message?.values?.openRouterBaseUrl + // Prioritize the new value from the UI input over the saved configuration for live testing + const openRouterApiKey = + message?.values?.openRouterApiKey !== undefined + ? message.values.openRouterApiKey + : apiConfiguration.openRouterApiKey + const openRouterBaseUrl = + message?.values?.openRouterBaseUrl !== undefined + ? message.values.openRouterBaseUrl + : apiConfiguration.openRouterBaseUrl + + await flushModels("openrouter") // force flush models cache when baseUrl changes const modelFetchPromises: Array<{ key: RouterName; options: GetModelsOptions }> = [ { diff --git a/webview-ui/src/components/settings/ApiOptions.tsx b/webview-ui/src/components/settings/ApiOptions.tsx index 6671418aa7..256de3e614 100644 --- a/webview-ui/src/components/settings/ApiOptions.tsx +++ b/webview-ui/src/components/settings/ApiOptions.tsx @@ -259,6 +259,21 @@ const ApiOptions = ({ vscode.postMessage({ type: "requestLmStudioModels" }) } else if (selectedProvider === "vscode-lm") { vscode.postMessage({ type: "requestVsCodeLmModels" }) + // kilocode_change start + } else if (selectedProvider === "openrouter") { + const headerObject = convertHeadersToObject(customHeaders) + vscode.postMessage({ + type: "requestRouterModels", + values: { + openRouterBaseUrl: apiConfiguration?.openRouterBaseUrl, + openRouterApiKey: apiConfiguration?.openRouterApiKey, + customHeaders: {}, + openAiHeaders: headerObject, + source: "ApiOptions.debounce.openrouter", + }, + }) + refetchRouterModels() + // kilocode_change end } else if (selectedProvider === "litellm") { vscode.postMessage({ type: "requestRouterModels" }) } else if (selectedProvider === "deepinfra") { @@ -278,6 +293,7 @@ const ApiOptions = ({ apiConfiguration?.deepInfraApiKey, apiConfiguration?.deepInfraBaseUrl, customHeaders, + refetchRouterModels, // kilocode_change ], ) @@ -290,6 +306,19 @@ const ApiOptions = ({ setErrorMessage(apiValidationResult) }, [apiConfiguration, routerModels, organizationAllowList, setErrorMessage]) + // kilocode_change start + // This will trigger whenever the baseUrl for OpenRouter changes. + useEffect(() => { + // We only want to do this if the selected provider is actually OpenRouter. + if (apiConfiguration.apiProvider === "openrouter") { + // 1. Flush the server-side cache for openrouter. + vscode.postMessage({ type: "flushRouterModels", text: "openrouter" }) + // 2. Trigger a client-side refetch using the new configuration. + refetchRouterModels() + } + }, [apiConfiguration.openRouterBaseUrl, apiConfiguration.apiProvider, refetchRouterModels]) + // kilocode_change end + const selectedProviderModels = useMemo(() => { const models = MODELS_BY_PROVIDER[selectedProvider] if (!models) return []