├── README.md
├── quarkus-embedding-app
├── .mvn
│ └── wrapper
│ │ ├── .gitignore
│ │ ├── maven-wrapper.properties
│ │ └── MavenWrapperDownloader.java
├── .dockerignore
├── src
│ └── main
│ │ ├── java
│ │ └── com
│ │ │ └── eldermoraes
│ │ │ └── embedding
│ │ │ ├── Customer.java
│ │ │ ├── Booking.java
│ │ │ ├── ChatSocket.java
│ │ │ ├── BookingTools.java
│ │ │ ├── AssistantForCustomerSupport.java
│ │ │ └── BookingService.java
│ │ ├── resources
│ │ ├── application.properties
│ │ ├── catalog
│ │ │ └── miles-of-smiles-terms-of-use.txt
│ │ └── META-INF
│ │ │ └── resources
│ │ │ └── chat-assistant.html
│ │ └── docker
│ │ ├── Dockerfile.native
│ │ ├── Dockerfile.native-micro
│ │ ├── Dockerfile.legacy-jar
│ │ └── Dockerfile.jvm
├── .gitignore
├── README.md
├── pom.xml
├── mvnw.cmd
└── mvnw
├── quarkus-langchain-app
├── .mvn
│ └── wrapper
│ │ ├── .gitignore
│ │ ├── maven-wrapper.properties
│ │ └── MavenWrapperDownloader.java
├── .dockerignore
├── src
│ └── main
│ │ ├── java
│ │ └── com
│ │ │ └── eldermoraes
│ │ │ ├── prompts
│ │ │ ├── Assistant.java
│ │ │ └── PromptResource.java
│ │ │ ├── memory
│ │ │ ├── AssistantWithMemory.java
│ │ │ ├── ChatMemoryBean.java
│ │ │ └── DeveloperResource.java
│ │ │ └── tools
│ │ │ ├── EmailMeAPoemResource.java
│ │ │ ├── EmailService.java
│ │ │ └── AssistantWithContext.java
│ │ ├── resources
│ │ └── application.properties
│ │ └── docker
│ │ ├── Dockerfile.native
│ │ ├── Dockerfile.native-micro
│ │ ├── Dockerfile.legacy-jar
│ │ └── Dockerfile.jvm
├── .gitignore
├── README.md
├── pom.xml
├── mvnw.cmd
└── mvnw
├── quarkus-ollama-app
├── .mvn
│ └── wrapper
│ │ ├── .gitignore
│ │ ├── maven-wrapper.properties
│ │ └── MavenWrapperDownloader.java
├── .dockerignore
├── src
│ └── main
│ │ ├── resources
│ │ └── application.properties
│ │ ├── java
│ │ └── com
│ │ │ └── eldermoraes
│ │ │ ├── Assistant.java
│ │ │ └── PromptResource.java
│ │ └── docker
│ │ ├── Dockerfile.native
│ │ ├── Dockerfile.native-micro
│ │ ├── Dockerfile.legacy-jar
│ │ └── Dockerfile.jvm
├── .gitignore
├── README.md
├── pom.xml
├── mvnw.cmd
└── mvnw
├── .quarkus
└── cli
│ └── plugins
│ └── quarkus-cli-catalog.json
├── .idea
├── vcs.xml
├── misc.xml
├── .gitignore
├── modules.xml
└── quarkus-langchain-demo.iml
├── .gitignore
└── LICENSE
/README.md:
--------------------------------------------------------------------------------
1 | # quarkus-langchain-demo
--------------------------------------------------------------------------------
/quarkus-embedding-app/.mvn/wrapper/.gitignore:
--------------------------------------------------------------------------------
1 | maven-wrapper.jar
2 |
--------------------------------------------------------------------------------
/quarkus-langchain-app/.mvn/wrapper/.gitignore:
--------------------------------------------------------------------------------
1 | maven-wrapper.jar
2 |
--------------------------------------------------------------------------------
/quarkus-ollama-app/.mvn/wrapper/.gitignore:
--------------------------------------------------------------------------------
1 | maven-wrapper.jar
2 |
--------------------------------------------------------------------------------
/quarkus-ollama-app/.dockerignore:
--------------------------------------------------------------------------------
1 | *
2 | !target/*-runner
3 | !target/*-runner.jar
4 | !target/lib/*
5 | !target/quarkus-app/*
--------------------------------------------------------------------------------
/quarkus-embedding-app/.dockerignore:
--------------------------------------------------------------------------------
1 | *
2 | !target/*-runner
3 | !target/*-runner.jar
4 | !target/lib/*
5 | !target/quarkus-app/*
--------------------------------------------------------------------------------
/quarkus-langchain-app/.dockerignore:
--------------------------------------------------------------------------------
1 | *
2 | !target/*-runner
3 | !target/*-runner.jar
4 | !target/lib/*
5 | !target/quarkus-app/*
--------------------------------------------------------------------------------
/.quarkus/cli/plugins/quarkus-cli-catalog.json:
--------------------------------------------------------------------------------
1 | {
2 | "version" : "v1",
3 | "lastUpdate" : "22/10/2025 12:01:26",
4 | "plugins" : { }
5 | }
--------------------------------------------------------------------------------
/quarkus-ollama-app/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | quarkus.langchain4j.ollama.chat-model.model-id=gpt-oss:20b
2 | quarkus.langchain4j.ollama.timeout=120s
--------------------------------------------------------------------------------
/quarkus-embedding-app/src/main/java/com/eldermoraes/embedding/Customer.java:
--------------------------------------------------------------------------------
1 | package com.eldermoraes.embedding;
2 |
3 | public record Customer(String name, String surname) {
4 | }
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/quarkus-ollama-app/src/main/java/com/eldermoraes/Assistant.java:
--------------------------------------------------------------------------------
1 | package com.eldermoraes;
2 |
3 | import io.quarkiverse.langchain4j.RegisterAiService;
4 |
5 | @RegisterAiService
6 | public interface Assistant {
7 | String chat(String message);
8 | }
--------------------------------------------------------------------------------
/quarkus-embedding-app/src/main/java/com/eldermoraes/embedding/Booking.java:
--------------------------------------------------------------------------------
1 | package com.eldermoraes.embedding;
2 |
3 | import java.time.LocalDate;
4 |
5 | public record Booking(String bookingNumber, LocalDate bookingFrom, LocalDate bookingTo, Customer customer) {
6 | }
--------------------------------------------------------------------------------
/quarkus-langchain-app/src/main/java/com/eldermoraes/prompts/Assistant.java:
--------------------------------------------------------------------------------
1 | package com.eldermoraes.prompts;
2 |
3 | import io.quarkiverse.langchain4j.RegisterAiService;
4 |
5 | @RegisterAiService
6 | public interface Assistant {
7 | String chat(String message);
8 | }
--------------------------------------------------------------------------------
/quarkus-langchain-app/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | quarkus.langchain4j.ollama.chat-model.model-id=gpt-oss:20b
2 | quarkus.langchain4j.ollama.timeout=120s
3 |
4 | %dev.quarkus.mailer.host=localhost
5 | %dev.quarkus.mailer.port=1025
6 | %dev.quarkus.mailer.mock=false
7 |
8 |
--------------------------------------------------------------------------------
/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 | # Editor-based HTTP Client requests
5 | /httpRequests/
6 | # Environment-dependent path to Maven home directory
7 | /mavenHomeManager.xml
8 | # Datasource local storage ignored files
9 | /dataSources/
10 | /dataSources.local.xml
11 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/quarkus-langchain-demo.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Compiled class file
2 | *.class
3 |
4 | # Log file
5 | *.log
6 |
7 | # BlueJ files
8 | *.ctxt
9 |
10 | # Mobile Tools for Java (J2ME)
11 | .mtj.tmp/
12 |
13 | # Package Files #
14 | *.jar
15 | *.war
16 | *.nar
17 | *.ear
18 | *.zip
19 | *.tar.gz
20 | *.rar
21 |
22 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
23 | hs_err_pid*
24 | replay_pid*
25 |
--------------------------------------------------------------------------------
/quarkus-langchain-app/src/main/java/com/eldermoraes/memory/AssistantWithMemory.java:
--------------------------------------------------------------------------------
1 | package com.eldermoraes.memory;
2 |
3 | import dev.langchain4j.service.MemoryId;
4 | import dev.langchain4j.service.UserMessage;
5 | import io.quarkiverse.langchain4j.RegisterAiService;
6 |
7 | @RegisterAiService
8 | interface AssistantWithMemory {
9 |
10 | String chat(@MemoryId Integer id, @UserMessage String msg);
11 |
12 | }
--------------------------------------------------------------------------------
/quarkus-embedding-app/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | quarkus.langchain4j.ollama.chat-model.model-id=gpt-oss:20b
2 | quarkus.langchain4j.ollama.timeout=120s
3 | quarkus.langchain4j.ollama.chat-model.temperature=0.0
4 |
5 | quarkus.langchain4j.easy-rag.path=src/main/resources/catalog
6 |
7 | quarkus.langchain4j.log-requests=true
8 | quarkus.langchain4j.log-responses=true
9 |
10 | booking.daystostart=1
11 | booking.daystoend=3
12 |
13 |
14 |
--------------------------------------------------------------------------------
/quarkus-ollama-app/src/main/java/com/eldermoraes/PromptResource.java:
--------------------------------------------------------------------------------
1 | package com.eldermoraes;
2 |
3 | import jakarta.inject.Inject;
4 | import jakarta.ws.rs.GET;
5 | import jakarta.ws.rs.Path;
6 | import jakarta.ws.rs.Produces;
7 | import jakarta.ws.rs.QueryParam;
8 | import jakarta.ws.rs.core.MediaType;
9 |
10 | @Path("/prompt")
11 | public class PromptResource {
12 |
13 | @Inject
14 | Assistant assistant;
15 |
16 | @GET
17 | @Produces(MediaType.TEXT_PLAIN)
18 | public String prompt(@QueryParam("message") String message) {
19 | return assistant.chat(message);
20 | }
21 | }
--------------------------------------------------------------------------------
/quarkus-ollama-app/.gitignore:
--------------------------------------------------------------------------------
1 | #Maven
2 | target/
3 | pom.xml.tag
4 | pom.xml.releaseBackup
5 | pom.xml.versionsBackup
6 | release.properties
7 | .flattened-pom.xml
8 |
9 | # Eclipse
10 | .project
11 | .classpath
12 | .settings/
13 | bin/
14 |
15 | # IntelliJ
16 | .idea
17 | *.ipr
18 | *.iml
19 | *.iws
20 |
21 | # NetBeans
22 | nb-configuration.xml
23 |
24 | # Visual Studio Code
25 | .vscode
26 | .factorypath
27 |
28 | # OSX
29 | .DS_Store
30 |
31 | # Vim
32 | *.swp
33 | *.swo
34 |
35 | # patch
36 | *.orig
37 | *.rej
38 |
39 | # Local environment
40 | .env
41 |
42 | # Plugin directory
43 | /.quarkus/cli/plugins/
44 |
--------------------------------------------------------------------------------
/quarkus-embedding-app/.gitignore:
--------------------------------------------------------------------------------
1 | #Maven
2 | target/
3 | pom.xml.tag
4 | pom.xml.releaseBackup
5 | pom.xml.versionsBackup
6 | release.properties
7 | .flattened-pom.xml
8 |
9 | # Eclipse
10 | .project
11 | .classpath
12 | .settings/
13 | bin/
14 |
15 | # IntelliJ
16 | .idea
17 | *.ipr
18 | *.iml
19 | *.iws
20 |
21 | # NetBeans
22 | nb-configuration.xml
23 |
24 | # Visual Studio Code
25 | .vscode
26 | .factorypath
27 |
28 | # OSX
29 | .DS_Store
30 |
31 | # Vim
32 | *.swp
33 | *.swo
34 |
35 | # patch
36 | *.orig
37 | *.rej
38 |
39 | # Local environment
40 | .env
41 |
42 | # Plugin directory
43 | /.quarkus/cli/plugins/
44 |
--------------------------------------------------------------------------------
/quarkus-langchain-app/.gitignore:
--------------------------------------------------------------------------------
1 | #Maven
2 | target/
3 | pom.xml.tag
4 | pom.xml.releaseBackup
5 | pom.xml.versionsBackup
6 | release.properties
7 | .flattened-pom.xml
8 |
9 | # Eclipse
10 | .project
11 | .classpath
12 | .settings/
13 | bin/
14 |
15 | # IntelliJ
16 | .idea
17 | *.ipr
18 | *.iml
19 | *.iws
20 |
21 | # NetBeans
22 | nb-configuration.xml
23 |
24 | # Visual Studio Code
25 | .vscode
26 | .factorypath
27 |
28 | # OSX
29 | .DS_Store
30 |
31 | # Vim
32 | *.swp
33 | *.swo
34 |
35 | # patch
36 | *.orig
37 | *.rej
38 |
39 | # Local environment
40 | .env
41 |
42 | # Plugin directory
43 | /.quarkus/cli/plugins/
44 |
--------------------------------------------------------------------------------
/quarkus-langchain-app/src/main/java/com/eldermoraes/prompts/PromptResource.java:
--------------------------------------------------------------------------------
1 | package com.eldermoraes.prompts;
2 |
3 | import jakarta.inject.Inject;
4 | import jakarta.ws.rs.GET;
5 | import jakarta.ws.rs.Path;
6 | import jakarta.ws.rs.Produces;
7 | import jakarta.ws.rs.QueryParam;
8 | import jakarta.ws.rs.core.MediaType;
9 |
10 | @Path("/prompt")
11 | public class PromptResource {
12 |
13 | @Inject
14 | Assistant assistant;
15 |
16 | @GET
17 | @Produces(MediaType.TEXT_PLAIN)
18 | public String prompt(@QueryParam("message") String message) {
19 |
20 | return assistant.chat(message);
21 | }
22 | }
--------------------------------------------------------------------------------
/quarkus-langchain-app/src/main/java/com/eldermoraes/tools/EmailMeAPoemResource.java:
--------------------------------------------------------------------------------
1 | package com.eldermoraes.tools;
2 |
3 | import jakarta.ws.rs.GET;
4 | import jakarta.ws.rs.Path;
5 | import jakarta.ws.rs.QueryParam;
6 |
7 | @Path("/email-me-a-poem")
8 | public class EmailMeAPoemResource {
9 |
10 | private final AssistantWithContext service;
11 |
12 | public EmailMeAPoemResource(AssistantWithContext service) {
13 | this.service = service;
14 | }
15 |
16 | @GET
17 | public String emailMeAPoem(@QueryParam("topic") String topic,
18 | @QueryParam("lines") int lines) {
19 |
20 | return service.writeAPoem(topic, lines);
21 | }
22 |
23 | }
--------------------------------------------------------------------------------
/quarkus-langchain-app/src/main/java/com/eldermoraes/tools/EmailService.java:
--------------------------------------------------------------------------------
1 | package com.eldermoraes.tools;
2 |
3 | import jakarta.enterprise.context.ApplicationScoped;
4 | import jakarta.inject.Inject;
5 |
6 | import dev.langchain4j.agent.tool.Tool;
7 | import io.quarkus.logging.Log;
8 | import io.quarkus.mailer.Mail;
9 | import io.quarkus.mailer.Mailer;
10 |
11 | @ApplicationScoped
12 | public class EmailService {
13 |
14 | @Inject
15 | Mailer mailer;
16 |
17 | @Tool("send the given content by email")
18 | public void sendAnEmail(String content) {
19 | Log.info("Sending an email: " + content);
20 | mailer.send(Mail.withText("sendMeALetter@quarkus.io", "A poem for you", content).setFrom("origin@quarkus.io"));
21 | }
22 |
23 | }
--------------------------------------------------------------------------------
/quarkus-embedding-app/src/main/java/com/eldermoraes/embedding/ChatSocket.java:
--------------------------------------------------------------------------------
1 | package com.eldermoraes.embedding;
2 |
3 | import io.quarkus.websockets.next.OnTextMessage;
4 | import io.quarkus.websockets.next.WebSocket;
5 | import jakarta.websocket.OnOpen;
6 |
7 | @WebSocket(path = "/chat")
8 | public class ChatSocket {
9 |
10 | private final AssistantForCustomerSupport assistant;
11 |
12 | public ChatSocket(AssistantForCustomerSupport assistant) {
13 | this.assistant = assistant;
14 | }
15 |
16 | @OnOpen
17 | public String onOpen() {
18 | return "Hello from Miles of Smiles, how can we help you?";
19 | }
20 |
21 | @OnTextMessage
22 | public String onMessage(String userMessage){
23 | return assistant.chat("sessionId", userMessage);
24 | }
25 | }
--------------------------------------------------------------------------------
/quarkus-ollama-app/src/main/docker/Dockerfile.native:
--------------------------------------------------------------------------------
1 | ####
2 | # This Dockerfile is used in order to build a container that runs the Quarkus application in native (no JVM) mode.
3 | #
4 | # Before building the container image run:
5 | #
6 | # ./mvnw package -Pnative
7 | #
8 | # Then, build the image with:
9 | #
10 | # docker build -f src/main/docker/Dockerfile.native -t quarkus/quarkus-ollama-app .
11 | #
12 | # Then run the container using:
13 | #
14 | # docker run -i --rm -p 8080:8080 quarkus/quarkus-ollama-app
15 | #
16 | ###
17 | FROM registry.access.redhat.com/ubi8/ubi-minimal:8.6
18 | WORKDIR /work/
19 | RUN chown 1001 /work \
20 | && chmod "g+rwX" /work \
21 | && chown 1001:root /work
22 | COPY --chown=1001:root target/*-runner /work/application
23 |
24 | EXPOSE 8080
25 | USER 1001
26 |
27 | CMD ["./application", "-Dquarkus.http.host=0.0.0.0"]
28 |
--------------------------------------------------------------------------------
/quarkus-embedding-app/src/main/docker/Dockerfile.native:
--------------------------------------------------------------------------------
1 | ####
2 | # This Dockerfile is used in order to build a container that runs the Quarkus application in native (no JVM) mode.
3 | #
4 | # Before building the container image run:
5 | #
6 | # ./mvnw package -Pnative
7 | #
8 | # Then, build the image with:
9 | #
10 | # docker build -f src/main/docker/Dockerfile.native -t quarkus/quarkus-embedding-app .
11 | #
12 | # Then run the container using:
13 | #
14 | # docker run -i --rm -p 8080:8080 quarkus/quarkus-embedding-app
15 | #
16 | ###
17 | FROM registry.access.redhat.com/ubi8/ubi-minimal:8.6
18 | WORKDIR /work/
19 | RUN chown 1001 /work \
20 | && chmod "g+rwX" /work \
21 | && chown 1001:root /work
22 | COPY --chown=1001:root target/*-runner /work/application
23 |
24 | EXPOSE 8080
25 | USER 1001
26 |
27 | CMD ["./application", "-Dquarkus.http.host=0.0.0.0"]
28 |
--------------------------------------------------------------------------------
/quarkus-langchain-app/src/main/docker/Dockerfile.native:
--------------------------------------------------------------------------------
1 | ####
2 | # This Dockerfile is used in order to build a container that runs the Quarkus application in native (no JVM) mode.
3 | #
4 | # Before building the container image run:
5 | #
6 | # ./mvnw package -Pnative
7 | #
8 | # Then, build the image with:
9 | #
10 | # docker build -f src/main/docker/Dockerfile.native -t quarkus/quarkus-langchain-app .
11 | #
12 | # Then run the container using:
13 | #
14 | # docker run -i --rm -p 8080:8080 quarkus/quarkus-langchain-app
15 | #
16 | ###
17 | FROM registry.access.redhat.com/ubi8/ubi-minimal:8.6
18 | WORKDIR /work/
19 | RUN chown 1001 /work \
20 | && chmod "g+rwX" /work \
21 | && chown 1001:root /work
22 | COPY --chown=1001:root target/*-runner /work/application
23 |
24 | EXPOSE 8080
25 | USER 1001
26 |
27 | CMD ["./application", "-Dquarkus.http.host=0.0.0.0"]
28 |
--------------------------------------------------------------------------------
/quarkus-langchain-app/src/main/java/com/eldermoraes/tools/AssistantWithContext.java:
--------------------------------------------------------------------------------
1 | package com.eldermoraes.tools;
2 |
3 | import dev.langchain4j.service.SystemMessage;
4 | import dev.langchain4j.service.UserMessage;
5 | import io.quarkiverse.langchain4j.RegisterAiService;
6 |
7 | @RegisterAiService(tools = EmailService.class)
8 | public interface AssistantWithContext {
9 |
10 | /**
11 | * Ask the LLM to create a poem about the given topic.
12 | *
13 | * @param topic the topic of the poem
14 | * @param lines the number of line of the poem
15 | * @return the poem
16 | */
17 | @SystemMessage("You are a professional poet. Translate all your poems to Spanish (from Colombia).")
18 | @UserMessage("Write a poem about {topic}. The poem should be {lines} lines long. Then send this poem by email.")
19 | String writeAPoem(String topic, int lines);
20 |
21 | }
--------------------------------------------------------------------------------
/quarkus-embedding-app/src/main/java/com/eldermoraes/embedding/BookingTools.java:
--------------------------------------------------------------------------------
1 | package com.eldermoraes.embedding;
2 |
3 | import dev.langchain4j.agent.tool.Tool;
4 | import jakarta.inject.Singleton;
5 |
6 | @Singleton
7 | public class BookingTools {
8 |
9 | private final BookingService bookingService;
10 |
11 | public BookingTools(BookingService bookingService) {
12 | this.bookingService = bookingService;
13 | }
14 |
15 | @Tool("Get details about bookings")
16 | public Booking getBookingDetails(String bookingNumber, String customerName, String customerSurname) {
17 | return bookingService.getBookingDetails(bookingNumber, customerName, customerSurname);
18 | }
19 |
20 | @Tool("Cancel a booking based on the [bookingNumber], [customerName] and [customerSurname]")
21 | public void cancelBooking(String bookingNumber, String customerName, String customerSurname) {
22 | bookingService.cancelBooking(bookingNumber, customerName, customerSurname);
23 | }
24 | }
--------------------------------------------------------------------------------
/quarkus-langchain-app/src/main/java/com/eldermoraes/memory/ChatMemoryBean.java:
--------------------------------------------------------------------------------
1 | package com.eldermoraes.memory;
2 |
3 | import java.util.Map;
4 | import java.util.concurrent.ConcurrentHashMap;
5 |
6 | import jakarta.annotation.PreDestroy;
7 | import jakarta.enterprise.context.ApplicationScoped;
8 |
9 | import dev.langchain4j.memory.ChatMemory;
10 | import dev.langchain4j.memory.chat.ChatMemoryProvider;
11 | import dev.langchain4j.memory.chat.MessageWindowChatMemory;
12 |
13 | @ApplicationScoped
14 | public class ChatMemoryBean implements ChatMemoryProvider {
15 |
16 | private final Map