This is an automated email from the ASF dual-hosted git repository.
jamesnetherton pushed a commit to branch camel-quarkus-main
in repository https://gitbox.apache.org/repos/asf/camel-quarkus-examples.git
The following commit(s) were added to refs/heads/camel-quarkus-main by this
push:
new d4ae31c Rework data-extract-langchain4j example to use
langchain4j-agent extension
d4ae31c is described below
commit d4ae31cfd0c64a2d273eaef2aab8e7ca6ec63eec
Author: James Netherton <[email protected]>
AuthorDate: Mon Sep 1 11:40:57 2025 +0100
Rework data-extract-langchain4j example to use langchain4j-agent extension
---
.github/dependabot.yml | 4 +-
data-extract-langchain4j/README.adoc | 6 +-
data-extract-langchain4j/pom.xml | 29 +++++-----
.../extraction/CustomPojoExtractionService.java | 27 +++------
.../java/org/acme/extraction/DataExtractAgent.java | 65 ++++++++++++++++++++++
.../extraction/DataExtractAgentConfiguration.java | 57 +++++++++++++++++++
.../src/main/java/org/acme/extraction/Routes.java | 12 ++--
.../langchain4j-ollama/reflect-config.json | 56 -------------------
.../src/main/resources/application.properties | 25 ++-------
.../org/acme/extraction/OllamaTestResource.java | 4 +-
..._chat-19930290-5d0d-4c09-b256-73adbbf23475.json | 24 --------
..._chat-2458b71a-4789-4a07-9424-ba7a1da8bf07.json | 24 ++++++++
..._chat-46e7b6b7-f983-471d-b7bf-7fd271067c10.json | 24 --------
..._chat-5dbaaf5e-5436-470c-a629-cee5ea860e64.json | 24 ++++++++
..._chat-69af07bd-686f-439f-92c9-7424d9506270.json | 24 --------
..._chat-a359a6fc-e37c-4383-a99c-efa92d6e650d.json | 24 ++++++++
16 files changed, 237 insertions(+), 192 deletions(-)
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index f2ca97a..effd2f5 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -37,10 +37,12 @@ updates:
allow:
# Quarkiverse extensions
- dependency-name: "io.quarkiverse.*:*"
- - dependency-name: "org.zeroturnaround:zt-exec"
+ # Misc third party dependencies
+ - dependency-name: "dev.langchain4j:*"
# Test dependencies
- dependency-name: "org.assertj:assertj-core"
- dependency-name: "org.wiremock:wiremock-standalone"
+ - dependency-name: "org.zeroturnaround:zt-exec"
# Maven plugins
- dependency-name: "*:*-maven-plugin"
- dependency-name: "org.apache.maven.plugins:*"
diff --git a/data-extract-langchain4j/README.adoc
b/data-extract-langchain4j/README.adoc
index c21b29f..8f0b98d 100644
--- a/data-extract-langchain4j/README.adoc
+++ b/data-extract-langchain4j/README.adoc
@@ -116,12 +116,14 @@ See how the LLM shows its capacity to:
* Manage issues related to date format, like the field `customerBirthday`
* Mixed structured and unstructured data (semi-structured data) with the
field `summary`.
-Cherry on the cake, all those informations are computed simultaneously during
a single LLM inference.
+Notice how all of this is computed simultaneously during a single LLM
inference.
At the end, the application should have extracted 3 POJOs.
For each of them, it could be interesting to compare the unstructured input
text and the corresponding structured POJO.
-More details can be found in the
`src/main/java/org/acme/extraction/CustomPojoExtractionService.java` class.
+Details of the LangChain4j `AiService` setup can be found in class
`CustomPojoExtractionService`.
+
+Details of the custom data extract `camel-langchain4j-agent` AI agent
implementation can be found in classes `DataExtractAgent` and
`DataExtractConfiguration`.
==== Native mode
diff --git a/data-extract-langchain4j/pom.xml b/data-extract-langchain4j/pom.xml
index af8421c..a6470a0 100644
--- a/data-extract-langchain4j/pom.xml
+++ b/data-extract-langchain4j/pom.xml
@@ -18,8 +18,8 @@
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>camel-quarkus-examples-data-extract-langchain4j</artifactId>
@@ -55,7 +55,7 @@
<maven-resources-plugin.version>3.3.1</maven-resources-plugin.version>
<maven-surefire-plugin.version>3.5.3</maven-surefire-plugin.version>
- <quarkus-langchain4j.version>1.1.1</quarkus-langchain4j.version>
+ <langchain4j.version>1.1.0</langchain4j.version>
<wiremock.version>3.13.1</wiremock.version>
</properties>
@@ -63,9 +63,9 @@
<dependencies>
<!-- Import BOM -->
<dependency>
- <groupId>io.quarkiverse.langchain4j</groupId>
- <artifactId>quarkus-langchain4j-bom</artifactId>
- <version>${quarkus-langchain4j.version}</version>
+ <groupId>dev.langchain4j</groupId>
+ <artifactId>langchain4j-bom</artifactId>
+ <version>${langchain4j.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
@@ -97,15 +97,19 @@
</dependency>
<dependency>
<groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-langchain4j</artifactId>
+ <artifactId>camel-quarkus-platform-http</artifactId>
</dependency>
<dependency>
<groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-platform-http</artifactId>
+ <artifactId>camel-quarkus-langchain4j-agent</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-bean</artifactId>
</dependency>
<dependency>
- <groupId>io.quarkiverse.langchain4j</groupId>
- <artifactId>quarkus-langchain4j-ollama</artifactId>
+ <groupId>dev.langchain4j</groupId>
+ <artifactId>langchain4j-ollama</artifactId>
</dependency>
<!-- Test -->
@@ -140,7 +144,6 @@
<build>
<pluginManagement>
<plugins>
-
<plugin>
<groupId>net.revelc.code.formatter</groupId>
<artifactId>formatter-maven-plugin</artifactId>
@@ -171,8 +174,6 @@
<showDeprecation>true</showDeprecation>
<showWarnings>true</showWarnings>
<compilerArgs>
- <!-- Specifying -parameters is optional, see
CustomPojoExtractionService.extractFromText javadoc -->
- <arg>-parameters</arg>
<arg>-Xlint:unchecked</arg>
</compilerArgs>
</configuration>
@@ -284,6 +285,7 @@
</build>
<profiles>
+ <!-- TODO: https://github.com/apache/camel-quarkus/issues/7568
<profile>
<id>native</id>
<activation>
@@ -311,6 +313,7 @@
</plugins>
</build>
</profile>
+ -->
<profile>
<id>skip-testcontainers-tests</id>
<activation>
diff --git
a/data-extract-langchain4j/src/main/java/org/acme/extraction/CustomPojoExtractionService.java
b/data-extract-langchain4j/src/main/java/org/acme/extraction/CustomPojoExtractionService.java
index 7db927e..35f6894 100644
---
a/data-extract-langchain4j/src/main/java/org/acme/extraction/CustomPojoExtractionService.java
+++
b/data-extract-langchain4j/src/main/java/org/acme/extraction/CustomPojoExtractionService.java
@@ -21,19 +21,13 @@ import java.util.Locale;
import com.fasterxml.jackson.annotation.JsonProperty;
import dev.langchain4j.service.UserMessage;
-import io.quarkiverse.langchain4j.RegisterAiService;
+import dev.langchain4j.service.V;
import io.quarkus.runtime.annotations.RegisterForReflection;
-import jakarta.enterprise.context.ApplicationScoped;
-import org.apache.camel.Handler;
-import org.apache.camel.Header;
-import org.apache.camel.jsonpath.JsonPath;
-@RegisterAiService
-@ApplicationScoped
public interface CustomPojoExtractionService {
@RegisterForReflection
- static class CustomPojo {
+ class CustomPojo {
@JsonProperty(required = true)
public boolean customerSatisfied;
@JsonProperty(required = true)
@@ -56,21 +50,14 @@ public interface CustomPojoExtractionService {
}
}
- static final String CUSTOM_POJO_EXTRACT_PROMPT = "Extract information
about a customer from the text delimited by triple backticks: ```{text}```."
- + "The customerBirthday field should be formatted as {dateFormat}."
+ String CUSTOM_POJO_EXTRACT_PROMPT = "Extract information about a customer
from the text delimited by triple backticks: ```{{text}}```."
+ + "The customerBirthday field should be formatted as
{{dateFormat}}."
+ "The summary field should concisely relate the customer main
ask.";
/**
- * The text parameter of this method is automatically injected as {text}
in the CUSTOM_POJO_EXTRACT_PROMPT. This is
- * made possible as the code is compiled with -parameters argument in the
maven-compiler-plugin related section of
- * the pom.xml file. Without -parameters, one would need to use the @V
annotation like in the method signature
- * proposed below: extractFromText(@dev.langchain4j.service.V("text")
String text);
- *
- * Notice how Camel maps the incoming exchange to the method parameters
with annotations like @JsonPath and @Header.
- * More information on the Camel bean parameter binding feature could be
found here:
- * https://camel.apache.org/manual/bean-binding.html#_parameter_binding
+ * The text and dateFormat parameters of this method are automatically
injected as {{text}} & {{dateFormat}} in the
+ * CUSTOM_POJO_EXTRACT_PROMPT.
*/
@UserMessage(CUSTOM_POJO_EXTRACT_PROMPT)
- @Handler
- CustomPojo extractFromText(@JsonPath("$.content") String text,
@Header("expectedDateFormat") String dateFormat);
+ CustomPojo extractFromText(@V("text") String text, @V("dateFormat") String
dateFormat);
}
diff --git
a/data-extract-langchain4j/src/main/java/org/acme/extraction/DataExtractAgent.java
b/data-extract-langchain4j/src/main/java/org/acme/extraction/DataExtractAgent.java
new file mode 100644
index 0000000..c084dd6
--- /dev/null
+++
b/data-extract-langchain4j/src/main/java/org/acme/extraction/DataExtractAgent.java
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.acme.extraction;
+
+import dev.langchain4j.service.AiServices;
+import dev.langchain4j.service.tool.ToolProvider;
+import org.acme.extraction.CustomPojoExtractionService.CustomPojo;
+import org.apache.camel.component.langchain4j.agent.api.Agent;
+import org.apache.camel.component.langchain4j.agent.api.AgentConfiguration;
+import org.apache.camel.component.langchain4j.agent.api.AiAgentBody;
+
+/**
+ * Custom agent to extract data from text.
+ */
+public class DataExtractAgent implements Agent {
+ public static final String DATE_FORMAT = "YYYY-MM-DD";
+ private final AgentConfiguration configuration;
+ private final CustomPojoStore pojoStore;
+
+ public DataExtractAgent(
+ AgentConfiguration configuration,
+ CustomPojoStore pojoStore) {
+ this.configuration = configuration;
+ this.pojoStore = pojoStore;
+ }
+
+ /**
+ * Returns a JSON representation of a {@link CustomPojo}.
+ */
+ @Override
+ public String chat(AiAgentBody aiAgentBody, ToolProvider toolProvider) {
+ CustomPojo response =
createService(toolProvider).extractFromText(aiAgentBody.getUserMessage(),
DATE_FORMAT);
+
+ // Store extracted CustomPojoExtractionService.CustomPojos objects
into the CustomPojoStore for later inspection
+ pojoStore.addPojo(response);
+
+ // Return a string representation of the result POJO
+ return response.toString();
+ }
+
+ CustomPojoExtractionService createService(ToolProvider toolProvider) {
+ var builder = AiServices.builder(CustomPojoExtractionService.class)
+ .chatModel(configuration.getChatModel());
+
+ if (toolProvider != null) {
+ builder.toolProvider(toolProvider);
+ }
+
+ return builder.build();
+ }
+}
diff --git
a/data-extract-langchain4j/src/main/java/org/acme/extraction/DataExtractAgentConfiguration.java
b/data-extract-langchain4j/src/main/java/org/acme/extraction/DataExtractAgentConfiguration.java
new file mode 100644
index 0000000..41caa51
--- /dev/null
+++
b/data-extract-langchain4j/src/main/java/org/acme/extraction/DataExtractAgentConfiguration.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.acme.extraction;
+
+import java.time.Duration;
+
+import dev.langchain4j.model.ollama.OllamaChatModel;
+import io.smallrye.common.annotation.Identifier;
+import jakarta.enterprise.context.ApplicationScoped;
+import jakarta.inject.Singleton;
+import org.apache.camel.component.langchain4j.agent.api.Agent;
+import org.apache.camel.component.langchain4j.agent.api.AgentConfiguration;
+import org.eclipse.microprofile.config.inject.ConfigProperty;
+
+@ApplicationScoped
+public class DataExtractAgentConfiguration {
+ public static final String AGENT_MEMORY_ID = "data-extract-agent-memory";
+ public static final String AGENT_ID = "data-extract-agent";
+
+ @ConfigProperty(name = "langchain4j.ollama.base-url")
+ String baseUrl;
+
+ @ConfigProperty(name = "langchain4j.ollama.chat-model.model-id")
+ String chatModelId;
+
+ @Singleton
+ AgentConfiguration agentConfiguration() {
+ return new AgentConfiguration().withChatModel(OllamaChatModel.builder()
+ .baseUrl(baseUrl)
+ .topK(1)
+ .topP(0.1)
+ .modelName(chatModelId)
+ .temperature(0.0)
+ .timeout(Duration.ofMinutes(3))
+ .build());
+ }
+
+ @Singleton
+ @Identifier(AGENT_ID)
+ Agent agent(AgentConfiguration configuration, CustomPojoStore pojoStore) {
+ return new DataExtractAgent(configuration, pojoStore);
+ }
+}
diff --git
a/data-extract-langchain4j/src/main/java/org/acme/extraction/Routes.java
b/data-extract-langchain4j/src/main/java/org/acme/extraction/Routes.java
index a376aca..1899e32 100644
--- a/data-extract-langchain4j/src/main/java/org/acme/extraction/Routes.java
+++ b/data-extract-langchain4j/src/main/java/org/acme/extraction/Routes.java
@@ -20,6 +20,8 @@ import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import org.apache.camel.builder.RouteBuilder;
+import static org.acme.extraction.DataExtractAgentConfiguration.AGENT_ID;
+
@ApplicationScoped
public class Routes extends RouteBuilder {
@@ -28,15 +30,13 @@ public class Routes extends RouteBuilder {
@Override
public void configure() {
-
// Consumes file documents that contain conversation transcripts (JSON
format)
from("file:target/transcripts?sortBy=file:name")
.log("A document has been received by the camel-quarkus-file
extension: ${body}")
- .setHeader("expectedDateFormat", constant("YYYY-MM-DD"))
- // The CustomPojoExtractionService transforms the conversation
transcript into a CustomPojoExtractionService.CustomPojo
- .bean(CustomPojoExtractionService.class)
- // Store extracted CustomPojoExtractionService.CustomPojos
objects into the CustomPojoStore for later inspection
- .bean(customPojoStore);
+ // Get the content to fulfill the CustomPojoExtractService
text argument
+ .setBody().jsonpath("$.content")
+ // Initiate a conversation with the LLM
+ .toF("langchain4j-agent:%s", AGENT_ID);
// This route make it possible to inspect the extracted POJOs, mainly
used for demo and test
from("platform-http:/custom-pojo-store?produces=application/json")
diff --git
a/data-extract-langchain4j/src/main/resources/META-INF/native-image/dev.langchain4j/langchain4j-ollama/reflect-config.json
b/data-extract-langchain4j/src/main/resources/META-INF/native-image/dev.langchain4j/langchain4j-ollama/reflect-config.json
deleted file mode 100644
index 06e9e8b..0000000
---
a/data-extract-langchain4j/src/main/resources/META-INF/native-image/dev.langchain4j/langchain4j-ollama/reflect-config.json
+++ /dev/null
@@ -1,56 +0,0 @@
-[
- {
- "name" : "dev.langchain4j.model.ollama.OllamaChatRequest",
- "allDeclaredConstructors" : true,
- "allPublicConstructors" : true,
- "allDeclaredMethods" : true,
- "allPublicMethods" : true,
- "allDeclaredFields" : true,
- "allPublicFields" : true
- },
- {
- "name" : "dev.langchain4j.model.ollama.Message",
- "allDeclaredConstructors" : true,
- "allPublicConstructors" : true,
- "allDeclaredMethods" : true,
- "allPublicMethods" : true,
- "allDeclaredFields" : true,
- "allPublicFields" : true
- },
- {
- "name" : "dev.langchain4j.model.ollama.Role",
- "allDeclaredConstructors" : true,
- "allPublicConstructors" : true,
- "allDeclaredMethods" : true,
- "allPublicMethods" : true,
- "allDeclaredFields" : true,
- "allPublicFields" : true
- },
- {
- "name" : "dev.langchain4j.model.ollama.FormatSerializer",
- "allDeclaredConstructors" : true,
- "allPublicConstructors" : true,
- "allDeclaredMethods" : true,
- "allPublicMethods" : true,
- "allDeclaredFields" : true,
- "allPublicFields" : true
- },
- {
- "name" : "dev.langchain4j.model.ollama.OllamaChatResponse",
- "allDeclaredConstructors" : true,
- "allPublicConstructors" : true,
- "allDeclaredMethods" : true,
- "allPublicMethods" : true,
- "allDeclaredFields" : true,
- "allPublicFields" : true
- },
- {
- "name" : "dev.langchain4j.model.ollama.Options",
- "allDeclaredConstructors" : true,
- "allPublicConstructors" : true,
- "allDeclaredMethods" : true,
- "allPublicMethods" : true,
- "allDeclaredFields" : true,
- "allPublicFields" : true
- }
-]
\ No newline at end of file
diff --git a/data-extract-langchain4j/src/main/resources/application.properties
b/data-extract-langchain4j/src/main/resources/application.properties
index c7ef726..2938667 100644
--- a/data-extract-langchain4j/src/main/resources/application.properties
+++ b/data-extract-langchain4j/src/main/resources/application.properties
@@ -14,25 +14,10 @@
## See the License for the specific language governing permissions and
## limitations under the License.
## ---------------------------------------------------------------------------
-
-quarkus.devservices.enabled=false
quarkus.banner.enabled = false
-
-# Configure Quarkus LangChain4j that handle interactions with the Large
Language Model
-quarkus.langchain4j.ollama.base-url = http://localhost:11434
-quarkus.langchain4j.ollama.timeout = 3m
-quarkus.langchain4j.ollama.chat-model.model-id = granite3.3:2b
-quarkus.langchain4j.ollama.chat-model.temperature = 0
-# Uncomment lines below to log Ollama client requests and responses
-#quarkus.langchain4j.ollama.log-requests=true
-#quarkus.langchain4j.ollama.log-responses=true
-
-# Or uncomment lines below to log HTTP traffic between LangChain4j & the LLM
API
-#quarkus.rest-client.logging.scope=request-response
-#quarkus.rest-client.logging.body-limit=10000
-#quarkus.log.category."org.jboss.resteasy.reactive.client.logging".level=DEBUG
-
-# Configure Quarkus LangChain4j to keep a single message in memory, forgetting
about previous data extractions
-quarkus.langchain4j.chat-memory.memory-window.max-messages = 1
-
quarkus.default-locale=en_US
+
+# Adjust as per your where your Ollama instance is running
+langchain4j.ollama.base-url=http://localhost:11434
+# The chat model to use
+langchain4j.ollama.chat-model.model-id=granite3.3:2b
diff --git
a/data-extract-langchain4j/src/test/java/org/acme/extraction/OllamaTestResource.java
b/data-extract-langchain4j/src/test/java/org/acme/extraction/OllamaTestResource.java
index 8c7d0d1..7a3ad63 100644
---
a/data-extract-langchain4j/src/test/java/org/acme/extraction/OllamaTestResource.java
+++
b/data-extract-langchain4j/src/test/java/org/acme/extraction/OllamaTestResource.java
@@ -88,7 +88,7 @@ public class OllamaTestResource implements
QuarkusTestResourceLifecycleManager {
.withLogConsumer(new
Slf4jLogConsumer(LOG).withPrefix("basicAuthContainer"));
ollamaContainer.start();
- String ollamaModelId =
getConfig().getValue("quarkus.langchain4j.ollama.chat-model.model-id",
String.class);
+ String ollamaModelId =
getConfig().getValue("langchain4j.ollama.chat-model.model-id", String.class);
ExecResult result =
ollamaContainer.execInContainer("ollama", "pull", ollamaModelId);
long pullBegin = currentTimeMillis();
@@ -111,7 +111,7 @@ public class OllamaTestResource implements
QuarkusTestResourceLifecycleManager {
}
}
- return Map.of("quarkus.langchain4j.ollama.base-url", baseUrl);
+ return Map.of("langchain4j.ollama.base-url", baseUrl);
} catch (Exception ex) {
throw new RuntimeException("An issue occurred while starting
ollama container", ex);
}
diff --git
a/data-extract-langchain4j/src/test/resources/mappings/api_chat-19930290-5d0d-4c09-b256-73adbbf23475.json
b/data-extract-langchain4j/src/test/resources/mappings/api_chat-19930290-5d0d-4c09-b256-73adbbf23475.json
deleted file mode 100644
index 6bb2a80..0000000
---
a/data-extract-langchain4j/src/test/resources/mappings/api_chat-19930290-5d0d-4c09-b256-73adbbf23475.json
+++ /dev/null
@@ -1,24 +0,0 @@
-{
- "id" : "19930290-5d0d-4c09-b256-73adbbf23475",
- "name" : "api_chat",
- "request" : {
- "url" : "/api/chat",
- "method" : "POST",
- "bodyPatterns" : [ {
- "equalToJson" : "{\n \"model\" : \"granite3.3:2b\",\n \"messages\" : [
{\n \"role\" : \"assistant\",\n \"content\" : \"{\\n
\\\"customerSatisfied\\\": true,\\n \\\"customerName\\\": \\\"Sarah
London\\\",\\n \\\"customerBirthday\\\": {\\\"year\\\": 1986, \\\"month\\\":
7, \\\"day\\\": 10},\\n \\\"summary\\\": \\\"The customer, Sarah London, is
calling to declare an accident and seek reimbursement for related
expenses.\\\"\\n}\",\n \"tool_calls\" : [ ]\n }, {\n \"r [...]
- "ignoreArrayOrder" : true,
- "ignoreExtraElements" : true
- } ]
- },
- "response" : {
- "status" : 200,
- "body" :
"{\"model\":\"granite3.3:2b\",\"created_at\":\"2025-07-24T09:35:47.141867421Z\",\"message\":{\"role\":\"assistant\",\"content\":\"{\\n
\\\"customerSatisfied\\\": false,\\n \\\"customerName\\\": \\\"John
Doe\\\",\\n \\\"customerBirthday\\\": {\\\"year\\\": 2001, \\\"month\\\": 11,
\\\"day\\\": 1},\\n \\\"summary\\\": \\\"Customer John Doe is dissatisfied
with the insurance company's automatic cancellation of full reimbursement
option from his contract. He was not informed [...]
- "headers" : {
- "Date" : "Thu, 24 Jul 2025 09:35:47 GMT",
- "Content-Type" : "application/json; charset=utf-8"
- }
- },
- "uuid" : "19930290-5d0d-4c09-b256-73adbbf23475",
- "persistent" : true,
- "insertionIndex" : 5
-}
\ No newline at end of file
diff --git
a/data-extract-langchain4j/src/test/resources/mappings/api_chat-2458b71a-4789-4a07-9424-ba7a1da8bf07.json
b/data-extract-langchain4j/src/test/resources/mappings/api_chat-2458b71a-4789-4a07-9424-ba7a1da8bf07.json
new file mode 100644
index 0000000..6445703
--- /dev/null
+++
b/data-extract-langchain4j/src/test/resources/mappings/api_chat-2458b71a-4789-4a07-9424-ba7a1da8bf07.json
@@ -0,0 +1,24 @@
+{
+ "id" : "2458b71a-4789-4a07-9424-ba7a1da8bf07",
+ "name" : "api_chat",
+ "request" : {
+ "url" : "/api/chat",
+ "method" : "POST",
+ "bodyPatterns" : [ {
+ "equalToJson" : "{\n \"model\" : \"granite3.3:2b\",\n \"messages\" : [
{\n \"role\" : \"user\",\n \"content\" : \"Extract information about a
customer from the text delimited by triple backticks: ```Operator: Hello, how
may I help you ?\\nCustomer: Hello, I'm John. I need to share a problem with
you. Actually, the insurance has reimbursed only half the money I have spent
due to the accident.\\nOperator: Hello John, could you please give me your last
name so that I can find [...]
+ "ignoreArrayOrder" : true,
+ "ignoreExtraElements" : true
+ } ]
+ },
+ "response" : {
+ "status" : 200,
+ "body" :
"{\"model\":\"granite3.3:2b\",\"created_at\":\"2025-09-01T09:21:38.075300267Z\",\"message\":{\"role\":\"assistant\",\"content\":\"{\\n\\\"customerSatisfied\\\":
false,\\n\\\"customerName\\\": \\\"John Doe\\\",\\n\\\"customerBirthday\\\":
\\\"2001-11-01\\\",\\n\\\"summary\\\": \\\"Customer John Doe is dissatisfied
with the insurance reimbursement issue. The full reimbursement option was
automatically cancelled, causing him to receive only half the amount due to an
accident.\\ [...]
+ "headers" : {
+ "Date" : "Mon, 01 Sep 2025 09:21:38 GMT",
+ "Content-Type" : "application/json; charset=utf-8"
+ }
+ },
+ "uuid" : "2458b71a-4789-4a07-9424-ba7a1da8bf07",
+ "persistent" : true,
+ "insertionIndex" : 5
+}
\ No newline at end of file
diff --git
a/data-extract-langchain4j/src/test/resources/mappings/api_chat-46e7b6b7-f983-471d-b7bf-7fd271067c10.json
b/data-extract-langchain4j/src/test/resources/mappings/api_chat-46e7b6b7-f983-471d-b7bf-7fd271067c10.json
deleted file mode 100644
index 191086c..0000000
---
a/data-extract-langchain4j/src/test/resources/mappings/api_chat-46e7b6b7-f983-471d-b7bf-7fd271067c10.json
+++ /dev/null
@@ -1,24 +0,0 @@
-{
- "id" : "46e7b6b7-f983-471d-b7bf-7fd271067c10",
- "name" : "api_chat",
- "request" : {
- "url" : "/api/chat",
- "method" : "POST",
- "bodyPatterns" : [ {
- "equalToJson" : "{\n \"model\" : \"granite3.3:2b\",\n \"messages\" : [
{\n \"role\" : \"user\",\n \"content\" : \"Extract information about a
customer from the text delimited by triple backticks: ```Operator: Hello, how
may I help you ?\\nCustomer: Hello, I'm calling because I need to declare an
accident on my main vehicle.\\nOperator: Ok, can you please give me your name
?\\nCustomer: My name is Sarah London.\\nOperator: Could you please give me
your birth date ?\\nCustome [...]
- "ignoreArrayOrder" : true,
- "ignoreExtraElements" : true
- } ]
- },
- "response" : {
- "status" : 200,
- "body" :
"{\"model\":\"granite3.3:2b\",\"created_at\":\"2025-07-24T09:35:35.362459065Z\",\"message\":{\"role\":\"assistant\",\"content\":\"{\\n
\\\"customerSatisfied\\\": true,\\n \\\"customerName\\\": \\\"Sarah
London\\\",\\n \\\"customerBirthday\\\": {\\\"year\\\": 1986, \\\"month\\\":
7, \\\"day\\\": 10},\\n \\\"summary\\\": \\\"The customer, Sarah London, is
calling to declare an accident and seek reimbursement for related
expenses.\\\"\\n}\"},\"done_reason\":\"stop\",\"done\ [...]
- "headers" : {
- "Date" : "Thu, 24 Jul 2025 09:35:35 GMT",
- "Content-Type" : "application/json; charset=utf-8"
- }
- },
- "uuid" : "46e7b6b7-f983-471d-b7bf-7fd271067c10",
- "persistent" : true,
- "insertionIndex" : 6
-}
\ No newline at end of file
diff --git
a/data-extract-langchain4j/src/test/resources/mappings/api_chat-5dbaaf5e-5436-470c-a629-cee5ea860e64.json
b/data-extract-langchain4j/src/test/resources/mappings/api_chat-5dbaaf5e-5436-470c-a629-cee5ea860e64.json
new file mode 100644
index 0000000..4dcd006
--- /dev/null
+++
b/data-extract-langchain4j/src/test/resources/mappings/api_chat-5dbaaf5e-5436-470c-a629-cee5ea860e64.json
@@ -0,0 +1,24 @@
+{
+ "id" : "5dbaaf5e-5436-470c-a629-cee5ea860e64",
+ "name" : "api_chat",
+ "request" : {
+ "url" : "/api/chat",
+ "method" : "POST",
+ "bodyPatterns" : [ {
+ "equalToJson" : "{\n \"model\" : \"granite3.3:2b\",\n \"messages\" : [
{\n \"role\" : \"user\",\n \"content\" : \"Extract information about a
customer from the text delimited by triple backticks: ```Operator: Hello, how
may I help you ?\\nCustomer: Hello, I'm calling because I need to declare an
accident on my main vehicle.\\nOperator: Ok, can you please give me your name
?\\nCustomer: My name is Sarah London.\\nOperator: Could you please give me
your birth date ?\\nCustome [...]
+ "ignoreArrayOrder" : true,
+ "ignoreExtraElements" : true
+ } ]
+ },
+ "response" : {
+ "status" : 200,
+ "body" :
"{\"model\":\"granite3.3:2b\",\"created_at\":\"2025-09-01T09:21:30.815238592Z\",\"message\":{\"role\":\"assistant\",\"content\":\"{\\n\\\"customerSatisfied\\\":
true,\\n\\\"customerName\\\": \\\"Sarah
London\\\",\\n\\\"customerBirthday\\\": \\\"1986-07-10\\\",\\n\\\"summary\\\":
\\\"The customer, Sarah London, is calling to declare an accident on her main
vehicle and seek reimbursement for related
expenses.\\\"\\n}\"},\"done_reason\":\"stop\",\"done\":true,\"total_duration\"
[...]
+ "headers" : {
+ "Date" : "Mon, 01 Sep 2025 09:21:30 GMT",
+ "Content-Type" : "application/json; charset=utf-8"
+ }
+ },
+ "uuid" : "5dbaaf5e-5436-470c-a629-cee5ea860e64",
+ "persistent" : true,
+ "insertionIndex" : 6
+}
\ No newline at end of file
diff --git
a/data-extract-langchain4j/src/test/resources/mappings/api_chat-69af07bd-686f-439f-92c9-7424d9506270.json
b/data-extract-langchain4j/src/test/resources/mappings/api_chat-69af07bd-686f-439f-92c9-7424d9506270.json
deleted file mode 100644
index 959b7ec..0000000
---
a/data-extract-langchain4j/src/test/resources/mappings/api_chat-69af07bd-686f-439f-92c9-7424d9506270.json
+++ /dev/null
@@ -1,24 +0,0 @@
-{
- "id" : "69af07bd-686f-439f-92c9-7424d9506270",
- "name" : "api_chat",
- "request" : {
- "url" : "/api/chat",
- "method" : "POST",
- "bodyPatterns" : [ {
- "equalToJson" : "{\n \"model\" : \"granite3.3:2b\",\n \"messages\" : [
{\n \"role\" : \"assistant\",\n \"content\" : \"{\\n
\\\"customerSatisfied\\\": false,\\n \\\"customerName\\\": \\\"John
Doe\\\",\\n \\\"customerBirthday\\\": {\\\"year\\\": 2001, \\\"month\\\": 11,
\\\"day\\\": 1},\\n \\\"summary\\\": \\\"Customer John Doe is dissatisfied
with the insurance company's automatic cancellation of full reimbursement
option from his contract. He was not informed about thi [...]
- "ignoreArrayOrder" : true,
- "ignoreExtraElements" : true
- } ]
- },
- "response" : {
- "status" : 200,
- "body" :
"{\"model\":\"granite3.3:2b\",\"created_at\":\"2025-07-24T09:36:00.605912393Z\",\"message\":{\"role\":\"assistant\",\"content\":\"{\\n
\\\"customerSatisfied\\\": true,\\n \\\"customerName\\\": \\\"Kate
Boss\\\",\\n \\\"customerBirthday\\\": {\\\"year\\\": 1999, \\\"month\\\": 8,
\\\"day\\\": 13},\\n \\\"summary\\\": \\\"Customer Kate Boss sought assistance
from the insurance operator regarding a car accident. She initially provided
incorrect information about her last na [...]
- "headers" : {
- "Date" : "Thu, 24 Jul 2025 09:36:00 GMT",
- "Content-Type" : "application/json; charset=utf-8"
- }
- },
- "uuid" : "69af07bd-686f-439f-92c9-7424d9506270",
- "persistent" : true,
- "insertionIndex" : 4
-}
\ No newline at end of file
diff --git
a/data-extract-langchain4j/src/test/resources/mappings/api_chat-a359a6fc-e37c-4383-a99c-efa92d6e650d.json
b/data-extract-langchain4j/src/test/resources/mappings/api_chat-a359a6fc-e37c-4383-a99c-efa92d6e650d.json
new file mode 100644
index 0000000..750cd18
--- /dev/null
+++
b/data-extract-langchain4j/src/test/resources/mappings/api_chat-a359a6fc-e37c-4383-a99c-efa92d6e650d.json
@@ -0,0 +1,24 @@
+{
+ "id" : "a359a6fc-e37c-4383-a99c-efa92d6e650d",
+ "name" : "api_chat",
+ "request" : {
+ "url" : "/api/chat",
+ "method" : "POST",
+ "bodyPatterns" : [ {
+ "equalToJson" : "{\n \"model\" : \"granite3.3:2b\",\n \"messages\" : [
{\n \"role\" : \"user\",\n \"content\" : \"Extract information about a
customer from the text delimited by triple backticks: ```Operator: Hello, how
may I help you?\\nCustomer: Hello, I am currently at the police station because
I've got an accident. The police would need a proof that I have an insurance.
Could you please help me?\\nOperator: Sure, could you please remind me your
name and birth date?\\nC [...]
+ "ignoreArrayOrder" : true,
+ "ignoreExtraElements" : true
+ } ]
+ },
+ "response" : {
+ "status" : 200,
+ "body" :
"{\"model\":\"granite3.3:2b\",\"created_at\":\"2025-09-01T09:21:46.990356099Z\",\"message\":{\"role\":\"assistant\",\"content\":\"{\\n\\\"customerSatisfied\\\":
true,\\n\\\"customerName\\\": \\\"Kate Boss\\\",\\n\\\"customerBirthday\\\":
\\\"1999-08-13\\\",\\n\\\"summary\\\": \\\"Customer Kate Boss sought assistance
from the operator at a police station to provide proof of insurance following
an accident. Initially, her name was mispronounced as Hart due to marriage, but
she [...]
+ "headers" : {
+ "Date" : "Mon, 01 Sep 2025 09:21:46 GMT",
+ "Content-Type" : "application/json; charset=utf-8"
+ }
+ },
+ "uuid" : "a359a6fc-e37c-4383-a99c-efa92d6e650d",
+ "persistent" : true,
+ "insertionIndex" : 4
+}
\ No newline at end of file