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;
+ }
+}