davsclaus opened a new pull request, #28401:
URL: https://github.com/apache/camel/pull/28401
_Claude Code on behalf of davsclaus_
This group adds the catalog body types (CAMEL-24961) for eleven AI
components:
- langchain4j-agent, -embeddings, -embeddingstore, -ingest and -web-search;
- spring-ai-chat, -embeddings, -image and -vector-store;
- djl and ai-resource.
Each change is an `@BodyTypes` annotation on the Endpoint, plus the JSON it
generates and the catalog copy. Two doc pages had their body text corrected.
**What the catalog says now**
| Component | Consumer | Producer input | Producer output |
|---|---|---|---|
| langchain4j-agent | | the user message as text, or an `AiAgentBody`;
bytes, a stream or a file of the file consumers as image, audio, video, PDF or
text content | the answer as text (JSON text with outputClass or jsonSchema);
the token counts and the sources in headers |
| langchain4j-web-search | | the search terms as text | the content of the
first result as text, or null; a `WebSearchOrganicResult` with that resultType;
a List with maxResults above 1 |
| langchain4j-embeddings | | a String or a `TextSegment`, or a List of them
| unchanged: the vector is a `float[]` in the CamelLangChain4jEmbeddingsVector
header, as qdrant and milvus expect |
| langchain4j-embeddingstore | | `any`: the embedding comes from the
headers, or the body is embedded with an embeddingModel; the id or ids for
REMOVE | the id (a List for a batch) for ADD; a List of `EmbeddingMatch` (or of
texts) for SEARCH; unchanged for REMOVE |
| langchain4j-ingest | | text, bytes, a stream or a file (no text in MEDIA
mode) | an `IngestResult` |
| spring-ai-chat | | `any`: text, a Message, bytes or a file as media; a Map
for the prompt template; a List of Messages | the answer as text; a POJO, Map
or List with outputFormat |
| spring-ai-embeddings | | text, or a List of texts | a `float[]`, or a List
of them |
| spring-ai-image | | a text prompt, or an `ImagePrompt` | an `Image`, or a
List of them with n above 1 |
| spring-ai-vector-store | | documents or text for ADD; ids for DELETE; text
for SIMILARITY_SEARCH | unchanged; a `List<Document>` for SIMILARITY_SEARCH |
| djl | | by application: an image or audio as bytes, a stream, a file or a
DJL object for cv and audio; a String for nlp; and so on | by application:
`Classifications`, `DetectedObjects`, an `Image`, text and so on |
| ai-resource | no body: the MCP bridge creates an empty exchange | | |
ai-resource answers the MCP read with the body the route ends with: text,
bytes, a stream or a file.
**Checked at runtime.** Throwaway tests, not part of the PR, used these
models:
- **langchain4j:** a fake ChatModel behind a real `AgentWithoutMemory`, a
fake WebSearchEngine, the in-process AllMiniLmL6V2 embedding model and an
`InMemoryEmbeddingStore`, and the deterministic models of the ingest tests.
- **spring-ai:** fake ChatModel, EmbeddingModel and ImageModel, and a real
`SimpleVectorStore`.
- **djl:** the local mnist model of the module and an identity model with
PyTorch, and the zoo models of two of its tests.
- **ai-resource:** the executor of its MCP bridge.
Each test sent text, bytes, a stream, a file, a Map, a POJO, a number and no
body.
Not run: real model providers, the memory and RAG advisors, and the djl zoo
applications beyond the two.
**Choices**
- langchain4j-embeddings leaves the body unchanged: the embedding goes in
headers, and the vector stores read it there.
- The djl `application` option is free text, but its values are fixed by
DJL, so byOption lists each one.
- The arrays (`float[]`, `String[]`, `Image[]`) count as `list`, as the
javadoc of the carrier says.
**Doc fixes**
- **djl:** the table of applications now has nlp/word_embedding and the two
tabular applications.
- **spring-ai-image:** an `Image` that only has a URL converts to the text
of the URL, not to the image, which is not downloaded. The page now suggests
responseFormat=b64_json.
PR #28354 adds options to langchain4j-agent and spring-ai-chat. Its changes
to the generated JSON do not overlap the `bodyTypes` block, but whichever PR is
merged second should regenerate.
**Bugs found, not fixed here.** The JIRAs, one per component, will follow.
- **langchain4j-agent:**
- Bytes, a stream or a file without the CamelLangChain4jAgentUserMessage
header put the content in the user message twice, which doubles the tokens.
- An `AiAgentBody` with a blank user message and a content fails with
"template cannot be null or blank".
- A `.json` file or JSON bytes fail with "Unsupported MIME type".
- There is no converter from `java.io.File` or `Path`.
- **langchain4j-web-search:**
- webSearchRequest is autowired, so a single `WebSearchRequest` bean in
the registry replaces the body of every endpoint.
- With maxResults=1, a result without content gives null, as no result
does.
- **langchain4j-embeddingstore:**
- With an embeddingModel, a TextSegment is stored as its toString, and a
List of texts is embedded as one text.
- REMOVE of a Map or a number removes an id like `{a=1}`, with no error.
- **langchain4j-embeddings:**
- Only text converts to a TextSegment, so the body of a file consumer
fails.
- The RESPONSE_MODEL header is never set.
- From the code: the single path does not clear an EMBEDDINGS header left
by an earlier batch, so a later ADD takes the batch path.
- **langchain4j-ingest:** in text mode, any body is ingested as its
toString, with no error.
- **spring-ai-chat:**
- outputFormat BEAN, MAP or LIST drops the question of the user, so the
model gets only the format instructions.
- Media without a user message fails with "text cannot be null or empty".
- An image as a `File` or a stream is sent as text.
- CHAT_MULTIPLE_MESSAGES with a List of Strings fails with a
ClassCastException.
- **spring-ai-embeddings:** a List of one text gives a `float[]`, not a List.
- **spring-ai-image:**
- An `ImagePrompt` body ignores the options and headers of the endpoint.
- An Image with only a URL, written to a file, writes the URL.
- **spring-ai-vector-store:**
- ADD of a `float[]` without the input text header stores `[F@…`.
- A SIMILARITY_SEARCH after spring-ai-embeddings searches for the text of
the `float[]`.
- A leftover CamelSpringAiEmbeddingInputText header makes ADD ignore the
body.
- ADD of a List of Maps fails with "Documents list cannot be empty".
- The count of deleted documents is the number of ids asked.
- DELETE reads the ids header that ADD and SIMILARITY_SEARCH set before
the body.
- **djl:**
- For cv and audio, a body without a converter reaches the model as null
and fails with "Could not process input or output", not "Data type is not
supported".
- From the code: a wrong model or translator name fails at the first
message, not at startup.
- **ai-resource:** a List body with a binary mimeType fails with a
misleading "argument type mismatch".
**Local checks**
- The changed modules build, with no change to the generated files after the
build.
- The catalog copies equal their modules.
- camel-catalog, camel-yaml-dsl-validator and camel-jbang-core tests pass.
- The Endpoint and Component DSLs regenerate with no change.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]