diff --git a/src/api/providers/openrouter.ts b/src/api/providers/openrouter.ts index 580b17331194..d16a410b1322 100644 --- a/src/api/providers/openrouter.ts +++ b/src/api/providers/openrouter.ts @@ -304,7 +304,8 @@ export class OpenRouterHandler extends BaseProvider implements SingleCompletionH } try { - const response = await fetch("https://openrouter.ai/api/v1/chat/completions", { + const baseURL = this.options.openRouterBaseUrl || "https://openrouter.ai/api/v1" + const response = await fetch(`${baseURL}/chat/completions`, { method: "POST", headers: { Authorization: `Bearer ${apiKey}`, diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index 2a5fc24adab0..d7fa1dde296e 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -785,7 +785,7 @@ export class ClineProvider webviewView.webview.html = this.contextProxy.extensionMode === vscode.ExtensionMode.Development ? await this.getHMRHtmlContent(webviewView.webview) - : this.getHtmlContent(webviewView.webview) + : await this.getHtmlContent(webviewView.webview) // Sets up an event listener to listen for messages passed from the webview view context // and executes code based on the message that is received. @@ -1019,6 +1019,12 @@ export class ClineProvider const nonce = getNonce() + // Get the OpenRouter base URL from configuration + const { apiConfiguration } = await this.getState() + const openRouterBaseUrl = apiConfiguration.openRouterBaseUrl || "https://openrouter.ai" + // Extract the domain for CSP + const openRouterDomain = openRouterBaseUrl.match(/^(https?:\/\/[^\/]+)/)?.[1] || "https://openrouter.ai" + const stylesUri = getUri(webview, this.contextProxy.extensionUri, [ "webview-ui", "build", @@ -1055,7 +1061,7 @@ export class ClineProvider `img-src ${webview.cspSource} https://storage.googleapis.com https://img.clerk.com data:`, `media-src ${webview.cspSource}`, `script-src 'unsafe-eval' ${webview.cspSource} https://* https://*.posthog.com http://${localServerUrl} http://0.0.0.0:${localPort} 'nonce-${nonce}'`, - `connect-src ${webview.cspSource} https://* https://*.posthog.com ws://${localServerUrl} ws://0.0.0.0:${localPort} http://${localServerUrl} http://0.0.0.0:${localPort}`, + `connect-src ${webview.cspSource} ${openRouterDomain} https://* https://*.posthog.com ws://${localServerUrl} ws://0.0.0.0:${localPort} http://${localServerUrl} http://0.0.0.0:${localPort}`, ] return /*html*/ ` @@ -1094,7 +1100,7 @@ export class ClineProvider * @returns A template string literal containing the HTML that should be * rendered within the webview panel */ - private getHtmlContent(webview: vscode.Webview): string { + private async getHtmlContent(webview: vscode.Webview): Promise { // Get the local path to main script run in the webview, // then convert it to a uri we can use in the webview. @@ -1129,6 +1135,12 @@ export class ClineProvider */ const nonce = getNonce() + // Get the OpenRouter base URL from configuration + const { apiConfiguration } = await this.getState() + const openRouterBaseUrl = apiConfiguration.openRouterBaseUrl || "https://openrouter.ai" + // Extract the domain for CSP + const openRouterDomain = openRouterBaseUrl.match(/^(https?:\/\/[^\/]+)/)?.[1] || "https://openrouter.ai" + // Tip: Install the es6-string-html VS Code extension to enable code highlighting below return /*html*/ ` @@ -1137,7 +1149,7 @@ export class ClineProvider - +