diff --git a/src/api/providers/fetchers/modelEndpointCache.ts b/src/api/providers/fetchers/modelEndpointCache.ts index 256ae8404..96285e506 100644 --- a/src/api/providers/fetchers/modelEndpointCache.ts +++ b/src/api/providers/fetchers/modelEndpointCache.ts @@ -34,10 +34,18 @@ export const getModelEndpoints = async ({ router, modelId, endpoint, + // kilocode_change start + baseUrl, + apiKey, + // kilocode_change end }: { router: RouterName modelId?: string endpoint?: string + // kilocode_change start + baseUrl?: string + apiKey?: 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 +61,15 @@ export const getModelEndpoints = async ({ return modelProviders } - modelProviders = await getOpenRouterModelEndpoints(modelId) + modelProviders = await getOpenRouterModelEndpoints( + modelId, + // kilocode_change start + { + openRouterBaseUrl: baseUrl, + openRouterApiKey: apiKey, + }, + // 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/fetchers/openrouter.ts b/src/api/providers/fetchers/openrouter.ts index 8f41d3953..0af63bbdf 100644 --- a/src/api/providers/fetchers/openrouter.ts +++ b/src/api/providers/fetchers/openrouter.ts @@ -105,7 +105,8 @@ export async function getOpenRouterModels( const baseURL = options?.openRouterBaseUrl || "https://openrouter.ai/api/v1" try { - const response = await axios.get(`${baseURL}/models`, { + const fullUrl = `${baseURL}/models` + const response = await axios.get(fullUrl, { headers: { ...DEFAULT_HEADERS, ...(options?.headers ?? {}) }, // kilocode_change: added headers }) const result = openRouterModelsResponseSchema.safeParse(response.data) diff --git a/src/api/providers/openrouter.ts b/src/api/providers/openrouter.ts index 3812858f0..4cd747cf7 100644 --- a/src/api/providers/openrouter.ts +++ b/src/api/providers/openrouter.ts @@ -295,11 +295,18 @@ 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, + apiKey: this.options.openRouterApiKey, + // kilocode_change end }), ]) diff --git a/src/core/webview/webviewMessageHandler.ts b/src/core/webview/webviewMessageHandler.ts index 7f061a8bc..8a94c76d4 100644 --- a/src/core/webview/webviewMessageHandler.ts +++ b/src/core/webview/webviewMessageHandler.ts @@ -753,8 +753,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 6671418aa..256de3e61 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 [] diff --git a/webview-ui/src/components/ui/hooks/useSelectedModel.ts b/webview-ui/src/components/ui/hooks/useSelectedModel.ts index 9b154ed25..1ec1b7614 100644 --- a/webview-ui/src/components/ui/hooks/useSelectedModel.ts +++ b/webview-ui/src/components/ui/hooks/useSelectedModel.ts @@ -79,8 +79,12 @@ export const useModelProviders = (kilocodeDefaultModel: string, apiConfiguration : provider === "openrouter" ? (apiConfiguration?.openRouterModelId ?? openRouterDefaultModelId) : undefined, - provider === "openrouter" ? apiConfiguration?.openRouterBaseUrl : undefined, - apiConfiguration?.apiKey, + provider === "openrouter" || provider === "kilocode" ? apiConfiguration?.openRouterBaseUrl : undefined, + provider === "openrouter" + ? apiConfiguration?.apiKey + : provider === "kilocode" + ? apiConfiguration?.kilocodeToken + : undefined, apiConfiguration?.kilocodeOrganizationId ?? "personal", ) }