From 1acf5da9e3b99725ff9a41f7c2177f417374c948 Mon Sep 17 00:00:00 2001 From: "damien.lecomte1" Date: Thu, 28 Aug 2025 18:50:42 +0200 Subject: [PATCH 1/4] Fix openrouter custome base url Merge pull request [#2181] https://github.com/Kilo-Org/kilocode/issues/2181) --- src/api/providers/fetchers/modelEndpointCache.ts | 9 ++++++++- src/api/providers/openrouter.ts | 4 +++- src/core/webview/webviewMessageHandler.ts | 4 ++++ webview-ui/src/components/ui/hooks/useSelectedModel.ts | 8 ++++++-- 4 files changed, 21 insertions(+), 4 deletions(-) diff --git a/src/api/providers/fetchers/modelEndpointCache.ts b/src/api/providers/fetchers/modelEndpointCache.ts index 256ae8404..f91022dfd 100644 --- a/src/api/providers/fetchers/modelEndpointCache.ts +++ b/src/api/providers/fetchers/modelEndpointCache.ts @@ -34,10 +34,14 @@ export const getModelEndpoints = async ({ router, modelId, endpoint, + baseUrl, + apiKey, }: { router: RouterName modelId?: string endpoint?: string + baseUrl?: string + apiKey?: string }): 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 +57,10 @@ export const getModelEndpoints = async ({ return modelProviders } - modelProviders = await getOpenRouterModelEndpoints(modelId) + modelProviders = await getOpenRouterModelEndpoints(modelId, { + openRouterBaseUrl: baseUrl, + openRouterApiKey: apiKey, + } as any) 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 51d99b6b2..04558b86a 100644 --- a/src/api/providers/openrouter.ts +++ b/src/api/providers/openrouter.ts @@ -253,11 +253,13 @@ 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 }), getModelEndpoints({ router: "openrouter", modelId: this.options.openRouterModelId, endpoint: this.options.openRouterSpecificProvider, + baseUrl: this.options.openRouterBaseUrl, + apiKey: this.options.openRouterApiKey, }), ]) diff --git a/src/core/webview/webviewMessageHandler.ts b/src/core/webview/webviewMessageHandler.ts index 2b7aa6616..4cd544d22 100644 --- a/src/core/webview/webviewMessageHandler.ts +++ b/src/core/webview/webviewMessageHandler.ts @@ -589,6 +589,10 @@ export const webviewMessageHandler = async ( const openRouterApiKey = apiConfiguration.openRouterApiKey || message?.values?.openRouterApiKey const openRouterBaseUrl = apiConfiguration.openRouterBaseUrl || message?.values?.openRouterBaseUrl + // kilocode_change start: force flush models cache when baseUrl changes + await flushModels("openrouter") + // kilocode_change end + const modelFetchPromises: Array<{ key: RouterName; options: GetModelsOptions }> = [ { key: "openrouter", diff --git a/webview-ui/src/components/ui/hooks/useSelectedModel.ts b/webview-ui/src/components/ui/hooks/useSelectedModel.ts index f593620ac..96179e7d5 100644 --- a/webview-ui/src/components/ui/hooks/useSelectedModel.ts +++ b/webview-ui/src/components/ui/hooks/useSelectedModel.ts @@ -77,8 +77,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", ) } From 4812986eef6919e4765ac91c12eb4d53d527e925 Mon Sep 17 00:00:00 2001 From: Christiaan Arnoldus Date: Fri, 29 Aug 2025 11:03:03 +0200 Subject: [PATCH 2/4] Add kilocode_change comments --- .../providers/fetchers/modelEndpointCache.ts | 17 +++++++++++++---- src/api/providers/openrouter.ts | 7 ++++++- src/core/webview/webviewMessageHandler.ts | 4 +--- 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/src/api/providers/fetchers/modelEndpointCache.ts b/src/api/providers/fetchers/modelEndpointCache.ts index f91022dfd..96285e506 100644 --- a/src/api/providers/fetchers/modelEndpointCache.ts +++ b/src/api/providers/fetchers/modelEndpointCache.ts @@ -34,14 +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. @@ -57,10 +61,15 @@ export const getModelEndpoints = async ({ return modelProviders } - modelProviders = await getOpenRouterModelEndpoints(modelId, { - openRouterBaseUrl: baseUrl, - openRouterApiKey: apiKey, - } as any) + 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/openrouter.ts b/src/api/providers/openrouter.ts index 04558b86a..6a2945445 100644 --- a/src/api/providers/openrouter.ts +++ b/src/api/providers/openrouter.ts @@ -253,13 +253,18 @@ export class OpenRouterHandler extends BaseProvider implements SingleCompletionH public async fetchModel() { const [models, endpoints] = await Promise.all([ - getModels({ provider: "openrouter", baseUrl: this.options.openRouterBaseUrl }), + 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 4cd544d22..7b4b223b8 100644 --- a/src/core/webview/webviewMessageHandler.ts +++ b/src/core/webview/webviewMessageHandler.ts @@ -589,9 +589,7 @@ export const webviewMessageHandler = async ( const openRouterApiKey = apiConfiguration.openRouterApiKey || message?.values?.openRouterApiKey const openRouterBaseUrl = apiConfiguration.openRouterBaseUrl || message?.values?.openRouterBaseUrl - // kilocode_change start: force flush models cache when baseUrl changes - await flushModels("openrouter") - // kilocode_change end + await flushModels("openrouter") // force flush models cache when baseUrl changes const modelFetchPromises: Array<{ key: RouterName; options: GetModelsOptions }> = [ { From 44462a30d4658ce45cd709d72302c9101af43889 Mon Sep 17 00:00:00 2001 From: Cobra91 Date: Mon, 1 Sep 2025 14:03:39 +0000 Subject: [PATCH 3/4] fix for recover from the good url the model list --- src/api/providers/fetchers/openrouter.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/api/providers/fetchers/openrouter.ts b/src/api/providers/fetchers/openrouter.ts index 5392212e5..e8914ce5f 100644 --- a/src/api/providers/fetchers/openrouter.ts +++ b/src/api/providers/fetchers/openrouter.ts @@ -103,7 +103,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) From b87b0d56666c5acd368bcdfbac0b70d453f1c071 Mon Sep 17 00:00:00 2001 From: Cobra91 Date: Mon, 1 Sep 2025 18:59:00 +0000 Subject: [PATCH 4/4] final commit test all work --- src/core/webview/webviewMessageHandler.ts | 11 +++++-- .../src/components/settings/ApiOptions.tsx | 29 +++++++++++++++++++ 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/src/core/webview/webviewMessageHandler.ts b/src/core/webview/webviewMessageHandler.ts index 979cdddcc..4f345c478 100644 --- a/src/core/webview/webviewMessageHandler.ts +++ b/src/core/webview/webviewMessageHandler.ts @@ -588,8 +588,15 @@ 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 diff --git a/webview-ui/src/components/settings/ApiOptions.tsx b/webview-ui/src/components/settings/ApiOptions.tsx index e152278ab..4f5a7dc8a 100644 --- a/webview-ui/src/components/settings/ApiOptions.tsx +++ b/webview-ui/src/components/settings/ApiOptions.tsx @@ -256,6 +256,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" }) } @@ -271,6 +286,7 @@ const ApiOptions = ({ apiConfiguration?.litellmBaseUrl, apiConfiguration?.litellmApiKey, customHeaders, + refetchRouterModels, // kilocode_change ], ) @@ -283,6 +299,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 []