You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by ac...@apache.org on 2024/03/04 11:06:54 UTC
(camel) 01/02: CAMEL-20511 - Camel-AWS-Bedrock: Support Amazon Titan Embeddings G1 Model
This is an automated email from the ASF dual-hosted git repository.
acosentino pushed a commit to branch CAMEL-20511
in repository https://gitbox.apache.org/repos/asf/camel.git
commit 0877702fa40bac8c0583e8bd28ef5fc195ee9426
Author: Andrea Cosentino <an...@gmail.com>
AuthorDate: Mon Mar 4 11:48:18 2024 +0100
CAMEL-20511 - Camel-AWS-Bedrock: Support Amazon Titan Embeddings G1 Model
Signed-off-by: Andrea Cosentino <an...@gmail.com>
---
.../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 +++++++++++
5 files changed, 79 insertions(+), 4 deletions(-)
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);
}
};
}