Croway commented on code in PR #29108:
URL: https://github.com/apache/camel/pull/29108#discussion_r4456929462


##########
components/camel-spring-parent/camel-spring-ai/camel-spring-ai-embeddings/src/main/java/org/apache/camel/component/springai/embeddings/SpringAiEmbeddingsProducer.java:
##########
@@ -109,4 +112,44 @@ public void process(Exchange exchange) throws Exception {
             message.setHeader(SpringAiEmbeddingsHeaders.EMBEDDING_METADATA, 
response.getMetadata());
         }
     }
+
+    /**
+     * The text to embed of a body, or of an element of a List body: a Spring 
AI Document as its text, and text, bytes,
+     * a stream, a Reader or a file read as text. Any other value, such as a 
Map or a POJO, fails as an
+     * InvalidPayloadException instead of being embedded as its toString().
+     *
+     * @param index the index of the element in a List body, or -1 for the 
body itself
+     */
+    private static String toText(Exchange exchange, Object value, int index)
+            throws InvalidPayloadException, NoTypeConversionAvailableException 
{
+        String what = index < 0 ? "" : "the element at index " + index + " of 
the List body is " + typeOf(value) + "; ";
+        if (value instanceof Document document) {
+            if (document.getText() == null) {
+                throw new InvalidPayloadException(
+                        exchange, String.class, exchange.getMessage(),
+                        what + "spring-ai-embeddings embeds the text of a 
Document, but the Document has no text");
+            }
+            return document.getText();
+        }
+        if (!isReadableAsText(value)) {
+            throw new InvalidPayloadException(
+                    exchange, String.class, exchange.getMessage(),
+                    what + "spring-ai-embeddings embeds text, bytes, a stream, 
a Reader, a file or a Spring AI Document;"
+                                                                   + " convert 
the body to text before the endpoint, such"
+                                                                   + " as with 
convertBodyTo(String) or a marshal to JSON");
+        }
+        return 
exchange.getContext().getTypeConverter().mandatoryConvertTo(String.class, 
exchange, value);
+    }
+
+    /** A value Camel converts to its text, rather than to the toString() of 
an object. */
+    private static boolean isReadableAsText(Object value) {

Review Comment:
   This list also fails bodies that have a real converter to `String` and were 
embedded correctly before. With the fake `EmbeddingModel`:
   
   | Body | main | PR |
   |---|---|---|
   | `char[]` `"hello"` | embeds `hello` | `InvalidPayloadException ... has 
type: char[]` |
   | Netty `ByteBuf` (netty-http with `disableStreamCache=true`) | embeds the 
text | `InvalidPayloadException ... InstrumentedUnpooledHeapByteBuf` |
   | a custom type with `addTypeConverter(String.class, Ticket.class, ...)` | 
embeds the converter's text | `InvalidPayloadException` |
   | a `List` of a `ByteBuf` and a `char[]` | embeds both | `the element at 
index 0 of the List body is ...ByteBuf` |
   
   `LangChain4jEmbeddingsProducer.isReadableAsText` has the same list, so this 
matches camel-langchain4j-embeddings and could be a follow-up for both. Asking 
the type converter is no way out: after one fallback conversion, 
`lookup(String.class, Map1.class)` returns the promoted 
`ToStringTypeConverter`. `BodyFacts.kindOf` does not help either: it classifies 
`ByteBuf` as DATA and `char[]` as COLLECTION, and an `Integer` as PAYLOAD.
   
   For this PR, the upgrade guide entry could mention these bodies and 
`convertBodyTo(String.class)`.



##########
components/camel-spring-parent/camel-spring-ai/camel-spring-ai-embeddings/src/main/java/org/apache/camel/component/springai/embeddings/SpringAiEmbeddingsProducer.java:
##########
@@ -109,4 +112,44 @@ public void process(Exchange exchange) throws Exception {
             message.setHeader(SpringAiEmbeddingsHeaders.EMBEDDING_METADATA, 
response.getMetadata());
         }
     }
+
+    /**
+     * The text to embed of a body, or of an element of a List body: a Spring 
AI Document as its text, and text, bytes,
+     * a stream, a Reader or a file read as text. Any other value, such as a 
Map or a POJO, fails as an
+     * InvalidPayloadException instead of being embedded as its toString().
+     *
+     * @param index the index of the element in a List body, or -1 for the 
body itself
+     */
+    private static String toText(Exchange exchange, Object value, int index)
+            throws InvalidPayloadException, NoTypeConversionAvailableException 
{
+        String what = index < 0 ? "" : "the element at index " + index + " of 
the List body is " + typeOf(value) + "; ";

Review Comment:
   Nit: `what` (with `typeOf(value)` and the concatenation) is built for every 
element of a `List` body, also when nothing fails. camel-langchain4j-embeddings 
builds it only in the throw branch.



##########
components/camel-spring-parent/camel-spring-ai/camel-spring-ai-embeddings/src/main/java/org/apache/camel/component/springai/embeddings/SpringAiEmbeddingsEndpoint.java:
##########
@@ -37,10 +37,11 @@
              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, and"
-                                                + " each element of a List, is 
converted to text (a Map or a POJO as its"
-                                                + " toString()); no body, or a 
null element in a List, fails"),
+@BodyTypes(producerIn = @BodyType(value = { Carrier.TEXT, Carrier.BYTES, 
Carrier.STREAM, Carrier.FILE, Carrier.LIST },

Review Comment:
   `Carrier.LIST` is documented as "A List, another Collection or an array", 
but only a `java.util.List` is batched. A `Set<String>` or `String[]` body 
fails with `InvalidPayloadException`. On main they were embedded as one text, 
`[a, b]` and `[Ljava.lang.String;@39b7c350`, so failing is better, but the 
description could say "a java.util.List of them" so that tooling does not offer 
a Set or an array.
   
   A `Document` is accepted, but `Carrier.POJO` is not declared. 
camel-langchain4j-embeddings does the same, so that part is up to you.



-- 
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]

Reply via email to