This is an automated email from the ASF dual-hosted git repository. acosentino pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/main by this push: new 1b0b17ead96 CAMEL-20511 - Camel-AWS-Bedrock: Support Amazon Titan Embeddings G1 Model (#13375) 1b0b17ead96 is described below commit 1b0b17ead960e59f1fa20b07442887317f0f4261 Author: Andrea Cosentino <anco...@gmail.com> AuthorDate: Mon Mar 4 12:37:07 2024 +0100 CAMEL-20511 - Camel-AWS-Bedrock: Support Amazon Titan Embeddings G1 Model (#13375) * CAMEL-20511 - Camel-AWS-Bedrock: Support Amazon Titan Embeddings G1 Model Signed-off-by: Andrea Cosentino <anco...@gmail.com> * CAMEL-20511 - Camel-AWS-Bedrock: Support Amazon Titan Embeddings G1 Model Signed-off-by: Andrea Cosentino <anco...@gmail.com> --------- Signed-off-by: Andrea Cosentino <anco...@gmail.com> --- .../camel/catalog/components/aws-bedrock.json | 4 +- .../camel/component/aws2/bedrock/aws-bedrock.json | 4 +- .../component/aws2/bedrock/BedrockModels.java | 4 +- .../component/aws2/bedrock/BedrockOperations.java | 4 +- .../component/aws2/bedrock/BedrockProducer.java | 48 ++++++++++++++++++++++ .../bedrock/integration/BedrockProducerIT.java | 23 +++++++++++ 6 files changed, 81 insertions(+), 6 deletions(-) diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/aws-bedrock.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/aws-bedrock.json index 02b0151a67e..be5a902c16b 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/aws-bedrock.json +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/aws-bedrock.json @@ -26,7 +26,7 @@ "configuration": { "index": 0, "kind": "property", "displayName": "Configuration", "group": "producer", "label": "", "required": false, "type": "object", "javaType": "org.apache.camel.component.aws2.bedrock.BedrockConfiguration", "deprecated": false, "autowired": false, "secret": false, "description": "Component configuration" }, "lazyStartProducer": { "index": 1, "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 [...] "modelId": { "index": 2, "kind": "property", "displayName": "Model Id", "group": "producer", "label": "", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": true, "configurationClass": "org.apache.camel.component.aws2.bedrock.BedrockConfiguration", "configurationField": "configuration", "description": "Define the model Id we are going to use" }, - "operation": { "index": 3, "kind": "property", "displayName": "Operation", "group": "producer", "label": "", "required": true, "type": "object", "javaType": "org.apache.camel.component.aws2.bedrock.BedrockOperations", "enum": [ "invokeTextModel", "invokeImageModel" ], "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.aws2.bedrock.BedrockConfiguration", "configurationField": "configuration", "description" [...] + "operation": { "index": 3, "kind": "property", "displayName": "Operation", "group": "producer", "label": "", "required": true, "type": "object", "javaType": "org.apache.camel.component.aws2.bedrock.BedrockOperations", "enum": [ "invokeTextModel", "invokeImageModel", "invokeEmbeddingsModel" ], "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.aws2.bedrock.BedrockConfiguration", "configurationField": "conf [...] "overrideEndpoint": { "index": 4, "kind": "property", "displayName": "Override Endpoint", "group": "producer", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "configurationClass": "org.apache.camel.component.aws2.bedrock.BedrockConfiguration", "configurationField": "configuration", "description": "Set the need for overriding the endpoint. This option needs to be used in combina [...] "pojoRequest": { "index": 5, "kind": "property", "displayName": "Pojo Request", "group": "producer", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "configurationClass": "org.apache.camel.component.aws2.bedrock.BedrockConfiguration", "configurationField": "configuration", "description": "If we want to use a POJO request as body or not" }, "profileCredentialsName": { "index": 6, "kind": "property", "displayName": "Profile Credentials Name", "group": "producer", "label": "", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "false", "configurationClass": "org.apache.camel.component.aws2.bedrock.BedrockConfiguration", "configurationField": "configuration", "description": "If using a profile credentials provider, this parameter wi [...] @@ -55,7 +55,7 @@ "properties": { "label": { "index": 0, "kind": "path", "displayName": "Label", "group": "producer", "label": "", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.aws2.bedrock.BedrockConfiguration", "configurationField": "configuration", "description": "Logical name" }, "modelId": { "index": 1, "kind": "parameter", "displayName": "Model Id", "group": "producer", "label": "", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": true, "configurationClass": "org.apache.camel.component.aws2.bedrock.BedrockConfiguration", "configurationField": "configuration", "description": "Define the model Id we are going to use" }, - "operation": { "index": 2, "kind": "parameter", "displayName": "Operation", "group": "producer", "label": "", "required": true, "type": "object", "javaType": "org.apache.camel.component.aws2.bedrock.BedrockOperations", "enum": [ "invokeTextModel", "invokeImageModel" ], "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.aws2.bedrock.BedrockConfiguration", "configurationField": "configuration", "description [...] + "operation": { "index": 2, "kind": "parameter", "displayName": "Operation", "group": "producer", "label": "", "required": true, "type": "object", "javaType": "org.apache.camel.component.aws2.bedrock.BedrockOperations", "enum": [ "invokeTextModel", "invokeImageModel", "invokeEmbeddingsModel" ], "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.aws2.bedrock.BedrockConfiguration", "configurationField": "con [...] "overrideEndpoint": { "index": 3, "kind": "parameter", "displayName": "Override Endpoint", "group": "producer", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "configurationClass": "org.apache.camel.component.aws2.bedrock.BedrockConfiguration", "configurationField": "configuration", "description": "Set the need for overriding the endpoint. This option needs to be used in combin [...] "pojoRequest": { "index": 4, "kind": "parameter", "displayName": "Pojo Request", "group": "producer", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "configurationClass": "org.apache.camel.component.aws2.bedrock.BedrockConfiguration", "configurationField": "configuration", "description": "If we want to use a POJO request as body or not" }, "profileCredentialsName": { "index": 5, "kind": "parameter", "displayName": "Profile Credentials Name", "group": "producer", "label": "", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "false", "configurationClass": "org.apache.camel.component.aws2.bedrock.BedrockConfiguration", "configurationField": "configuration", "description": "If using a profile credentials provider, this parameter w [...] diff --git a/components/camel-aws/camel-aws-bedrock/src/generated/resources/META-INF/org/apache/camel/component/aws2/bedrock/aws-bedrock.json b/components/camel-aws/camel-aws-bedrock/src/generated/resources/META-INF/org/apache/camel/component/aws2/bedrock/aws-bedrock.json index 02b0151a67e..be5a902c16b 100644 --- a/components/camel-aws/camel-aws-bedrock/src/generated/resources/META-INF/org/apache/camel/component/aws2/bedrock/aws-bedrock.json +++ b/components/camel-aws/camel-aws-bedrock/src/generated/resources/META-INF/org/apache/camel/component/aws2/bedrock/aws-bedrock.json @@ -26,7 +26,7 @@ "configuration": { "index": 0, "kind": "property", "displayName": "Configuration", "group": "producer", "label": "", "required": false, "type": "object", "javaType": "org.apache.camel.component.aws2.bedrock.BedrockConfiguration", "deprecated": false, "autowired": false, "secret": false, "description": "Component configuration" }, "lazyStartProducer": { "index": 1, "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 [...] "modelId": { "index": 2, "kind": "property", "displayName": "Model Id", "group": "producer", "label": "", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": true, "configurationClass": "org.apache.camel.component.aws2.bedrock.BedrockConfiguration", "configurationField": "configuration", "description": "Define the model Id we are going to use" }, - "operation": { "index": 3, "kind": "property", "displayName": "Operation", "group": "producer", "label": "", "required": true, "type": "object", "javaType": "org.apache.camel.component.aws2.bedrock.BedrockOperations", "enum": [ "invokeTextModel", "invokeImageModel" ], "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.aws2.bedrock.BedrockConfiguration", "configurationField": "configuration", "description" [...] + "operation": { "index": 3, "kind": "property", "displayName": "Operation", "group": "producer", "label": "", "required": true, "type": "object", "javaType": "org.apache.camel.component.aws2.bedrock.BedrockOperations", "enum": [ "invokeTextModel", "invokeImageModel", "invokeEmbeddingsModel" ], "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.aws2.bedrock.BedrockConfiguration", "configurationField": "conf [...] "overrideEndpoint": { "index": 4, "kind": "property", "displayName": "Override Endpoint", "group": "producer", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "configurationClass": "org.apache.camel.component.aws2.bedrock.BedrockConfiguration", "configurationField": "configuration", "description": "Set the need for overriding the endpoint. This option needs to be used in combina [...] "pojoRequest": { "index": 5, "kind": "property", "displayName": "Pojo Request", "group": "producer", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "configurationClass": "org.apache.camel.component.aws2.bedrock.BedrockConfiguration", "configurationField": "configuration", "description": "If we want to use a POJO request as body or not" }, "profileCredentialsName": { "index": 6, "kind": "property", "displayName": "Profile Credentials Name", "group": "producer", "label": "", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "false", "configurationClass": "org.apache.camel.component.aws2.bedrock.BedrockConfiguration", "configurationField": "configuration", "description": "If using a profile credentials provider, this parameter wi [...] @@ -55,7 +55,7 @@ "properties": { "label": { "index": 0, "kind": "path", "displayName": "Label", "group": "producer", "label": "", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.aws2.bedrock.BedrockConfiguration", "configurationField": "configuration", "description": "Logical name" }, "modelId": { "index": 1, "kind": "parameter", "displayName": "Model Id", "group": "producer", "label": "", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": true, "configurationClass": "org.apache.camel.component.aws2.bedrock.BedrockConfiguration", "configurationField": "configuration", "description": "Define the model Id we are going to use" }, - "operation": { "index": 2, "kind": "parameter", "displayName": "Operation", "group": "producer", "label": "", "required": true, "type": "object", "javaType": "org.apache.camel.component.aws2.bedrock.BedrockOperations", "enum": [ "invokeTextModel", "invokeImageModel" ], "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.aws2.bedrock.BedrockConfiguration", "configurationField": "configuration", "description [...] + "operation": { "index": 2, "kind": "parameter", "displayName": "Operation", "group": "producer", "label": "", "required": true, "type": "object", "javaType": "org.apache.camel.component.aws2.bedrock.BedrockOperations", "enum": [ "invokeTextModel", "invokeImageModel", "invokeEmbeddingsModel" ], "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.aws2.bedrock.BedrockConfiguration", "configurationField": "con [...] "overrideEndpoint": { "index": 3, "kind": "parameter", "displayName": "Override Endpoint", "group": "producer", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "configurationClass": "org.apache.camel.component.aws2.bedrock.BedrockConfiguration", "configurationField": "configuration", "description": "Set the need for overriding the endpoint. This option needs to be used in combin [...] "pojoRequest": { "index": 4, "kind": "parameter", "displayName": "Pojo Request", "group": "producer", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "configurationClass": "org.apache.camel.component.aws2.bedrock.BedrockConfiguration", "configurationField": "configuration", "description": "If we want to use a POJO request as body or not" }, "profileCredentialsName": { "index": 5, "kind": "parameter", "displayName": "Profile Credentials Name", "group": "producer", "label": "", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "false", "configurationClass": "org.apache.camel.component.aws2.bedrock.BedrockConfiguration", "configurationField": "configuration", "description": "If using a profile credentials provider, this parameter w [...] diff --git a/components/camel-aws/camel-aws-bedrock/src/main/java/org/apache/camel/component/aws2/bedrock/BedrockModels.java b/components/camel-aws/camel-aws-bedrock/src/main/java/org/apache/camel/component/aws2/bedrock/BedrockModels.java index c1cce5e044c..e4c27372a9f 100644 --- a/components/camel-aws/camel-aws-bedrock/src/main/java/org/apache/camel/component/aws2/bedrock/BedrockModels.java +++ b/components/camel-aws/camel-aws-bedrock/src/main/java/org/apache/camel/component/aws2/bedrock/BedrockModels.java @@ -20,7 +20,9 @@ public enum BedrockModels { TITAN_TEXT_EXPRESS_V1("amazon.titan-text-express-v1"), TITAN_TEXT_LITE_V1("amazon.titan-text-lite-v1"), - TITAN_IMAGE_GENERATOR_V1("amazon.titan-image-generator-v1"); + TITAN_IMAGE_GENERATOR_V1("amazon.titan-image-generator-v1"), + + TITAN_EMBEDDINGS_G1("amazon.titan-embed-text-v1"); public final String model; diff --git a/components/camel-aws/camel-aws-bedrock/src/main/java/org/apache/camel/component/aws2/bedrock/BedrockOperations.java b/components/camel-aws/camel-aws-bedrock/src/main/java/org/apache/camel/component/aws2/bedrock/BedrockOperations.java index e99f0e08f9e..0c0ff54ff6a 100644 --- a/components/camel-aws/camel-aws-bedrock/src/main/java/org/apache/camel/component/aws2/bedrock/BedrockOperations.java +++ b/components/camel-aws/camel-aws-bedrock/src/main/java/org/apache/camel/component/aws2/bedrock/BedrockOperations.java @@ -20,5 +20,7 @@ public enum BedrockOperations { invokeTextModel, - invokeImageModel + invokeImageModel, + + invokeEmbeddingsModel } diff --git a/components/camel-aws/camel-aws-bedrock/src/main/java/org/apache/camel/component/aws2/bedrock/BedrockProducer.java b/components/camel-aws/camel-aws-bedrock/src/main/java/org/apache/camel/component/aws2/bedrock/BedrockProducer.java index 584a2faef22..bcf73b0c804 100644 --- a/components/camel-aws/camel-aws-bedrock/src/main/java/org/apache/camel/component/aws2/bedrock/BedrockProducer.java +++ b/components/camel-aws/camel-aws-bedrock/src/main/java/org/apache/camel/component/aws2/bedrock/BedrockProducer.java @@ -56,6 +56,9 @@ public class BedrockProducer extends DefaultProducer { case invokeImageModel: invokeImageModel(getEndpoint().getBedrockRuntimeClient(), exchange); break; + case invokeEmbeddingsModel: + invokeEmbeddingsModel(getEndpoint().getBedrockRuntimeClient(), exchange); + break; default: throw new IllegalArgumentException("Unsupported operation"); } @@ -178,6 +181,51 @@ public class BedrockProducer extends DefaultProducer { } } + private void invokeEmbeddingsModel(BedrockRuntimeClient bedrockRuntimeClient, Exchange exchange) + throws InvalidPayloadException { + if (getConfiguration().isPojoRequest()) { + Object payload = exchange.getMessage().getMandatoryBody(); + if (payload instanceof InvokeModelRequest) { + InvokeModelResponse result; + try { + result = bedrockRuntimeClient.invokeModel((InvokeModelRequest) payload); + } catch (AwsServiceException ase) { + LOG.trace("Invoke Image Model command returned the error code {}", ase.awsErrorDetails().errorCode()); + throw ase; + } + Message message = getMessageForResponse(exchange); + message.setBody(result); + } + } else { + InvokeModelRequest.Builder builder = InvokeModelRequest.builder(); + if (ObjectHelper.isNotEmpty(exchange.getMessage().getHeader(BedrockConstants.MODEL_CONTENT_TYPE))) { + String contentType = exchange.getIn().getHeader(BedrockConstants.MODEL_CONTENT_TYPE, String.class); + builder.contentType(contentType); + } else { + throw new IllegalArgumentException("Model Content Type must be specified"); + } + if (ObjectHelper.isNotEmpty(exchange.getMessage().getHeader(BedrockConstants.MODEL_ACCEPT_CONTENT_TYPE))) { + String acceptContentType = exchange.getIn().getHeader(BedrockConstants.MODEL_ACCEPT_CONTENT_TYPE, String.class); + builder.accept(acceptContentType); + } else { + throw new IllegalArgumentException("Model Accept Content Type must be specified"); + } + InvokeModelRequest request = builder + .body(SdkBytes.fromUtf8String(String.valueOf(exchange.getMessage().getBody()))) + .modelId(getConfiguration().getModelId()) + .build(); + InvokeModelResponse result; + try { + result = bedrockRuntimeClient.invokeModel(request); + } catch (AwsServiceException ase) { + LOG.trace("Invoke Model command returned the error code {}", ase.awsErrorDetails().errorCode()); + throw ase; + } + Message message = getMessageForResponse(exchange); + message.setBody(result); + } + } + private static void setBase64Image(InvokeModelResponse result, Message message) throws JsonProcessingException { ObjectMapper mapper = new ObjectMapper(); JsonNode jsonString = mapper.readTree(result.body().asUtf8String()); diff --git a/components/camel-aws/camel-aws-bedrock/src/test/java/org/apache/camel/component/aws2/bedrock/integration/BedrockProducerIT.java b/components/camel-aws/camel-aws-bedrock/src/test/java/org/apache/camel/component/aws2/bedrock/integration/BedrockProducerIT.java index 05d34f2479c..8c192b239b8 100644 --- a/components/camel-aws/camel-aws-bedrock/src/test/java/org/apache/camel/component/aws2/bedrock/integration/BedrockProducerIT.java +++ b/components/camel-aws/camel-aws-bedrock/src/test/java/org/apache/camel/component/aws2/bedrock/integration/BedrockProducerIT.java @@ -134,6 +134,24 @@ class BedrockProducerIT extends CamelTestSupport { MockEndpoint.assertIsSatisfied(context); } + @Test + public void testInvokeTitanEmbeddingsModel() throws InterruptedException { + + result.expectedMessageCount(1); + final Exchange result = template.send("direct:send_titan_embeddings", exchange -> { + ObjectMapper mapper = new ObjectMapper(); + ObjectNode rootNode = mapper.createObjectNode(); + rootNode.putIfAbsent("inputText", + new TextNode("A Sci-fi camel running in the desert")); + + exchange.getMessage().setBody(mapper.writer().writeValueAsString(rootNode)); + exchange.getMessage().setHeader(BedrockConstants.MODEL_CONTENT_TYPE, "application/json"); + exchange.getMessage().setHeader(BedrockConstants.MODEL_ACCEPT_CONTENT_TYPE, "*/*"); + }); + + MockEndpoint.assertIsSatisfied(context); + } + @Override protected RouteBuilder createRouteBuilder() { return new RouteBuilder() { @@ -156,6 +174,11 @@ class BedrockProducerIT extends CamelTestSupport { .unmarshal().base64() .setHeader("CamelFileName", simple("image-${random(128)}.png")).to("file:target/generated_images") .to(result); + + from("direct:send_titan_embeddings") + .to("aws-bedrock:label?accessKey=RAW({{aws.manual.access.key}})&secretKey=RAW({{aws.manual.secret.key}}®ion=us-east-1&operation=invokeEmbeddingsModel&modelId=" + + BedrockModels.TITAN_EMBEDDINGS_G1.model) + .to(result); } }; }