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

commit ea05bb1985f34d18edc106861ea13cfbf2650dc7
Author: Claus Ibsen <[email protected]>
AuthorDate: Sat Oct 24 19:57:04 2026 +0200

    CAMEL-24961: Catalog body types for five langchain4j, four spring-ai 
components, djl and ai-resource (#28401)
    
    Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
    Signed-off-by: Claus Ibsen <[email protected]>
---
 .../camel/catalog/components/ai-resource.json      |   4 +
 .../org/apache/camel/catalog/components/djl.json   |   4 +
 .../catalog/components/langchain4j-agent.json      |   4 +
 .../catalog/components/langchain4j-embeddings.json |   4 +
 .../components/langchain4j-embeddingstore.json     |   4 +
 .../catalog/components/langchain4j-ingest.json     |   4 +
 .../catalog/components/langchain4j-web-search.json |   4 +
 .../camel/catalog/components/spring-ai-chat.json   |   4 +
 .../catalog/components/spring-ai-embeddings.json   |   4 +
 .../camel/catalog/components/spring-ai-image.json  |   4 +
 .../catalog/components/spring-ai-vector-store.json |   4 +
 .../apache/camel/catalog/docs/djl-component.adoc   |  12 ++
 .../catalog/docs/spring-ai-image-component.adoc    |   7 +-
 .../camel/component/ai/resource/ai-resource.json   |   4 +
 .../component/ai/resource/AiResourceEndpoint.java  |  13 ++
 .../org/apache/camel/component/djl/djl.json        |   4 +
 .../camel-djl/src/main/docs/djl-component.adoc     |  12 ++
 .../apache/camel/component/djl/DJLEndpoint.java    | 133 +++++++++++++++++++++
 .../langchain4j/agent/langchain4j-agent.json       |   4 +
 .../agent/LangChain4jAgentEndpoint.java            |  14 +++
 .../embeddings/langchain4j-embeddings.json         |   4 +
 .../embeddings/LangChain4jEmbeddingsEndpoint.java  |  14 +++
 .../embeddingstore/langchain4j-embeddingstore.json |   4 +
 .../LangChain4jEmbeddingStoreEndpoint.java         |  26 ++++
 .../langchain4j/ingest/langchain4j-ingest.json     |   4 +
 .../ingest/LangChain4jIngestEndpoint.java          |  17 +++
 .../web/search/langchain4j-web-search.json         |   4 +
 .../web/search/LangChain4jWebSearchEndpoint.java   |  16 +++
 .../component/springai/chat/spring-ai-chat.json    |   4 +
 .../springai/chat/SpringAiChatEndpoint.java        |  30 +++++
 .../springai/embeddings/spring-ai-embeddings.json  |   4 +
 .../embeddings/SpringAiEmbeddingsEndpoint.java     |  11 ++
 .../component/springai/image/spring-ai-image.json  |   4 +
 .../src/main/docs/spring-ai-image-component.adoc   |   7 +-
 .../springai/image/SpringAiImageEndpoint.java      |  12 ++
 .../vectorstore/spring-ai-vector-store.json        |   4 +
 .../vectorstore/SpringAiVectorStoreEndpoint.java   |  21 ++++
 37 files changed, 427 insertions(+), 6 deletions(-)

diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/ai-resource.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/ai-resource.json
index 5398475d3ab3..b58a6ef20efa 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/ai-resource.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/ai-resource.json
@@ -33,6 +33,10 @@
     "title": { "index": 6, "kind": "property", "displayName": "Title", 
"group": "consumer", "label": "consumer", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.ai.resource.AiResourceConfiguration", 
"configurationField": "configuration", "description": "Optional display title 
for resource listings. Advisory hint for clients only." },
     "autowiredEnabled": { "index": 7, "kind": "property", "displayName": 
"Autowired Enabled", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": true, "description": 
"Whether autowiring is enabled. This is used for automatic autowiring options 
(the option must be marked as autowired) by looking up in the registry to find 
if there is a single instance of matching t [...]
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "null" ], "description": "No body and no 
headers: a resource read carries no arguments. The route fetches the content 
itself, for example with pollEnrich or a producer with a read operation" },
+    "consumerReply": { "carriers": [ "text", "bytes", "stream", "file" ], 
"description": "The content the route ends with: converted to a String when the 
mimeType is textual (the default text\/plain, json, xml, yaml), else to a 
byte[] sent as a blob. A Map, a List or another object is sent as its toString 
as text and fails as a blob: marshal it first. No body is an error" }
+  },
   "properties": {
     "resourceName": { "index": 0, "kind": "path", "displayName": "Resource 
Name", "group": "consumer", "label": "", "required": true, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "The resource name. This is 
the human-readable label clients see in resource listings." },
     "description": { "index": 1, "kind": "parameter", "displayName": 
"Description", "group": "consumer", "label": "consumer", "required": false, 
"type": "string", "javaType": "java.lang.String", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, 
"configurationClass": 
"org.apache.camel.component.ai.resource.AiResourceConfiguration", 
"configurationField": "configuration", "description": "Human-readable 
description of what this resource contains. Passed verbati [...]
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/djl.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/djl.json
index faf1a1f5cb10..368f90157bb4 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/djl.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/djl.json
@@ -31,6 +31,10 @@
     "CamelDjlInput": { "index": 0, "kind": "header", "displayName": "", 
"group": "producer", "label": "", "required": false, "javaType": "", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The input data used for prediction", "constantName": 
"org.apache.camel.component.djl.DJLConstants#INPUT" },
     "CamelDjlFileType": { "index": 1, "kind": "header", "displayName": "", 
"group": "producer", "label": "", "required": false, "javaType": "", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The file type of the message body data. It is used when 
the body is converted to bytes.", "constantName": 
"org.apache.camel.component.djl.DJLConstants#FILE_TYPE" }
   },
+  "bodyTypes": {
+    "producerIn": { "carriers": [ "bytes", "stream", "file", "pojo", "text", 
"list" ], "byOption": [ { "option": "application", "value": 
"cv\/image_classification", "carriers": [ "bytes", "stream", "file", "pojo" ] 
}, { "option": "application", "value": "cv\/object_detection", "carriers": [ 
"bytes", "stream", "file", "pojo" ] }, { "option": "application", "value": 
"cv\/semantic_segmentation", "carriers": [ "bytes", "stream", "file", "pojo" ] 
}, { "option": "application", "value": "cv\/in [...]
+    "producerOut": { "carriers": [ "pojo", "text", "list", "bytes" ], 
"byOption": [ { "option": "application", "value": "cv\/image_classification", 
"carriers": [ "pojo" ], "javaType": "ai.djl.modality.Classifications" }, { 
"option": "application", "value": "cv\/object_detection", "carriers": [ "pojo" 
], "javaType": "ai.djl.modality.cv.output.DetectedObjects" }, { "option": 
"application", "value": "cv\/semantic_segmentation", "carriers": [ "pojo" ], 
"javaType": "ai.djl.modality.cv.output. [...]
+  },
   "properties": {
     "application": { "index": 0, "kind": "path", "displayName": "Application", 
"group": "producer", "label": "", "required": true, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "Application name" },
     "artifactId": { "index": 1, "kind": "parameter", "displayName": "Artifact 
Id", "group": "producer", "label": "", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "description": "Model Artifact" },
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 3e02990335b6..0dd49fafab27 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
@@ -64,6 +64,10 @@
     "CamelLangChain4jAgentToolExecutions": { "index": 13, "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" },
     "CamelLangChain4jAgentModerationFlagged": { "index": 14, "kind": "header", 
"displayName": "", "group": "producer", "label": "", "required": false, 
"javaType": "Boolean", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "Set to true when user input is rejected 
by the configured moderation model; not set on success.", "constantName": 
"org.apache.camel.component.langchain4j.agent.api.Headers#MODERATION_FLAGGED" }
   },
+  "bodyTypes": {
+    "producerIn": { "carriers": [ "text", "pojo", "bytes", "stream", "file" ], 
"description": "The user message as text, or an AiAgentBody with the user 
message, the system message, the memory id and a content. Bytes, a stream or a 
file of the file consumers is sent as an image, audio, video, PDF or text 
content after the text of the CamelLangChain4jAgentUserMessage header; bytes 
and a stream need the CamelLangChain4jAgentMediaType or Content-Type header. A 
Map, a java.io.File or another [...]
+    "producerOut": { "carriers": [ "text" ], "description": "The answer of the 
agent as text, also with outputClass or jsonSchema: unmarshal the JSON to read 
its fields. The token counts, the finish reason, the sources and the tool 
executions are in headers" }
+  },
   "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" },
     "agent": { "index": 1, "kind": "parameter", "displayName": "Agent", 
"group": "producer", "label": "", "required": false, "type": "object", 
"javaType": "org.apache.camel.component.langchain4j.agent.api.Agent", 
"deprecated": false, "deprecationNote": "", "autowired": true, "secret": false, 
"configurationClass": 
"org.apache.camel.component.langchain4j.agent.LangChain4jAgentConfiguration", 
"configurationField": "configuration", "description": "The agent to use for the 
component" },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/langchain4j-embeddings.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/langchain4j-embeddings.json
index 0f2dddb9afa8..892805beec83 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/langchain4j-embeddings.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/langchain4j-embeddings.json
@@ -50,6 +50,10 @@
     "CamelLangChain4jEmbeddingsTextSegment": { "index": 9, "kind": "header", 
"displayName": "", "group": "producer", "label": "", "required": false, 
"javaType": " dev.langchain4j.data.segment.TextSegment", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": "A 
TextSegment representation of the vector embedding input text", "constantName": 
"org.apache.camel.component.langchain4j.embeddings.LangChain4jEmbeddingsHeaders#TEXT_SEGMENT"
 },
     "CamelLangChain4jEmbeddingsTextSegments": { "index": 10, "kind": "header", 
"displayName": "", "group": "producer", "label": "", "required": false, 
"javaType": "java.util.List<dev.langchain4j.data.segment.TextSegment>", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "List of text segments from a batch embedAll operation", 
"constantName": 
"org.apache.camel.component.langchain4j.embeddings.LangChain4jEmbeddingsHeaders#TEXT_SEGMENTS"
 }
   },
+  "bodyTypes": {
+    "producerIn": { "carriers": [ "text", "pojo", "list" ], "description": 
"The text to embed as a String or a TextSegment, or a non-empty List of them to 
embed in one batch. Bytes, a stream, a file, a Map and no body fail: convert 
the body to a String first" },
+    "producerOut": { "carriers": [ "unchanged" ], "description": "The body is 
kept. The vector goes in the CamelLangChain4jEmbeddingsVector header as a float 
array, with the Embedding and the TextSegment in the 
CamelLangChain4jEmbeddingsEmbedding and CamelLangChain4jEmbeddingsTextSegment 
headers; a List body gives Lists of them in the 
CamelLangChain4jEmbeddingsEmbeddings and CamelLangChain4jEmbeddingsTextSegments 
headers instead" }
+  },
   "properties": {
     "embeddingId": { "index": 0, "kind": "path", "displayName": "Embedding 
Id", "group": "producer", "label": "", "required": true, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "The id" },
     "embeddingModel": { "index": 1, "kind": "parameter", "displayName": 
"Embedding Model", "group": "producer", "label": "", "required": false, "type": 
"object", "javaType": "dev.langchain4j.model.embedding.EmbeddingModel", 
"deprecated": false, "deprecationNote": "", "autowired": true, "secret": false, 
"configurationClass": 
"org.apache.camel.component.langchain4j.embeddings.LangChain4jEmbeddingsConfiguration",
 "configurationField": "configuration", "description": "The EmbeddingModel engi 
[...]
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/langchain4j-embeddingstore.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/langchain4j-embeddingstore.json
index 10ee7dd047e2..03dd71668c8d 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/langchain4j-embeddingstore.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/langchain4j-embeddingstore.json
@@ -43,6 +43,10 @@
     "CamelLangchain4jEmbeddingStoreEmbeddingId": { "index": 4, "kind": 
"header", "displayName": "", "group": "producer", "label": "", "required": 
false, "javaType": "String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "Caller-supplied embedding 
ID for single ADD operations", "constantName": 
"org.apache.camel.component.langchain4j.embeddingstore.LangChain4jEmbeddingStoreHeaders#EMBEDDING_ID"
 },
     "CamelLangchain4jEmbeddingStoreEmbeddingIds": { "index": 5, "kind": 
"header", "displayName": "", "group": "producer", "label": "", "required": 
false, "javaType": "java.util.List<java.lang.String>", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": 
"Caller-supplied embedding IDs for batch ADD operations", "constantName": 
"org.apache.camel.component.langchain4j.embeddingstore.LangChain4jEmbeddingStoreHeaders#EMBEDDING_IDS"
 }
   },
+  "bodyTypes": {
+    "producerIn": { "carriers": [ "any" ], "byOption": [ { "option": "action", 
"value": "REMOVE", "carriers": [ "text", "list" ] } ], "description": "ADD and 
SEARCH take the embedding from the CamelLangChain4jEmbeddingsEmbedding header 
(a batch ADD from the CamelLangChain4jEmbeddingsEmbeddings header) and ignore 
the body, but with an embeddingModel and no such header they embed the body 
read as a String, so no body fails and another body, a TextSegment too, is 
embedded as its toString(). [...]
+    "producerOut": { "carriers": [ "text", "list", "unchanged" ], "byOption": 
[ { "option": "action", "value": "ADD", "carriers": [ "text", "list" ] }, { 
"option": "action", "value": "REMOVE", "carriers": [ "unchanged" ] }, { 
"option": "action", "value": "SEARCH", "carriers": [ "list" ] } ], 
"description": "By the action, from the endpoint or the 
CamelLangchain4jEmbeddingStoreAction header: the id of the added embedding as a 
String for ADD, a List of the ids for a batch ADD, and a List o [...]
+  },
   "properties": {
     "embeddingStoreId": { "index": 0, "kind": "path", "displayName": 
"Embedding Store Id", "group": "producer", "label": "", "required": true, 
"type": "string", "javaType": "java.lang.String", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": "The 
id of the embedding store" },
     "action": { "index": 1, "kind": "parameter", "displayName": "Action", 
"group": "producer", "label": "", "required": false, "type": "enum", 
"javaType": 
"org.apache.camel.component.langchain4j.embeddingstore.LangChain4jEmbeddingStoreAction",
 "enum": [ "ADD", "REMOVE", "SEARCH" ], "deprecated": false, "autowired": 
false, "secret": false, "configurationClass": 
"org.apache.camel.component.langchain4j.embeddingstore.LangChain4jEmbeddingStoreConfiguration",
 "configurationField": "configurat [...]
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/langchain4j-ingest.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/langchain4j-ingest.json
index 18342ddc34fa..c090ee548b21 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/langchain4j-ingest.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/langchain4j-ingest.json
@@ -46,6 +46,10 @@
   "headers": {
     "CamelLangChain4jIngestDocumentId": { "index": 0, "kind": "header", 
"displayName": "", "group": "producer", "label": "", "required": false, 
"javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The stable document id of the ingested 
payload, read when the documentIdHeader endpoint option does not name another 
header. The CamelLangChain4jIngestDocumentId exchange property, when set, takes 
precedence over any header.", "c [...]
   },
+  "bodyTypes": {
+    "producerIn": { "carriers": [ "text", "bytes", "stream", "file", "null" ], 
"byOption": [ { "option": "modality", "value": "MEDIA", "carriers": [ "bytes", 
"stream", "file", "null" ] } ], "description": "The document read as a String, 
then split and embedded; another body, such as a Map or a TextSegment, is 
ingested as its toString(). With modality=MEDIA it is read as bytes and 
embedded whole, and a Map or a POJO fails. No body or a blank one writes 
nothing. The document id comes from  [...]
+    "producerOut": { "carriers": [ "pojo" ], "javaType": 
"org.apache.camel.component.langchain4j.ingest.IngestResult", "description": 
"An IngestResult with the pipeline, the document id, the number of segments 
written and the outcome: INGESTED, EMPTY, SKIPPED or FILTERED" }
+  },
   "properties": {
     "pipelineName": { "index": 0, "kind": "path", "displayName": "Pipeline 
Name", "group": "producer", "label": "", "required": true, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "The pipeline name, stamped 
on every written segment as the camel_ingest_pipeline metadata and used in 
error messages" },
     "contentType": { "index": 1, "kind": "parameter", "displayName": "Content 
Type", "group": "producer", "label": "", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "configurationClass": 
"org.apache.camel.component.langchain4j.ingest.LangChain4jIngestConfiguration", 
"configurationField": "configuration", "description": "MIME type of a media 
body, such as audio\/wav or image\/png, handed to the embedding mode [...]
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/langchain4j-web-search.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/langchain4j-web-search.json
index 51f53e82d740..958cb858d59e 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/langchain4j-web-search.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/langchain4j-web-search.json
@@ -27,6 +27,10 @@
     "lazyStartProducer": { "index": 0, "kind": "property", "displayName": 
"Lazy Start Producer", "group": "producer", "label": "producer", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": false, "description": 
"Whether the producer should be started lazy (on the first message). By 
starting lazy you can use this to allow CamelContext and routes to startup in 
situations where a producer may otherwise fail [...]
     "autowiredEnabled": { "index": 1, "kind": "property", "displayName": 
"Autowired Enabled", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": true, "description": 
"Whether autowiring is enabled. This is used for automatic autowiring options 
(the option must be marked as autowired) by looking up in the registry to find 
if there is a single instance of matching t [...]
   },
+  "bodyTypes": {
+    "producerIn": { "carriers": [ "any" ], "description": "The search terms as 
text; another body is converted to text, so a Map or a POJO is searched as its 
toString(), and no body fails. With webSearchRequest the body is not read" },
+    "producerOut": { "carriers": [ "text", "null" ], "dependsOn": [ 
"maxResults", "webSearchRequest" ], "byOption": [ { "option": "resultType", 
"value": "LANGCHAIN4J_WEB_SEARCH_ORGANIC_RESULT", "carriers": [ "pojo", "null" 
] } ], "description": "The content of the first result as text (its snippet 
with resultType SNIPPET, the WebSearchOrganicResult with 
LANGCHAIN4J_WEB_SEARCH_ORGANIC_RESULT), or null when there is no result or the 
engine gives no content. With maxResults above 1 it is a  [...]
+  },
   "properties": {
     "searchId": { "index": 0, "kind": "path", "displayName": "Search Id", 
"group": "producer", "label": "", "required": true, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "The id" },
     "additionalParams": { "index": 1, "kind": "parameter", "displayName": 
"Additional Params", "group": "producer", "label": "", "required": false, 
"type": "object", "javaType": "java.util.Map<java.lang.String, 
java.lang.Object>", "deprecated": false, "deprecationNote": "", "autowired": 
true, "secret": false, "configurationClass": 
"org.apache.camel.component.langchain4j.web.search.LangChain4jWebSearchConfiguration",
 "configurationField": "configuration", "description": "The additionalPar [...]
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/spring-ai-chat.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/spring-ai-chat.json
index c109251e5e93..eca6eea78e58 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/spring-ai-chat.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/spring-ai-chat.json
@@ -62,6 +62,10 @@
     "CamelSpringAiChatToolNames": { "index": 30, "kind": "header", 
"displayName": "", "group": "producer", "label": "", "required": false, 
"javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "Comma-separated tool names for 
selecting tools by name via ToolCallbackResolver", "constantName": 
"org.apache.camel.component.springai.chat.SpringAiChatConstants#TOOL_NAMES" },
     "CamelSpringAiChatToolContext": { "index": 31, "kind": "header", 
"displayName": "", "group": "producer", "label": "", "required": false, 
"javaType": "java.util.Map<String, Object>", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": 
"Context map to pass to tools during execution", "constantName": 
"org.apache.camel.component.springai.chat.SpringAiChatConstants#TOOL_CONTEXT" }
   },
+  "bodyTypes": {
+    "producerIn": { "carriers": [ "any" ], "byOption": [ { "option": 
"chatOperation", "value": "CHAT_SINGLE_MESSAGE_WITH_PROMPT", "carriers": [ 
"map" ] }, { "option": "chatOperation", "value": "CHAT_MULTIPLE_MESSAGES", 
"carriers": [ "list" ] } ], "description": "The prompt as text, or a 
UserMessage or another Spring AI Message. A byte[] is sent as media (image\/png 
unless the CamelSpringAiChatMediaType header says otherwise), and a WrappedFile 
of a local file, or a List of them, as media [...]
+    "producerOut": { "carriers": [ "text" ], "dependsOn": [ "entityClass", 
"structuredOutputConverter" ], "byOption": [ { "option": "outputFormat", 
"value": "BEAN", "carriers": [ "pojo" ] }, { "option": "outputFormat", "value": 
"MAP", "carriers": [ "map" ] }, { "option": "outputFormat", "value": "LIST", 
"carriers": [ "list" ] } ], "description": "The answer of the model as text, 
also in the CamelSpringAiChatResponse header. entityClass makes it an object of 
that class, and outputFormat a [...]
+  },
   "properties": {
     "chatId": { "index": 0, "kind": "path", "displayName": "Chat Id", "group": 
"producer", "label": "", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "The ID of the chat endpoint" },
     "chatClient": { "index": 1, "kind": "parameter", "displayName": "Chat 
Client", "group": "producer", "label": "", "required": false, "type": "object", 
"javaType": "org.springframework.ai.chat.client.ChatClient", "deprecated": 
false, "deprecationNote": "", "autowired": true, "secret": false, 
"configurationClass": 
"org.apache.camel.component.springai.chat.SpringAiChatConfiguration", 
"configurationField": "configuration", "description": "The ChatClient instance 
to use for chat operations [...]
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/spring-ai-embeddings.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/spring-ai-embeddings.json
index 3eefb7b912f5..6b33fa8447b1 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/spring-ai-embeddings.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/spring-ai-embeddings.json
@@ -37,6 +37,10 @@
     "CamelSpringAiEmbeddings": { "index": 4, "kind": "header", "displayName": 
"", "group": "producer", "label": "", "required": false, "javaType": 
"java.util.List<org.springframework.ai.embedding.Embedding>", "deprecated": 
false, "deprecationNote": "", "autowired": false, "secret": false, 
"description": "List of Embedding objects", "constantName": 
"org.apache.camel.component.springai.embeddings.SpringAiEmbeddingsHeaders#EMBEDDINGS"
 },
     "CamelSpringAiEmbeddingInputTexts": { "index": 5, "kind": "header", 
"displayName": "", "group": "producer", "label": "", "required": false, 
"javaType": "java.util.List<String>", "deprecated": false, "deprecationNote": 
"", "autowired": false, "secret": false, "description": "List of input texts 
that were embedded", "constantName": 
"org.apache.camel.component.springai.embeddings.SpringAiEmbeddingsHeaders#INPUT_TEXTS"
 }
   },
+  "bodyTypes": {
+    "producerIn": { "carriers": [ "any" ], "description": "The text to embed, 
or a List of texts for a batch. Another body is converted to text (a Map or a 
POJO as its toString()), and no body fails" },
+    "producerOut": { "carriers": [ "list" ], "description": "The vector as a 
float[] for one text, also for a List with one text, and a List of float[] for 
a List of more texts. The Embedding and the input text are in headers, which 
spring-ai-vector-store reads" }
+  },
   "properties": {
     "embeddingId": { "index": 0, "kind": "path", "displayName": "Embedding 
Id", "group": "producer", "label": "", "required": true, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "The id" },
     "embeddingModel": { "index": 1, "kind": "parameter", "displayName": 
"Embedding Model", "group": "producer", "label": "", "required": true, "type": 
"object", "javaType": "org.springframework.ai.embedding.EmbeddingModel", 
"deprecated": false, "deprecationNote": "", "autowired": true, "secret": false, 
"configurationClass": 
"org.apache.camel.component.springai.embeddings.SpringAiEmbeddingsConfiguration",
 "configurationField": "configuration", "description": "The EmbeddingModel to 
use for [...]
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/spring-ai-image.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/spring-ai-image.json
index 854fa8e6e4b1..c5bd30f01384 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/spring-ai-image.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/spring-ai-image.json
@@ -46,6 +46,10 @@
     "CamelSpringAiImageGeneration": { "index": 7, "kind": "header", 
"displayName": "", "group": "producer", "label": "", "required": false, 
"javaType": "org.springframework.ai.image.ImageGeneration", "deprecated": 
false, "deprecationNote": "", "autowired": false, "secret": false, 
"description": "The ImageGeneration object for single image results", 
"constantName": 
"org.apache.camel.component.springai.image.SpringAiImageHeaders#IMAGE_GENERATION"
 },
     "CamelSpringAiImageGenerations": { "index": 8, "kind": "header", 
"displayName": "", "group": "producer", "label": "", "required": false, 
"javaType": "java.util.List<org.springframework.ai.image.ImageGeneration>", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "List of ImageGeneration objects for multiple image 
results", "constantName": 
"org.apache.camel.component.springai.image.SpringAiImageHeaders#IMAGE_GENERATIONS"
 }
   },
+  "bodyTypes": {
+    "producerIn": { "carriers": [ "any" ], "description": "The prompt as text, 
or an ImagePrompt, which keeps its own options: n, width and the other options 
and headers then do not apply. Another body is converted to text, and no body 
fails" },
+    "producerOut": { "carriers": [ "pojo", "list" ], "description": "The 
generated org.springframework.ai.image.Image, with a URL or base64 data, or a 
List of Image when the model returns more than one (n above 1). An Image 
converts to byte[] by decoding the base64 data; an Image with only a URL gives 
the bytes of the URL text" }
+  },
   "properties": {
     "imageId": { "index": 0, "kind": "path", "displayName": "Image Id", 
"group": "producer", "label": "", "required": true, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "The id" },
     "height": { "index": 1, "kind": "parameter", "displayName": "Height", 
"group": "producer", "label": "", "required": false, "type": "integer", 
"javaType": "java.lang.Integer", "deprecated": false, "autowired": false, 
"secret": false, "configurationClass": 
"org.apache.camel.component.springai.image.SpringAiImageConfiguration", 
"configurationField": "configuration", "description": "Image height in pixels" 
},
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/spring-ai-vector-store.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/spring-ai-vector-store.json
index 2ec8e1c5f601..c4e957c49f71 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/spring-ai-vector-store.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/spring-ai-vector-store.json
@@ -43,6 +43,10 @@
     "CamelSpringAiVectorStoreDocumentsAdded": { "index": 6, "kind": "header", 
"displayName": "", "group": "producer", "label": "", "required": false, 
"javaType": "Integer", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "Number of documents added", 
"constantName": 
"org.apache.camel.component.springai.vectorstore.SpringAiVectorStoreHeaders#DOCUMENTS_ADDED"
 },
     "CamelSpringAiVectorStoreDocumentsDeleted": { "index": 7, "kind": 
"header", "displayName": "", "group": "producer", "label": "", "required": 
false, "javaType": "Integer", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "Number of documents 
deleted", "constantName": 
"org.apache.camel.component.springai.vectorstore.SpringAiVectorStoreHeaders#DOCUMENTS_DELETED"
 }
   },
+  "bodyTypes": {
+    "producerIn": { "carriers": [ "any" ], "byOption": [ { "option": 
"operation", "value": "DELETE", "carriers": [ "text", "list" ] }, { "option": 
"operation", "value": "SIMILARITY_SEARCH", "carriers": [ "text" ] } ], 
"description": "ADD takes a Document, a List of Document or of texts, or text 
(another body is added as its text). After spring-ai-embeddings it adds the 
texts in the CamelSpringAiEmbeddingInputText(s) headers instead of the body. 
DELETE takes the id or a List of ids, unles [...]
+    "producerOut": { "carriers": [ "unchanged" ], "byOption": [ { "option": 
"operation", "value": "SIMILARITY_SEARCH", "carriers": [ "list" ] } ], 
"description": "SIMILARITY_SEARCH gives the List of Document found. ADD and 
DELETE keep the body, with the ids and the count in headers" }
+  },
   "properties": {
     "storeId": { "index": 0, "kind": "path", "displayName": "Store Id", 
"group": "producer", "label": "", "required": true, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "The id" },
     "filterExpression": { "index": 1, "kind": "parameter", "displayName": 
"Filter Expression", "group": "producer", "label": "", "required": false, 
"type": "string", "javaType": "java.lang.String", "deprecated": false, 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.springai.vectorstore.SpringAiVectorStoreConfiguration",
 "configurationField": "configuration", "description": "Filter expression for 
metadata-based filtering in searches." },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/djl-component.adoc
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/djl-component.adoc
index 00b7e62ab189..3f30bd095040 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/djl-component.adoc
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/djl-component.adoc
@@ -142,6 +142,10 @@ String[]`
 | `String`
 | `ai.djl.ndarray.NDArray`
 
+| `nlp/word_embedding` (custom model only)
+| `String`
+| `byte[]` (the encoded `ai.djl.ndarray.NDList`)
+
 | `audio`
 | `ai.djl.modality.audio.Audio +
 byte[] +
@@ -153,6 +157,14 @@ File`
 | `ai.djl.timeseries.TimeSeriesData`
 | `ai.djl.timeseries.Forecast`
 
+| `tabular/linear_regression` (custom model only)
+| Any body: the input type of the translator
+| The output type of the translator
+
+| `tabular/softmax_regression` (custom model only)
+| Any body: the input type of the translator
+| The output type of the translator
+
 |===
 
 // component options: START
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/spring-ai-image-component.adoc
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/spring-ai-image-component.adoc
index 3be56a4b68d6..c097f5613dc7 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/spring-ai-image-component.adoc
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/spring-ai-image-component.adoc
@@ -157,7 +157,8 @@ YAML::
 ----
 ====
 
-The `Image` → `byte[]` conversion decodes the base64 data automatically.
+The `Image` → `byte[]` conversion decodes the base64 data automatically. Set 
`responseFormat=b64_json` when the
+provider returns a URL by default, as the URL is not downloaded.
 
 === Using with Ollama (Local Image Generation)
 
@@ -256,8 +257,8 @@ The component registers automatic type converters for 
`Image` objects:
 |===
 | From | To | Behavior
 
-| `Image` | `byte[]` | Decodes base64 data
-| `Image` | `InputStream` | Wraps decoded bytes in ByteArrayInputStream
+| `Image` | `byte[]` | Decodes base64 data. An `Image` with only a URL gives 
the bytes of the URL text: the image is not downloaded
+| `Image` | `InputStream` | Wraps the `byte[]` above in ByteArrayInputStream
 | `Image` | `String` | Returns base64 string or URL
 |===
 
diff --git 
a/components/camel-ai/camel-ai-resource/src/generated/resources/META-INF/org/apache/camel/component/ai/resource/ai-resource.json
 
b/components/camel-ai/camel-ai-resource/src/generated/resources/META-INF/org/apache/camel/component/ai/resource/ai-resource.json
index 5398475d3ab3..b58a6ef20efa 100644
--- 
a/components/camel-ai/camel-ai-resource/src/generated/resources/META-INF/org/apache/camel/component/ai/resource/ai-resource.json
+++ 
b/components/camel-ai/camel-ai-resource/src/generated/resources/META-INF/org/apache/camel/component/ai/resource/ai-resource.json
@@ -33,6 +33,10 @@
     "title": { "index": 6, "kind": "property", "displayName": "Title", 
"group": "consumer", "label": "consumer", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.ai.resource.AiResourceConfiguration", 
"configurationField": "configuration", "description": "Optional display title 
for resource listings. Advisory hint for clients only." },
     "autowiredEnabled": { "index": 7, "kind": "property", "displayName": 
"Autowired Enabled", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": true, "description": 
"Whether autowiring is enabled. This is used for automatic autowiring options 
(the option must be marked as autowired) by looking up in the registry to find 
if there is a single instance of matching t [...]
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "null" ], "description": "No body and no 
headers: a resource read carries no arguments. The route fetches the content 
itself, for example with pollEnrich or a producer with a read operation" },
+    "consumerReply": { "carriers": [ "text", "bytes", "stream", "file" ], 
"description": "The content the route ends with: converted to a String when the 
mimeType is textual (the default text\/plain, json, xml, yaml), else to a 
byte[] sent as a blob. A Map, a List or another object is sent as its toString 
as text and fails as a blob: marshal it first. No body is an error" }
+  },
   "properties": {
     "resourceName": { "index": 0, "kind": "path", "displayName": "Resource 
Name", "group": "consumer", "label": "", "required": true, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "The resource name. This is 
the human-readable label clients see in resource listings." },
     "description": { "index": 1, "kind": "parameter", "displayName": 
"Description", "group": "consumer", "label": "consumer", "required": false, 
"type": "string", "javaType": "java.lang.String", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, 
"configurationClass": 
"org.apache.camel.component.ai.resource.AiResourceConfiguration", 
"configurationField": "configuration", "description": "Human-readable 
description of what this resource contains. Passed verbati [...]
diff --git 
a/components/camel-ai/camel-ai-resource/src/main/java/org/apache/camel/component/ai/resource/AiResourceEndpoint.java
 
b/components/camel-ai/camel-ai-resource/src/main/java/org/apache/camel/component/ai/resource/AiResourceEndpoint.java
index 67d72589ea4c..622da011ba8c 100644
--- 
a/components/camel-ai/camel-ai-resource/src/main/java/org/apache/camel/component/ai/resource/AiResourceEndpoint.java
+++ 
b/components/camel-ai/camel-ai-resource/src/main/java/org/apache/camel/component/ai/resource/AiResourceEndpoint.java
@@ -20,6 +20,9 @@ import org.apache.camel.Category;
 import org.apache.camel.Consumer;
 import org.apache.camel.Processor;
 import org.apache.camel.Producer;
+import org.apache.camel.spi.BodyType;
+import org.apache.camel.spi.BodyType.Carrier;
+import org.apache.camel.spi.BodyTypes;
 import org.apache.camel.spi.Metadata;
 import org.apache.camel.spi.UriEndpoint;
 import org.apache.camel.spi.UriParam;
@@ -42,6 +45,16 @@ import static 
org.apache.camel.component.ai.resource.AiResource.SCHEME;
              consumerOnly = true,
              remote = false,
              category = { Category.AI })
+@BodyTypes(consumerOut = @BodyType(value = Carrier.NULL,
+                                   description = "No body and no headers: a 
resource read carries no arguments. The"
+                                                 + " route fetches the content 
itself, for example with pollEnrich or a"
+                                                 + " producer with a read 
operation"),
+           consumerReply = @BodyType(value = { Carrier.TEXT, Carrier.BYTES, 
Carrier.STREAM, Carrier.FILE },
+                                     description = "The content the route ends 
with: converted to a String when the"
+                                                   + " mimeType is textual 
(the default text/plain, json, xml, yaml), else"
+                                                   + " to a byte[] sent as a 
blob. A Map, a List or another object is sent"
+                                                   + " as its toString as text 
and fails as a blob: marshal it first. No"
+                                                   + " body is an error"))
 public class AiResourceEndpoint extends DefaultEndpoint {
 
     @Metadata(required = true)
diff --git 
a/components/camel-ai/camel-djl/src/generated/resources/META-INF/org/apache/camel/component/djl/djl.json
 
b/components/camel-ai/camel-djl/src/generated/resources/META-INF/org/apache/camel/component/djl/djl.json
index faf1a1f5cb10..368f90157bb4 100644
--- 
a/components/camel-ai/camel-djl/src/generated/resources/META-INF/org/apache/camel/component/djl/djl.json
+++ 
b/components/camel-ai/camel-djl/src/generated/resources/META-INF/org/apache/camel/component/djl/djl.json
@@ -31,6 +31,10 @@
     "CamelDjlInput": { "index": 0, "kind": "header", "displayName": "", 
"group": "producer", "label": "", "required": false, "javaType": "", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The input data used for prediction", "constantName": 
"org.apache.camel.component.djl.DJLConstants#INPUT" },
     "CamelDjlFileType": { "index": 1, "kind": "header", "displayName": "", 
"group": "producer", "label": "", "required": false, "javaType": "", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The file type of the message body data. It is used when 
the body is converted to bytes.", "constantName": 
"org.apache.camel.component.djl.DJLConstants#FILE_TYPE" }
   },
+  "bodyTypes": {
+    "producerIn": { "carriers": [ "bytes", "stream", "file", "pojo", "text", 
"list" ], "byOption": [ { "option": "application", "value": 
"cv\/image_classification", "carriers": [ "bytes", "stream", "file", "pojo" ] 
}, { "option": "application", "value": "cv\/object_detection", "carriers": [ 
"bytes", "stream", "file", "pojo" ] }, { "option": "application", "value": 
"cv\/semantic_segmentation", "carriers": [ "bytes", "stream", "file", "pojo" ] 
}, { "option": "application", "value": "cv\/in [...]
+    "producerOut": { "carriers": [ "pojo", "text", "list", "bytes" ], 
"byOption": [ { "option": "application", "value": "cv\/image_classification", 
"carriers": [ "pojo" ], "javaType": "ai.djl.modality.Classifications" }, { 
"option": "application", "value": "cv\/object_detection", "carriers": [ "pojo" 
], "javaType": "ai.djl.modality.cv.output.DetectedObjects" }, { "option": 
"application", "value": "cv\/semantic_segmentation", "carriers": [ "pojo" ], 
"javaType": "ai.djl.modality.cv.output. [...]
+  },
   "properties": {
     "application": { "index": 0, "kind": "path", "displayName": "Application", 
"group": "producer", "label": "", "required": true, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "Application name" },
     "artifactId": { "index": 1, "kind": "parameter", "displayName": "Artifact 
Id", "group": "producer", "label": "", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "description": "Model Artifact" },
diff --git a/components/camel-ai/camel-djl/src/main/docs/djl-component.adoc 
b/components/camel-ai/camel-djl/src/main/docs/djl-component.adoc
index 00b7e62ab189..3f30bd095040 100644
--- a/components/camel-ai/camel-djl/src/main/docs/djl-component.adoc
+++ b/components/camel-ai/camel-djl/src/main/docs/djl-component.adoc
@@ -142,6 +142,10 @@ String[]`
 | `String`
 | `ai.djl.ndarray.NDArray`
 
+| `nlp/word_embedding` (custom model only)
+| `String`
+| `byte[]` (the encoded `ai.djl.ndarray.NDList`)
+
 | `audio`
 | `ai.djl.modality.audio.Audio +
 byte[] +
@@ -153,6 +157,14 @@ File`
 | `ai.djl.timeseries.TimeSeriesData`
 | `ai.djl.timeseries.Forecast`
 
+| `tabular/linear_regression` (custom model only)
+| Any body: the input type of the translator
+| The output type of the translator
+
+| `tabular/softmax_regression` (custom model only)
+| Any body: the input type of the translator
+| The output type of the translator
+
 |===
 
 // component options: START
diff --git 
a/components/camel-ai/camel-djl/src/main/java/org/apache/camel/component/djl/DJLEndpoint.java
 
b/components/camel-ai/camel-djl/src/main/java/org/apache/camel/component/djl/DJLEndpoint.java
index 04487a883ded..461044dc7168 100644
--- 
a/components/camel-ai/camel-djl/src/main/java/org/apache/camel/component/djl/DJLEndpoint.java
+++ 
b/components/camel-ai/camel-djl/src/main/java/org/apache/camel/component/djl/DJLEndpoint.java
@@ -20,6 +20,9 @@ import org.apache.camel.Category;
 import org.apache.camel.Consumer;
 import org.apache.camel.Processor;
 import org.apache.camel.Producer;
+import org.apache.camel.spi.BodyType;
+import org.apache.camel.spi.BodyType.Carrier;
+import org.apache.camel.spi.BodyTypes;
 import org.apache.camel.spi.Metadata;
 import org.apache.camel.spi.UriEndpoint;
 import org.apache.camel.spi.UriParam;
@@ -31,6 +34,136 @@ import org.apache.camel.support.DefaultEndpoint;
  */
 @UriEndpoint(firstVersion = "3.3.0", scheme = "djl", title = "Deep Java 
Library", syntax = "djl:application",
              remote = false, category = { Category.AI }, producerOnly = true, 
headersClass = DJLConstants.class)
+@BodyTypes(producerIn = @BodyType(value = {
+        Carrier.BYTES, Carrier.STREAM, Carrier.FILE, Carrier.POJO, 
Carrier.TEXT, Carrier.LIST },
+                                  byOption = {
+                                          @BodyType.When(option = 
"application", value = "cv/image_classification",
+                                                         carriers = {
+                                                                 
Carrier.BYTES, Carrier.STREAM, Carrier.FILE, Carrier.POJO }),
+                                          @BodyType.When(option = 
"application", value = "cv/object_detection",
+                                                         carriers = {
+                                                                 
Carrier.BYTES, Carrier.STREAM, Carrier.FILE, Carrier.POJO }),
+                                          @BodyType.When(option = 
"application", value = "cv/semantic_segmentation",
+                                                         carriers = {
+                                                                 
Carrier.BYTES, Carrier.STREAM, Carrier.FILE, Carrier.POJO }),
+                                          @BodyType.When(option = 
"application", value = "cv/instance_segmentation",
+                                                         carriers = {
+                                                                 
Carrier.BYTES, Carrier.STREAM, Carrier.FILE, Carrier.POJO }),
+                                          @BodyType.When(option = 
"application", value = "cv/pose_estimation",
+                                                         carriers = {
+                                                                 
Carrier.BYTES, Carrier.STREAM, Carrier.FILE, Carrier.POJO }),
+                                          @BodyType.When(option = 
"application", value = "cv/action_recognition",
+                                                         carriers = {
+                                                                 
Carrier.BYTES, Carrier.STREAM, Carrier.FILE, Carrier.POJO }),
+                                          @BodyType.When(option = 
"application", value = "cv/word_recognition",
+                                                         carriers = {
+                                                                 
Carrier.BYTES, Carrier.STREAM, Carrier.FILE, Carrier.POJO }),
+                                          @BodyType.When(option = 
"application", value = "cv/image_enhancement",
+                                                         carriers = {
+                                                                 
Carrier.BYTES, Carrier.STREAM, Carrier.FILE, Carrier.POJO }),
+                                          @BodyType.When(option = 
"application", value = "cv/image_generation",
+                                                         carriers = 
Carrier.LIST, javaType = "int[]"),
+                                          @BodyType.When(option = 
"application", value = "nlp/fill_mask",
+                                                         carriers = 
Carrier.TEXT, javaType = "java.lang.String"),
+                                          @BodyType.When(option = 
"application", value = "nlp/text_classification",
+                                                         carriers = 
Carrier.TEXT, javaType = "java.lang.String"),
+                                          @BodyType.When(option = 
"application", value = "nlp/sentiment_analysis",
+                                                         carriers = 
Carrier.TEXT, javaType = "java.lang.String"),
+                                          @BodyType.When(option = 
"application", value = "nlp/token_classification",
+                                                         carriers = 
Carrier.TEXT, javaType = "java.lang.String"),
+                                          @BodyType.When(option = 
"application", value = "nlp/word_embedding",
+                                                         carriers = 
Carrier.TEXT, javaType = "java.lang.String"),
+                                          @BodyType.When(option = 
"application", value = "nlp/text_generation",
+                                                         carriers = 
Carrier.TEXT, javaType = "java.lang.String"),
+                                          @BodyType.When(option = 
"application", value = "nlp/machine_translation",
+                                                         carriers = 
Carrier.TEXT, javaType = "java.lang.String"),
+                                          @BodyType.When(option = 
"application", value = "nlp/multiple_choice",
+                                                         carriers = 
Carrier.TEXT, javaType = "java.lang.String"),
+                                          @BodyType.When(option = 
"application", value = "nlp/text_embedding",
+                                                         carriers = 
Carrier.TEXT, javaType = "java.lang.String"),
+                                          @BodyType.When(option = 
"application", value = "nlp/question_answer",
+                                                         carriers = { 
Carrier.POJO, Carrier.LIST }),
+                                          @BodyType.When(option = 
"application", value = "audio",
+                                                         carriers = {
+                                                                 
Carrier.BYTES, Carrier.STREAM, Carrier.FILE, Carrier.POJO }),
+                                          @BodyType.When(option = 
"application", value = "timeseries/forecasting",
+                                                         carriers = 
Carrier.POJO,
+                                                         javaType = 
"ai.djl.timeseries.TimeSeriesData"),
+                                          @BodyType.When(option = 
"application", value = "tabular/linear_regression",
+                                                         carriers = 
Carrier.ANY),
+                                          @BodyType.When(option = 
"application", value = "tabular/softmax_regression",
+                                                         carriers = 
Carrier.ANY) },
+                                  description = "Depends on the application. 
The cv applications and audio take an image"
+                                                + " or audio clip as bytes, a 
stream, a File or a Path, or a DJL Image or"
+                                                + " Audio (a BufferedImage or 
a file name as text is not converted);"
+                                                + " cv/image_generation an 
int[] of seeds. The nlp applications take a String"
+                                                + " only (bytes or a stream 
fail: convert to text first), nlp/question_answer"
+                                                + " a QAInput or a String[] of 
the question and the paragraph,"
+                                                + " timeseries/forecasting a 
TimeSeriesData. No body fails"),
+           producerOut = @BodyType(value = { Carrier.POJO, Carrier.TEXT, 
Carrier.LIST, Carrier.BYTES },
+                                   byOption = {
+                                           @BodyType.When(option = 
"application", value = "cv/image_classification",
+                                                          carriers = 
Carrier.POJO,
+                                                          javaType = 
"ai.djl.modality.Classifications"),
+                                           @BodyType.When(option = 
"application", value = "cv/object_detection",
+                                                          carriers = 
Carrier.POJO,
+                                                          javaType = 
"ai.djl.modality.cv.output.DetectedObjects"),
+                                           @BodyType.When(option = 
"application", value = "cv/semantic_segmentation",
+                                                          carriers = 
Carrier.POJO,
+                                                          javaType = 
"ai.djl.modality.cv.output.CategoryMask"),
+                                           @BodyType.When(option = 
"application", value = "cv/instance_segmentation",
+                                                          carriers = 
Carrier.POJO,
+                                                          javaType = 
"ai.djl.modality.cv.output.DetectedObjects"),
+                                           @BodyType.When(option = 
"application", value = "cv/pose_estimation",
+                                                          carriers = 
Carrier.POJO,
+                                                          javaType = 
"ai.djl.modality.cv.output.Joints"),
+                                           @BodyType.When(option = 
"application", value = "cv/action_recognition",
+                                                          carriers = 
Carrier.POJO,
+                                                          javaType = 
"ai.djl.modality.Classifications"),
+                                           @BodyType.When(option = 
"application", value = "cv/word_recognition",
+                                                          carriers = 
Carrier.TEXT, javaType = "java.lang.String"),
+                                           @BodyType.When(option = 
"application", value = "cv/image_generation",
+                                                          carriers = 
Carrier.LIST, javaType = "ai.djl.modality.cv.Image[]"),
+                                           @BodyType.When(option = 
"application", value = "cv/image_enhancement",
+                                                          carriers = 
Carrier.POJO, javaType = "ai.djl.modality.cv.Image"),
+                                           @BodyType.When(option = 
"application", value = "nlp/fill_mask",
+                                                          carriers = 
Carrier.LIST, javaType = "java.lang.String[]"),
+                                           @BodyType.When(option = 
"application", value = "nlp/question_answer",
+                                                          carriers = 
Carrier.TEXT, javaType = "java.lang.String"),
+                                           @BodyType.When(option = 
"application", value = "nlp/text_classification",
+                                                          carriers = 
Carrier.POJO,
+                                                          javaType = 
"ai.djl.modality.Classifications"),
+                                           @BodyType.When(option = 
"application", value = "nlp/sentiment_analysis",
+                                                          carriers = 
Carrier.POJO,
+                                                          javaType = 
"ai.djl.modality.Classifications"),
+                                           @BodyType.When(option = 
"application", value = "nlp/token_classification",
+                                                          carriers = 
Carrier.POJO,
+                                                          javaType = 
"ai.djl.modality.Classifications"),
+                                           @BodyType.When(option = 
"application", value = "nlp/word_embedding",
+                                                          carriers = 
Carrier.BYTES, javaType = "byte[]"),
+                                           @BodyType.When(option = 
"application", value = "nlp/text_generation",
+                                                          carriers = 
Carrier.TEXT, javaType = "java.lang.String"),
+                                           @BodyType.When(option = 
"application", value = "nlp/machine_translation",
+                                                          carriers = 
Carrier.TEXT, javaType = "java.lang.String"),
+                                           @BodyType.When(option = 
"application", value = "nlp/multiple_choice",
+                                                          carriers = 
Carrier.TEXT, javaType = "java.lang.String"),
+                                           @BodyType.When(option = 
"application", value = "nlp/text_embedding",
+                                                          carriers = 
Carrier.POJO, javaType = "ai.djl.ndarray.NDArray"),
+                                           @BodyType.When(option = 
"application", value = "audio", carriers = Carrier.TEXT,
+                                                          javaType = 
"java.lang.String"),
+                                           @BodyType.When(option = 
"application", value = "timeseries/forecasting",
+                                                          carriers = 
Carrier.POJO, javaType = "ai.djl.timeseries.Forecast"),
+                                           @BodyType.When(option = 
"application", value = "tabular/linear_regression",
+                                                          carriers = 
Carrier.UNKNOWN),
+                                           @BodyType.When(option = 
"application", value = "tabular/softmax_regression",
+                                                          carriers = 
Carrier.UNKNOWN) },
+                                   description = "The prediction of the model, 
as a DJL object: Classifications,"
+                                                 + " DetectedObjects, 
CategoryMask, Joints, an Image, an NDArray or a"
+                                                 + " Forecast, or text for 
word_recognition, question_answer, text_generation,"
+                                                 + " machine_translation, 
multiple_choice and audio; nlp/word_embedding gives"
+                                                 + " the encoded NDList as 
bytes. With a custom model, it is what its"
+                                                 + " translator returns. The 
input the model took, such as the Image, is in"
+                                                 + " the CamelDjlInput 
header"))
 public class DJLEndpoint extends DefaultEndpoint {
 
     @UriPath
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 3e02990335b6..0dd49fafab27 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
@@ -64,6 +64,10 @@
     "CamelLangChain4jAgentToolExecutions": { "index": 13, "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" },
     "CamelLangChain4jAgentModerationFlagged": { "index": 14, "kind": "header", 
"displayName": "", "group": "producer", "label": "", "required": false, 
"javaType": "Boolean", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "Set to true when user input is rejected 
by the configured moderation model; not set on success.", "constantName": 
"org.apache.camel.component.langchain4j.agent.api.Headers#MODERATION_FLAGGED" }
   },
+  "bodyTypes": {
+    "producerIn": { "carriers": [ "text", "pojo", "bytes", "stream", "file" ], 
"description": "The user message as text, or an AiAgentBody with the user 
message, the system message, the memory id and a content. Bytes, a stream or a 
file of the file consumers is sent as an image, audio, video, PDF or text 
content after the text of the CamelLangChain4jAgentUserMessage header; bytes 
and a stream need the CamelLangChain4jAgentMediaType or Content-Type header. A 
Map, a java.io.File or another [...]
+    "producerOut": { "carriers": [ "text" ], "description": "The answer of the 
agent as text, also with outputClass or jsonSchema: unmarshal the JSON to read 
its fields. The token counts, the finish reason, the sources and the tool 
executions are in headers" }
+  },
   "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" },
     "agent": { "index": 1, "kind": "parameter", "displayName": "Agent", 
"group": "producer", "label": "", "required": false, "type": "object", 
"javaType": "org.apache.camel.component.langchain4j.agent.api.Agent", 
"deprecated": false, "deprecationNote": "", "autowired": true, "secret": false, 
"configurationClass": 
"org.apache.camel.component.langchain4j.agent.LangChain4jAgentConfiguration", 
"configurationField": "configuration", "description": "The agent to use for the 
component" },
diff --git 
a/components/camel-ai/camel-langchain4j-agent/src/main/java/org/apache/camel/component/langchain4j/agent/LangChain4jAgentEndpoint.java
 
b/components/camel-ai/camel-langchain4j-agent/src/main/java/org/apache/camel/component/langchain4j/agent/LangChain4jAgentEndpoint.java
index 65583b13b1d3..ca22f0e9c6c9 100644
--- 
a/components/camel-ai/camel-langchain4j-agent/src/main/java/org/apache/camel/component/langchain4j/agent/LangChain4jAgentEndpoint.java
+++ 
b/components/camel-ai/camel-langchain4j-agent/src/main/java/org/apache/camel/component/langchain4j/agent/LangChain4jAgentEndpoint.java
@@ -22,6 +22,9 @@ import org.apache.camel.Consumer;
 import org.apache.camel.Processor;
 import org.apache.camel.Producer;
 import org.apache.camel.component.langchain4j.agent.api.Headers;
+import org.apache.camel.spi.BodyType;
+import org.apache.camel.spi.BodyType.Carrier;
+import org.apache.camel.spi.BodyTypes;
 import org.apache.camel.spi.Metadata;
 import org.apache.camel.spi.UriEndpoint;
 import org.apache.camel.spi.UriParam;
@@ -35,6 +38,17 @@ import static 
org.apache.camel.component.langchain4j.agent.LangChain4jAgent.SCHE
              syntax = "langchain4j-agent:agentId",
              producerOnly = true,
              category = { Category.AI }, headersClass = Headers.class)
+@BodyTypes(producerIn = @BodyType(value = { Carrier.TEXT, Carrier.POJO, 
Carrier.BYTES, Carrier.STREAM, Carrier.FILE },
+                                  description = "The user message as text, or 
an AiAgentBody with the user message, the system"
+                                                + " message, the memory id and 
a content. Bytes, a stream or a file of the file"
+                                                + " consumers is sent as an 
image, audio, video, PDF or text content after the"
+                                                + " text of the 
CamelLangChain4jAgentUserMessage header; bytes and a stream need"
+                                                + " the 
CamelLangChain4jAgentMediaType or Content-Type header. A Map, a"
+                                                + " java.io.File or another 
object fails, and no body fails"),
+           producerOut = @BodyType(value = Carrier.TEXT,
+                                   description = "The answer of the agent as 
text, also with outputClass or jsonSchema:"
+                                                 + " unmarshal the JSON to 
read its fields. The token counts, the finish"
+                                                 + " reason, the sources and 
the tool executions are in headers"))
 public class LangChain4jAgentEndpoint extends DefaultEndpoint {
     @Metadata(required = true)
     @UriPath(description = "The Agent id")
diff --git 
a/components/camel-ai/camel-langchain4j-embeddings/src/generated/resources/META-INF/org/apache/camel/component/langchain4j/embeddings/langchain4j-embeddings.json
 
b/components/camel-ai/camel-langchain4j-embeddings/src/generated/resources/META-INF/org/apache/camel/component/langchain4j/embeddings/langchain4j-embeddings.json
index 0f2dddb9afa8..892805beec83 100644
--- 
a/components/camel-ai/camel-langchain4j-embeddings/src/generated/resources/META-INF/org/apache/camel/component/langchain4j/embeddings/langchain4j-embeddings.json
+++ 
b/components/camel-ai/camel-langchain4j-embeddings/src/generated/resources/META-INF/org/apache/camel/component/langchain4j/embeddings/langchain4j-embeddings.json
@@ -50,6 +50,10 @@
     "CamelLangChain4jEmbeddingsTextSegment": { "index": 9, "kind": "header", 
"displayName": "", "group": "producer", "label": "", "required": false, 
"javaType": " dev.langchain4j.data.segment.TextSegment", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": "A 
TextSegment representation of the vector embedding input text", "constantName": 
"org.apache.camel.component.langchain4j.embeddings.LangChain4jEmbeddingsHeaders#TEXT_SEGMENT"
 },
     "CamelLangChain4jEmbeddingsTextSegments": { "index": 10, "kind": "header", 
"displayName": "", "group": "producer", "label": "", "required": false, 
"javaType": "java.util.List<dev.langchain4j.data.segment.TextSegment>", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "List of text segments from a batch embedAll operation", 
"constantName": 
"org.apache.camel.component.langchain4j.embeddings.LangChain4jEmbeddingsHeaders#TEXT_SEGMENTS"
 }
   },
+  "bodyTypes": {
+    "producerIn": { "carriers": [ "text", "pojo", "list" ], "description": 
"The text to embed as a String or a TextSegment, or a non-empty List of them to 
embed in one batch. Bytes, a stream, a file, a Map and no body fail: convert 
the body to a String first" },
+    "producerOut": { "carriers": [ "unchanged" ], "description": "The body is 
kept. The vector goes in the CamelLangChain4jEmbeddingsVector header as a float 
array, with the Embedding and the TextSegment in the 
CamelLangChain4jEmbeddingsEmbedding and CamelLangChain4jEmbeddingsTextSegment 
headers; a List body gives Lists of them in the 
CamelLangChain4jEmbeddingsEmbeddings and CamelLangChain4jEmbeddingsTextSegments 
headers instead" }
+  },
   "properties": {
     "embeddingId": { "index": 0, "kind": "path", "displayName": "Embedding 
Id", "group": "producer", "label": "", "required": true, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "The id" },
     "embeddingModel": { "index": 1, "kind": "parameter", "displayName": 
"Embedding Model", "group": "producer", "label": "", "required": false, "type": 
"object", "javaType": "dev.langchain4j.model.embedding.EmbeddingModel", 
"deprecated": false, "deprecationNote": "", "autowired": true, "secret": false, 
"configurationClass": 
"org.apache.camel.component.langchain4j.embeddings.LangChain4jEmbeddingsConfiguration",
 "configurationField": "configuration", "description": "The EmbeddingModel engi 
[...]
diff --git 
a/components/camel-ai/camel-langchain4j-embeddings/src/main/java/org/apache/camel/component/langchain4j/embeddings/LangChain4jEmbeddingsEndpoint.java
 
b/components/camel-ai/camel-langchain4j-embeddings/src/main/java/org/apache/camel/component/langchain4j/embeddings/LangChain4jEmbeddingsEndpoint.java
index 421838114c41..3671438bbd53 100644
--- 
a/components/camel-ai/camel-langchain4j-embeddings/src/main/java/org/apache/camel/component/langchain4j/embeddings/LangChain4jEmbeddingsEndpoint.java
+++ 
b/components/camel-ai/camel-langchain4j-embeddings/src/main/java/org/apache/camel/component/langchain4j/embeddings/LangChain4jEmbeddingsEndpoint.java
@@ -21,6 +21,9 @@ import org.apache.camel.Component;
 import org.apache.camel.Consumer;
 import org.apache.camel.Processor;
 import org.apache.camel.Producer;
+import org.apache.camel.spi.BodyType;
+import org.apache.camel.spi.BodyType.Carrier;
+import org.apache.camel.spi.BodyTypes;
 import org.apache.camel.spi.Metadata;
 import org.apache.camel.spi.UriEndpoint;
 import org.apache.camel.spi.UriParam;
@@ -34,6 +37,17 @@ import org.apache.camel.support.DefaultEndpoint;
              syntax = "langchain4j-embeddings:embeddingId", producerOnly = 
true, category = {
                      Category.AI
              }, headersClass = LangChain4jEmbeddingsHeaders.class)
+@BodyTypes(producerIn = @BodyType(value = { Carrier.TEXT, Carrier.POJO, 
Carrier.LIST },
+                                  description = "The text to embed as a String 
or a TextSegment, or a non-empty List of"
+                                                + " them to embed in one 
batch. Bytes, a stream, a file, a Map and no body"
+                                                + " fail: convert the body to 
a String first"),
+           producerOut = @BodyType(value = Carrier.UNCHANGED,
+                                   description = "The body is kept. The vector 
goes in the CamelLangChain4jEmbeddingsVector"
+                                                 + " header as a float array, 
with the Embedding and the TextSegment in the"
+                                                 + " 
CamelLangChain4jEmbeddingsEmbedding and CamelLangChain4jEmbeddingsTextSegment"
+                                                 + " headers; a List body 
gives Lists of them in the"
+                                                 + " 
CamelLangChain4jEmbeddingsEmbeddings and CamelLangChain4jEmbeddingsTextSegments"
+                                                 + " headers instead"))
 public class LangChain4jEmbeddingsEndpoint extends DefaultEndpoint {
     @Metadata(required = true)
     @UriPath(description = "The id")
diff --git 
a/components/camel-ai/camel-langchain4j-embeddingstore/src/generated/resources/META-INF/org/apache/camel/component/langchain4j/embeddingstore/langchain4j-embeddingstore.json
 
b/components/camel-ai/camel-langchain4j-embeddingstore/src/generated/resources/META-INF/org/apache/camel/component/langchain4j/embeddingstore/langchain4j-embeddingstore.json
index 10ee7dd047e2..03dd71668c8d 100644
--- 
a/components/camel-ai/camel-langchain4j-embeddingstore/src/generated/resources/META-INF/org/apache/camel/component/langchain4j/embeddingstore/langchain4j-embeddingstore.json
+++ 
b/components/camel-ai/camel-langchain4j-embeddingstore/src/generated/resources/META-INF/org/apache/camel/component/langchain4j/embeddingstore/langchain4j-embeddingstore.json
@@ -43,6 +43,10 @@
     "CamelLangchain4jEmbeddingStoreEmbeddingId": { "index": 4, "kind": 
"header", "displayName": "", "group": "producer", "label": "", "required": 
false, "javaType": "String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "Caller-supplied embedding 
ID for single ADD operations", "constantName": 
"org.apache.camel.component.langchain4j.embeddingstore.LangChain4jEmbeddingStoreHeaders#EMBEDDING_ID"
 },
     "CamelLangchain4jEmbeddingStoreEmbeddingIds": { "index": 5, "kind": 
"header", "displayName": "", "group": "producer", "label": "", "required": 
false, "javaType": "java.util.List<java.lang.String>", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": 
"Caller-supplied embedding IDs for batch ADD operations", "constantName": 
"org.apache.camel.component.langchain4j.embeddingstore.LangChain4jEmbeddingStoreHeaders#EMBEDDING_IDS"
 }
   },
+  "bodyTypes": {
+    "producerIn": { "carriers": [ "any" ], "byOption": [ { "option": "action", 
"value": "REMOVE", "carriers": [ "text", "list" ] } ], "description": "ADD and 
SEARCH take the embedding from the CamelLangChain4jEmbeddingsEmbedding header 
(a batch ADD from the CamelLangChain4jEmbeddingsEmbeddings header) and ignore 
the body, but with an embeddingModel and no such header they embed the body 
read as a String, so no body fails and another body, a TextSegment too, is 
embedded as its toString(). [...]
+    "producerOut": { "carriers": [ "text", "list", "unchanged" ], "byOption": 
[ { "option": "action", "value": "ADD", "carriers": [ "text", "list" ] }, { 
"option": "action", "value": "REMOVE", "carriers": [ "unchanged" ] }, { 
"option": "action", "value": "SEARCH", "carriers": [ "list" ] } ], 
"description": "By the action, from the endpoint or the 
CamelLangchain4jEmbeddingStoreAction header: the id of the added embedding as a 
String for ADD, a List of the ids for a batch ADD, and a List o [...]
+  },
   "properties": {
     "embeddingStoreId": { "index": 0, "kind": "path", "displayName": 
"Embedding Store Id", "group": "producer", "label": "", "required": true, 
"type": "string", "javaType": "java.lang.String", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": "The 
id of the embedding store" },
     "action": { "index": 1, "kind": "parameter", "displayName": "Action", 
"group": "producer", "label": "", "required": false, "type": "enum", 
"javaType": 
"org.apache.camel.component.langchain4j.embeddingstore.LangChain4jEmbeddingStoreAction",
 "enum": [ "ADD", "REMOVE", "SEARCH" ], "deprecated": false, "autowired": 
false, "secret": false, "configurationClass": 
"org.apache.camel.component.langchain4j.embeddingstore.LangChain4jEmbeddingStoreConfiguration",
 "configurationField": "configurat [...]
diff --git 
a/components/camel-ai/camel-langchain4j-embeddingstore/src/main/java/org/apache/camel/component/langchain4j/embeddingstore/LangChain4jEmbeddingStoreEndpoint.java
 
b/components/camel-ai/camel-langchain4j-embeddingstore/src/main/java/org/apache/camel/component/langchain4j/embeddingstore/LangChain4jEmbeddingStoreEndpoint.java
index a983d1d32b46..8c1b63b80c98 100644
--- 
a/components/camel-ai/camel-langchain4j-embeddingstore/src/main/java/org/apache/camel/component/langchain4j/embeddingstore/LangChain4jEmbeddingStoreEndpoint.java
+++ 
b/components/camel-ai/camel-langchain4j-embeddingstore/src/main/java/org/apache/camel/component/langchain4j/embeddingstore/LangChain4jEmbeddingStoreEndpoint.java
@@ -21,6 +21,9 @@ import org.apache.camel.Component;
 import org.apache.camel.Consumer;
 import org.apache.camel.Processor;
 import org.apache.camel.Producer;
+import org.apache.camel.spi.BodyType;
+import org.apache.camel.spi.BodyType.Carrier;
+import org.apache.camel.spi.BodyTypes;
 import org.apache.camel.spi.Metadata;
 import org.apache.camel.spi.UriEndpoint;
 import org.apache.camel.spi.UriParam;
@@ -41,6 +44,29 @@ import org.apache.camel.support.DefaultEndpoint;
                      Category.AI
              },
              headersClass = LangChain4jEmbeddingStoreHeaders.class)
+@BodyTypes(producerIn = @BodyType(value = Carrier.ANY,
+                                  byOption = @BodyType.When(option = "action", 
value = "REMOVE",
+                                                            carriers = { 
Carrier.TEXT, Carrier.LIST }),
+                                  description = "ADD and SEARCH take the 
embedding from the"
+                                                + " 
CamelLangChain4jEmbeddingsEmbedding header (a batch ADD from the"
+                                                + " 
CamelLangChain4jEmbeddingsEmbeddings header) and ignore the body, but with"
+                                                + " an embeddingModel and no 
such header they embed the body read as a String,"
+                                                + " so no body fails and 
another body, a TextSegment too, is embedded as its"
+                                                + " toString(). REMOVE takes 
the id as text or a Collection of ids, unless the"
+                                                + " 
CamelLangchain4jEmbeddingStoreFilter header is set"),
+           producerOut = @BodyType(value = { Carrier.TEXT, Carrier.LIST, 
Carrier.UNCHANGED },
+                                   byOption = {
+                                           @BodyType.When(option = "action", 
value = "ADD",
+                                                          carriers = { 
Carrier.TEXT, Carrier.LIST }),
+                                           @BodyType.When(option = "action", 
value = "REMOVE",
+                                                          carriers = 
Carrier.UNCHANGED),
+                                           @BodyType.When(option = "action", 
value = "SEARCH",
+                                                          carriers = 
Carrier.LIST) },
+                                   description = "By the action, from the 
endpoint or the"
+                                                 + " 
CamelLangchain4jEmbeddingStoreAction header: the id of the added embedding"
+                                                 + " as a String for ADD, a 
List of the ids for a batch ADD, and a List of"
+                                                 + " EmbeddingMatch for SEARCH 
(a List of the matched texts with"
+                                                 + " returnTextContent). 
REMOVE keeps the body"))
 public class LangChain4jEmbeddingStoreEndpoint extends DefaultEndpoint {
     @Metadata(required = true)
     @UriPath(description = "The id of the embedding store")
diff --git 
a/components/camel-ai/camel-langchain4j-ingest/src/generated/resources/META-INF/org/apache/camel/component/langchain4j/ingest/langchain4j-ingest.json
 
b/components/camel-ai/camel-langchain4j-ingest/src/generated/resources/META-INF/org/apache/camel/component/langchain4j/ingest/langchain4j-ingest.json
index 18342ddc34fa..c090ee548b21 100644
--- 
a/components/camel-ai/camel-langchain4j-ingest/src/generated/resources/META-INF/org/apache/camel/component/langchain4j/ingest/langchain4j-ingest.json
+++ 
b/components/camel-ai/camel-langchain4j-ingest/src/generated/resources/META-INF/org/apache/camel/component/langchain4j/ingest/langchain4j-ingest.json
@@ -46,6 +46,10 @@
   "headers": {
     "CamelLangChain4jIngestDocumentId": { "index": 0, "kind": "header", 
"displayName": "", "group": "producer", "label": "", "required": false, 
"javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The stable document id of the ingested 
payload, read when the documentIdHeader endpoint option does not name another 
header. The CamelLangChain4jIngestDocumentId exchange property, when set, takes 
precedence over any header.", "c [...]
   },
+  "bodyTypes": {
+    "producerIn": { "carriers": [ "text", "bytes", "stream", "file", "null" ], 
"byOption": [ { "option": "modality", "value": "MEDIA", "carriers": [ "bytes", 
"stream", "file", "null" ] } ], "description": "The document read as a String, 
then split and embedded; another body, such as a Map or a TextSegment, is 
ingested as its toString(). With modality=MEDIA it is read as bytes and 
embedded whole, and a Map or a POJO fails. No body or a blank one writes 
nothing. The document id comes from  [...]
+    "producerOut": { "carriers": [ "pojo" ], "javaType": 
"org.apache.camel.component.langchain4j.ingest.IngestResult", "description": 
"An IngestResult with the pipeline, the document id, the number of segments 
written and the outcome: INGESTED, EMPTY, SKIPPED or FILTERED" }
+  },
   "properties": {
     "pipelineName": { "index": 0, "kind": "path", "displayName": "Pipeline 
Name", "group": "producer", "label": "", "required": true, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "The pipeline name, stamped 
on every written segment as the camel_ingest_pipeline metadata and used in 
error messages" },
     "contentType": { "index": 1, "kind": "parameter", "displayName": "Content 
Type", "group": "producer", "label": "", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "configurationClass": 
"org.apache.camel.component.langchain4j.ingest.LangChain4jIngestConfiguration", 
"configurationField": "configuration", "description": "MIME type of a media 
body, such as audio\/wav or image\/png, handed to the embedding mode [...]
diff --git 
a/components/camel-ai/camel-langchain4j-ingest/src/main/java/org/apache/camel/component/langchain4j/ingest/LangChain4jIngestEndpoint.java
 
b/components/camel-ai/camel-langchain4j-ingest/src/main/java/org/apache/camel/component/langchain4j/ingest/LangChain4jIngestEndpoint.java
index 0fb77464ce19..3cadcb98c265 100644
--- 
a/components/camel-ai/camel-langchain4j-ingest/src/main/java/org/apache/camel/component/langchain4j/ingest/LangChain4jIngestEndpoint.java
+++ 
b/components/camel-ai/camel-langchain4j-ingest/src/main/java/org/apache/camel/component/langchain4j/ingest/LangChain4jIngestEndpoint.java
@@ -21,6 +21,9 @@ import org.apache.camel.Component;
 import org.apache.camel.Consumer;
 import org.apache.camel.Processor;
 import org.apache.camel.Producer;
+import org.apache.camel.spi.BodyType;
+import org.apache.camel.spi.BodyType.Carrier;
+import org.apache.camel.spi.BodyTypes;
 import org.apache.camel.spi.Metadata;
 import org.apache.camel.spi.UriEndpoint;
 import org.apache.camel.spi.UriParam;
@@ -40,6 +43,20 @@ import org.apache.camel.support.DefaultEndpoint;
                      Category.AI
              },
              headersClass = LangChain4jIngestHeaders.class)
+@BodyTypes(producerIn = @BodyType(value = { Carrier.TEXT, Carrier.BYTES, 
Carrier.STREAM, Carrier.FILE, Carrier.NULL },
+                                  byOption = @BodyType.When(option = 
"modality", value = "MEDIA",
+                                                            carriers = {
+                                                                    
Carrier.BYTES, Carrier.STREAM, Carrier.FILE,
+                                                                    
Carrier.NULL }),
+                                  description = "The document read as a 
String, then split and embedded; another body,"
+                                                + " such as a Map or a 
TextSegment, is ingested as its toString(). With"
+                                                + " modality=MEDIA it is read 
as bytes and embedded whole, and a Map or a POJO"
+                                                + " fails. No body or a blank 
one writes nothing. The document id comes from"
+                                                + " the 
CamelLangChain4jIngestDocumentId header or exchange property"),
+           producerOut = @BodyType(value = Carrier.POJO,
+                                   javaType = 
"org.apache.camel.component.langchain4j.ingest.IngestResult",
+                                   description = "An IngestResult with the 
pipeline, the document id, the number of segments"
+                                                 + " written and the outcome: 
INGESTED, EMPTY, SKIPPED or FILTERED"))
 public class LangChain4jIngestEndpoint extends DefaultEndpoint {
 
     @Metadata(required = true)
diff --git 
a/components/camel-ai/camel-langchain4j-web-search/src/generated/resources/META-INF/org/apache/camel/component/langchain4j/web/search/langchain4j-web-search.json
 
b/components/camel-ai/camel-langchain4j-web-search/src/generated/resources/META-INF/org/apache/camel/component/langchain4j/web/search/langchain4j-web-search.json
index 51f53e82d740..958cb858d59e 100644
--- 
a/components/camel-ai/camel-langchain4j-web-search/src/generated/resources/META-INF/org/apache/camel/component/langchain4j/web/search/langchain4j-web-search.json
+++ 
b/components/camel-ai/camel-langchain4j-web-search/src/generated/resources/META-INF/org/apache/camel/component/langchain4j/web/search/langchain4j-web-search.json
@@ -27,6 +27,10 @@
     "lazyStartProducer": { "index": 0, "kind": "property", "displayName": 
"Lazy Start Producer", "group": "producer", "label": "producer", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": false, "description": 
"Whether the producer should be started lazy (on the first message). By 
starting lazy you can use this to allow CamelContext and routes to startup in 
situations where a producer may otherwise fail [...]
     "autowiredEnabled": { "index": 1, "kind": "property", "displayName": 
"Autowired Enabled", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": true, "description": 
"Whether autowiring is enabled. This is used for automatic autowiring options 
(the option must be marked as autowired) by looking up in the registry to find 
if there is a single instance of matching t [...]
   },
+  "bodyTypes": {
+    "producerIn": { "carriers": [ "any" ], "description": "The search terms as 
text; another body is converted to text, so a Map or a POJO is searched as its 
toString(), and no body fails. With webSearchRequest the body is not read" },
+    "producerOut": { "carriers": [ "text", "null" ], "dependsOn": [ 
"maxResults", "webSearchRequest" ], "byOption": [ { "option": "resultType", 
"value": "LANGCHAIN4J_WEB_SEARCH_ORGANIC_RESULT", "carriers": [ "pojo", "null" 
] } ], "description": "The content of the first result as text (its snippet 
with resultType SNIPPET, the WebSearchOrganicResult with 
LANGCHAIN4J_WEB_SEARCH_ORGANIC_RESULT), or null when there is no result or the 
engine gives no content. With maxResults above 1 it is a  [...]
+  },
   "properties": {
     "searchId": { "index": 0, "kind": "path", "displayName": "Search Id", 
"group": "producer", "label": "", "required": true, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "The id" },
     "additionalParams": { "index": 1, "kind": "parameter", "displayName": 
"Additional Params", "group": "producer", "label": "", "required": false, 
"type": "object", "javaType": "java.util.Map<java.lang.String, 
java.lang.Object>", "deprecated": false, "deprecationNote": "", "autowired": 
true, "secret": false, "configurationClass": 
"org.apache.camel.component.langchain4j.web.search.LangChain4jWebSearchConfiguration",
 "configurationField": "configuration", "description": "The additionalPar [...]
diff --git 
a/components/camel-ai/camel-langchain4j-web-search/src/main/java/org/apache/camel/component/langchain4j/web/search/LangChain4jWebSearchEndpoint.java
 
b/components/camel-ai/camel-langchain4j-web-search/src/main/java/org/apache/camel/component/langchain4j/web/search/LangChain4jWebSearchEndpoint.java
index 0a905e43303f..0e63f22959f1 100644
--- 
a/components/camel-ai/camel-langchain4j-web-search/src/main/java/org/apache/camel/component/langchain4j/web/search/LangChain4jWebSearchEndpoint.java
+++ 
b/components/camel-ai/camel-langchain4j-web-search/src/main/java/org/apache/camel/component/langchain4j/web/search/LangChain4jWebSearchEndpoint.java
@@ -21,6 +21,9 @@ import org.apache.camel.Component;
 import org.apache.camel.Consumer;
 import org.apache.camel.Processor;
 import org.apache.camel.Producer;
+import org.apache.camel.spi.BodyType;
+import org.apache.camel.spi.BodyType.Carrier;
+import org.apache.camel.spi.BodyTypes;
 import org.apache.camel.spi.Metadata;
 import org.apache.camel.spi.UriEndpoint;
 import org.apache.camel.spi.UriParam;
@@ -34,6 +37,19 @@ import org.apache.camel.support.DefaultEndpoint;
              syntax = "langchain4j-web-search:searchId", producerOnly = true, 
category = {
                      Category.AI
              })
+@BodyTypes(producerIn = @BodyType(value = Carrier.ANY,
+                                  description = "The search terms as text; 
another body is converted to text, so a Map or a"
+                                                + " POJO is searched as its 
toString(), and no body fails. With"
+                                                + " webSearchRequest the body 
is not read"),
+           producerOut = @BodyType(value = { Carrier.TEXT, Carrier.NULL }, 
dependsOn = { "maxResults", "webSearchRequest" },
+                                   byOption = @BodyType.When(option = 
"resultType",
+                                                             value = 
"LANGCHAIN4J_WEB_SEARCH_ORGANIC_RESULT",
+                                                             carriers = { 
Carrier.POJO, Carrier.NULL }),
+                                   description = "The content of the first 
result as text (its snippet with resultType"
+                                                 + " SNIPPET, the 
WebSearchOrganicResult with"
+                                                 + " 
LANGCHAIN4J_WEB_SEARCH_ORGANIC_RESULT), or null when there is no result"
+                                                 + " or the engine gives no 
content. With maxResults above 1 it is a List of"
+                                                 + " them, which can hold 
nulls"))
 public class LangChain4jWebSearchEndpoint extends DefaultEndpoint {
 
     @Metadata(required = true)
diff --git 
a/components/camel-spring-parent/camel-spring-ai/camel-spring-ai-chat/src/generated/resources/META-INF/org/apache/camel/component/springai/chat/spring-ai-chat.json
 
b/components/camel-spring-parent/camel-spring-ai/camel-spring-ai-chat/src/generated/resources/META-INF/org/apache/camel/component/springai/chat/spring-ai-chat.json
index c109251e5e93..eca6eea78e58 100644
--- 
a/components/camel-spring-parent/camel-spring-ai/camel-spring-ai-chat/src/generated/resources/META-INF/org/apache/camel/component/springai/chat/spring-ai-chat.json
+++ 
b/components/camel-spring-parent/camel-spring-ai/camel-spring-ai-chat/src/generated/resources/META-INF/org/apache/camel/component/springai/chat/spring-ai-chat.json
@@ -62,6 +62,10 @@
     "CamelSpringAiChatToolNames": { "index": 30, "kind": "header", 
"displayName": "", "group": "producer", "label": "", "required": false, 
"javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "Comma-separated tool names for 
selecting tools by name via ToolCallbackResolver", "constantName": 
"org.apache.camel.component.springai.chat.SpringAiChatConstants#TOOL_NAMES" },
     "CamelSpringAiChatToolContext": { "index": 31, "kind": "header", 
"displayName": "", "group": "producer", "label": "", "required": false, 
"javaType": "java.util.Map<String, Object>", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": 
"Context map to pass to tools during execution", "constantName": 
"org.apache.camel.component.springai.chat.SpringAiChatConstants#TOOL_CONTEXT" }
   },
+  "bodyTypes": {
+    "producerIn": { "carriers": [ "any" ], "byOption": [ { "option": 
"chatOperation", "value": "CHAT_SINGLE_MESSAGE_WITH_PROMPT", "carriers": [ 
"map" ] }, { "option": "chatOperation", "value": "CHAT_MULTIPLE_MESSAGES", 
"carriers": [ "list" ] } ], "description": "The prompt as text, or a 
UserMessage or another Spring AI Message. A byte[] is sent as media (image\/png 
unless the CamelSpringAiChatMediaType header says otherwise), and a WrappedFile 
of a local file, or a List of them, as media [...]
+    "producerOut": { "carriers": [ "text" ], "dependsOn": [ "entityClass", 
"structuredOutputConverter" ], "byOption": [ { "option": "outputFormat", 
"value": "BEAN", "carriers": [ "pojo" ] }, { "option": "outputFormat", "value": 
"MAP", "carriers": [ "map" ] }, { "option": "outputFormat", "value": "LIST", 
"carriers": [ "list" ] } ], "description": "The answer of the model as text, 
also in the CamelSpringAiChatResponse header. entityClass makes it an object of 
that class, and outputFormat a [...]
+  },
   "properties": {
     "chatId": { "index": 0, "kind": "path", "displayName": "Chat Id", "group": 
"producer", "label": "", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "The ID of the chat endpoint" },
     "chatClient": { "index": 1, "kind": "parameter", "displayName": "Chat 
Client", "group": "producer", "label": "", "required": false, "type": "object", 
"javaType": "org.springframework.ai.chat.client.ChatClient", "deprecated": 
false, "deprecationNote": "", "autowired": true, "secret": false, 
"configurationClass": 
"org.apache.camel.component.springai.chat.SpringAiChatConfiguration", 
"configurationField": "configuration", "description": "The ChatClient instance 
to use for chat operations [...]
diff --git 
a/components/camel-spring-parent/camel-spring-ai/camel-spring-ai-chat/src/main/java/org/apache/camel/component/springai/chat/SpringAiChatEndpoint.java
 
b/components/camel-spring-parent/camel-spring-ai/camel-spring-ai-chat/src/main/java/org/apache/camel/component/springai/chat/SpringAiChatEndpoint.java
index 82ff1c2df23e..06325a139fee 100644
--- 
a/components/camel-spring-parent/camel-spring-ai/camel-spring-ai-chat/src/main/java/org/apache/camel/component/springai/chat/SpringAiChatEndpoint.java
+++ 
b/components/camel-spring-parent/camel-spring-ai/camel-spring-ai-chat/src/main/java/org/apache/camel/component/springai/chat/SpringAiChatEndpoint.java
@@ -21,6 +21,9 @@ import org.apache.camel.Component;
 import org.apache.camel.Consumer;
 import org.apache.camel.Processor;
 import org.apache.camel.Producer;
+import org.apache.camel.spi.BodyType;
+import org.apache.camel.spi.BodyType.Carrier;
+import org.apache.camel.spi.BodyTypes;
 import org.apache.camel.spi.EndpointServiceLocation;
 import org.apache.camel.spi.UriEndpoint;
 import org.apache.camel.spi.UriParam;
@@ -33,6 +36,33 @@ import org.apache.camel.support.DefaultEndpoint;
 @UriEndpoint(firstVersion = "4.17.0", scheme = "spring-ai-chat", title = 
"Spring AI Chat",
              syntax = "spring-ai-chat:chatId", producerOnly = true, category = 
{ Category.AI },
              headersClass = SpringAiChatConstants.class)
+@BodyTypes(producerIn = @BodyType(value = Carrier.ANY,
+                                  byOption = {
+                                          @BodyType.When(option = 
"chatOperation", value = "CHAT_SINGLE_MESSAGE_WITH_PROMPT",
+                                                         carriers = 
Carrier.MAP),
+                                          @BodyType.When(option = 
"chatOperation", value = "CHAT_MULTIPLE_MESSAGES",
+                                                         carriers = 
Carrier.LIST) },
+                                  description = "The prompt as text, or a 
UserMessage or another Spring AI Message. A"
+                                                + " byte[] is sent as media 
(image/png unless the"
+                                                + " CamelSpringAiChatMediaType 
header says otherwise), and a WrappedFile"
+                                                + " of a local file, or a List 
of them, as media files: these need"
+                                                + " userMessage or the 
CamelSpringAiChatUserMessage header for the text."
+                                                + " A stream, a java.io.File 
or another body is sent as its text, and no"
+                                                + " body fails. 
CHAT_SINGLE_MESSAGE_WITH_PROMPT takes the variables of"
+                                                + " the template in the 
CamelSpringAiChatPromptTemplate header as a Map,"
+                                                + " and CHAT_MULTIPLE_MESSAGES 
a List of Message"),
+           producerOut = @BodyType(value = Carrier.TEXT,
+                                   dependsOn = { "entityClass", 
"structuredOutputConverter" },
+                                   byOption = {
+                                           @BodyType.When(option = 
"outputFormat", value = "BEAN", carriers = Carrier.POJO),
+                                           @BodyType.When(option = 
"outputFormat", value = "MAP", carriers = Carrier.MAP),
+                                           @BodyType.When(option = 
"outputFormat", value = "LIST",
+                                                          carriers = 
Carrier.LIST) },
+                                   description = "The answer of the model as 
text, also in the CamelSpringAiChatResponse"
+                                                 + " header. entityClass makes 
it an object of that class, and"
+                                                 + " outputFormat an object of 
outputClass, a Map or a List of texts;"
+                                                 + " the 
CamelSpringAiChatEntityClass and CamelSpringAiChatOutputFormat"
+                                                 + " headers do the same per 
message"))
 public class SpringAiChatEndpoint extends DefaultEndpoint implements 
EndpointServiceLocation {
 
     @UriPath(description = "The ID of the chat endpoint")
diff --git 
a/components/camel-spring-parent/camel-spring-ai/camel-spring-ai-embeddings/src/generated/resources/META-INF/org/apache/camel/component/springai/embeddings/spring-ai-embeddings.json
 
b/components/camel-spring-parent/camel-spring-ai/camel-spring-ai-embeddings/src/generated/resources/META-INF/org/apache/camel/component/springai/embeddings/spring-ai-embeddings.json
index 3eefb7b912f5..6b33fa8447b1 100644
--- 
a/components/camel-spring-parent/camel-spring-ai/camel-spring-ai-embeddings/src/generated/resources/META-INF/org/apache/camel/component/springai/embeddings/spring-ai-embeddings.json
+++ 
b/components/camel-spring-parent/camel-spring-ai/camel-spring-ai-embeddings/src/generated/resources/META-INF/org/apache/camel/component/springai/embeddings/spring-ai-embeddings.json
@@ -37,6 +37,10 @@
     "CamelSpringAiEmbeddings": { "index": 4, "kind": "header", "displayName": 
"", "group": "producer", "label": "", "required": false, "javaType": 
"java.util.List<org.springframework.ai.embedding.Embedding>", "deprecated": 
false, "deprecationNote": "", "autowired": false, "secret": false, 
"description": "List of Embedding objects", "constantName": 
"org.apache.camel.component.springai.embeddings.SpringAiEmbeddingsHeaders#EMBEDDINGS"
 },
     "CamelSpringAiEmbeddingInputTexts": { "index": 5, "kind": "header", 
"displayName": "", "group": "producer", "label": "", "required": false, 
"javaType": "java.util.List<String>", "deprecated": false, "deprecationNote": 
"", "autowired": false, "secret": false, "description": "List of input texts 
that were embedded", "constantName": 
"org.apache.camel.component.springai.embeddings.SpringAiEmbeddingsHeaders#INPUT_TEXTS"
 }
   },
+  "bodyTypes": {
+    "producerIn": { "carriers": [ "any" ], "description": "The text to embed, 
or a List of texts for a batch. Another body is converted to text (a Map or a 
POJO as its toString()), and no body fails" },
+    "producerOut": { "carriers": [ "list" ], "description": "The vector as a 
float[] for one text, also for a List with one text, and a List of float[] for 
a List of more texts. The Embedding and the input text are in headers, which 
spring-ai-vector-store reads" }
+  },
   "properties": {
     "embeddingId": { "index": 0, "kind": "path", "displayName": "Embedding 
Id", "group": "producer", "label": "", "required": true, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "The id" },
     "embeddingModel": { "index": 1, "kind": "parameter", "displayName": 
"Embedding Model", "group": "producer", "label": "", "required": true, "type": 
"object", "javaType": "org.springframework.ai.embedding.EmbeddingModel", 
"deprecated": false, "deprecationNote": "", "autowired": true, "secret": false, 
"configurationClass": 
"org.apache.camel.component.springai.embeddings.SpringAiEmbeddingsConfiguration",
 "configurationField": "configuration", "description": "The EmbeddingModel to 
use for [...]
diff --git 
a/components/camel-spring-parent/camel-spring-ai/camel-spring-ai-embeddings/src/main/java/org/apache/camel/component/springai/embeddings/SpringAiEmbeddingsEndpoint.java
 
b/components/camel-spring-parent/camel-spring-ai/camel-spring-ai-embeddings/src/main/java/org/apache/camel/component/springai/embeddings/SpringAiEmbeddingsEndpoint.java
index 081d641e61cd..a0e3683f2a24 100644
--- 
a/components/camel-spring-parent/camel-spring-ai/camel-spring-ai-embeddings/src/main/java/org/apache/camel/component/springai/embeddings/SpringAiEmbeddingsEndpoint.java
+++ 
b/components/camel-spring-parent/camel-spring-ai/camel-spring-ai-embeddings/src/main/java/org/apache/camel/component/springai/embeddings/SpringAiEmbeddingsEndpoint.java
@@ -21,6 +21,9 @@ import org.apache.camel.Component;
 import org.apache.camel.Consumer;
 import org.apache.camel.Processor;
 import org.apache.camel.Producer;
+import org.apache.camel.spi.BodyType;
+import org.apache.camel.spi.BodyType.Carrier;
+import org.apache.camel.spi.BodyTypes;
 import org.apache.camel.spi.Metadata;
 import org.apache.camel.spi.UriEndpoint;
 import org.apache.camel.spi.UriParam;
@@ -34,6 +37,14 @@ import org.apache.camel.support.DefaultEndpoint;
              syntax = "spring-ai-embeddings:embeddingId", producerOnly = true, 
category = {
                      Category.AI
              }, headersClass = SpringAiEmbeddingsHeaders.class)
+@BodyTypes(producerIn = @BodyType(value = Carrier.ANY,
+                                  description = "The text to embed, or a List 
of texts for a batch. Another body is"
+                                                + " converted to text (a Map 
or a POJO as its toString()), and no body"
+                                                + " fails"),
+           producerOut = @BodyType(value = Carrier.LIST,
+                                   description = "The vector as a float[] for 
one text, also for a List with one text,"
+                                                 + " and a List of float[] for 
a List of more texts. The Embedding and"
+                                                 + " the input text are in 
headers, which spring-ai-vector-store reads"))
 public class SpringAiEmbeddingsEndpoint extends DefaultEndpoint {
     @Metadata(required = true)
     @UriPath(description = "The id")
diff --git 
a/components/camel-spring-parent/camel-spring-ai/camel-spring-ai-image/src/generated/resources/META-INF/org/apache/camel/component/springai/image/spring-ai-image.json
 
b/components/camel-spring-parent/camel-spring-ai/camel-spring-ai-image/src/generated/resources/META-INF/org/apache/camel/component/springai/image/spring-ai-image.json
index 854fa8e6e4b1..c5bd30f01384 100644
--- 
a/components/camel-spring-parent/camel-spring-ai/camel-spring-ai-image/src/generated/resources/META-INF/org/apache/camel/component/springai/image/spring-ai-image.json
+++ 
b/components/camel-spring-parent/camel-spring-ai/camel-spring-ai-image/src/generated/resources/META-INF/org/apache/camel/component/springai/image/spring-ai-image.json
@@ -46,6 +46,10 @@
     "CamelSpringAiImageGeneration": { "index": 7, "kind": "header", 
"displayName": "", "group": "producer", "label": "", "required": false, 
"javaType": "org.springframework.ai.image.ImageGeneration", "deprecated": 
false, "deprecationNote": "", "autowired": false, "secret": false, 
"description": "The ImageGeneration object for single image results", 
"constantName": 
"org.apache.camel.component.springai.image.SpringAiImageHeaders#IMAGE_GENERATION"
 },
     "CamelSpringAiImageGenerations": { "index": 8, "kind": "header", 
"displayName": "", "group": "producer", "label": "", "required": false, 
"javaType": "java.util.List<org.springframework.ai.image.ImageGeneration>", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "List of ImageGeneration objects for multiple image 
results", "constantName": 
"org.apache.camel.component.springai.image.SpringAiImageHeaders#IMAGE_GENERATIONS"
 }
   },
+  "bodyTypes": {
+    "producerIn": { "carriers": [ "any" ], "description": "The prompt as text, 
or an ImagePrompt, which keeps its own options: n, width and the other options 
and headers then do not apply. Another body is converted to text, and no body 
fails" },
+    "producerOut": { "carriers": [ "pojo", "list" ], "description": "The 
generated org.springframework.ai.image.Image, with a URL or base64 data, or a 
List of Image when the model returns more than one (n above 1). An Image 
converts to byte[] by decoding the base64 data; an Image with only a URL gives 
the bytes of the URL text" }
+  },
   "properties": {
     "imageId": { "index": 0, "kind": "path", "displayName": "Image Id", 
"group": "producer", "label": "", "required": true, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "The id" },
     "height": { "index": 1, "kind": "parameter", "displayName": "Height", 
"group": "producer", "label": "", "required": false, "type": "integer", 
"javaType": "java.lang.Integer", "deprecated": false, "autowired": false, 
"secret": false, "configurationClass": 
"org.apache.camel.component.springai.image.SpringAiImageConfiguration", 
"configurationField": "configuration", "description": "Image height in pixels" 
},
diff --git 
a/components/camel-spring-parent/camel-spring-ai/camel-spring-ai-image/src/main/docs/spring-ai-image-component.adoc
 
b/components/camel-spring-parent/camel-spring-ai/camel-spring-ai-image/src/main/docs/spring-ai-image-component.adoc
index 3be56a4b68d6..c097f5613dc7 100644
--- 
a/components/camel-spring-parent/camel-spring-ai/camel-spring-ai-image/src/main/docs/spring-ai-image-component.adoc
+++ 
b/components/camel-spring-parent/camel-spring-ai/camel-spring-ai-image/src/main/docs/spring-ai-image-component.adoc
@@ -157,7 +157,8 @@ YAML::
 ----
 ====
 
-The `Image` → `byte[]` conversion decodes the base64 data automatically.
+The `Image` → `byte[]` conversion decodes the base64 data automatically. Set 
`responseFormat=b64_json` when the
+provider returns a URL by default, as the URL is not downloaded.
 
 === Using with Ollama (Local Image Generation)
 
@@ -256,8 +257,8 @@ The component registers automatic type converters for 
`Image` objects:
 |===
 | From | To | Behavior
 
-| `Image` | `byte[]` | Decodes base64 data
-| `Image` | `InputStream` | Wraps decoded bytes in ByteArrayInputStream
+| `Image` | `byte[]` | Decodes base64 data. An `Image` with only a URL gives 
the bytes of the URL text: the image is not downloaded
+| `Image` | `InputStream` | Wraps the `byte[]` above in ByteArrayInputStream
 | `Image` | `String` | Returns base64 string or URL
 |===
 
diff --git 
a/components/camel-spring-parent/camel-spring-ai/camel-spring-ai-image/src/main/java/org/apache/camel/component/springai/image/SpringAiImageEndpoint.java
 
b/components/camel-spring-parent/camel-spring-ai/camel-spring-ai-image/src/main/java/org/apache/camel/component/springai/image/SpringAiImageEndpoint.java
index 7558d279c75d..7b0609c1ca9e 100644
--- 
a/components/camel-spring-parent/camel-spring-ai/camel-spring-ai-image/src/main/java/org/apache/camel/component/springai/image/SpringAiImageEndpoint.java
+++ 
b/components/camel-spring-parent/camel-spring-ai/camel-spring-ai-image/src/main/java/org/apache/camel/component/springai/image/SpringAiImageEndpoint.java
@@ -21,6 +21,9 @@ import org.apache.camel.Component;
 import org.apache.camel.Consumer;
 import org.apache.camel.Processor;
 import org.apache.camel.Producer;
+import org.apache.camel.spi.BodyType;
+import org.apache.camel.spi.BodyType.Carrier;
+import org.apache.camel.spi.BodyTypes;
 import org.apache.camel.spi.Metadata;
 import org.apache.camel.spi.UriEndpoint;
 import org.apache.camel.spi.UriParam;
@@ -34,6 +37,15 @@ import org.apache.camel.support.DefaultEndpoint;
              syntax = "spring-ai-image:imageId", producerOnly = true, category 
= {
                      Category.AI
              }, headersClass = SpringAiImageHeaders.class)
+@BodyTypes(producerIn = @BodyType(value = Carrier.ANY,
+                                  description = "The prompt as text, or an 
ImagePrompt, which keeps its own options: n,"
+                                                + " width and the other 
options and headers then do not apply. Another"
+                                                + " body is converted to text, 
and no body fails"),
+           producerOut = @BodyType(value = { Carrier.POJO, Carrier.LIST },
+                                   description = "The generated 
org.springframework.ai.image.Image, with a URL or base64"
+                                                 + " data, or a List of Image 
when the model returns more than one (n"
+                                                 + " above 1). An Image 
converts to byte[] by decoding the base64 data;"
+                                                 + " an Image with only a URL 
gives the bytes of the URL text"))
 public class SpringAiImageEndpoint extends DefaultEndpoint {
     @Metadata(required = true)
     @UriPath(description = "The id")
diff --git 
a/components/camel-spring-parent/camel-spring-ai/camel-spring-ai-vector-store/src/generated/resources/META-INF/org/apache/camel/component/springai/vectorstore/spring-ai-vector-store.json
 
b/components/camel-spring-parent/camel-spring-ai/camel-spring-ai-vector-store/src/generated/resources/META-INF/org/apache/camel/component/springai/vectorstore/spring-ai-vector-store.json
index 2ec8e1c5f601..c4e957c49f71 100644
--- 
a/components/camel-spring-parent/camel-spring-ai/camel-spring-ai-vector-store/src/generated/resources/META-INF/org/apache/camel/component/springai/vectorstore/spring-ai-vector-store.json
+++ 
b/components/camel-spring-parent/camel-spring-ai/camel-spring-ai-vector-store/src/generated/resources/META-INF/org/apache/camel/component/springai/vectorstore/spring-ai-vector-store.json
@@ -43,6 +43,10 @@
     "CamelSpringAiVectorStoreDocumentsAdded": { "index": 6, "kind": "header", 
"displayName": "", "group": "producer", "label": "", "required": false, 
"javaType": "Integer", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "Number of documents added", 
"constantName": 
"org.apache.camel.component.springai.vectorstore.SpringAiVectorStoreHeaders#DOCUMENTS_ADDED"
 },
     "CamelSpringAiVectorStoreDocumentsDeleted": { "index": 7, "kind": 
"header", "displayName": "", "group": "producer", "label": "", "required": 
false, "javaType": "Integer", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "Number of documents 
deleted", "constantName": 
"org.apache.camel.component.springai.vectorstore.SpringAiVectorStoreHeaders#DOCUMENTS_DELETED"
 }
   },
+  "bodyTypes": {
+    "producerIn": { "carriers": [ "any" ], "byOption": [ { "option": 
"operation", "value": "DELETE", "carriers": [ "text", "list" ] }, { "option": 
"operation", "value": "SIMILARITY_SEARCH", "carriers": [ "text" ] } ], 
"description": "ADD takes a Document, a List of Document or of texts, or text 
(another body is added as its text). After spring-ai-embeddings it adds the 
texts in the CamelSpringAiEmbeddingInputText(s) headers instead of the body. 
DELETE takes the id or a List of ids, unles [...]
+    "producerOut": { "carriers": [ "unchanged" ], "byOption": [ { "option": 
"operation", "value": "SIMILARITY_SEARCH", "carriers": [ "list" ] } ], 
"description": "SIMILARITY_SEARCH gives the List of Document found. ADD and 
DELETE keep the body, with the ids and the count in headers" }
+  },
   "properties": {
     "storeId": { "index": 0, "kind": "path", "displayName": "Store Id", 
"group": "producer", "label": "", "required": true, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "The id" },
     "filterExpression": { "index": 1, "kind": "parameter", "displayName": 
"Filter Expression", "group": "producer", "label": "", "required": false, 
"type": "string", "javaType": "java.lang.String", "deprecated": false, 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.springai.vectorstore.SpringAiVectorStoreConfiguration",
 "configurationField": "configuration", "description": "Filter expression for 
metadata-based filtering in searches." },
diff --git 
a/components/camel-spring-parent/camel-spring-ai/camel-spring-ai-vector-store/src/main/java/org/apache/camel/component/springai/vectorstore/SpringAiVectorStoreEndpoint.java
 
b/components/camel-spring-parent/camel-spring-ai/camel-spring-ai-vector-store/src/main/java/org/apache/camel/component/springai/vectorstore/SpringAiVectorStoreEndpoint.java
index 5c13475bb9f7..582433eb1d0a 100644
--- 
a/components/camel-spring-parent/camel-spring-ai/camel-spring-ai-vector-store/src/main/java/org/apache/camel/component/springai/vectorstore/SpringAiVectorStoreEndpoint.java
+++ 
b/components/camel-spring-parent/camel-spring-ai/camel-spring-ai-vector-store/src/main/java/org/apache/camel/component/springai/vectorstore/SpringAiVectorStoreEndpoint.java
@@ -21,6 +21,9 @@ import org.apache.camel.Component;
 import org.apache.camel.Consumer;
 import org.apache.camel.Processor;
 import org.apache.camel.Producer;
+import org.apache.camel.spi.BodyType;
+import org.apache.camel.spi.BodyType.Carrier;
+import org.apache.camel.spi.BodyTypes;
 import org.apache.camel.spi.Metadata;
 import org.apache.camel.spi.UriEndpoint;
 import org.apache.camel.spi.UriParam;
@@ -34,6 +37,24 @@ import org.apache.camel.support.DefaultEndpoint;
              syntax = "spring-ai-vector-store:storeId", producerOnly = true, 
category = {
                      Category.AI
              }, headersClass = SpringAiVectorStoreHeaders.class)
+@BodyTypes(producerIn = @BodyType(value = Carrier.ANY,
+                                  byOption = {
+                                          @BodyType.When(option = "operation", 
value = "DELETE",
+                                                         carriers = { 
Carrier.TEXT, Carrier.LIST }),
+                                          @BodyType.When(option = "operation", 
value = "SIMILARITY_SEARCH",
+                                                         carriers = 
Carrier.TEXT) },
+                                  description = "ADD takes a Document, a List 
of Document or of texts, or text (another"
+                                                + " body is added as its 
text). After spring-ai-embeddings it adds the"
+                                                + " texts in the 
CamelSpringAiEmbeddingInputText(s) headers instead of the"
+                                                + " body. DELETE takes the id 
or a List of ids, unless the"
+                                                + " 
CamelSpringAiVectorStoreDocumentIds header has them, and"
+                                                + " SIMILARITY_SEARCH the 
query text. No body fails. The"
+                                                + " 
CamelSpringAiVectorStoreOperation header overrides operation"),
+           producerOut = @BodyType(value = Carrier.UNCHANGED,
+                                   byOption = @BodyType.When(option = 
"operation", value = "SIMILARITY_SEARCH",
+                                                             carriers = 
Carrier.LIST),
+                                   description = "SIMILARITY_SEARCH gives the 
List of Document found. ADD and DELETE keep"
+                                                 + " the body, with the ids 
and the count in headers"))
 public class SpringAiVectorStoreEndpoint extends DefaultEndpoint {
 
     @Metadata(required = true)

Reply via email to