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)
