mirror of
https://github.com/pacnpal/Roo-Code.git
synced 2025-12-20 04:11:10 -05:00
feat(vscode-lm): implement VS Code Language Models provider
This commit is contained in:
@@ -41,6 +41,7 @@ type SecretKey =
|
||||
| "geminiApiKey"
|
||||
| "openAiNativeApiKey"
|
||||
| "deepSeekApiKey"
|
||||
|
||||
type GlobalStateKey =
|
||||
| "apiProvider"
|
||||
| "apiModelId"
|
||||
@@ -79,6 +80,8 @@ type GlobalStateKey =
|
||||
| "writeDelayMs"
|
||||
| "terminalOutputLineLimit"
|
||||
| "mcpEnabled"
|
||||
| "vsCodeLmModelSelector"
|
||||
|
||||
export const GlobalFileNames = {
|
||||
apiConversationHistory: "api_conversation_history.json",
|
||||
uiMessages: "ui_messages.json",
|
||||
@@ -228,7 +231,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
||||
diffEnabled,
|
||||
fuzzyMatchThreshold
|
||||
} = await this.getState()
|
||||
|
||||
|
||||
this.cline = new Cline(
|
||||
this,
|
||||
apiConfiguration,
|
||||
@@ -248,7 +251,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
||||
diffEnabled,
|
||||
fuzzyMatchThreshold
|
||||
} = await this.getState()
|
||||
|
||||
|
||||
this.cline = new Cline(
|
||||
this,
|
||||
apiConfiguration,
|
||||
@@ -314,15 +317,15 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
||||
|
||||
// Use a nonce to only allow a specific script to be run.
|
||||
/*
|
||||
content security policy of your webview to only allow scripts that have a specific nonce
|
||||
create a content security policy meta tag so that only loading scripts with a nonce is allowed
|
||||
As your extension grows you will likely want to add custom styles, fonts, and/or images to your webview. If you do, you will need to update the content security policy meta tag to explicity allow for these resources. E.g.
|
||||
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; style-src ${webview.cspSource}; font-src ${webview.cspSource}; img-src ${webview.cspSource} https:; script-src 'nonce-${nonce}';">
|
||||
content security policy of your webview to only allow scripts that have a specific nonce
|
||||
create a content security policy meta tag so that only loading scripts with a nonce is allowed
|
||||
As your extension grows you will likely want to add custom styles, fonts, and/or images to your webview. If you do, you will need to update the content security policy meta tag to explicity allow for these resources. E.g.
|
||||
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; style-src ${webview.cspSource}; font-src ${webview.cspSource}; img-src ${webview.cspSource} https:; script-src 'nonce-${nonce}';">
|
||||
- 'unsafe-inline' is required for styles due to vscode-webview-toolkit's dynamic style injection
|
||||
- since we pass base64 images to the webview, we need to specify img-src ${webview.cspSource} data:;
|
||||
|
||||
in meta tag we add nonce attribute: A cryptographic nonce (only used once) to allow scripts. The server must generate a unique nonce value each time it transmits a policy. It is critical to provide a nonce that cannot be guessed as bypassing a resource's policy is otherwise trivial.
|
||||
*/
|
||||
in meta tag we add nonce attribute: A cryptographic nonce (only used once) to allow scripts. The server must generate a unique nonce value each time it transmits a policy. It is critical to provide a nonce that cannot be guessed as bypassing a resource's policy is otherwise trivial.
|
||||
*/
|
||||
const nonce = getNonce()
|
||||
|
||||
// Tip: Install the es6-string-html VS Code extension to enable code highlighting below
|
||||
@@ -426,6 +429,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
||||
openRouterModelId,
|
||||
openRouterModelInfo,
|
||||
openRouterUseMiddleOutTransform,
|
||||
vsCodeLmModelSelector,
|
||||
} = message.apiConfiguration
|
||||
await this.updateGlobalState("apiProvider", apiProvider)
|
||||
await this.updateGlobalState("apiModelId", apiModelId)
|
||||
@@ -454,6 +458,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
||||
await this.updateGlobalState("openRouterModelId", openRouterModelId)
|
||||
await this.updateGlobalState("openRouterModelInfo", openRouterModelInfo)
|
||||
await this.updateGlobalState("openRouterUseMiddleOutTransform", openRouterUseMiddleOutTransform)
|
||||
await this.updateGlobalState("vsCodeLmModelSelector", vsCodeLmModelSelector)
|
||||
if (this.cline) {
|
||||
this.cline.api = buildApiHandler(message.apiConfiguration)
|
||||
}
|
||||
@@ -525,6 +530,10 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
||||
const lmStudioModels = await this.getLmStudioModels(message.text)
|
||||
this.postMessageToWebview({ type: "lmStudioModels", lmStudioModels })
|
||||
break
|
||||
case "requestVsCodeLmModels":
|
||||
const vsCodeLmModels = await this.getVsCodeLmModels()
|
||||
this.postMessageToWebview({ type: "vsCodeLmModels", vsCodeLmModels })
|
||||
break
|
||||
case "refreshOpenRouterModels":
|
||||
await this.refreshOpenRouterModels()
|
||||
break
|
||||
@@ -532,7 +541,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
||||
if (message?.values?.baseUrl && message?.values?.apiKey) {
|
||||
const openAiModels = await this.getOpenAiModels(message?.values?.baseUrl, message?.values?.apiKey)
|
||||
this.postMessageToWebview({ type: "openAiModels", openAiModels })
|
||||
}
|
||||
}
|
||||
break
|
||||
case "openImage":
|
||||
openImage(message.text!)
|
||||
@@ -664,7 +673,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
||||
)
|
||||
if (answer === "Yes" && this.cline && typeof message.value === 'number' && message.value) {
|
||||
const timeCutoff = message.value - 1000; // 1 second buffer before the message to delete
|
||||
const messageIndex = this.cline.clineMessages.findIndex(msg => msg.ts && msg.ts >= timeCutoff)
|
||||
const messageIndex = this.cline.clineMessages.findIndex(msg => msg.ts && msg.ts >= timeCutoff)
|
||||
const apiConversationHistoryIndex = this.cline.apiConversationHistory.findIndex(msg => msg.ts && msg.ts >= timeCutoff)
|
||||
if (messageIndex !== -1) {
|
||||
const { historyItem } = await this.getTaskWithId(this.cline.taskId)
|
||||
@@ -773,6 +782,17 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
||||
}
|
||||
}
|
||||
|
||||
// VSCode LM API
|
||||
private async getVsCodeLmModels() {
|
||||
try {
|
||||
const models = await vscode.lm.selectChatModels({});
|
||||
return models || [];
|
||||
} catch (error) {
|
||||
console.error('Error fetching VS Code LM models:', error);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
// OpenAi
|
||||
|
||||
async getOpenAiModels(baseUrl?: string, apiKey?: string) {
|
||||
@@ -1042,9 +1062,9 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
||||
}
|
||||
|
||||
async getStateToPostToWebview() {
|
||||
const {
|
||||
apiConfiguration,
|
||||
lastShownAnnouncementId,
|
||||
const {
|
||||
apiConfiguration,
|
||||
lastShownAnnouncementId,
|
||||
customInstructions,
|
||||
alwaysAllowReadOnly,
|
||||
alwaysAllowWrite,
|
||||
@@ -1063,7 +1083,8 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
||||
fuzzyMatchThreshold,
|
||||
mcpEnabled,
|
||||
} = await this.getState()
|
||||
|
||||
|
||||
|
||||
const allowedCommands = vscode.workspace
|
||||
.getConfiguration('roo-cline')
|
||||
.get<string[]>('allowedCommands') || []
|
||||
@@ -1196,6 +1217,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
||||
screenshotQuality,
|
||||
terminalOutputLineLimit,
|
||||
mcpEnabled,
|
||||
vsCodeLmModelSelector,
|
||||
] = await Promise.all([
|
||||
this.getGlobalState("apiProvider") as Promise<ApiProvider | undefined>,
|
||||
this.getGlobalState("apiModelId") as Promise<string | undefined>,
|
||||
@@ -1243,6 +1265,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
||||
this.getGlobalState("screenshotQuality") as Promise<number | undefined>,
|
||||
this.getGlobalState("terminalOutputLineLimit") as Promise<number | undefined>,
|
||||
this.getGlobalState("mcpEnabled") as Promise<boolean | undefined>,
|
||||
this.getGlobalState("vsCodeLmModelSelector") as Promise<vscode.LanguageModelChatSelector | undefined>,
|
||||
])
|
||||
|
||||
let apiProvider: ApiProvider
|
||||
@@ -1288,6 +1311,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
||||
openRouterModelId,
|
||||
openRouterModelInfo,
|
||||
openRouterUseMiddleOutTransform,
|
||||
vsCodeLmModelSelector,
|
||||
},
|
||||
lastShownAnnouncementId,
|
||||
customInstructions,
|
||||
|
||||
Reference in New Issue
Block a user