From 30c04a5427dea0f3db503a09e2f20f234de9598e Mon Sep 17 00:00:00 2001 From: Aditya Sharma <70089590+Aditya-eddy@users.noreply.github.com> Date: Mon, 7 Oct 2024 06:35:48 +0530 Subject: [PATCH] Adding the chatbot screen. (#64) * chore: adding a chatbot screen Signed-off-by: Aditya-eddy * chore:adding example prompts Signed-off-by: Aditya-eddy --------- Signed-off-by: Aditya-eddy --- scripts/utg.sh | 49 ++-- src/SidebarProvider.ts | 66 ++++- src/Utg.ts | 9 +- src/extension.ts | 40 ++- webviews/components/KeployChat.svelte | 402 ++++++++++++++++++++++++++ webviews/pages/KeployChat.ts | 7 + 6 files changed, 543 insertions(+), 30 deletions(-) create mode 100644 webviews/components/KeployChat.svelte create mode 100644 webviews/pages/KeployChat.ts diff --git a/scripts/utg.sh b/scripts/utg.sh index 24fe909..60dff1b 100644 --- a/scripts/utg.sh +++ b/scripts/utg.sh @@ -2,12 +2,11 @@ export API_KEY="1234" - sourceFilePath=$1 testFilePath=$2 coverageReportPath=$3 command=$4 - +additional_prompts=$5 # Get the file extension extension="${sourceFilePath##*.}" @@ -40,26 +39,32 @@ if [ "$extension" = "go" ]; then export PATH=$PATH:$(go env GOPATH)/bin fi -# Add env variables to the npm test command -# utgEnv=" -- --coverage --coverageReporters=text --coverageReporters=cobertura --coverageDirectory=./coverage" - # Construct the keploy gen command if [ "$extension" = "java" ]; then - keploy gen --source-file-path="$sourceFilePath" \ - --test-file-path="$testFilePath" \ - --test-command="$command" \ - --coverage-report-path="$coverageReportPath" \ - --llmApiVersion "2024-02-01" \ - --llmBaseUrl "https://api.keploy.io" \ - --max-iterations "5" \ - --coverageFormat jacoco + keployCommand="keploy gen --source-file-path=\"$sourceFilePath\" \ + --test-file-path=\"$testFilePath\" \ + --test-command=\"$command\" \ + --coverage-report-path=\"$coverageReportPath\" \ + --llmApiVersion \"2024-02-01\" \ + --llmBaseUrl \"https://api.keploy.io\" \ + --max-iterations \"5\" \ + --coverageFormat jacoco" else - keploy gen --source-file-path="$sourceFilePath" \ - --test-file-path="$testFilePath" \ - --test-command="$command" \ - --coverage-report-path="$coverageReportPath" \ - --llmApiVersion "2024-02-01" \ - --llmBaseUrl "https://api.keploy.io" \ - --max-iterations "5" \ - --coverageFormat cobertura -fi \ No newline at end of file + keployCommand="keploy gen --source-file-path=\"$sourceFilePath\" \ + --test-file-path=\"$testFilePath\" \ + --test-command=\"$command\" \ + --coverage-report-path=\"$coverageReportPath\" \ + --llmApiVersion \"2024-02-01\" \ + --llmBaseUrl \"https://api.keploy.io\" \ + --max-iterations \"5\" \ + --coverageFormat cobertura" +fi + +# Add the additional prompt if it's provided and not an empty string +if [ -n "$additional_prompts" ] && [ "$additional_prompts" != " " ]; then + keployCommand="$keployCommand --additional-prompt \"$additional_prompts\"" +fi + +# Run the keploy command +# echo "Running: $keployCommand" +eval $keployCommand diff --git a/src/SidebarProvider.ts b/src/SidebarProvider.ts index 190d568..f597b4a 100644 --- a/src/SidebarProvider.ts +++ b/src/SidebarProvider.ts @@ -65,9 +65,40 @@ export class SidebarProvider implements vscode.WebviewViewProvider { constructor(private readonly _extensionUri: vscode.Uri, private readonly _context: vscode.ExtensionContext) { } - public postMessage(type: any, value: any) { - console.log('postMessage'); - this._view?.webview.postMessage({ type: type, value: value }); + public postMessage(value: any) { + if (!this._view) { + vscode.window.showErrorMessage('Webview is not available'); + return; + } + + let webviewView = this._view; + + try { + console.log('Navigate to ' + value); + let sveltePageJs: vscode.Uri; + let sveltePageCss: vscode.Uri; + if(value = "KeployChatBot"){ + sveltePageJs = webviewView.webview.asWebviewUri( + vscode.Uri.joinPath(this._extensionUri, "out", "compiled", "KeployChat.js") + ); + sveltePageCss = webviewView.webview.asWebviewUri( + vscode.Uri.joinPath(this._extensionUri, "out", "compiled", "KeployChat.css") + ); + + } + else { + throw new Error("Unsupported navigation value"); + } + + // Save the language state + // vscode.getState().then(() => { + // vscode.setState({ language: data.language }); + // }); + + webviewView.webview.html = this._getHtmlForWebview(webviewView.webview, sveltePageCss, sveltePageJs); + } catch (error) { + this._view?.webview.postMessage({ type: 'error', value: `Failed to open page ${error}` }); + } } public resolveWebviewView(webviewView: vscode.WebviewView) { @@ -321,7 +352,16 @@ export class SidebarProvider implements vscode.WebviewViewProvider { sveltePageCss = webviewView.webview.asWebviewUri( vscode.Uri.joinPath(this._extensionUri, "out", "compiled", "KeployHome.css") ); - } else { + }else if(data.value = "KeployChatBot"){ + sveltePageJs = webviewView.webview.asWebviewUri( + vscode.Uri.joinPath(this._extensionUri, "out", "compiled", "KeployChat.js") + ); + sveltePageCss = webviewView.webview.asWebviewUri( + vscode.Uri.joinPath(this._extensionUri, "out", "compiled", "KeployChat.css") + ); + + } + else { throw new Error("Unsupported navigation value"); } @@ -345,6 +385,24 @@ export class SidebarProvider implements vscode.WebviewViewProvider { vscode.window.showErrorMessage('Failed to sign in. Please try again.'); } break; + } + //cannot make it a case of generate unit test as we will taking the input from the user and keploy gen with additional prompts will from a cta hence making a new case for it. + case "keployGenWithAdditionalPrompts":{ + try{ + const additional_prompts = data.prompt; + const editor = vscode.window.activeTextEditor; + if (!editor) { + vscode.window.showErrorMessage("No file is currently open."); + return; + } + + const fileUri = editor.document.uri; + console.log("additional prompts and uri: ", additional_prompts , fileUri); + await vscode.commands.executeCommand('keploy.utg' , fileUri , additional_prompts ); + }catch(error){ + console.error("Error executing keploy.utg command:", error); + } + break; } case "openLink": { diff --git a/src/Utg.ts b/src/Utg.ts index a4de359..49cccc6 100644 --- a/src/Utg.ts +++ b/src/Utg.ts @@ -4,7 +4,7 @@ import * as path from 'path'; import axios, { AxiosResponse } from 'axios'; -async function Utg(context: vscode.ExtensionContext) { +async function Utg(context: vscode.ExtensionContext , additional_prompts?:string) { try { return new Promise(async (resolve, reject) => { @@ -106,7 +106,12 @@ async function Utg(context: vscode.ExtensionContext) { return; } - terminal.sendText(`sh "${scriptPath}" "${sourceFilePath}" "${testFilePath}" "${coverageReportPath}" "${command}";`); + if(!additional_prompts){ + additional_prompts = ""; + } + + + terminal.sendText(`sh "${scriptPath}" "${sourceFilePath}" "${testFilePath}" "${coverageReportPath}" "${command}" "${additional_prompts}";`); const delay = (ms: number) => new Promise(resolve => setTimeout(resolve, ms)); diff --git a/src/extension.ts b/src/extension.ts index 7da3aa6..640c448 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -67,6 +67,11 @@ class KeployCodeLensProvider implements vscode.CodeLensProvider { command: 'keploy.utg', arguments: [document.uri.fsPath] })); + codeLenses.push(new vscode.CodeLens(range, { + title: '🐰 Additional Prompts', + command: 'keploy.showSidebar', + arguments: [document.uri.fsPath] + })); } else if (fileName.endsWith('.js') || fileName.endsWith('.ts')) { if (node.type === 'arrow_function') { const parent = ancestors[ancestors.length - 1]; @@ -78,6 +83,12 @@ class KeployCodeLensProvider implements vscode.CodeLensProvider { command: 'keploy.utg', arguments: [document.uri.fsPath] })); + + codeLenses.push(new vscode.CodeLens(range, { + title: '🐰 Additional Prompts', + command: 'keploy.showSidebar', + arguments: [document.uri.fsPath] + })); } } } else if (fileName.endsWith('.py') && node.type === 'function_definition') { @@ -88,6 +99,11 @@ class KeployCodeLensProvider implements vscode.CodeLensProvider { command: 'keploy.utg', arguments: [document.uri.fsPath] })); + codeLenses.push(new vscode.CodeLens(range, { + title: '🐰 Additional Prompts', + command: 'keploy.showSidebar', + arguments: [document.uri.fsPath] + })); } else if (fileName.endsWith('.java') && (node.type === 'method_declaration' || node.type === 'constructor_declaration')) { const line = document.positionAt(node.startIndex).line; const range = new vscode.Range(line, 0, line, 0); @@ -96,6 +112,11 @@ class KeployCodeLensProvider implements vscode.CodeLensProvider { command: 'keploy.utg', arguments: [document.uri.fsPath] })); + codeLenses.push(new vscode.CodeLens(range, { + title: '🐰 Additional Prompts', + command: 'keploy.showSidebar', + arguments: [document.uri.fsPath] + })); } else if (fileName.endsWith('.go') && (node.type === 'function_declaration' || node.type === 'method_declaration')) { const line = document.positionAt(node.startIndex).line; const range = new vscode.Range(line, 0, line, 0); @@ -104,6 +125,11 @@ class KeployCodeLensProvider implements vscode.CodeLensProvider { command: 'keploy.utg', arguments: [document.uri.fsPath] })); + codeLenses.push(new vscode.CodeLens(range, { + title: '🐰 Additional Prompts', + command: 'keploy.showSidebar', + arguments: [document.uri.fsPath] + })); } // Traverse to the first child node @@ -357,8 +383,18 @@ export function activate(context: vscode.ExtensionContext) { context.subscriptions.push(updateKeployDisposable); + let showSidebarDisposable = vscode.commands.registerCommand('keploy.showSidebar', async () => { + // Show the sidebar when this command is executed + vscode.commands.executeCommand('workbench.view.extension.Keploy-Sidebar'); + sidebarProvider.postMessage("KeployChatBot") + vscode.window.showInformationMessage('Sidebar opened for additional prompts.'); + }); + + context.subscriptions.push(showSidebarDisposable); + + // Register the command - let disposable = vscode.commands.registerCommand('keploy.utg', async (uri: vscode.Uri) => { + let disposable = vscode.commands.registerCommand('keploy.utg', async (uri: vscode.Uri , additional_prompts?:string) => { // Check if the user is already signed in const signedIn = await context.globalState.get('accessToken'); const signedInOthers = await context.globalState.get('SignedOthers'); @@ -400,7 +436,7 @@ export function activate(context: vscode.ExtensionContext) { if (updatedSubscriptionEnded === false) { // If SubscriptionEnded is false or undefined, continue running Utg vscode.window.showInformationMessage('Welcome to Keploy!'); - await Utg(context); + await Utg(context , additional_prompts); } } }); diff --git a/webviews/components/KeployChat.svelte b/webviews/components/KeployChat.svelte new file mode 100644 index 0000000..b72c443 --- /dev/null +++ b/webviews/components/KeployChat.svelte @@ -0,0 +1,402 @@ + + + + +
+
+

Keploy Chatbot

+ +
+ +
+
+ + +

Hey, there

+

How can I help you today?

+
+ +
+ + + +
+ + +
+ + + + + + + + + + + + + + + + + + +
+
+
diff --git a/webviews/pages/KeployChat.ts b/webviews/pages/KeployChat.ts new file mode 100644 index 0000000..b110ee8 --- /dev/null +++ b/webviews/pages/KeployChat.ts @@ -0,0 +1,7 @@ +import App from "../components/KeployChat.svelte"; + +const app = new App({ + target: document.body, +}); + +export default app; \ No newline at end of file