This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/main by this push:
     new 0e98c78172eb CAMEL-23951: Expose agent Result sources and tool 
executions as headers
0e98c78172eb is described below

commit 0e98c78172eb42807771cb2866cf21c22b7e3da7
Author: Omar Atie <[email protected]>
AuthorDate: Tue Jul 21 00:06:51 2026 -0700

    CAMEL-23951: Expose agent Result sources and tool executions as headers
    
    Add CamelLangChain4jAgentSources and CamelLangChain4jAgentToolExecutions
    output headers to the langchain4j-agent producer. RAG sources and tool
    execution details from the LangChain4j Result are now available on the
    exchange for observability, auditing, and downstream routing. Headers are
    only set when the result contains non-empty data.
    
    Closes #24917
---
 .../catalog/components/langchain4j-agent.json      |   4 +-
 .../component/langchain4j/agent/api/Headers.java   |   8 +
 .../langchain4j/agent/langchain4j-agent.json       |   4 +-
 .../agent/LangChain4jAgentProducer.java            |  12 +-
 .../agent/LangChain4jAgentResultHeadersTest.java   | 223 +++++++++++++++++++++
 .../ROOT/pages/camel-4x-upgrade-guide-4_22.adoc    |   5 +
 .../LangChain4jAgentEndpointBuilderFactory.java    |  27 +++
 7 files changed, 279 insertions(+), 4 deletions(-)

diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/langchain4j-agent.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/langchain4j-agent.json
index 3adf1145df77..69f27508f539 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/langchain4j-agent.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/langchain4j-agent.json
@@ -46,7 +46,9 @@
     "CamelLangChain4jAgentFinishReason": { "index": 6, "kind": "header", 
"displayName": "", "group": "producer", "label": "", "required": false, 
"javaType": "dev.langchain4j.model.output.FinishReason", "enum": [ "STOP", 
"LENGTH", "TOOL_EXECUTION", "CONTENT_FILTER", "OTHER" ], "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": "The 
Finish Reason.", "constantName": 
"org.apache.camel.component.langchain4j.agent.api.Headers#FINISH_REASON" },
     "CamelLangChain4jAgentInputTokenCount": { "index": 7, "kind": "header", 
"displayName": "", "group": "producer", "label": "", "required": false, 
"javaType": "int", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The Input Token Count.", 
"constantName": 
"org.apache.camel.component.langchain4j.agent.api.Headers#INPUT_TOKEN_COUNT" },
     "CamelLangChain4jAgentOutputTokenCount": { "index": 8, "kind": "header", 
"displayName": "", "group": "producer", "label": "", "required": false, 
"javaType": "int", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The Output Token Count.", 
"constantName": 
"org.apache.camel.component.langchain4j.agent.api.Headers#OUTPUT_TOKEN_COUNT" },
-    "CamelLangChain4jAgentTotalTokenCount": { "index": 9, "kind": "header", 
"displayName": "", "group": "producer", "label": "", "required": false, 
"javaType": "int", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The Total Token Count.", 
"constantName": 
"org.apache.camel.component.langchain4j.agent.api.Headers#TOTAL_TOKEN_COUNT" }
+    "CamelLangChain4jAgentTotalTokenCount": { "index": 9, "kind": "header", 
"displayName": "", "group": "producer", "label": "", "required": false, 
"javaType": "int", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The Total Token Count.", 
"constantName": 
"org.apache.camel.component.langchain4j.agent.api.Headers#TOTAL_TOKEN_COUNT" },
+    "CamelLangChain4jAgentSources": { "index": 10, "kind": "header", 
"displayName": "", "group": "producer", "label": "", "required": false, 
"javaType": "java.util.List<dev.langchain4j.rag.content.Content>", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "RAG sources retrieved during agent invocation.", 
"constantName": 
"org.apache.camel.component.langchain4j.agent.api.Headers#SOURCES" },
+    "CamelLangChain4jAgentToolExecutions": { "index": 11, "kind": "header", 
"displayName": "", "group": "producer", "label": "", "required": false, 
"javaType": "java.util.List<dev.langchain4j.service.tool.ToolExecution>", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "Tool executions performed during agent invocation.", 
"constantName": 
"org.apache.camel.component.langchain4j.agent.api.Headers#TOOL_EXECUTIONS" }
   },
   "properties": {
     "agentId": { "index": 0, "kind": "path", "displayName": "Agent Id", 
"group": "producer", "label": "", "required": true, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "The Agent id" },
diff --git 
a/components/camel-ai/camel-langchain4j-agent-api/src/main/java/org/apache/camel/component/langchain4j/agent/api/Headers.java
 
b/components/camel-ai/camel-langchain4j-agent-api/src/main/java/org/apache/camel/component/langchain4j/agent/api/Headers.java
index bb858e62da52..c10f933ffa7d 100644
--- 
a/components/camel-ai/camel-langchain4j-agent-api/src/main/java/org/apache/camel/component/langchain4j/agent/api/Headers.java
+++ 
b/components/camel-ai/camel-langchain4j-agent-api/src/main/java/org/apache/camel/component/langchain4j/agent/api/Headers.java
@@ -55,4 +55,12 @@ public class Headers {
 
     @Metadata(description = "The Total Token Count.", javaType = "int")
     public static final String TOTAL_TOKEN_COUNT = 
"CamelLangChain4jAgentTotalTokenCount";
+
+    @Metadata(description = "RAG sources retrieved during agent invocation.",
+              javaType = "java.util.List<dev.langchain4j.rag.content.Content>")
+    public static final String SOURCES = "CamelLangChain4jAgentSources";
+
+    @Metadata(description = "Tool executions performed during agent 
invocation.",
+              javaType = 
"java.util.List<dev.langchain4j.service.tool.ToolExecution>")
+    public static final String TOOL_EXECUTIONS = 
"CamelLangChain4jAgentToolExecutions";
 }
diff --git 
a/components/camel-ai/camel-langchain4j-agent/src/generated/resources/META-INF/org/apache/camel/component/langchain4j/agent/langchain4j-agent.json
 
b/components/camel-ai/camel-langchain4j-agent/src/generated/resources/META-INF/org/apache/camel/component/langchain4j/agent/langchain4j-agent.json
index 3adf1145df77..69f27508f539 100644
--- 
a/components/camel-ai/camel-langchain4j-agent/src/generated/resources/META-INF/org/apache/camel/component/langchain4j/agent/langchain4j-agent.json
+++ 
b/components/camel-ai/camel-langchain4j-agent/src/generated/resources/META-INF/org/apache/camel/component/langchain4j/agent/langchain4j-agent.json
@@ -46,7 +46,9 @@
     "CamelLangChain4jAgentFinishReason": { "index": 6, "kind": "header", 
"displayName": "", "group": "producer", "label": "", "required": false, 
"javaType": "dev.langchain4j.model.output.FinishReason", "enum": [ "STOP", 
"LENGTH", "TOOL_EXECUTION", "CONTENT_FILTER", "OTHER" ], "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": "The 
Finish Reason.", "constantName": 
"org.apache.camel.component.langchain4j.agent.api.Headers#FINISH_REASON" },
     "CamelLangChain4jAgentInputTokenCount": { "index": 7, "kind": "header", 
"displayName": "", "group": "producer", "label": "", "required": false, 
"javaType": "int", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The Input Token Count.", 
"constantName": 
"org.apache.camel.component.langchain4j.agent.api.Headers#INPUT_TOKEN_COUNT" },
     "CamelLangChain4jAgentOutputTokenCount": { "index": 8, "kind": "header", 
"displayName": "", "group": "producer", "label": "", "required": false, 
"javaType": "int", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The Output Token Count.", 
"constantName": 
"org.apache.camel.component.langchain4j.agent.api.Headers#OUTPUT_TOKEN_COUNT" },
-    "CamelLangChain4jAgentTotalTokenCount": { "index": 9, "kind": "header", 
"displayName": "", "group": "producer", "label": "", "required": false, 
"javaType": "int", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The Total Token Count.", 
"constantName": 
"org.apache.camel.component.langchain4j.agent.api.Headers#TOTAL_TOKEN_COUNT" }
+    "CamelLangChain4jAgentTotalTokenCount": { "index": 9, "kind": "header", 
"displayName": "", "group": "producer", "label": "", "required": false, 
"javaType": "int", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The Total Token Count.", 
"constantName": 
"org.apache.camel.component.langchain4j.agent.api.Headers#TOTAL_TOKEN_COUNT" },
+    "CamelLangChain4jAgentSources": { "index": 10, "kind": "header", 
"displayName": "", "group": "producer", "label": "", "required": false, 
"javaType": "java.util.List<dev.langchain4j.rag.content.Content>", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "RAG sources retrieved during agent invocation.", 
"constantName": 
"org.apache.camel.component.langchain4j.agent.api.Headers#SOURCES" },
+    "CamelLangChain4jAgentToolExecutions": { "index": 11, "kind": "header", 
"displayName": "", "group": "producer", "label": "", "required": false, 
"javaType": "java.util.List<dev.langchain4j.service.tool.ToolExecution>", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "Tool executions performed during agent invocation.", 
"constantName": 
"org.apache.camel.component.langchain4j.agent.api.Headers#TOOL_EXECUTIONS" }
   },
   "properties": {
     "agentId": { "index": 0, "kind": "path", "displayName": "Agent Id", 
"group": "producer", "label": "", "required": true, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "The Agent id" },
diff --git 
a/components/camel-ai/camel-langchain4j-agent/src/main/java/org/apache/camel/component/langchain4j/agent/LangChain4jAgentProducer.java
 
b/components/camel-ai/camel-langchain4j-agent/src/main/java/org/apache/camel/component/langchain4j/agent/LangChain4jAgentProducer.java
index 13219372ccb6..b03386367032 100644
--- 
a/components/camel-ai/camel-langchain4j-agent/src/main/java/org/apache/camel/component/langchain4j/agent/LangChain4jAgentProducer.java
+++ 
b/components/camel-ai/camel-langchain4j-agent/src/main/java/org/apache/camel/component/langchain4j/agent/LangChain4jAgentProducer.java
@@ -128,10 +128,10 @@ public class LangChain4jAgentProducer extends 
DefaultProducer {
         ToolProvider toolProvider = createComposedToolProvider(tags, exchange);
         Result<String> result = agent.chat(aiAgentBody, toolProvider);
         exchange.getMessage().setBody(result.content());
-        populateTokenUsageHeaders(result, exchange);
+        populateResultHeaders(result, exchange);
     }
 
-    private void populateTokenUsageHeaders(Result<String> result, Exchange 
exchange) {
+    private void populateResultHeaders(Result<String> result, Exchange 
exchange) {
         Message message = exchange.getMessage();
 
         if (result.finishReason() != null) {
@@ -143,6 +143,14 @@ public class LangChain4jAgentProducer extends 
DefaultProducer {
             message.setHeader(Headers.OUTPUT_TOKEN_COUNT, 
result.tokenUsage().outputTokenCount());
             message.setHeader(Headers.TOTAL_TOKEN_COUNT, 
result.tokenUsage().totalTokenCount());
         }
+
+        if (result.sources() != null && !result.sources().isEmpty()) {
+            message.setHeader(Headers.SOURCES, result.sources());
+        }
+
+        if (result.toolExecutions() != null && 
!result.toolExecutions().isEmpty()) {
+            message.setHeader(Headers.TOOL_EXECUTIONS, 
result.toolExecutions());
+        }
     }
 
     /**
diff --git 
a/components/camel-ai/camel-langchain4j-agent/src/test/java/org/apache/camel/component/langchain4j/agent/LangChain4jAgentResultHeadersTest.java
 
b/components/camel-ai/camel-langchain4j-agent/src/test/java/org/apache/camel/component/langchain4j/agent/LangChain4jAgentResultHeadersTest.java
new file mode 100644
index 000000000000..ad359d87a093
--- /dev/null
+++ 
b/components/camel-ai/camel-langchain4j-agent/src/test/java/org/apache/camel/component/langchain4j/agent/LangChain4jAgentResultHeadersTest.java
@@ -0,0 +1,223 @@
+/*
+ * 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.apache.camel.component.langchain4j.agent;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
+
+import dev.langchain4j.agent.tool.ToolExecutionRequest;
+import dev.langchain4j.invocation.InvocationContext;
+import dev.langchain4j.model.output.FinishReason;
+import dev.langchain4j.model.output.TokenUsage;
+import dev.langchain4j.rag.content.Content;
+import dev.langchain4j.service.Result;
+import dev.langchain4j.service.tool.ToolExecution;
+import dev.langchain4j.service.tool.ToolExecutionResult;
+import org.apache.camel.Exchange;
+import org.apache.camel.RoutesBuilder;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.langchain4j.agent.api.Agent;
+import org.apache.camel.component.langchain4j.agent.api.Headers;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.spi.Registry;
+import org.apache.camel.test.junit6.CamelTestSupport;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertSame;
+
+class LangChain4jAgentResultHeadersTest extends CamelTestSupport {
+
+    private final AtomicReference<Agent> agentRef = new AtomicReference<>();
+
+    @Override
+    protected void bindToRegistry(Registry registry) {
+        registry.bind("testAgent", (Agent) (body, exchange) -> 
agentRef.get().chat(body, exchange));
+    }
+
+    @Override
+    protected RoutesBuilder createRouteBuilder() {
+        return new RouteBuilder() {
+            @Override
+            public void configure() {
+                from("direct:start")
+                        .to("langchain4j-agent:test?agent=#testAgent")
+                        .to("mock:result");
+            }
+        };
+    }
+
+    @BeforeEach
+    void resetAgent() {
+        agentRef.set((body, exchange) -> {
+            throw new UnsupportedOperationException("Agent stub must be 
configured per test");
+        });
+    }
+
+    @Test
+    void shouldPopulateAllResultHeaders() throws Exception {
+        Content ragSource = Content.from("Apache Camel documentation excerpt");
+        ToolExecution toolExecution = toolExecution("call-1", "weather", 
"{\"city\":\"London\"}", "Sunny, 22C");
+
+        agentRef.set((body, exchange) -> Result.<String> builder()
+                .content("The weather in London is sunny.")
+                .finishReason(FinishReason.STOP)
+                .tokenUsage(new TokenUsage(120, 30, 150))
+                .sources(List.of(ragSource))
+                .toolExecutions(List.of(toolExecution))
+                .build());
+
+        MockEndpoint mock = getMockEndpoint("mock:result");
+        mock.expectedMessageCount(1);
+
+        template.sendBody("direct:start", "What is the weather in London?");
+
+        mock.assertIsSatisfied(10, TimeUnit.SECONDS);
+
+        Exchange exchange = mock.getExchanges().get(0);
+        assertEquals("The weather in London is sunny.", 
exchange.getMessage().getBody(String.class));
+        assertEquals(FinishReason.STOP, 
exchange.getMessage().getHeader(Headers.FINISH_REASON));
+        assertEquals(120, 
exchange.getMessage().getHeader(Headers.INPUT_TOKEN_COUNT, Integer.class));
+        assertEquals(30, 
exchange.getMessage().getHeader(Headers.OUTPUT_TOKEN_COUNT, Integer.class));
+        assertEquals(150, 
exchange.getMessage().getHeader(Headers.TOTAL_TOKEN_COUNT, Integer.class));
+
+        @SuppressWarnings("unchecked")
+        List<Content> sources = 
exchange.getMessage().getHeader(Headers.SOURCES, List.class);
+        assertEquals(1, sources.size());
+        assertSame(ragSource, sources.get(0));
+
+        @SuppressWarnings("unchecked")
+        List<ToolExecution> toolExecutions = 
exchange.getMessage().getHeader(Headers.TOOL_EXECUTIONS, List.class);
+        assertEquals(1, toolExecutions.size());
+        assertSame(toolExecution, toolExecutions.get(0));
+        assertEquals("weather", toolExecutions.get(0).request().name());
+        assertEquals("Sunny, 22C", toolExecutions.get(0).result());
+    }
+
+    @Test
+    void shouldNotSetSourcesOrToolExecutionsWhenEmpty() throws Exception {
+        agentRef.set((body, exchange) -> Result.<String> builder()
+                .content("Plain answer")
+                .finishReason(FinishReason.STOP)
+                .tokenUsage(new TokenUsage(10, 5, 15))
+                .sources(Collections.emptyList())
+                .toolExecutions(Collections.emptyList())
+                .build());
+
+        MockEndpoint mock = getMockEndpoint("mock:result");
+        mock.expectedMessageCount(1);
+
+        template.sendBody("direct:start", "Hello");
+
+        mock.assertIsSatisfied(10, TimeUnit.SECONDS);
+
+        Exchange exchange = mock.getExchanges().get(0);
+        assertEquals("Plain answer", 
exchange.getMessage().getBody(String.class));
+        assertEquals(FinishReason.STOP, 
exchange.getMessage().getHeader(Headers.FINISH_REASON));
+        assertNull(exchange.getMessage().getHeader(Headers.SOURCES));
+        assertNull(exchange.getMessage().getHeader(Headers.TOOL_EXECUTIONS));
+    }
+
+    @Test
+    void shouldNotSetSourcesOrToolExecutionsWhenAbsent() throws Exception {
+        agentRef.set((body, exchange) -> Result.<String> builder()
+                .content("Minimal answer")
+                .build());
+
+        MockEndpoint mock = getMockEndpoint("mock:result");
+        mock.expectedMessageCount(1);
+
+        template.sendBody("direct:start", "Hello");
+
+        mock.assertIsSatisfied(10, TimeUnit.SECONDS);
+
+        Exchange exchange = mock.getExchanges().get(0);
+        assertEquals("Minimal answer", 
exchange.getMessage().getBody(String.class));
+        assertNull(exchange.getMessage().getHeader(Headers.FINISH_REASON));
+        assertNull(exchange.getMessage().getHeader(Headers.INPUT_TOKEN_COUNT));
+        
assertNull(exchange.getMessage().getHeader(Headers.OUTPUT_TOKEN_COUNT));
+        assertNull(exchange.getMessage().getHeader(Headers.TOTAL_TOKEN_COUNT));
+        assertNull(exchange.getMessage().getHeader(Headers.SOURCES));
+        assertNull(exchange.getMessage().getHeader(Headers.TOOL_EXECUTIONS));
+    }
+
+    @Test
+    void shouldPopulateOnlySourcesWhenNoToolsExecuted() throws Exception {
+        Content ragSource = Content.from("Product manual section 3.2");
+
+        agentRef.set((body, exchange) -> Result.<String> builder()
+                .content("Based on the manual, reset the device.")
+                .sources(List.of(ragSource))
+                .build());
+
+        MockEndpoint mock = getMockEndpoint("mock:result");
+        mock.expectedMessageCount(1);
+
+        template.sendBody("direct:start", "How do I reset?");
+
+        mock.assertIsSatisfied(10, TimeUnit.SECONDS);
+
+        Exchange exchange = mock.getExchanges().get(0);
+        @SuppressWarnings("unchecked")
+        List<Content> sources = 
exchange.getMessage().getHeader(Headers.SOURCES, List.class);
+        assertEquals(1, sources.size());
+        assertSame(ragSource, sources.get(0));
+        assertNull(exchange.getMessage().getHeader(Headers.TOOL_EXECUTIONS));
+    }
+
+    @Test
+    void shouldPopulateOnlyToolExecutionsWhenNoRagSources() throws Exception {
+        ToolExecution toolExecution = toolExecution("call-2", "inventory", 
"{\"sku\":\"ABC-123\"}", "42 units in stock");
+
+        agentRef.set((body, exchange) -> Result.<String> builder()
+                .content("There are 42 units in stock.")
+                .toolExecutions(List.of(toolExecution))
+                .build());
+
+        MockEndpoint mock = getMockEndpoint("mock:result");
+        mock.expectedMessageCount(1);
+
+        template.sendBody("direct:start", "Stock level for ABC-123?");
+
+        mock.assertIsSatisfied(10, TimeUnit.SECONDS);
+
+        Exchange exchange = mock.getExchanges().get(0);
+        assertNull(exchange.getMessage().getHeader(Headers.SOURCES));
+        @SuppressWarnings("unchecked")
+        List<ToolExecution> toolExecutions = 
exchange.getMessage().getHeader(Headers.TOOL_EXECUTIONS, List.class);
+        assertEquals(1, toolExecutions.size());
+        assertEquals("inventory", toolExecutions.get(0).request().name());
+        assertFalse(toolExecutions.get(0).hasFailed());
+    }
+
+    private static ToolExecution toolExecution(String id, String name, String 
arguments, String resultText) {
+        return ToolExecution.builder()
+                .request(ToolExecutionRequest.builder()
+                        .id(id)
+                        .name(name)
+                        .arguments(arguments)
+                        .build())
+                
.result(ToolExecutionResult.builder().resultText(resultText).build())
+                .invocationContext(InvocationContext.builder().build())
+                .build();
+    }
+}
diff --git 
a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_22.adoc 
b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_22.adoc
index 25be5e69c485..5013105a3376 100644
--- a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_22.adoc
+++ b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_22.adoc
@@ -176,6 +176,11 @@ String chat(AiAgentBody<?> aiAgentBody, ToolProvider 
toolProvider);
 Result<String> chat(AiAgentBody<?> aiAgentBody, ToolProvider toolProvider);
 ----
 
+When RAG or tools are used, the agent producer also exposes 
`CamelLangChain4jAgentSources`
+(`List<dev.langchain4j.rag.content.Content>`) and 
`CamelLangChain4jAgentToolExecutions`
+(`List<dev.langchain4j.service.tool.ToolExecution>`) as exchange headers when 
present in the
+`Result`.
+
 === camel-langchain4j-chat
 
 The helper classes `OpenAiChatLanguageModelBuilder` and 
`HugginFaceChatLanguageModelBuilder` have been removed.
diff --git 
a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/LangChain4jAgentEndpointBuilderFactory.java
 
b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/LangChain4jAgentEndpointBuilderFactory.java
index f5bcb6644e06..2bb0c6dfa507 100644
--- 
a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/LangChain4jAgentEndpointBuilderFactory.java
+++ 
b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/LangChain4jAgentEndpointBuilderFactory.java
@@ -556,6 +556,33 @@ public interface LangChain4jAgentEndpointBuilderFactory {
         public String langChain4jAgentTotalTokenCount() {
             return "CamelLangChain4jAgentTotalTokenCount";
         }
+        /**
+         * RAG sources retrieved during agent invocation.
+         * 
+         * The option is a: {@code
+         * java.util.List<dev.langchain4j.rag.content.Content>} type.
+         * 
+         * Group: producer
+         * 
+         * @return the name of the header {@code LangChain4jAgentSources}.
+         */
+        public String langChain4jAgentSources() {
+            return "CamelLangChain4jAgentSources";
+        }
+        /**
+         * Tool executions performed during agent invocation.
+         * 
+         * The option is a: {@code
+         * java.util.List<dev.langchain4j.service.tool.ToolExecution>} type.
+         * 
+         * Group: producer
+         * 
+         * @return the name of the header {@code
+         * LangChain4jAgentToolExecutions}.
+         */
+        public String langChain4jAgentToolExecutions() {
+            return "CamelLangChain4jAgentToolExecutions";
+        }
     }
     static LangChain4jAgentEndpointBuilder endpointBuilder(String 
componentName, String path) {
         class LangChain4jAgentEndpointBuilderImpl extends 
AbstractEndpointBuilder implements LangChain4jAgentEndpointBuilder, 
AdvancedLangChain4jAgentEndpointBuilder {

Reply via email to