|
|
@@ -10,7 +10,18 @@ import * as vscode from "vscode"
|
|
|
|
|
|
import { changeLanguage, t } from "../../i18n"
|
|
|
import { setPanel } from "../../activate/registerCommands"
|
|
|
-import { ApiConfiguration, ApiProvider, ModelInfo, API_CONFIG_KEYS } from "../../shared/api"
|
|
|
+import {
|
|
|
+ ApiConfiguration,
|
|
|
+ ApiProvider,
|
|
|
+ ModelInfo,
|
|
|
+ API_CONFIG_KEYS,
|
|
|
+ requestyDefaultModelId,
|
|
|
+ requestyDefaultModelInfo,
|
|
|
+ openRouterDefaultModelId,
|
|
|
+ openRouterDefaultModelInfo,
|
|
|
+ glamaDefaultModelId,
|
|
|
+ glamaDefaultModelInfo,
|
|
|
+} from "../../shared/api"
|
|
|
import { findLast } from "../../shared/array"
|
|
|
import { supportPrompt } from "../../shared/support-prompt"
|
|
|
import { GlobalFileNames } from "../../shared/globalFileNames"
|
|
|
@@ -593,6 +604,8 @@ export class ClineProvider extends EventEmitter<ClineProviderEvents> implements
|
|
|
"codicon.css",
|
|
|
])
|
|
|
|
|
|
+ const imagesUri = getUri(webview, this.contextProxy.extensionUri, ["assets", "images"])
|
|
|
+
|
|
|
const file = "src/index.tsx"
|
|
|
const scriptUri = `http://${localServerUrl}/${file}`
|
|
|
|
|
|
@@ -611,7 +624,7 @@ export class ClineProvider extends EventEmitter<ClineProviderEvents> implements
|
|
|
`font-src ${webview.cspSource}`,
|
|
|
`style-src ${webview.cspSource} 'unsafe-inline' https://* http://${localServerUrl} http://0.0.0.0:${localPort}`,
|
|
|
`img-src ${webview.cspSource} data:`,
|
|
|
- `script-src 'unsafe-eval' https://* https://*.posthog.com http://${localServerUrl} http://0.0.0.0:${localPort} 'nonce-${nonce}'`,
|
|
|
+ `script-src 'unsafe-eval' ${webview.cspSource} https://* https://*.posthog.com http://${localServerUrl} http://0.0.0.0:${localPort} 'nonce-${nonce}'`,
|
|
|
`connect-src https://* https://*.posthog.com ws://${localServerUrl} ws://0.0.0.0:${localPort} http://${localServerUrl} http://0.0.0.0:${localPort}`,
|
|
|
]
|
|
|
|
|
|
@@ -624,6 +637,9 @@ export class ClineProvider extends EventEmitter<ClineProviderEvents> implements
|
|
|
<meta http-equiv="Content-Security-Policy" content="${csp.join("; ")}">
|
|
|
<link rel="stylesheet" type="text/css" href="${stylesUri}">
|
|
|
<link href="${codiconsUri}" rel="stylesheet" />
|
|
|
+ <script nonce="${nonce}">
|
|
|
+ window.IMAGES_BASE_URI = "${imagesUri}"
|
|
|
+ </script>
|
|
|
<title>Roo Code</title>
|
|
|
</head>
|
|
|
<body>
|
|
|
@@ -672,6 +688,8 @@ export class ClineProvider extends EventEmitter<ClineProviderEvents> implements
|
|
|
"codicon.css",
|
|
|
])
|
|
|
|
|
|
+ const imagesUri = getUri(webview, this.contextProxy.extensionUri, ["assets", "images"])
|
|
|
+
|
|
|
// const scriptUri = webview.asWebviewUri(vscode.Uri.joinPath(this._extensionUri, "assets", "main.js"))
|
|
|
|
|
|
// const styleResetUri = webview.asWebviewUri(vscode.Uri.joinPath(this._extensionUri, "assets", "reset.css"))
|
|
|
@@ -704,6 +722,9 @@ export class ClineProvider extends EventEmitter<ClineProviderEvents> implements
|
|
|
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; font-src ${webview.cspSource}; style-src ${webview.cspSource} 'unsafe-inline'; img-src ${webview.cspSource} data:; script-src 'nonce-${nonce}' https://us-assets.i.posthog.com; connect-src https://openrouter.ai https://us.i.posthog.com https://us-assets.i.posthog.com;">
|
|
|
<link rel="stylesheet" type="text/css" href="${stylesUri}">
|
|
|
<link href="${codiconsUri}" rel="stylesheet" />
|
|
|
+ <script nonce="${nonce}">
|
|
|
+ window.IMAGES_BASE_URI = "${imagesUri}"
|
|
|
+ </script>
|
|
|
<title>Roo Code</title>
|
|
|
</head>
|
|
|
<body>
|
|
|
@@ -1811,23 +1832,7 @@ export class ClineProvider extends EventEmitter<ClineProviderEvents> implements
|
|
|
break
|
|
|
case "upsertApiConfiguration":
|
|
|
if (message.text && message.apiConfiguration) {
|
|
|
- try {
|
|
|
- await this.configManager.saveConfig(message.text, message.apiConfiguration)
|
|
|
- const listApiConfig = await this.configManager.listConfig()
|
|
|
-
|
|
|
- await Promise.all([
|
|
|
- this.updateGlobalState("listApiConfigMeta", listApiConfig),
|
|
|
- this.updateApiConfiguration(message.apiConfiguration),
|
|
|
- this.updateGlobalState("currentApiConfigName", message.text),
|
|
|
- ])
|
|
|
-
|
|
|
- await this.postStateToWebview()
|
|
|
- } catch (error) {
|
|
|
- this.outputChannel.appendLine(
|
|
|
- `Error create new api configuration: ${JSON.stringify(error, Object.getOwnPropertyNames(error), 2)}`,
|
|
|
- )
|
|
|
- vscode.window.showErrorMessage(t("common:errors.create_api_config"))
|
|
|
- }
|
|
|
+ await this.upsertApiConfiguration(message.text, message.apiConfiguration)
|
|
|
}
|
|
|
break
|
|
|
case "renameApiConfiguration":
|
|
|
@@ -2251,9 +2256,10 @@ export class ClineProvider extends EventEmitter<ClineProviderEvents> implements
|
|
|
// OpenRouter
|
|
|
|
|
|
async handleOpenRouterCallback(code: string) {
|
|
|
+ let { apiConfiguration, currentApiConfigName } = await this.getState()
|
|
|
+
|
|
|
let apiKey: string
|
|
|
try {
|
|
|
- const { apiConfiguration } = await this.getState()
|
|
|
const baseUrl = apiConfiguration.openRouterBaseUrl || "https://openrouter.ai/api/v1"
|
|
|
// Extract the base domain for the auth endpoint
|
|
|
const baseUrlDomain = baseUrl.match(/^(https?:\/\/[^\/]+)/)?.[1] || "https://openrouter.ai"
|
|
|
@@ -2270,17 +2276,15 @@ export class ClineProvider extends EventEmitter<ClineProviderEvents> implements
|
|
|
throw error
|
|
|
}
|
|
|
|
|
|
- const openrouter: ApiProvider = "openrouter"
|
|
|
- await this.contextProxy.setValues({
|
|
|
- apiProvider: openrouter,
|
|
|
+ const newConfiguration: ApiConfiguration = {
|
|
|
+ ...apiConfiguration,
|
|
|
+ apiProvider: "openrouter",
|
|
|
openRouterApiKey: apiKey,
|
|
|
- })
|
|
|
-
|
|
|
- await this.postStateToWebview()
|
|
|
- if (this.getCurrentCline()) {
|
|
|
- this.getCurrentCline()!.api = buildApiHandler({ apiProvider: openrouter, openRouterApiKey: apiKey })
|
|
|
+ openRouterModelId: apiConfiguration?.openRouterModelId || openRouterDefaultModelId,
|
|
|
+ openRouterModelInfo: apiConfiguration?.openRouterModelInfo || openRouterDefaultModelInfo,
|
|
|
}
|
|
|
- // await this.postMessageToWebview({ type: "action", action: "settingsButtonClicked" }) // bad ux if user is on welcome
|
|
|
+
|
|
|
+ await this.upsertApiConfiguration(currentApiConfigName, newConfiguration)
|
|
|
}
|
|
|
|
|
|
// Glama
|
|
|
@@ -2301,19 +2305,55 @@ export class ClineProvider extends EventEmitter<ClineProviderEvents> implements
|
|
|
throw error
|
|
|
}
|
|
|
|
|
|
- const glama: ApiProvider = "glama"
|
|
|
- await this.contextProxy.setValues({
|
|
|
- apiProvider: glama,
|
|
|
+ const { apiConfiguration, currentApiConfigName } = await this.getState()
|
|
|
+
|
|
|
+ const newConfiguration: ApiConfiguration = {
|
|
|
+ ...apiConfiguration,
|
|
|
+ apiProvider: "glama",
|
|
|
glamaApiKey: apiKey,
|
|
|
- })
|
|
|
- await this.postStateToWebview()
|
|
|
- if (this.getCurrentCline()) {
|
|
|
- this.getCurrentCline()!.api = buildApiHandler({
|
|
|
- apiProvider: glama,
|
|
|
- glamaApiKey: apiKey,
|
|
|
- })
|
|
|
+ glamaModelId: apiConfiguration?.glamaModelId || glamaDefaultModelId,
|
|
|
+ glamaModelInfo: apiConfiguration?.glamaModelInfo || glamaDefaultModelInfo,
|
|
|
+ }
|
|
|
+
|
|
|
+ await this.upsertApiConfiguration(currentApiConfigName, newConfiguration)
|
|
|
+ }
|
|
|
+
|
|
|
+ // Requesty
|
|
|
+
|
|
|
+ async handleRequestyCallback(code: string) {
|
|
|
+ let { apiConfiguration, currentApiConfigName } = await this.getState()
|
|
|
+
|
|
|
+ const newConfiguration: ApiConfiguration = {
|
|
|
+ ...apiConfiguration,
|
|
|
+ apiProvider: "requesty",
|
|
|
+ requestyApiKey: code,
|
|
|
+ requestyModelId: apiConfiguration?.requestyModelId || requestyDefaultModelId,
|
|
|
+ requestyModelInfo: apiConfiguration?.requestyModelInfo || requestyDefaultModelInfo,
|
|
|
+ }
|
|
|
+
|
|
|
+ await this.upsertApiConfiguration(currentApiConfigName, newConfiguration)
|
|
|
+ }
|
|
|
+
|
|
|
+ // Save configuration
|
|
|
+
|
|
|
+ async upsertApiConfiguration(configName: string, apiConfiguration: ApiConfiguration) {
|
|
|
+ try {
|
|
|
+ await this.configManager.saveConfig(configName, apiConfiguration)
|
|
|
+ const listApiConfig = await this.configManager.listConfig()
|
|
|
+
|
|
|
+ await Promise.all([
|
|
|
+ this.updateGlobalState("listApiConfigMeta", listApiConfig),
|
|
|
+ this.updateApiConfiguration(apiConfiguration),
|
|
|
+ this.updateGlobalState("currentApiConfigName", configName),
|
|
|
+ ])
|
|
|
+
|
|
|
+ await this.postStateToWebview()
|
|
|
+ } catch (error) {
|
|
|
+ this.outputChannel.appendLine(
|
|
|
+ `Error create new api configuration: ${JSON.stringify(error, Object.getOwnPropertyNames(error), 2)}`,
|
|
|
+ )
|
|
|
+ vscode.window.showErrorMessage(t("common:errors.create_api_config"))
|
|
|
}
|
|
|
- // await this.postMessageToWebview({ type: "action", action: "settingsButtonClicked" }) // bad ux if user is on welcome
|
|
|
}
|
|
|
|
|
|
// Task history
|
|
|
@@ -2627,14 +2667,7 @@ export class ClineProvider extends EventEmitter<ClineProviderEvents> implements
|
|
|
if (stateValues.apiProvider) {
|
|
|
apiProvider = stateValues.apiProvider
|
|
|
} else {
|
|
|
- // Either new user or legacy user that doesn't have the apiProvider stored in state
|
|
|
- // (If they're using OpenRouter or Bedrock, then apiProvider state will exist)
|
|
|
- if (secretValues.apiKey) {
|
|
|
- apiProvider = "anthropic"
|
|
|
- } else {
|
|
|
- // New users should default to openrouter
|
|
|
- apiProvider = "openrouter"
|
|
|
- }
|
|
|
+ apiProvider = "anthropic"
|
|
|
}
|
|
|
|
|
|
// Build the apiConfiguration object combining state values and secrets
|