diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/BootJavaLanguageServerComponents.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/BootJavaLanguageServerComponents.java index 3189437c4..2f21f605a 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/BootJavaLanguageServerComponents.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/BootJavaLanguageServerComponents.java @@ -56,6 +56,7 @@ import org.springframework.ide.vscode.boot.java.requestmapping.LiveAppURLSymbolP import org.springframework.ide.vscode.boot.java.requestmapping.RequestMappingHoverProvider; import org.springframework.ide.vscode.boot.java.requestmapping.WebfluxHandlerCodeLensProvider; import org.springframework.ide.vscode.boot.java.requestmapping.WebfluxRouteHighlightProdivder; +import org.springframework.ide.vscode.boot.java.spel.SpelSemanticTokens; import org.springframework.ide.vscode.boot.java.utils.CompilationUnitCache; import org.springframework.ide.vscode.boot.java.utils.SpringLiveChangeDetectionWatchdog; import org.springframework.ide.vscode.boot.java.value.ValueHoverProvider; @@ -118,6 +119,7 @@ public class BootJavaLanguageServerComponents implements LanguageServerComponent private DocumentSymbolHandler docSymbolProvider; private JdtSemanticTokensHandler semanticTokensHandler; private JdtInlayHintsHandler inlayHintsHandler; + private SpelSemanticTokens spelSemanticTokens; public BootJavaLanguageServerComponents(ApplicationContext appContext) { this.server = appContext.getBean(SimpleLanguageServer.class); @@ -175,8 +177,10 @@ public class BootJavaLanguageServerComponents implements LanguageServerComponent projectFinder, Duration.ofSeconds(5), sourceLinks); + + spelSemanticTokens = appContext.getBean(SpelSemanticTokens.class); - codeLensHandler = createCodeLensEngine(springSymbolIndex, projectFinder, server); + codeLensHandler = createCodeLensEngine(springSymbolIndex, projectFinder, server, spelSemanticTokens); highlightsEngine = createDocumentHighlightEngine(appContext); documents.onDocumentHighlight(highlightsEngine); @@ -312,10 +316,10 @@ public class BootJavaLanguageServerComponents implements LanguageServerComponent return new BootJavaReferencesHandler(this, cuCache, projectFinder, providers); } - protected BootJavaCodeLensEngine createCodeLensEngine(SpringSymbolIndex index, JavaProjectFinder projectFinder, SimpleLanguageServer server) { + protected BootJavaCodeLensEngine createCodeLensEngine(SpringSymbolIndex index, JavaProjectFinder projectFinder, SimpleLanguageServer server, SpelSemanticTokens spelSemanticTokens) { Collection codeLensProvider = new ArrayList<>(); codeLensProvider.add(new WebfluxHandlerCodeLensProvider(index)); - codeLensProvider.add(new QueryCodeLensProvider(projectFinder, server)); + codeLensProvider.add(new QueryCodeLensProvider(projectFinder, server, spelSemanticTokens)); return new BootJavaCodeLensEngine(this, codeLensProvider); } diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/handlers/QueryCodeLensProvider.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/handlers/QueryCodeLensProvider.java index e4d1773d4..43c198d92 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/handlers/QueryCodeLensProvider.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/handlers/QueryCodeLensProvider.java @@ -10,26 +10,35 @@ *******************************************************************************/ package org.springframework.ide.vscode.boot.java.handlers; +import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.List; import java.util.Optional; +import java.util.Set; import java.util.concurrent.CompletableFuture; +import java.util.stream.Collectors; import org.eclipse.jdt.core.dom.ASTVisitor; import org.eclipse.jdt.core.dom.Annotation; import org.eclipse.jdt.core.dom.CompilationUnit; import org.eclipse.jdt.core.dom.Expression; import org.eclipse.jdt.core.dom.MemberValuePair; +import org.eclipse.jdt.core.dom.MethodDeclaration; import org.eclipse.jdt.core.dom.NormalAnnotation; import org.eclipse.jdt.core.dom.SingleMemberAnnotation; import org.eclipse.lsp4j.CodeLens; import org.eclipse.lsp4j.Command; import org.eclipse.lsp4j.jsonrpc.CancelChecker; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.ide.vscode.boot.java.spel.AnnotationParamSpelExtractor; import org.springframework.ide.vscode.boot.java.spel.AnnotationParamSpelExtractor.Snippet; +import org.springframework.ide.vscode.boot.java.spel.SpelSemanticTokens; import org.springframework.ide.vscode.commons.java.IJavaProject; import org.springframework.ide.vscode.commons.java.SpringProjectUtil; import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder; +import org.springframework.ide.vscode.commons.languageserver.semantic.tokens.SemanticTokenData; import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer; import org.springframework.ide.vscode.commons.util.BadLocationException; import org.springframework.ide.vscode.commons.util.text.TextDocument; @@ -42,39 +51,37 @@ import com.google.gson.JsonPrimitive; */ public class QueryCodeLensProvider implements CodeLensProvider { - + protected static Logger logger = LoggerFactory.getLogger(QueryCodeLensProvider.class); + public static final String CMD_ENABLE_COPILOT_FEATURES = "sts/enable/copilot/features"; - public static final String EXPLAIN_SPEL_TITLE = "Explain Spel Expression using Copilot"; - public static final String EXPLAIN_QUERY_TITLE = "Explain Query using Copilot"; - + private static final String QUERY = "Query"; private static final String FQN_QUERY = "org.springframework.data.jpa.repository." + QUERY; - private static final String SPEL_EXPRESSION_QUERY_PROMPT = "Explain the following SpEL Expression in detail: \n"; - private static final String JPQL_QUERY_PROMPT = "Explain the following JPQL query in detail. If the query contains any SpEL expressions, explain those parts as well: \n"; - private static final String HQL_QUERY_PROMPT = "Explain the following HQL query in detail. If the query contains any SpEL expressions, explain those parts as well: \n"; - private static final String DEFAULT_QUERY_PROMPT = "Explain the following query in detail: \n"; - private static final String CMD = "vscode-spring-boot.query.explain"; - + private static final String CMD = "vscode-spring-boot.query.explain"; + private final AnnotationParamSpelExtractor[] spelExtractors = AnnotationParamSpelExtractor.SPEL_EXTRACTORS; - + private final JavaProjectFinder projectFinder; + private SpelSemanticTokens spelSemanticTokens; + private static boolean showCodeLenses; - - public QueryCodeLensProvider(JavaProjectFinder projectFinder, SimpleLanguageServer server) { + + public QueryCodeLensProvider(JavaProjectFinder projectFinder, SimpleLanguageServer server, SpelSemanticTokens spelSemanticTokens) { this.projectFinder = projectFinder; + this.spelSemanticTokens = spelSemanticTokens; server.onCommand(CMD_ENABLE_COPILOT_FEATURES, params -> { if (params.getArguments().get(0) instanceof JsonPrimitive) { - QueryCodeLensProvider.showCodeLenses = ((JsonPrimitive)params.getArguments().get(0)).getAsBoolean(); + QueryCodeLensProvider.showCodeLenses = ((JsonPrimitive) params.getArguments().get(0)).getAsBoolean(); } - return CompletableFuture.completedFuture(showCodeLenses); + return CompletableFuture.completedFuture(showCodeLenses); }); } @Override public void provideCodeLenses(CancelChecker cancelToken, TextDocument document, CompilationUnit cu, List resultAccumulator) { - if(!showCodeLenses) { + if (!showCodeLenses) { return; } cu.accept(new ASTVisitor() { @@ -83,12 +90,15 @@ public class QueryCodeLensProvider implements CodeLensProvider { public boolean visit(SingleMemberAnnotation node) { Arrays.stream(spelExtractors).map(e -> e.getSpelRegion(node)).filter(o -> o.isPresent()) .map(o -> o.get()).forEach(snippet -> { - provideCodeLensForSpelExpression(cancelToken, node, document, snippet, resultAccumulator); + String additionalContext = parseSpelAndFetchContext(cu, snippet.text()); + provideCodeLensForSpelExpression(cancelToken, node, document, snippet, + additionalContext, resultAccumulator); }); if (isQueryAnnotation(node)) { String queryPrompt = determineQueryPrompt(document); - provideCodeLensForQuery(cancelToken, node, document, node.getValue(), queryPrompt, resultAccumulator); + provideCodeLensForQuery(cancelToken, node, document, node.getValue(), queryPrompt, + resultAccumulator); } return super.visit(node); @@ -96,9 +106,13 @@ public class QueryCodeLensProvider implements CodeLensProvider { @Override public boolean visit(NormalAnnotation node) { + + Arrays.stream(spelExtractors).map(e -> e.getSpelRegion(node)).filter(o -> o.isPresent()) .map(o -> o.get()).forEach(snippet -> { - provideCodeLensForSpelExpression(cancelToken, node, document, snippet, resultAccumulator); + String additionalContext = parseSpelAndFetchContext(cu, snippet.text()); + provideCodeLensForSpelExpression(cancelToken, node, document, snippet, additionalContext, + resultAccumulator); }); if (isQueryAnnotation(node)) { @@ -107,7 +121,8 @@ public class QueryCodeLensProvider implements CodeLensProvider { if (value instanceof MemberValuePair) { MemberValuePair pair = (MemberValuePair) value; if ("value".equals(pair.getName().getIdentifier())) { - provideCodeLensForQuery(cancelToken, node, document, pair.getValue(), queryPrompt, resultAccumulator); + provideCodeLensForQuery(cancelToken, node, document, pair.getValue(), queryPrompt, + resultAccumulator); break; } } @@ -119,20 +134,26 @@ public class QueryCodeLensProvider implements CodeLensProvider { }); } - protected void provideCodeLensForSpelExpression(CancelChecker cancelToken, Annotation node, TextDocument document, Snippet snippet, - List resultAccumulator) { + protected void provideCodeLensForSpelExpression(CancelChecker cancelToken, Annotation node, TextDocument document, + Snippet snippet, String additionalContext, List resultAccumulator) { cancelToken.checkCanceled(); if (snippet != null) { try { + String context = additionalContext != null && !additionalContext.isEmpty() ? String.format( + """ + Finally, provide a brief summary of what the following method does, focusing on its role within the SpEL expression. + The summary should mention key criteria the method checks but avoid detailed implementation steps. + Please include this summary as an appendix to the main explanation, and avoid repeating information covered earlier.\n\n%s + """,additionalContext) : ""; CodeLens codeLens = new CodeLens(); codeLens.setRange(document.toRange(snippet.offset(), snippet.text().length())); Command cmd = new Command(); - cmd.setTitle(EXPLAIN_SPEL_TITLE); + cmd.setTitle(QueryType.SPEL.getTitle()); cmd.setCommand(CMD); - cmd.setArguments(ImmutableList.of(SPEL_EXPRESSION_QUERY_PROMPT + snippet.text())); + cmd.setArguments(ImmutableList.of(QueryType.SPEL.getPrompt() + snippet.text() + "\n\n" + context)); codeLens.setCommand(cmd); resultAccumulator.add(codeLens); @@ -153,14 +174,14 @@ public class QueryCodeLensProvider implements CodeLensProvider { codeLens.setRange(document.toRange(valueExp.getStartPosition(), valueExp.getLength())); Command cmd = new Command(); - cmd.setTitle(EXPLAIN_QUERY_TITLE); + cmd.setTitle(QueryType.DEFAULT.getTitle()); cmd.setCommand(CMD); cmd.setArguments(ImmutableList.of(query + valueExp.toString())); codeLens.setCommand(cmd); resultAccumulator.add(codeLens); } catch (BadLocationException e) { - e.printStackTrace(); + logger.error("Error providing code lens: " + e.getMessage()); } } } @@ -169,14 +190,52 @@ public class QueryCodeLensProvider implements CodeLensProvider { return FQN_QUERY.equals(a.getTypeName().getFullyQualifiedName()) || QUERY.equals(a.getTypeName().getFullyQualifiedName()); } - + private String determineQueryPrompt(TextDocument document) { - Optional optProject = projectFinder.find(document.getId()); - if (optProject.isPresent()) { - IJavaProject jp = optProject.get(); - return SpringProjectUtil.hasDependencyStartingWith(jp, "hibernate-core", null) ? HQL_QUERY_PROMPT : JPQL_QUERY_PROMPT; - } - return DEFAULT_QUERY_PROMPT; + Optional optProject = projectFinder.find(document.getId()); + if (optProject.isPresent()) { + IJavaProject jp = optProject.get(); + return SpringProjectUtil.hasDependencyStartingWith(jp, "hibernate-core", null) ? QueryType.HQL.getPrompt() + : QueryType.JPQL.getPrompt(); + } + return QueryType.DEFAULT.getPrompt(); + } + + private String parseSpelAndFetchContext(CompilationUnit cu, String spelExpression) { + List tokens = parseSpelExpression(spelExpression); + Set methodNames = extractMethodNames(tokens, spelExpression); + List context = collectMethodContexts(methodNames, cu); + return String.join("\n", context); + } + + private List parseSpelExpression(String spelText) { + try { + return spelSemanticTokens.computeTokens(spelText, 0); + } catch (Exception e) { + logger.error("Error computing tokens: " + e.getMessage()); + return Collections.emptyList(); + } + } + + private static Set extractMethodNames(List tokens, String spelText) { + return tokens.stream().filter(token -> "method".equals(token.type())) + .map(token -> spelText.substring(token.start(), token.end())).collect(Collectors.toSet()); + } + + private List collectMethodContexts(Set methodNames, CompilationUnit cu) { + List methodContext = new ArrayList<>(); + for (String methodName : methodNames) { + cu.accept(new ASTVisitor() { + @Override + public boolean visit(MethodDeclaration node) { + if (node.getName().getIdentifier().equals(methodName)) { + methodContext.add(node.toString()); + } + return super.visit(node); + } + }); + } + return methodContext; } } \ No newline at end of file diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/handlers/QueryType.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/handlers/QueryType.java new file mode 100644 index 000000000..feb6f3ffc --- /dev/null +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/handlers/QueryType.java @@ -0,0 +1,24 @@ +package org.springframework.ide.vscode.boot.java.handlers; + +public enum QueryType { + SPEL("Explain SpEL Expression using Copilot", "Explain the following SpEL Expression with a clear summary first, followed by a breakdown of the expression with details: \n\n"), + JPQL("Explain Query using Copilot", "Explain the following JPQL query with a clear summary first, followed by a detailed explanation. If the query contains any SpEL expressions, explain those parts as well: \n\n"), + HQL("Explain Query using Copilot", "Explain the following HQL query with a clear summary first, followed by a detailed explanation. If the query contains any SpEL expressions, explain those parts as well: \n\n"), + DEFAULT("Explain Query using Copilot", "Explain the following query with a clear summary first, followed by a detailed explanation: \n\n"); + + private final String title; + private final String prompt; + + QueryType(String title, String prompt) { + this.title = title; + this.prompt = prompt; + } + + public String getTitle() { + return title; + } + + public String getPrompt() { + return prompt; + } +} diff --git a/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/handlers/test/QueryCodeLensProviderTest.java b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/handlers/test/QueryCodeLensProviderTest.java index 301047caf..ead394037 100644 --- a/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/handlers/test/QueryCodeLensProviderTest.java +++ b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/handlers/test/QueryCodeLensProviderTest.java @@ -39,6 +39,8 @@ import org.springframework.ide.vscode.boot.app.SpringSymbolIndex; import org.springframework.ide.vscode.boot.bootiful.BootLanguageServerTest; import org.springframework.ide.vscode.boot.bootiful.SymbolProviderTestConf; import org.springframework.ide.vscode.boot.java.handlers.QueryCodeLensProvider; +import org.springframework.ide.vscode.boot.java.handlers.QueryType; +import org.springframework.ide.vscode.boot.java.spel.SpelSemanticTokens; import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder; import org.springframework.ide.vscode.commons.languageserver.util.ExecuteCommandHandler; import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer; @@ -66,6 +68,9 @@ public class QueryCodeLensProviderTest { @Autowired private SpringSymbolIndex indexer; private SimpleLanguageServer server; + + @Autowired + private SpelSemanticTokens spelSemanticTokens; private ArgumentCaptor commandHandlerCaptor; private QueryCodeLensProvider queryCodeLensProvider; @@ -78,7 +83,7 @@ public class QueryCodeLensProviderTest { String projectDir = directory.toURI().toString(); server = mock(SimpleLanguageServer.class); commandHandlerCaptor = ArgumentCaptor.forClass(ExecuteCommandHandler.class); - queryCodeLensProvider = new QueryCodeLensProvider(projectFinder, server); + queryCodeLensProvider = new QueryCodeLensProvider(projectFinder, server, spelSemanticTokens); // trigger project creation projectFinder.find(new TextDocumentIdentifier(projectDir)).get(); @@ -102,9 +107,9 @@ public class QueryCodeLensProviderTest { assertEquals(3, codeLenses.size()); - assertTrue(containsCodeLens(codeLenses.get(0), QueryCodeLensProvider.EXPLAIN_QUERY_TITLE, 9, 8, 9, 108)); - assertTrue(containsCodeLens(codeLenses.get(1), QueryCodeLensProvider.EXPLAIN_QUERY_TITLE, 13, 8, 13, 39)); - assertTrue(containsCodeLens(codeLenses.get(2), QueryCodeLensProvider.EXPLAIN_QUERY_TITLE, 17, 14, 17, 92)); + assertTrue(containsCodeLens(codeLenses.get(0), QueryType.DEFAULT.getTitle(), 9, 8, 9, 108)); + assertTrue(containsCodeLens(codeLenses.get(1), QueryType.DEFAULT.getTitle(), 13, 8, 13, 39)); + assertTrue(containsCodeLens(codeLenses.get(2), QueryType.DEFAULT.getTitle(), 17, 14, 17, 92)); } @Test @@ -118,11 +123,75 @@ public class QueryCodeLensProviderTest { TextDocumentInfo openedDoc = harness.openDocument(doc); List codeLenses = harness.getCodeLenses(openedDoc); + + String expectedPrompt = """ +Explain the following SpEL Expression with a clear summary first, followed by a breakdown of the expression with details: \n +T(org.test.SpelController).isValidVersion('${app.version}') ? 'Valid Version' :'Invalid Version' - assertEquals(2, codeLenses.size()); + Finally, provide a brief summary of what the following method does, focusing on its role within the SpEL expression. + The summary should mention key criteria the method checks but avoid detailed implementation steps. + Please include this summary as an appendix to the main explanation, and avoid repeating information covered earlier. - assertTrue(containsCodeLens(codeLenses.get(0), QueryCodeLensProvider.EXPLAIN_SPEL_TITLE, 13, 17, 13, 111)); - assertTrue(containsCodeLens(codeLenses.get(1), QueryCodeLensProvider.EXPLAIN_SPEL_TITLE, 16, 11, 16, 142)); +public static boolean isValidVersion(String version){ + if (version.matches("\\\\d+\\\\.\\\\d+\\\\.\\\\d+")) { + String[] parts=version.split("\\\\."); + int major=Integer.parseInt(parts[0]); + int minor=Integer.parseInt(parts[1]); + int patch=Integer.parseInt(parts[2]); + return (major > 3) || (major == 3 && (minor > 0 || (minor == 0 && patch >= 0))); + } + return false; +} + + """; + + assertEquals(3, codeLenses.size()); + + String actualPrompt = codeLenses.get(1).getCommand().getArguments().get(0).toString(); + + assertTrue(containsCodeLens(codeLenses.get(0), QueryType.SPEL.getTitle(), 13, 17, 13, 111)); + assertTrue(containsCodeLens(codeLenses.get(1), QueryType.SPEL.getTitle(), 16, 11, 16, 107)); + + assertEquals(expectedPrompt, actualPrompt); + } + + @Test + public void testShowCodeLensesTrueForSpelWithMultipleMethods() throws Exception { + + // Simulate the command execution with true parameter + setCommandParamsHandler(true); + + String docUri = directory.toPath().resolve("src/main/java/org/test/SpelController.java").toUri().toString(); + TextDocumentInfo doc = harness.getOrReadFile(new File(new URI(docUri)), LanguageId.JAVA.getId()); + TextDocumentInfo openedDoc = harness.openDocument(doc); + + List codeLenses = harness.getCodeLenses(openedDoc); + + String expectedPrompt = """ +Explain the following SpEL Expression with a clear summary first, followed by a breakdown of the expression with details: \n +T(org.test.SpelController).toUpperCase('hello') + ' ' + T(org.test.SpelController).concat('world', '!') + + Finally, provide a brief summary of what the following method does, focusing on its role within the SpEL expression. + The summary should mention key criteria the method checks but avoid detailed implementation steps. + Please include this summary as an appendix to the main explanation, and avoid repeating information covered earlier. + +public static String toUpperCase(String input){ + return input.toUpperCase(); +} + +public static String concat(String str1,String str2){ + return str1 + str2; +} + + """; + + assertEquals(3, codeLenses.size()); + + String actualPrompt = codeLenses.get(2).getCommand().getArguments().get(0).toString(); + + assertTrue(containsCodeLens(codeLenses.get(2), QueryType.SPEL.getTitle(), 19, 11, 19, 114)); + + assertEquals(expectedPrompt, actualPrompt); } @Test diff --git a/headless-services/spring-boot-language-server/src/test/resources/test-projects/test-spel-query-codelense/src/main/java/org/test/SpelController.java b/headless-services/spring-boot-language-server/src/test/resources/test-projects/test-spel-query-codelense/src/main/java/org/test/SpelController.java index 9f892ad44..3045a5da6 100644 --- a/headless-services/spring-boot-language-server/src/test/resources/test-projects/test-spel-query-codelense/src/main/java/org/test/SpelController.java +++ b/headless-services/spring-boot-language-server/src/test/resources/test-projects/test-spel-query-codelense/src/main/java/org/test/SpelController.java @@ -14,8 +14,11 @@ public class SpelController { @Value(value="#{'${app.version}' matches '\\\\d+\\\\.\\\\d+\\\\.\\\\d+' ? '${app.version}' : 'Invalid Version'}") private String version; - @Value("#{T(org.springframework.samples.petclinic.owner.SpelController).isValidVersion('${app.version}') ? 'Valid Version' :'Invalid Version'}") + @Value("#{T(org.test.SpelController).isValidVersion('${app.version}') ? 'Valid Version' :'Invalid Version'}") private String versionValidity; + + @Value("#{T(org.test.SpelController).toUpperCase('hello') + ' ' + T(org.test.SpelController).concat('world', '!')}") + private String greeting; @GetMapping("/version") @ResponseBody @@ -39,5 +42,13 @@ public class SpelController { } return false; } + + public static String toUpperCase(String input) { + return input.toUpperCase(); + } + + public static String concat(String str1, String str2) { + return str1 + str2; + } } diff --git a/vscode-extensions/vscode-spring-boot/lib/copilot/index.ts b/vscode-extensions/vscode-spring-boot/lib/copilot/index.ts index 459088a1e..f78d581fa 100644 --- a/vscode-extensions/vscode-spring-boot/lib/copilot/index.ts +++ b/vscode-extensions/vscode-spring-boot/lib/copilot/index.ts @@ -92,9 +92,6 @@ async function updateConfiguration(value: boolean) { async function explainQueryWithCopilot() { commands.registerCommand('vscode-spring-boot.query.explain', async (userPrompt) => { - console.log('spel.explain: ' + userPrompt); - console.log('messages: ' + userPrompt); - await commands.executeCommand('workbench.action.chat.open', { query: userPrompt }); }) }