allowed urls updating when configuration changes

This commit is contained in:
w1gs
2024-09-21 04:56:41 -04:00
parent f29f347a4a
commit 5204cfbb86
6 changed files with 80 additions and 28 deletions
+46 -19
View File
@@ -18,6 +18,8 @@ export class SidebarWebviewProvider implements vscode.WebviewViewProvider {
private readonly _extensionUri: vscode.Uri
private _res: (c: vscode.Webview) => void // used to resolve the webview
private allowed_urls: string[] = ['https://api.anthropic.com', 'https://api.openai.com', 'https://api.greptile.com', 'http://localhost:11434'];
private _webviewView?: vscode.WebviewView;
constructor(context: vscode.ExtensionContext) {
// const extensionPath = context.extensionPath // the directory where the extension is installed, might be useful later, not sure for what though... was included in webviewProvider code
@@ -27,6 +29,45 @@ export class SidebarWebviewProvider implements vscode.WebviewViewProvider {
this.webview = new Promise((res, rej) => { temp_res = res })
if (!temp_res) throw new Error("sidebar provider: resolver was undefined")
this._res = temp_res
vscode.workspace.onDidChangeConfiguration(event => {
if (event.affectsConfiguration('void.ollamaSettings.endpoint')) {
this.updateAllowedUrls();
// Regenerate the webview's HTML content
if (this._webviewView) {
this._webviewView.webview.html = this.getWebviewContent(this._webviewView.webview);
}
}
});
}
private getWebviewContent(webview: vscode.Webview): string {
const scriptUri = webview.asWebviewUri(vscode.Uri.joinPath(this._extensionUri, 'dist/sidebar/index.js'));
const stylesUri = webview.asWebviewUri(vscode.Uri.joinPath(this._extensionUri, 'dist/sidebar/styles.css'));
const rootUri = webview.asWebviewUri(vscode.Uri.joinPath(this._extensionUri));
const nonce = getNonce();
const allowed_urls = this.allowed_urls;
return `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Custom View</title>
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; connect-src ${allowed_urls.join(' ')}; img-src vscode-resource: https:; script-src 'nonce-${nonce}'; style-src vscode-resource: 'unsafe-inline' http: https: data:;">
<base href="${rootUri}/">
<link href="${stylesUri}" rel="stylesheet">
</head>
<body>
<div id="root"></div>
<script nonce="${nonce}" src="${scriptUri}"></script>
</body>
</html>`;
}
private updateAllowedUrls() {
const ollamaEndpoint: string = vscode.workspace.getConfiguration('void').get('ollamaSettings.endpoint') || 'http://localhost:11434';
this.allowed_urls = ['https://api.anthropic.com', 'https://api.openai.com', 'https://api.greptile.com', ollamaEndpoint];
}
// called internally by vscode
@@ -35,6 +76,7 @@ export class SidebarWebviewProvider implements vscode.WebviewViewProvider {
context: vscode.WebviewViewResolveContext,
token: vscode.CancellationToken,
) {
this._webviewView = webviewView;
const webview = webviewView.webview
@@ -54,25 +96,10 @@ export class SidebarWebviewProvider implements vscode.WebviewViewProvider {
const nonce = getNonce(); // only scripts with the nonce are allowed to run, this is a recommended security measure
// Allow Ollama endpoint
const ollamaEndpoint = vscode.workspace.getConfiguration('void').get('ollamaSettings.endpoint') || 'http://localhost:11434'
const allowed_urls = ['https://api.anthropic.com', 'https://api.openai.com', 'https://api.greptile.com', ollamaEndpoint ]
webview.html = `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Custom View</title>
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; connect-src ${allowed_urls.join(' ')}; img-src vscode-resource: https:; script-src 'nonce-${nonce}';style-src vscode-resource: 'unsafe-inline' http: https: data:;">
<base href="${rootUri}/">
<link href="${stylesUri}" rel="stylesheet">
</head>
<body>
<div id="root"></div>
<script nonce="${nonce}" src="${scriptUri}"></script>
</body>
</html>`;
// Regenerate the Sidebar html whenever the allowed_urls changes
this.updateAllowedUrls();
const allowed_urls = this.allowed_urls;
webview.html = this.getWebviewContent(webview);
this._res(webview);
}
+19 -4
View File
@@ -1,6 +1,8 @@
import Anthropic from '@anthropic-ai/sdk';
import OpenAI from 'openai';
import { Ollama } from 'ollama/browser'
import { getVSCodeAPI } from '../sidebar/getVscodeApi';
export type ApiConfig = {
anthropic: {
@@ -220,9 +222,21 @@ const sendGreptileMsg: SendLLMMessageFnTypeInternal = ({ messages, onText, onFin
export const sendLLMMessage: SendLLMMessageFnTypeExternal = ({ messages, onText, onFinalMessage, apiConfig }) => {
if (!apiConfig) return { abort: () => { } }
const whichApi = apiConfig.whichApi;
if (
apiConfig.anthropic.apikey === "" &&
apiConfig.greptile.apikey === "" &&
apiConfig.openai.apikey === "" &&
apiConfig.ollama.endpoint === "" &&
apiConfig.ollama.model === ""
) {
getVSCodeAPI().postMessage({ type: 'displayError', message: 'Required API keys are not set.' })
onFinalMessage("Required API keys are not set.");
return { abort: () => { }}
}
switch (whichApi) {
switch (apiConfig.whichApi) {
case 'anthropic':
return sendClaudeMsg({ messages, onText, onFinalMessage, apiConfig });
case 'openai':
@@ -232,8 +246,9 @@ export const sendLLMMessage: SendLLMMessageFnTypeExternal = ({ messages, onText,
case 'ollama':
return sendOllamaMsg({ messages, onText, onFinalMessage, apiConfig });
default:
console.error(`Error: whichApi was ${whichApi}, which is not recognized!`);
return sendClaudeMsg({ messages, onText, onFinalMessage, apiConfig }); // TODO
console.error(`Error: whichApi was ${apiConfig.whichApi}, which is not recognized!`);
return { abort: () => { } }
//return sendClaudeMsg({ messages, onText, onFinalMessage, apiConfig }); // TODO
}
}
+5 -2
View File
@@ -33,6 +33,7 @@ const getApiConfig = () => {
return apiConfig
}
export function activate(context: vscode.ExtensionContext) {
// 1. Mount the chat sidebar
@@ -116,14 +117,16 @@ export function activate(context: vscode.ExtensionContext) {
const oldContents = await readFileContentOfUri(editor.document.uri)
const suggestedEdits = getDiffedLines(oldContents, m.code)
await approvalCodeLensProvider.addNewApprovals(editor, suggestedEdits)
}
else if (m.type === 'getApiConfig') {
} else if (m.type === 'getApiConfig') {
const apiConfig = getApiConfig()
console.log('Api config:', apiConfig)
webview.postMessage({ type: 'apiConfig', apiConfig } satisfies WebviewMessage)
} else if (m.type === 'displayError') {
vscode.window.showWarningMessage(m.message, { modal: true });
}
else {
+3
View File
@@ -27,6 +27,9 @@ type WebviewMessage = (
// editor -> sidebar
| { type: 'apiConfig', apiConfig: ApiConfig }
// Display native vscode error
| { type: 'displayError', message: string } //
)
type Command = WebviewMessage['type']
+5 -2
View File
@@ -166,6 +166,7 @@ const Sidebar = () => {
// if user pressed ctrl+l, add their selection to the sidebar
if (m.type === 'ctrl+l') {
setSelection(m.selection)
const filepath = m.selection.filePath
@@ -223,10 +224,12 @@ const Sidebar = () => {
},
apiConfig: apiConfig
})
abortFnRef.current = abort
abortFnRef.current = abort
}
const onStop = useCallback(() => {
// abort claude
abortFnRef.current?.()
@@ -266,7 +269,7 @@ const Sidebar = () => {
{!selection?.selectionStr ? null
: (
<div className="relative">
<button
<button
onClick={clearSelection}
className="absolute top-2 right-2 text-white hover:text-gray-300 z-10"
>
+2 -1
View File
@@ -9,7 +9,8 @@ const awaiting: { [c in Command]: ((res: any) => void)[] } = {
"requestFiles": [],
"files": [],
"apiConfig": [],
"getApiConfig": []
"getApiConfig": [],
"displayError": []
}
// use this function to await responses