From 0ad9f33ecf930920a319dec7b63195043713bc85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20M=C3=BCller?= Date: Sun, 2 Jun 2024 16:42:34 +0200 Subject: [PATCH] feat: Add check for ollama installation --- .../fmueller/jarvis/ai/OllamaService.kt | 74 +------------------ .../fmueller/jarvis/commands/ChatCommand.kt | 10 +++ 2 files changed, 14 insertions(+), 70 deletions(-) diff --git a/src/main/kotlin/com/github/fmueller/jarvis/ai/OllamaService.kt b/src/main/kotlin/com/github/fmueller/jarvis/ai/OllamaService.kt index defd5ec..200ac3a 100644 --- a/src/main/kotlin/com/github/fmueller/jarvis/ai/OllamaService.kt +++ b/src/main/kotlin/com/github/fmueller/jarvis/ai/OllamaService.kt @@ -1,12 +1,8 @@ package com.github.fmueller.jarvis.ai import com.github.fmueller.jarvis.conversation.Message -import com.intellij.openapi.Disposable import com.intellij.openapi.components.Service -import com.intellij.openapi.diagnostic.thisLogger import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.delay -import kotlinx.coroutines.runBlocking import kotlinx.coroutines.withContext import kotlinx.serialization.Serializable import kotlinx.serialization.decodeFromString @@ -16,7 +12,6 @@ import java.net.URI import java.net.http.HttpClient import java.net.http.HttpRequest import java.net.http.HttpResponse -import java.util.* @Serializable private data class ChatMessage(val role: String, val content: String) @@ -32,38 +27,11 @@ private data class ChatRequest( private data class ChatResponse(val message: ChatMessage) @Service(Service.Level.PROJECT) -class OllamaService : Disposable { - - private val process = OllamaProcess() - - init { - // TODO remove this autostart logic and show messages in conversation panel instead - if (isOllamaRunning()) { - thisLogger().info("Ollama process is already running") - } else { - process.start() - runBlocking { - val startTime = System.currentTimeMillis() - while (System.currentTimeMillis() - startTime < 5000) { - if (isOllamaRunning()) { - thisLogger().info("Ollama process started") - break - } else { - delay(500) - } - } - - if (!isOllamaRunning()) { - thisLogger().error("Failed to start Ollama process") - // TODO send message to user interface - } - } - } - } +class OllamaService { suspend fun chat(messages: List): String = withContext(Dispatchers.IO) { // TODO check if model is available - // TODO if not download model + // TODO if not, download model try { val client = HttpClient.newHttpClient() val chatRequest = ChatRequest( @@ -100,11 +68,7 @@ class OllamaService : Disposable { } } - override fun dispose() { - process.stop() - } - - private fun isOllamaRunning(): Boolean { + fun isAvailable(): Boolean { return try { val client = HttpClient.newHttpClient() val request = HttpRequest.newBuilder() @@ -117,34 +81,4 @@ class OllamaService : Disposable { false } } - - private class OllamaProcess { - - private var process: Process? = null - - fun start() { - thisLogger().info("Starting Ollama process") - try { - process = ProcessBuilder(getOllamaCommand(), "serve").start() - } catch (e: UnsupportedOperationException) { - thisLogger().error("Unsupported operating system", e) - } catch (e: Exception) { - thisLogger().error("Failed to start Ollama process", e) - } - } - - fun stop() { - thisLogger().info("Destroying Ollama process") - process?.destroy() - } - - private fun getOllamaCommand(): String { - val os = System.getProperty("os.name").lowercase(Locale.getDefault()) - return when { - os.contains("win") -> "ollama.exe" - os.contains("nix") || os.contains("nux") || os.contains("mac") -> "ollama" - else -> throw UnsupportedOperationException("Unsupported operating system: $os") - } - } - } -} \ No newline at end of file +} diff --git a/src/main/kotlin/com/github/fmueller/jarvis/commands/ChatCommand.kt b/src/main/kotlin/com/github/fmueller/jarvis/commands/ChatCommand.kt index 9afc297..eb70693 100644 --- a/src/main/kotlin/com/github/fmueller/jarvis/commands/ChatCommand.kt +++ b/src/main/kotlin/com/github/fmueller/jarvis/commands/ChatCommand.kt @@ -8,6 +8,16 @@ import com.github.fmueller.jarvis.conversation.Role class ChatCommand(private val ollamaService: OllamaService) : SlashCommand { override suspend fun run(conversation: Conversation): Conversation { + if (!ollamaService.isAvailable()) { + conversation.addMessage( + Message( + Role.ASSISTANT, + "I can't access Ollama at ```http://localhost:11434```. You need to install it first and download the ```llama3``` model." + ) + ) + return conversation + } + val response = ollamaService.chat(conversation.messages).trim() conversation.addMessage(Message(Role.ASSISTANT, response)) return conversation