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 033bdd5f data-extract: improve date and name handling
033bdd5f is described below
commit 033bdd5f5df897a2bbfcc9686ca626837b53cdc8
Author: Alexandre Gallice <[email protected]>
AuthorDate: Wed Jan 21 15:40:38 2026 +0100
data-extract: improve date and name handling
---
.../extraction/CustomPojoExtractionService.java | 29 ++++++++++++++--------
.../java/org/acme/extraction/DataExtractAgent.java | 5 ++--
.../test/java/org/acme/extraction/RouteTest.java | 6 ++---
..._chat-18cda03a-bbe5-48d0-a35b-262b36c541a7.json | 24 ++++++++++++++++++
..._chat-4b63856f-cac5-4bc1-b66a-d01255ac40e0.json | 24 ------------------
..._chat-ae3edfa4-a510-4121-9eb2-6051c3072e69.json | 24 ++++++++++++++++++
...chat-d0af43a7-81b5-49cd-8624-a4c222c5eb4b.json} | 10 ++++----
..._chat-e8f3defd-bdcb-47f4-8782-687fd3cae6d1.json | 24 ------------------
8 files changed, 77 insertions(+), 69 deletions(-)
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 5a8a7994..c153d19b 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
@@ -16,7 +16,7 @@
*/
package org.acme.extraction;
-import java.time.LocalDate;
+import java.time.Month;
import java.util.Locale;
import com.fasterxml.jackson.annotation.JsonProperty;
@@ -24,42 +24,51 @@ import dev.langchain4j.service.UserMessage;
import dev.langchain4j.service.V;
import io.quarkus.runtime.annotations.RegisterForReflection;
-@RegisterForReflection(targets = LocalDate.class)
+@RegisterForReflection
public interface CustomPojoExtractionService {
+ @RegisterForReflection(registerFullHierarchy = true)
class CustomPojo {
@JsonProperty(required = true)
public boolean customerSatisfied;
@JsonProperty(required = true)
public String customerName;
@JsonProperty(required = true)
- public LocalDate customerBirthday;
+ public Birthday customerBirthday;
@JsonProperty(required = true)
public String summary;
private final static String FORMAT = "\n{\n"
+ "\t\"customerSatisfied\": \"%s\",\n"
+ "\t\"customerName\": \"%s\",\n"
- + "\t\"customerBirthday\": \"%td %tB %tY\",\n"
+ + "\t\"customerBirthday\": \"%02d %s %04d\",\n"
+ "\t\"summary\": \"%s\"\n"
+ "}\n";
public String toString() {
- return String.format(Locale.US, FORMAT, this.customerSatisfied,
this.customerName, this.customerBirthday,
- this.customerBirthday, this.customerBirthday,
this.summary);
+ return String.format(Locale.US, FORMAT, this.customerSatisfied,
this.customerName, this.customerBirthday.day,
+ Month.of(this.customerBirthday.month),
this.customerBirthday.year, this.summary);
}
}
+ class Birthday {
+ @JsonProperty(required = true)
+ public int year;
+ @JsonProperty(required = true)
+ public short month;
+ @JsonProperty(required = true)
+ public short day;
+ }
+
String CUSTOM_POJO_EXTRACT_PROMPT = "Extract information about a customer
from the transcript delimited by triple backticks: ```{{text}}```."
- + "The customerBirthday field should be formatted as
{{dateFormat}}."
+ + "The customerName field should be formatted as FIRSTNAME
LASTNAME, for instance Isaac Newton."
+ "The summary field should concisely relate the customer main
ask."
+ "Source any extracted field values from what is explicitly
mentioned in the transcript."
+ "Extracted field values should be as accurate as possible.";
/**
- * The text and dateFormat parameters of this method are automatically
injected as {{text}} & {{dateFormat}} in the
- * CUSTOM_POJO_EXTRACT_PROMPT.
+ * The text parameter of this method is automatically injected as {{text}}
in the CUSTOM_POJO_EXTRACT_PROMPT.
*/
@UserMessage(CUSTOM_POJO_EXTRACT_PROMPT)
- CustomPojo extractFromText(@V("text") String text, @V("dateFormat") String
dateFormat);
+ CustomPojo extractFromText(@V("text") String text);
}
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
index c084dd6a..b4de066f 100644
---
a/data-extract-langchain4j/src/main/java/org/acme/extraction/DataExtractAgent.java
+++
b/data-extract-langchain4j/src/main/java/org/acme/extraction/DataExtractAgent.java
@@ -27,7 +27,6 @@ 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;
@@ -42,8 +41,8 @@ public class DataExtractAgent implements Agent {
* 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);
+ public String chat(AiAgentBody<?> aiAgentBody, ToolProvider toolProvider) {
+ CustomPojo response =
createService(toolProvider).extractFromText(aiAgentBody.getUserMessage());
// Store extracted CustomPojoExtractionService.CustomPojos objects
into the CustomPojoStore for later inspection
pojoStore.addPojo(response);
diff --git
a/data-extract-langchain4j/src/test/java/org/acme/extraction/RouteTest.java
b/data-extract-langchain4j/src/test/java/org/acme/extraction/RouteTest.java
index fe466c44..913a34fe 100644
--- a/data-extract-langchain4j/src/test/java/org/acme/extraction/RouteTest.java
+++ b/data-extract-langchain4j/src/test/java/org/acme/extraction/RouteTest.java
@@ -67,17 +67,17 @@ public class RouteTest {
// Assert values of the first extracted POJO
.body("pojos[0].customerSatisfied", is("true"))
.body("pojos[0].customerName", is("Sarah London"))
- .body("pojos[0].customerBirthday", is("10 July 1986"))
+ .body("pojos[0].customerBirthday", is("10 JULY 1986"))
.body("pojos[0].summary", not(empty()))
// Assert values of the second extracted POJO
.body("pojos[1].customerSatisfied", is("false"))
.body("pojos[1].customerName", is("John Doe"))
- .body("pojos[1].customerBirthday", is("01 November 2001"))
+ .body("pojos[1].customerBirthday", is("01 NOVEMBER 2001"))
.body("pojos[1].summary", not(empty()))
// Assert values of the third extracted POJO
.body("pojos[2].customerSatisfied", is("true"))
.body("pojos[2].customerName", is("Kate Boss"))
- .body("pojos[2].customerBirthday", is("13 August 1999"))
+ .body("pojos[2].customerBirthday", is("13 AUGUST 1999"))
.body("pojos[2].summary", not(empty()));
}
diff --git
a/data-extract-langchain4j/src/test/resources/mappings/api_chat-18cda03a-bbe5-48d0-a35b-262b36c541a7.json
b/data-extract-langchain4j/src/test/resources/mappings/api_chat-18cda03a-bbe5-48d0-a35b-262b36c541a7.json
new file mode 100644
index 00000000..2e325121
--- /dev/null
+++
b/data-extract-langchain4j/src/test/resources/mappings/api_chat-18cda03a-bbe5-48d0-a35b-262b36c541a7.json
@@ -0,0 +1,24 @@
+{
+ "id" : "18cda03a-bbe5-48d0-a35b-262b36c541a7",
+ "name" : "api_chat",
+ "request" : {
+ "url" : "/api/chat",
+ "method" : "POST",
+ "bodyPatterns" : [ {
+ "equalToJson" : "{\n \"model\" : \"granite4:3b-h\",\n \"messages\" : [
{\n \"role\" : \"user\",\n \"content\" : \"Extract information about a
customer from the transcript 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 ?\\nC [...]
+ "ignoreArrayOrder" : true,
+ "ignoreExtraElements" : true
+ } ]
+ },
+ "response" : {
+ "status" : 200,
+ "body" :
"{\"model\":\"granite4:3b-h\",\"created_at\":\"2026-01-20T14:46:58.833215508Z\",\"message\":{\"role\":\"assistant\",\"content\":\"{\\n
\\\"customerSatisfied\\\": true,\\n \\\"customerName\\\": \\\"Sarah
London\\\",\\n \\\"customerBirthday\\\": {\\n \\\"year\\\": 1986,\\n
\\\"month\\\": 7,\\n \\\"day\\\": 10\\n },\\n \\\"summary\\\": \\\"The
customer, Sarah London, needed to declare an accident on her main vehicle and
was informed that all expenses linked to the [...]
+ "headers" : {
+ "Date" : "Tue, 20 Jan 2026 14:46:58 GMT",
+ "Content-Type" : "application/json; charset=utf-8"
+ }
+ },
+ "uuid" : "18cda03a-bbe5-48d0-a35b-262b36c541a7",
+ "persistent" : true,
+ "insertionIndex" : 6
+}
\ No newline at end of file
diff --git
a/data-extract-langchain4j/src/test/resources/mappings/api_chat-4b63856f-cac5-4bc1-b66a-d01255ac40e0.json
b/data-extract-langchain4j/src/test/resources/mappings/api_chat-4b63856f-cac5-4bc1-b66a-d01255ac40e0.json
deleted file mode 100644
index 12285be4..00000000
---
a/data-extract-langchain4j/src/test/resources/mappings/api_chat-4b63856f-cac5-4bc1-b66a-d01255ac40e0.json
+++ /dev/null
@@ -1,24 +0,0 @@
-{
- "id" : "4b63856f-cac5-4bc1-b66a-d01255ac40e0",
- "name" : "api_chat",
- "request" : {
- "url" : "/api/chat",
- "method" : "POST",
- "bodyPatterns" : [ {
- "equalToJson" : "{\n \"model\" : \"granite4:3b-h\",\n \"messages\" : [
{\n \"role\" : \"user\",\n \"content\" : \"Extract information about a
customer from the transcript 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 ?\\nC [...]
- "ignoreArrayOrder" : true,
- "ignoreExtraElements" : true
- } ]
- },
- "response" : {
- "status" : 200,
- "body" :
"{\"model\":\"granite4:3b-h\",\"created_at\":\"2026-01-15T15:03:26.59496985Z\",\"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,
called to declare an accident on her main vehicle. The operator confirmed that
all expenses linked to the accident would be [...]
- "headers" : {
- "Date" : "Thu, 15 Jan 2026 15:03:26 GMT",
- "Content-Type" : "application/json; charset=utf-8"
- }
- },
- "uuid" : "4b63856f-cac5-4bc1-b66a-d01255ac40e0",
- "persistent" : true,
- "insertionIndex" : 6
-}
\ No newline at end of file
diff --git
a/data-extract-langchain4j/src/test/resources/mappings/api_chat-ae3edfa4-a510-4121-9eb2-6051c3072e69.json
b/data-extract-langchain4j/src/test/resources/mappings/api_chat-ae3edfa4-a510-4121-9eb2-6051c3072e69.json
new file mode 100644
index 00000000..4a9422da
--- /dev/null
+++
b/data-extract-langchain4j/src/test/resources/mappings/api_chat-ae3edfa4-a510-4121-9eb2-6051c3072e69.json
@@ -0,0 +1,24 @@
+{
+ "id" : "ae3edfa4-a510-4121-9eb2-6051c3072e69",
+ "name" : "api_chat",
+ "request" : {
+ "url" : "/api/chat",
+ "method" : "POST",
+ "bodyPatterns" : [ {
+ "equalToJson" : "{\n \"model\" : \"granite4:3b-h\",\n \"messages\" : [
{\n \"role\" : \"user\",\n \"content\" : \"Extract information about a
customer from the transcript 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 dat [...]
+ "ignoreArrayOrder" : true,
+ "ignoreExtraElements" : true
+ } ]
+ },
+ "response" : {
+ "status" : 200,
+ "body" :
"{\"model\":\"granite4:3b-h\",\"created_at\":\"2026-01-20T14:47:27.992920518Z\",\"message\":{\"role\":\"assistant\",\"content\":\"{\\n
\\\"customerSatisfied\\\": true,\\n \\\"customerName\\\": \\\"Kate
Boss\\\",\\n \\\"customerBirthday\\\": {\\n \\\"year\\\": 1999,\\n
\\\"month\\\": 8,\\n \\\"day\\\": 13\\n },\\n \\\"summary\\\": \\\"The
customer, Kate Boss, had an accident and needed proof of insurance from the
police station. The operator helped by verifying [...]
+ "headers" : {
+ "Date" : "Tue, 20 Jan 2026 14:47:27 GMT",
+ "Content-Type" : "application/json; charset=utf-8"
+ }
+ },
+ "uuid" : "ae3edfa4-a510-4121-9eb2-6051c3072e69",
+ "persistent" : true,
+ "insertionIndex" : 4
+}
\ No newline at end of file
diff --git
a/data-extract-langchain4j/src/test/resources/mappings/api_chat-be38bae8-7817-4141-8b20-2cff30446e53.json
b/data-extract-langchain4j/src/test/resources/mappings/api_chat-d0af43a7-81b5-49cd-8624-a4c222c5eb4b.json
similarity index 50%
rename from
data-extract-langchain4j/src/test/resources/mappings/api_chat-be38bae8-7817-4141-8b20-2cff30446e53.json
rename to
data-extract-langchain4j/src/test/resources/mappings/api_chat-d0af43a7-81b5-49cd-8624-a4c222c5eb4b.json
index f72b3e9e..fdb405c8 100644
---
a/data-extract-langchain4j/src/test/resources/mappings/api_chat-be38bae8-7817-4141-8b20-2cff30446e53.json
+++
b/data-extract-langchain4j/src/test/resources/mappings/api_chat-d0af43a7-81b5-49cd-8624-a4c222c5eb4b.json
@@ -1,24 +1,24 @@
{
- "id" : "be38bae8-7817-4141-8b20-2cff30446e53",
+ "id" : "d0af43a7-81b5-49cd-8624-a4c222c5eb4b",
"name" : "api_chat",
"request" : {
"url" : "/api/chat",
"method" : "POST",
"bodyPatterns" : [ {
- "equalToJson" : "{\n \"model\" : \"granite4:3b-h\",\n \"messages\" : [
{\n \"role\" : \"user\",\n \"content\" : \"Extract information about a
customer from the transcript 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 [...]
+ "equalToJson" : "{\n \"model\" : \"granite4:3b-h\",\n \"messages\" : [
{\n \"role\" : \"user\",\n \"content\" : \"Extract information about a
customer from the transcript 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 [...]
"ignoreArrayOrder" : true,
"ignoreExtraElements" : true
} ]
},
"response" : {
"status" : 200,
- "body" :
"{\"model\":\"granite4:3b-h\",\"created_at\":\"2026-01-15T15:03:40.273238709Z\",\"message\":{\"role\":\"assistant\",\"content\":\"{\\n
\\\"customerSatisfied\\\": false,\\n \\\"customerName\\\": \\\"John
Doe\\\",\\n \\\"customerBirthday\\\": {\\n \\\"year\\\": 2001,\\n
\\\"month\\\": 11,\\n \\\"day\\\": 1\\n },\\n \\\"summary\\\":
\\\"Customer John Doe is dissatisfied with the insurance company's decision to
cancel the full reimbursement option automatically. He [...]
+ "body" :
"{\"model\":\"granite4:3b-h\",\"created_at\":\"2026-01-20T14:47:13.730091697Z\",\"message\":{\"role\":\"assistant\",\"content\":\"{\\n
\\\"customerSatisfied\\\": false,\\n \\\"customerName\\\": \\\"John
Doe\\\",\\n \\\"customerBirthday\\\": {\\n \\\"year\\\": 2001,\\n
\\\"month\\\": 11,\\n \\\"day\\\": 1\\n },\\n \\\"summary\\\": \\\"The
customer, John Doe, is dissatisfied as his insurance company did not notify him
about the cancellation of full reimbursement [...]
"headers" : {
- "Date" : "Thu, 15 Jan 2026 15:03:40 GMT",
+ "Date" : "Tue, 20 Jan 2026 14:47:13 GMT",
"Content-Type" : "application/json; charset=utf-8"
}
},
- "uuid" : "be38bae8-7817-4141-8b20-2cff30446e53",
+ "uuid" : "d0af43a7-81b5-49cd-8624-a4c222c5eb4b",
"persistent" : true,
"insertionIndex" : 5
}
\ No newline at end of file
diff --git
a/data-extract-langchain4j/src/test/resources/mappings/api_chat-e8f3defd-bdcb-47f4-8782-687fd3cae6d1.json
b/data-extract-langchain4j/src/test/resources/mappings/api_chat-e8f3defd-bdcb-47f4-8782-687fd3cae6d1.json
deleted file mode 100644
index 3c634a2b..00000000
---
a/data-extract-langchain4j/src/test/resources/mappings/api_chat-e8f3defd-bdcb-47f4-8782-687fd3cae6d1.json
+++ /dev/null
@@ -1,24 +0,0 @@
-{
- "id" : "e8f3defd-bdcb-47f4-8782-687fd3cae6d1",
- "name" : "api_chat",
- "request" : {
- "url" : "/api/chat",
- "method" : "POST",
- "bodyPatterns" : [ {
- "equalToJson" : "{\n \"model\" : \"granite4:3b-h\",\n \"messages\" : [
{\n \"role\" : \"user\",\n \"content\" : \"Extract information about a
customer from the transcript 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 dat [...]
- "ignoreArrayOrder" : true,
- "ignoreExtraElements" : true
- } ]
- },
- "response" : {
- "status" : 200,
- "body" :
"{\"model\":\"granite4:3b-h\",\"created_at\":\"2026-01-15T15:03:54.19103477Z\",\"message\":{\"role\":\"assistant\",\"content\":\"{\\n
\\\"customerSatisfied\\\": true,\\n \\\"customerName\\\": \\\"Kate
Boss\\\",\\n \\\"customerBirthday\\\": {\\\"year\\\": 1999, \\\"month\\\": 8,
\\\"day\\\": 13},\\n \\\"summary\\\": \\\"The customer Kate Boss requested
assistance in providing proof of insurance for an accident she was involved in
at a police station. The operator helped v [...]
- "headers" : {
- "Date" : "Thu, 15 Jan 2026 15:03:54 GMT",
- "Content-Type" : "application/json; charset=utf-8"
- }
- },
- "uuid" : "e8f3defd-bdcb-47f4-8782-687fd3cae6d1",
- "persistent" : true,
- "insertionIndex" : 4
-}
\ No newline at end of file