From 0c8725d91998f94582f7ec1eb8fc2ed4c45c57af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20M=C3=BCller?= Date: Sun, 28 Apr 2024 21:24:16 +0200 Subject: [PATCH] Add simple question answering ui and llm interaction Also, remove some generated template example code --- .../jarvis/services/MyProjectService.kt | 17 -------- .../fmueller/jarvis/services/OllamaService.kt | 35 ++++++++++++++++ .../toolWindow/ConversationWindowFactory.kt | 40 ++++++++++++------- .../github/fmueller/jarvis/MyPluginTest.kt | 39 ------------------ src/test/testData/rename/foo.xml | 3 -- src/test/testData/rename/foo_after.xml | 3 -- 6 files changed, 60 insertions(+), 77 deletions(-) delete mode 100644 src/main/kotlin/com/github/fmueller/jarvis/services/MyProjectService.kt delete mode 100644 src/test/kotlin/com/github/fmueller/jarvis/MyPluginTest.kt delete mode 100644 src/test/testData/rename/foo.xml delete mode 100644 src/test/testData/rename/foo_after.xml diff --git a/src/main/kotlin/com/github/fmueller/jarvis/services/MyProjectService.kt b/src/main/kotlin/com/github/fmueller/jarvis/services/MyProjectService.kt deleted file mode 100644 index 8619d75..0000000 --- a/src/main/kotlin/com/github/fmueller/jarvis/services/MyProjectService.kt +++ /dev/null @@ -1,17 +0,0 @@ -package com.github.fmueller.jarvis.services - -import com.intellij.openapi.components.Service -import com.intellij.openapi.diagnostic.thisLogger -import com.intellij.openapi.project.Project -import com.github.fmueller.jarvis.MyBundle - -@Service(Service.Level.PROJECT) -class MyProjectService(project: Project) { - - init { - thisLogger().info(MyBundle.message("projectService", project.name)) - thisLogger().warn("Don't forget to remove all non-needed sample code files with their corresponding registration entries in `plugin.xml`.") - } - - fun getRandomNumber() = (1..100).random() -} diff --git a/src/main/kotlin/com/github/fmueller/jarvis/services/OllamaService.kt b/src/main/kotlin/com/github/fmueller/jarvis/services/OllamaService.kt index 93b9f6c..aafe590 100644 --- a/src/main/kotlin/com/github/fmueller/jarvis/services/OllamaService.kt +++ b/src/main/kotlin/com/github/fmueller/jarvis/services/OllamaService.kt @@ -40,6 +40,41 @@ class OllamaService : Disposable { } } + // TODO make it non-blocking + fun ask(question: String): String = runBlocking { + // TODO check if model is available + // TODO if not download model + try { + val client = HttpClient.newHttpClient() + val request = HttpRequest.newBuilder() + .uri(URI.create("http://localhost:11434/api/chat")) + .POST( + HttpRequest.BodyPublishers.ofString( + """ + { + "model": "llama3", + "messages": [ + { + "role": "user", + "content": "$question" + } + ], + "stream": false + } + """.trimIndent() + ) + ) + .build() + + val response = client.send(request, HttpResponse.BodyHandlers.ofString()) + val body = response.body() + thisLogger().warn("Response: $body") + body + } catch (e: Exception) { + "Error: ${e.message}" + } + } + override fun dispose() { process.stop() } diff --git a/src/main/kotlin/com/github/fmueller/jarvis/toolWindow/ConversationWindowFactory.kt b/src/main/kotlin/com/github/fmueller/jarvis/toolWindow/ConversationWindowFactory.kt index 1003a36..016ffe8 100644 --- a/src/main/kotlin/com/github/fmueller/jarvis/toolWindow/ConversationWindowFactory.kt +++ b/src/main/kotlin/com/github/fmueller/jarvis/toolWindow/ConversationWindowFactory.kt @@ -1,16 +1,16 @@ package com.github.fmueller.jarvis.toolWindow -import com.github.fmueller.jarvis.MyBundle -import com.github.fmueller.jarvis.services.MyProjectService import com.github.fmueller.jarvis.services.OllamaService import com.intellij.openapi.components.service import com.intellij.openapi.project.Project import com.intellij.openapi.wm.ToolWindow import com.intellij.openapi.wm.ToolWindowFactory import com.intellij.ui.components.JBLabel -import com.intellij.ui.components.JBPanel +import com.intellij.ui.components.JBTextArea import com.intellij.ui.content.ContentFactory -import javax.swing.JButton +import com.intellij.util.ui.components.BorderLayoutPanel +import java.awt.event.KeyAdapter +import java.awt.event.KeyEvent class ConversationWindowFactory : ToolWindowFactory { @@ -24,17 +24,27 @@ class ConversationWindowFactory : ToolWindowFactory { class ConversationWindow(toolWindow: ToolWindow) { - private val ollama = toolWindow.project.service() - private val service = toolWindow.project.service() - - fun getContent() = JBPanel>().apply { - val label = JBLabel(MyBundle.message("randomLabel", "?")) - - add(label) - add(JButton(MyBundle.message("shuffle")).apply { - addActionListener { - label.text = MyBundle.message("randomLabel", service.getRandomNumber()) - } + private val project = toolWindow.project + private val ollama = project.service() + + fun getContent() = BorderLayoutPanel().apply { + val label = + JBLabel("I am Jarvis, your personal coding assistant. I try to be helpful, but I am not perfect.") + val responseArea = JBTextArea() + + addToTop(label) + addToCenter(responseArea) + addToBottom(JBTextArea().apply { + text = "Please enter your question" + addKeyListener(object : KeyAdapter() { + override fun keyPressed(e: KeyEvent) { + if (e.keyCode == KeyEvent.VK_ENTER) { + val question = text + text = "" + responseArea.text = ollama.ask(question) + } + } + }) }) } } diff --git a/src/test/kotlin/com/github/fmueller/jarvis/MyPluginTest.kt b/src/test/kotlin/com/github/fmueller/jarvis/MyPluginTest.kt deleted file mode 100644 index a4701bc..0000000 --- a/src/test/kotlin/com/github/fmueller/jarvis/MyPluginTest.kt +++ /dev/null @@ -1,39 +0,0 @@ -package com.github.fmueller.jarvis - -import com.intellij.ide.highlighter.XmlFileType -import com.intellij.openapi.components.service -import com.intellij.psi.xml.XmlFile -import com.intellij.testFramework.TestDataPath -import com.intellij.testFramework.fixtures.BasePlatformTestCase -import com.intellij.util.PsiErrorElementUtil -import com.github.fmueller.jarvis.services.MyProjectService - -@TestDataPath("\$CONTENT_ROOT/src/test/testData") -class MyPluginTest : BasePlatformTestCase() { - - fun testXMLFile() { - val psiFile = myFixture.configureByText(XmlFileType.INSTANCE, "bar") - val xmlFile = assertInstanceOf(psiFile, XmlFile::class.java) - - assertFalse(PsiErrorElementUtil.hasErrors(project, xmlFile.virtualFile)) - - assertNotNull(xmlFile.rootTag) - - xmlFile.rootTag?.let { - assertEquals("foo", it.name) - assertEquals("bar", it.value.text) - } - } - - fun testRename() { - myFixture.testRename("foo.xml", "foo_after.xml", "a2") - } - - fun testProjectService() { - val projectService = project.service() - - assertNotSame(projectService.getRandomNumber(), projectService.getRandomNumber()) - } - - override fun getTestDataPath() = "src/test/testData/rename" -} diff --git a/src/test/testData/rename/foo.xml b/src/test/testData/rename/foo.xml deleted file mode 100644 index b21e9f2..0000000 --- a/src/test/testData/rename/foo.xml +++ /dev/null @@ -1,3 +0,0 @@ - - 1>Foo - diff --git a/src/test/testData/rename/foo_after.xml b/src/test/testData/rename/foo_after.xml deleted file mode 100644 index 980ca96..0000000 --- a/src/test/testData/rename/foo_after.xml +++ /dev/null @@ -1,3 +0,0 @@ - - Foo -