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

Reply via email to