diff --git a/pom.xml b/pom.xml index 02bae75..3e5bb67 100644 --- a/pom.xml +++ b/pom.xml @@ -62,6 +62,19 @@ viritin 2.8.14 + + org.springframework.boot + spring-boot-testcontainers + + + org.testcontainers + ollama + + + org.apache.commons + commons-compress + 1.26.0 + org.springframework.boot spring-boot-starter-test diff --git a/src/main/java/com/example/demo/MainView.java b/src/main/java/com/example/demo/MainView.java index cfdf673..85ab93f 100644 --- a/src/main/java/com/example/demo/MainView.java +++ b/src/main/java/com/example/demo/MainView.java @@ -4,11 +4,16 @@ import com.vaadin.flow.component.orderedlayout.Scroller; import com.vaadin.flow.component.orderedlayout.VerticalLayout; import com.vaadin.flow.router.Route; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.PreDestroy; import org.springframework.ai.chat.client.ChatClient; import org.springframework.ai.chat.messages.*; import org.springframework.ai.chat.prompt.Prompt; +import org.springframework.stereotype.Service; +import org.testcontainers.ollama.OllamaContainer; import org.vaadin.firitin.components.messagelist.MarkdownMessage; +import java.io.IOException; import java.util.ArrayList; @Route("") // map view to the root @@ -20,7 +25,7 @@ public class MainView extends VerticalLayout { Scroller messageScroller = new Scroller(messageList); MessageInput messageInput = new MessageInput(); - public MainView(ChatClient.Builder chatClientBuilder) { + public MainView(OllamaService ollamaService) { add(messageScroller, messageInput); setSizeFull(); setMargin(false); @@ -31,7 +36,7 @@ public MainView(ChatClient.Builder chatClientBuilder) { chatHistory.add(new SystemMessage("Answer politely to user. When user asks you about Vaadin, reply in bro style. Always show a piece a code.")); // Init the client - ChatClient chatClient = chatClientBuilder.build(); + ChatClient chatClient = ollamaService.getChatClient(); // Pass user input to chatClient messageInput.addSubmitListener(ev -> { diff --git a/src/main/java/com/example/demo/OllamaService.java b/src/main/java/com/example/demo/OllamaService.java new file mode 100644 index 0000000..c1ff410 --- /dev/null +++ b/src/main/java/com/example/demo/OllamaService.java @@ -0,0 +1,50 @@ +package com.example.demo; + +import com.github.dockerjava.api.model.*; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.PreDestroy; +import org.springframework.ai.chat.client.ChatClient; +import org.springframework.stereotype.Service; +import org.springframework.web.context.annotation.ApplicationScope; +import org.testcontainers.ollama.OllamaContainer; + +import java.io.IOException; + +@Service +@ApplicationScope +public class OllamaService { + + private final OllamaContainer ollama; + + private final ChatClient.Builder chatClientBuilder; + + public OllamaService(ChatClient.Builder chatClientBuilder) { + ollama = new OllamaContainer("ollama/ollama:0.1.48") + .withCreateContainerCmdModifier(cmd -> + { + cmd.withBinds(Bind.parse("ollama:/root/.ollama")); + cmd.withPortBindings(new PortBinding(Ports.Binding.bindPort(11434), new ExposedPort(11434))); + }); + + this.chatClientBuilder = chatClientBuilder; + } + + @PostConstruct + public void start() throws IOException, InterruptedException { + ollama.start(); + ollama.execInContainer("ollama", "pull", "mistral"); + } + @PreDestroy + public void stop() { + if (ollama.isRunning()) { + ollama.stop(); + } + } + + public ChatClient getChatClient() { + if (ollama.isRunning()) { + return chatClientBuilder.build(); + } + return null; + } +}