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 38cef858f4d CAMEL-21597 - Camel AWS Bedrock: Support Amazon Nova
models - CAMEL-21598 - Camel AWS Bedrock: Update supported models (#19292)
38cef858f4d is described below
commit 38cef858f4dbc0b9b37ca4867867472cfe6ac6bc
Author: Andrea Cosentino <[email protected]>
AuthorDate: Tue Sep 23 13:56:30 2025 +0200
CAMEL-21597 - Camel AWS Bedrock: Support Amazon Nova models - CAMEL-21598
- Camel AWS Bedrock: Update supported models (#19292)
* CAMEL-21597 - Camel AWS Bedrock: Support Amazon Nova models
CAMEL-21598 - Camel AWS Bedrock: Update supported models
Signed-off-by: Andrea Cosentino <[email protected]>
* CAMEL-21598 - Camel AWS Bedrock: Update supported models
Signed-off-by: Andrea Cosentino <[email protected]>
---------
Signed-off-by: Andrea Cosentino <[email protected]>
---
.../camel/catalog/components/aws-bedrock.json | 4 +-
.../aws2/bedrock/runtime/aws-bedrock.json | 4 +-
.../component/aws2/bedrock/BedrockModels.java | 69 ++-
.../aws2/bedrock/runtime/BedrockConfiguration.java | 2 +-
.../aws2/bedrock/runtime/BedrockProducer.java | 112 ++++-
.../component/aws2/bedrock/BedrockModelsTest.java | 178 +++++++
.../runtime/integration/BedrockProducerIT.java | 512 +++++++++++++++++++--
7 files changed, 828 insertions(+), 53 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 4dc6a29b81b..5aebf9c663f 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 @@
"componentProperties": {
"configuration": { "index": 0, "kind": "property", "displayName":
"Configuration", "group": "producer", "label": "", "required": false, "type":
"object", "javaType":
"org.apache.camel.component.aws2.bedrock.runtime.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": true, "type": "string",
"javaType": "java.lang.String", "enum": [ "amazon.titan-text-express-v1",
"amazon.titan-text-lite-v1", "amazon.titan-image-generator-v1",
"amazon.titan-embed-text-v1", "ai21.j2-ultra-v1", "ai21.j2-mid-v1",
"anthropic.claude-instant-v1", "anthropic.claude-v2", "anthropic.claude-v2:1",
"anthropic.claude-3-sonnet-20240229-v1:0", "anthropic.claude- [...]
+ "modelId": { "index": 2, "kind": "property", "displayName": "Model Id",
"group": "producer", "label": "", "required": true, "type": "string",
"javaType": "java.lang.String", "enum": [ "amazon.titan-text-express-v1",
"amazon.titan-text-lite-v1", "amazon.titan-image-generator-v1",
"amazon.titan-embed-text-v1", "amazon.titan-embed-image-v1",
"amazon.titan-text-premier-v1:0", "amazon.titan-embed-text-v2:0",
"amazon.titan-image-generator-v2:0", "amazon.nova-canvas-v1:0",
"amazon.nova-lite [...]
"operation": { "index": 3, "kind": "property", "displayName": "Operation",
"group": "producer", "label": "", "required": true, "type": "object",
"javaType":
"org.apache.camel.component.aws2.bedrock.runtime.BedrockOperations", "enum": [
"invokeTextModel", "invokeImageModel", "invokeEmbeddingsModel" ], "deprecated":
false, "deprecationNote": "", "autowired": false, "secret": false,
"configurationClass":
"org.apache.camel.component.aws2.bedrock.runtime.BedrockConfiguration",
"configurat [...]
"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.runtime.BedrockConfiguration",
"configurationField": "configuration", "description": "Set the need for
overriding the endpoint. This option needs to be used in [...]
"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.runtime.BedrockConfiguration",
"configurationField": "configuration", "description": "If we want to use a POJO
request as body or not" },
@@ -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.runtime.BedrockConfiguration",
"configurationField": "configuration", "description": "Logical name" },
- "modelId": { "index": 1, "kind": "parameter", "displayName": "Model Id",
"group": "producer", "label": "", "required": true, "type": "string",
"javaType": "java.lang.String", "enum": [ "amazon.titan-text-express-v1",
"amazon.titan-text-lite-v1", "amazon.titan-image-generator-v1",
"amazon.titan-embed-text-v1", "ai21.j2-ultra-v1", "ai21.j2-mid-v1",
"anthropic.claude-instant-v1", "anthropic.claude-v2", "anthropic.claude-v2:1",
"anthropic.claude-3-sonnet-20240229-v1:0", "anthropic.claude [...]
+ "modelId": { "index": 1, "kind": "parameter", "displayName": "Model Id",
"group": "producer", "label": "", "required": true, "type": "string",
"javaType": "java.lang.String", "enum": [ "amazon.titan-text-express-v1",
"amazon.titan-text-lite-v1", "amazon.titan-image-generator-v1",
"amazon.titan-embed-text-v1", "amazon.titan-embed-image-v1",
"amazon.titan-text-premier-v1:0", "amazon.titan-embed-text-v2:0",
"amazon.titan-image-generator-v2:0", "amazon.nova-canvas-v1:0",
"amazon.nova-lit [...]
"operation": { "index": 2, "kind": "parameter", "displayName":
"Operation", "group": "producer", "label": "", "required": true, "type":
"object", "javaType":
"org.apache.camel.component.aws2.bedrock.runtime.BedrockOperations", "enum": [
"invokeTextModel", "invokeImageModel", "invokeEmbeddingsModel" ], "deprecated":
false, "deprecationNote": "", "autowired": false, "secret": false,
"configurationClass":
"org.apache.camel.component.aws2.bedrock.runtime.BedrockConfiguration",
"configura [...]
"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.runtime.BedrockConfiguration",
"configurationField": "configuration", "description": "Set the need for
overriding the endpoint. This option needs to be used i [...]
"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.runtime.BedrockConfiguration",
"configurationField": "configuration", "description": "If we want to use a POJO
request as body or not" },
diff --git
a/components/camel-aws/camel-aws-bedrock/src/generated/resources/META-INF/org/apache/camel/component/aws2/bedrock/runtime/aws-bedrock.json
b/components/camel-aws/camel-aws-bedrock/src/generated/resources/META-INF/org/apache/camel/component/aws2/bedrock/runtime/aws-bedrock.json
index 4dc6a29b81b..5aebf9c663f 100644
---
a/components/camel-aws/camel-aws-bedrock/src/generated/resources/META-INF/org/apache/camel/component/aws2/bedrock/runtime/aws-bedrock.json
+++
b/components/camel-aws/camel-aws-bedrock/src/generated/resources/META-INF/org/apache/camel/component/aws2/bedrock/runtime/aws-bedrock.json
@@ -26,7 +26,7 @@
"componentProperties": {
"configuration": { "index": 0, "kind": "property", "displayName":
"Configuration", "group": "producer", "label": "", "required": false, "type":
"object", "javaType":
"org.apache.camel.component.aws2.bedrock.runtime.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": true, "type": "string",
"javaType": "java.lang.String", "enum": [ "amazon.titan-text-express-v1",
"amazon.titan-text-lite-v1", "amazon.titan-image-generator-v1",
"amazon.titan-embed-text-v1", "ai21.j2-ultra-v1", "ai21.j2-mid-v1",
"anthropic.claude-instant-v1", "anthropic.claude-v2", "anthropic.claude-v2:1",
"anthropic.claude-3-sonnet-20240229-v1:0", "anthropic.claude- [...]
+ "modelId": { "index": 2, "kind": "property", "displayName": "Model Id",
"group": "producer", "label": "", "required": true, "type": "string",
"javaType": "java.lang.String", "enum": [ "amazon.titan-text-express-v1",
"amazon.titan-text-lite-v1", "amazon.titan-image-generator-v1",
"amazon.titan-embed-text-v1", "amazon.titan-embed-image-v1",
"amazon.titan-text-premier-v1:0", "amazon.titan-embed-text-v2:0",
"amazon.titan-image-generator-v2:0", "amazon.nova-canvas-v1:0",
"amazon.nova-lite [...]
"operation": { "index": 3, "kind": "property", "displayName": "Operation",
"group": "producer", "label": "", "required": true, "type": "object",
"javaType":
"org.apache.camel.component.aws2.bedrock.runtime.BedrockOperations", "enum": [
"invokeTextModel", "invokeImageModel", "invokeEmbeddingsModel" ], "deprecated":
false, "deprecationNote": "", "autowired": false, "secret": false,
"configurationClass":
"org.apache.camel.component.aws2.bedrock.runtime.BedrockConfiguration",
"configurat [...]
"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.runtime.BedrockConfiguration",
"configurationField": "configuration", "description": "Set the need for
overriding the endpoint. This option needs to be used in [...]
"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.runtime.BedrockConfiguration",
"configurationField": "configuration", "description": "If we want to use a POJO
request as body or not" },
@@ -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.runtime.BedrockConfiguration",
"configurationField": "configuration", "description": "Logical name" },
- "modelId": { "index": 1, "kind": "parameter", "displayName": "Model Id",
"group": "producer", "label": "", "required": true, "type": "string",
"javaType": "java.lang.String", "enum": [ "amazon.titan-text-express-v1",
"amazon.titan-text-lite-v1", "amazon.titan-image-generator-v1",
"amazon.titan-embed-text-v1", "ai21.j2-ultra-v1", "ai21.j2-mid-v1",
"anthropic.claude-instant-v1", "anthropic.claude-v2", "anthropic.claude-v2:1",
"anthropic.claude-3-sonnet-20240229-v1:0", "anthropic.claude [...]
+ "modelId": { "index": 1, "kind": "parameter", "displayName": "Model Id",
"group": "producer", "label": "", "required": true, "type": "string",
"javaType": "java.lang.String", "enum": [ "amazon.titan-text-express-v1",
"amazon.titan-text-lite-v1", "amazon.titan-image-generator-v1",
"amazon.titan-embed-text-v1", "amazon.titan-embed-image-v1",
"amazon.titan-text-premier-v1:0", "amazon.titan-embed-text-v2:0",
"amazon.titan-image-generator-v2:0", "amazon.nova-canvas-v1:0",
"amazon.nova-lit [...]
"operation": { "index": 2, "kind": "parameter", "displayName":
"Operation", "group": "producer", "label": "", "required": true, "type":
"object", "javaType":
"org.apache.camel.component.aws2.bedrock.runtime.BedrockOperations", "enum": [
"invokeTextModel", "invokeImageModel", "invokeEmbeddingsModel" ], "deprecated":
false, "deprecationNote": "", "autowired": false, "secret": false,
"configurationClass":
"org.apache.camel.component.aws2.bedrock.runtime.BedrockConfiguration",
"configura [...]
"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.runtime.BedrockConfiguration",
"configurationField": "configuration", "description": "Set the need for
overriding the endpoint. This option needs to be used i [...]
"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.runtime.BedrockConfiguration",
"configurationField": "configuration", "description": "If we want to use a POJO
request as body or not" },
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 7b66ca4ff24..1434ea55c16 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
@@ -18,6 +18,7 @@ package org.apache.camel.component.aws2.bedrock;
public enum BedrockModels {
+ // Amazon Titan Models
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"),
@@ -25,19 +26,85 @@ public enum BedrockModels {
TITAN_MULTIMODAL_EMBEDDINGS_G1("amazon.titan-embed-image-v1"),
TITAN_TEXT_PREMIER_V1("amazon.titan-text-premier-v1:0"),
TITAN_TEXT_EMBEDDINGS_V2("amazon.titan-embed-text-v2:0"),
+ TITAN_IMAGE_GENERATOR_V2("amazon.titan-image-generator-v2:0"),
+
+ // Amazon Nova Models
+ NOVA_CANVAS_V1("amazon.nova-canvas-v1:0"),
+ NOVA_LITE_V1("amazon.nova-lite-v1:0"),
+ NOVA_MICRO_V1("amazon.nova-micro-v1:0"),
+ NOVA_PREMIER_V1("amazon.nova-premier-v1:0"),
+ NOVA_PRO_V1("amazon.nova-pro-v1:0"),
+ NOVA_REEL_V1("amazon.nova-reel-v1:0"),
+ NOVA_REEL_V1_1("amazon.nova-reel-v1:1"),
+ NOVA_SONIC_V1("amazon.nova-sonic-v1:0"),
+
+ // Amazon Rerank
+ RERANK_V1("amazon.rerank-v1:0"),
+
+ // AI21 Labs Models
+ /** @deprecated Deprecated October 2024, use JAMBA_1_5_LARGE instead */
+ @Deprecated(since = "4.10.0", forRemoval = true)
JURASSIC2_ULTRA("ai21.j2-ultra-v1"),
+ /** @deprecated Deprecated October 2024, use JAMBA_1_5_MINI instead */
+ @Deprecated(since = "4.10.0", forRemoval = true)
JURASSIC2_MID("ai21.j2-mid-v1"),
+ JAMBA_1_5_LARGE("ai21.jamba-1-5-large-v1:0"),
+ JAMBA_1_5_MINI("ai21.jamba-1-5-mini-v1:0"),
+
+ // Anthropic Claude Models
+ /** @deprecated Deprecated July 2025, use ANTROPHIC_CLAUDE_HAIKU_V3
instead */
+ @Deprecated(since = "4.10.0", forRemoval = true)
ANTROPHIC_CLAUDE_INSTANT_V1("anthropic.claude-instant-v1"),
+ /** @deprecated Deprecated July 2025, use ANTROPHIC_CLAUDE_V3 instead */
+ @Deprecated(since = "4.10.0", forRemoval = true)
ANTROPHIC_CLAUDE_V2("anthropic.claude-v2"),
+ /** @deprecated Deprecated July 2025, use ANTROPHIC_CLAUDE_V3 instead */
+ @Deprecated(since = "4.10.0", forRemoval = true)
ANTROPHIC_CLAUDE_V2_1("anthropic.claude-v2:1"),
ANTROPHIC_CLAUDE_V3("anthropic.claude-3-sonnet-20240229-v1:0"),
ANTROPHIC_CLAUDE_V35("anthropic.claude-3-5-sonnet-20240620-v1:0"),
ANTROPHIC_CLAUDE_V35_2("anthropic.claude-3-5-sonnet-20241022-v2:0"),
ANTROPHIC_CLAUDE_HAIKU_V3("anthropic.claude-3-haiku-20240307-v1:0"),
ANTROPHIC_CLAUDE_HAIKU_V35("anthropic.claude-3-5-haiku-20241022-v1:0"),
+ ANTROPHIC_CLAUDE_OPUS_V3("anthropic.claude-3-opus-20240229-v1:0"),
+ ANTROPHIC_CLAUDE_V37("anthropic.claude-3-7-sonnet-20250219-v1:0"),
+ ANTROPHIC_CLAUDE_OPUS_V4("anthropic.claude-opus-4-20250514-v1:0"),
+ ANTROPHIC_CLAUDE_SONNET_V4("anthropic.claude-sonnet-4-20250514-v1:0"),
+
+ // Cohere Models
+ COHERE_COMMAND_R_PLUS("cohere.command-r-plus-v1:0"),
+ COHERE_COMMAND_R("cohere.command-r-v1:0"),
+ COHERE_EMBED_ENGLISH_V3("cohere.embed-english-v3"),
+ COHERE_EMBED_MULTILINGUAL_V3("cohere.embed-multilingual-v3"),
+ COHERE_RERANK_V3_5("cohere.rerank-v3-5:0"),
+
+ // Meta Llama Models (Llama 2 deprecated Oct 2024, Llama 3+ supported)
+ LLAMA3_8B_INSTRUCT("meta.llama3-8b-instruct-v1:0"),
+ LLAMA3_70B_INSTRUCT("meta.llama3-70b-instruct-v1:0"),
+ LLAMA3_1_8B_INSTRUCT("meta.llama3-1-8b-instruct-v1:0"),
+ LLAMA3_1_70B_INSTRUCT("meta.llama3-1-70b-instruct-v1:0"),
+ LLAMA3_1_405B_INSTRUCT("meta.llama3-1-405b-instruct-v1:0"),
+ LLAMA3_2_1B_INSTRUCT("meta.llama3-2-1b-instruct-v1:0"),
+ LLAMA3_2_3B_INSTRUCT("meta.llama3-2-3b-instruct-v1:0"),
+ LLAMA3_2_11B_INSTRUCT("meta.llama3-2-11b-instruct-v1:0"),
+ LLAMA3_2_90B_INSTRUCT("meta.llama3-2-90b-instruct-v1:0"),
+ LLAMA3_3_70B_INSTRUCT("meta.llama3-3-70b-instruct-v1:0"),
+ LLAMA4_MAVERICK_17B_INSTRUCT("meta.llama4-maverick-17b-instruct-v1:0"),
+ LLAMA4_SCOUT_17B_INSTRUCT("meta.llama4-scout-17b-instruct-v1:0"),
+
+ // Mistral AI Models
MISTRAL_7B_INSTRUCT("mistral.mistral-7b-instruct-v0:2"),
MISTRAL_8x7B_INSTRUCT("mistral.mixtral-8x7b-instruct-v0:1"),
- MISTRAL_LARGE("mistral.mistral-large-2402-v1:0");
+ MISTRAL_LARGE("mistral.mistral-large-2402-v1:0"),
+ MISTRAL_LARGE_2407("mistral.mistral-large-2407-v1:0"),
+ MISTRAL_SMALL_2402("mistral.mistral-small-2402-v1:0"),
+ PIXTRAL_LARGE("mistral.pixtral-large-2502-v1:0"),
+
+ // Stability AI Models
+ STABLE_DIFFUSION_3_5_LARGE("stability.sd3-5-large-v1:0"),
+ STABLE_IMAGE_CONTROL_SKETCH("stability.stable-image-control-sketch-v1:0"),
+
STABLE_IMAGE_CONTROL_STRUCTURE("stability.stable-image-control-structure-v1:0"),
+ STABLE_IMAGE_CORE("stability.stable-image-core-v1:1");
public final String model;
diff --git
a/components/camel-aws/camel-aws-bedrock/src/main/java/org/apache/camel/component/aws2/bedrock/runtime/BedrockConfiguration.java
b/components/camel-aws/camel-aws-bedrock/src/main/java/org/apache/camel/component/aws2/bedrock/runtime/BedrockConfiguration.java
index 6557c616834..75a0d5b037d 100644
---
a/components/camel-aws/camel-aws-bedrock/src/main/java/org/apache/camel/component/aws2/bedrock/runtime/BedrockConfiguration.java
+++
b/components/camel-aws/camel-aws-bedrock/src/main/java/org/apache/camel/component/aws2/bedrock/runtime/BedrockConfiguration.java
@@ -39,7 +39,7 @@ public class BedrockConfiguration implements Cloneable {
private String secretKey;
@UriParam(label = "security", secret = true)
private String sessionToken;
- @UriParam(enums =
"amazon.titan-text-express-v1,amazon.titan-text-lite-v1,amazon.titan-image-generator-v1,amazon.titan-embed-text-v1,ai21.j2-ultra-v1,ai21.j2-mid-v1,anthropic.claude-instant-v1,anthropic.claude-v2,anthropic.claude-v2:1,anthropic.claude-3-sonnet-20240229-v1:0,anthropic.claude-3-haiku-20240307-v1:0,amazon.titan-text-premier-v1:0,amazon.titan-embed-text-v2:0")
+ @UriParam(enums =
"amazon.titan-text-express-v1,amazon.titan-text-lite-v1,amazon.titan-image-generator-v1,amazon.titan-embed-text-v1,amazon.titan-embed-image-v1,amazon.titan-text-premier-v1:0,amazon.titan-embed-text-v2:0,amazon.titan-image-generator-v2:0,amazon.nova-canvas-v1:0,amazon.nova-lite-v1:0,amazon.nova-micro-v1:0,amazon.nova-premier-v1:0,amazon.nova-pro-v1:0,amazon.nova-reel-v1:0,amazon.nova-reel-v1:1,amazon.nova-sonic-v1:0,amazon.rerank-v1:0,ai21.jamba-1-5-large-v1:0,ai21.j
[...]
@Metadata(required = true)
private String modelId;
@UriParam
diff --git
a/components/camel-aws/camel-aws-bedrock/src/main/java/org/apache/camel/component/aws2/bedrock/runtime/BedrockProducer.java
b/components/camel-aws/camel-aws-bedrock/src/main/java/org/apache/camel/component/aws2/bedrock/runtime/BedrockProducer.java
index 99f32f3c10a..3e54aa0e3f1 100644
---
a/components/camel-aws/camel-aws-bedrock/src/main/java/org/apache/camel/component/aws2/bedrock/runtime/BedrockProducer.java
+++
b/components/camel-aws/camel-aws-bedrock/src/main/java/org/apache/camel/component/aws2/bedrock/runtime/BedrockProducer.java
@@ -233,40 +233,114 @@ public class BedrockProducer extends DefaultProducer {
}
protected void setResponseText(InvokeModelResponse result, Message
message) {
- switch (getConfiguration().getModelId()) {
- case "amazon.titan-text-express-v1", "amazon.titan-text-lite-v1",
"amazon.titan-text-premier-v1:0",
- "amazon.titan-embed-text-v2:0" ->
+ String modelId = getConfiguration().getModelId();
+ switch (modelId) {
+ // Amazon Titan Models
+ case "amazon.titan-text-express-v1":
+ case "amazon.titan-text-lite-v1":
+ case "amazon.titan-text-premier-v1:0":
+ case "amazon.titan-embed-text-v2:0":
setTitanText(result, message);
- case "ai21.j2-ultra-v1", "ai21.j2-mid-v1" -> {
+ break;
+
+ // AI21 Labs Models
+ case "ai21.j2-ultra-v1":
+ case "ai21.j2-mid-v1":
+ case "ai21.jamba-1-5-large-v1:0":
+ case "ai21.jamba-1-5-mini-v1:0":
try {
setAi21Text(result, message);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
- }
- case "anthropic.claude-instant-v1", "anthropic.claude-v2",
"anthropic.claude-v2:1" -> {
+ break;
+
+ // Anthropic Claude Models (legacy format - deprecated)
+ case "anthropic.claude-instant-v1":
+ case "anthropic.claude-v2":
+ case "anthropic.claude-v2:1":
try {
setAnthropicText(result, message);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
- }
- case "anthropic.claude-3-sonnet-20240229-v1:0",
"anthropic.claude-3-haiku-20240307-v1:0" -> {
+ break;
+
+ // Anthropic Claude Models (v3+ format)
+ case "anthropic.claude-3-sonnet-20240229-v1:0":
+ case "anthropic.claude-3-5-sonnet-20240620-v1:0":
+ case "anthropic.claude-3-5-sonnet-20241022-v2:0":
+ case "anthropic.claude-3-haiku-20240307-v1:0":
+ case "anthropic.claude-3-5-haiku-20241022-v1:0":
+ case "anthropic.claude-3-opus-20240229-v1:0":
+ case "anthropic.claude-3-7-sonnet-20250219-v1:0":
+ case "anthropic.claude-opus-4-20250514-v1:0":
+ case "anthropic.claude-sonnet-4-20250514-v1:0":
try {
setAnthropicV3Text(result, message);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
- }
- case "mistral.mistral-7b-instruct-v0:2",
"mistral.mixtral-8x7b-instruct-v0:1",
- "mistral.mistral-large-2402-v1:0" -> {
+ break;
+
+ // Mistral AI Models
+ case "mistral.mistral-7b-instruct-v0:2":
+ case "mistral.mixtral-8x7b-instruct-v0:1":
+ case "mistral.mistral-large-2402-v1:0":
+ case "mistral.mistral-large-2407-v1:0":
+ case "mistral.mistral-small-2402-v1:0":
+ case "mistral.pixtral-large-2502-v1:0":
try {
setMistralText(result, message);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
- }
- default -> throw new IllegalStateException("Unexpected value: " +
getConfiguration().getModelId());
+ break;
+
+ // Amazon Nova Models (using v3 format)
+ case "amazon.nova-lite-v1:0":
+ case "amazon.nova-micro-v1:0":
+ case "amazon.nova-premier-v1:0":
+ case "amazon.nova-pro-v1:0":
+ try {
+ setAnthropicV3Text(result, message);
+ } catch (JsonProcessingException e) {
+ throw new RuntimeException(e);
+ }
+ break;
+
+ // Cohere Models
+ case "cohere.command-r-plus-v1:0":
+ case "cohere.command-r-v1:0":
+ try {
+ setCohereText(result, message);
+ } catch (JsonProcessingException e) {
+ throw new RuntimeException(e);
+ }
+ break;
+
+ // Meta Llama Models (Llama 3+ supported)
+ case "meta.llama3-8b-instruct-v1:0":
+ case "meta.llama3-70b-instruct-v1:0":
+ case "meta.llama3-1-8b-instruct-v1:0":
+ case "meta.llama3-1-70b-instruct-v1:0":
+ case "meta.llama3-1-405b-instruct-v1:0":
+ case "meta.llama3-2-1b-instruct-v1:0":
+ case "meta.llama3-2-3b-instruct-v1:0":
+ case "meta.llama3-2-11b-instruct-v1:0":
+ case "meta.llama3-2-90b-instruct-v1:0":
+ case "meta.llama3-3-70b-instruct-v1:0":
+ case "meta.llama4-maverick-17b-instruct-v1:0":
+ case "meta.llama4-scout-17b-instruct-v1:0":
+ try {
+ setLlamaText(result, message);
+ } catch (JsonProcessingException e) {
+ throw new RuntimeException(e);
+ }
+ break;
+
+ default:
+ throw new IllegalStateException("Unexpected model: " +
modelId);
}
}
@@ -298,6 +372,18 @@ public class BedrockProducer extends DefaultProducer {
message.setBody(jsonString);
}
+ private void setCohereText(InvokeModelResponse result, Message message)
throws JsonProcessingException {
+ ObjectMapper mapper = new ObjectMapper();
+ JsonNode jsonString = mapper.readTree(result.body().asUtf8String());
+ message.setBody(jsonString.get("text"));
+ }
+
+ private void setLlamaText(InvokeModelResponse result, Message message)
throws JsonProcessingException {
+ ObjectMapper mapper = new ObjectMapper();
+ JsonNode jsonString = mapper.readTree(result.body().asUtf8String());
+ message.setBody(jsonString.get("generation"));
+ }
+
public static Message getMessageForResponse(final Exchange exchange) {
return exchange.getMessage();
}
diff --git
a/components/camel-aws/camel-aws-bedrock/src/test/java/org/apache/camel/component/aws2/bedrock/BedrockModelsTest.java
b/components/camel-aws/camel-aws-bedrock/src/test/java/org/apache/camel/component/aws2/bedrock/BedrockModelsTest.java
new file mode 100644
index 00000000000..120e0903e1d
--- /dev/null
+++
b/components/camel-aws/camel-aws-bedrock/src/test/java/org/apache/camel/component/aws2/bedrock/BedrockModelsTest.java
@@ -0,0 +1,178 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.aws2.bedrock;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.EnumSource;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class BedrockModelsTest {
+
+ @ParameterizedTest
+ @EnumSource(BedrockModels.class)
+ void testAllModelsHaveValidModelIds(BedrockModels model) {
+ assertNotNull(model.model, "Model ID should not be null for " +
model.name());
+ assertFalse(model.model.isEmpty(), "Model ID should not be empty for "
+ model.name());
+ assertTrue(model.model.contains("."), "Model ID should contain
provider prefix for " + model.name());
+ }
+
+ @Test
+ void testAmazonTitanModels() {
+ assertEquals("amazon.titan-text-express-v1",
BedrockModels.TITAN_TEXT_EXPRESS_V1.model);
+ assertEquals("amazon.titan-text-lite-v1",
BedrockModels.TITAN_TEXT_LITE_V1.model);
+ assertEquals("amazon.titan-image-generator-v1",
BedrockModels.TITAN_IMAGE_GENERATOR_V1.model);
+ assertEquals("amazon.titan-embed-text-v1",
BedrockModels.TITAN_EMBEDDINGS_G1.model);
+ assertEquals("amazon.titan-embed-image-v1",
BedrockModels.TITAN_MULTIMODAL_EMBEDDINGS_G1.model);
+ assertEquals("amazon.titan-text-premier-v1:0",
BedrockModels.TITAN_TEXT_PREMIER_V1.model);
+ assertEquals("amazon.titan-embed-text-v2:0",
BedrockModels.TITAN_TEXT_EMBEDDINGS_V2.model);
+ assertEquals("amazon.titan-image-generator-v2:0",
BedrockModels.TITAN_IMAGE_GENERATOR_V2.model);
+ }
+
+ @Test
+ void testAmazonNovaModels() {
+ assertEquals("amazon.nova-canvas-v1:0",
BedrockModels.NOVA_CANVAS_V1.model);
+ assertEquals("amazon.nova-lite-v1:0",
BedrockModels.NOVA_LITE_V1.model);
+ assertEquals("amazon.nova-micro-v1:0",
BedrockModels.NOVA_MICRO_V1.model);
+ assertEquals("amazon.nova-premier-v1:0",
BedrockModels.NOVA_PREMIER_V1.model);
+ assertEquals("amazon.nova-pro-v1:0", BedrockModels.NOVA_PRO_V1.model);
+ assertEquals("amazon.nova-reel-v1:0",
BedrockModels.NOVA_REEL_V1.model);
+ assertEquals("amazon.nova-reel-v1:1",
BedrockModels.NOVA_REEL_V1_1.model);
+ assertEquals("amazon.nova-sonic-v1:0",
BedrockModels.NOVA_SONIC_V1.model);
+ }
+
+ @Test
+ void testAmazonRerankModel() {
+ assertEquals("amazon.rerank-v1:0", BedrockModels.RERANK_V1.model);
+ }
+
+ @Test
+ void testAI21LabsModels() {
+ assertEquals("ai21.j2-ultra-v1", BedrockModels.JURASSIC2_ULTRA.model);
+ assertEquals("ai21.j2-mid-v1", BedrockModels.JURASSIC2_MID.model);
+ assertEquals("ai21.jamba-1-5-large-v1:0",
BedrockModels.JAMBA_1_5_LARGE.model);
+ assertEquals("ai21.jamba-1-5-mini-v1:0",
BedrockModels.JAMBA_1_5_MINI.model);
+ }
+
+ @Test
+ void testAnthropicClaudeModels() {
+ assertEquals("anthropic.claude-instant-v1",
BedrockModels.ANTROPHIC_CLAUDE_INSTANT_V1.model);
+ assertEquals("anthropic.claude-v2",
BedrockModels.ANTROPHIC_CLAUDE_V2.model);
+ assertEquals("anthropic.claude-v2:1",
BedrockModels.ANTROPHIC_CLAUDE_V2_1.model);
+ assertEquals("anthropic.claude-3-sonnet-20240229-v1:0",
BedrockModels.ANTROPHIC_CLAUDE_V3.model);
+ assertEquals("anthropic.claude-3-5-sonnet-20240620-v1:0",
BedrockModels.ANTROPHIC_CLAUDE_V35.model);
+ assertEquals("anthropic.claude-3-5-sonnet-20241022-v2:0",
BedrockModels.ANTROPHIC_CLAUDE_V35_2.model);
+ assertEquals("anthropic.claude-3-haiku-20240307-v1:0",
BedrockModels.ANTROPHIC_CLAUDE_HAIKU_V3.model);
+ assertEquals("anthropic.claude-3-5-haiku-20241022-v1:0",
BedrockModels.ANTROPHIC_CLAUDE_HAIKU_V35.model);
+ assertEquals("anthropic.claude-3-opus-20240229-v1:0",
BedrockModels.ANTROPHIC_CLAUDE_OPUS_V3.model);
+ assertEquals("anthropic.claude-3-7-sonnet-20250219-v1:0",
BedrockModels.ANTROPHIC_CLAUDE_V37.model);
+ assertEquals("anthropic.claude-opus-4-20250514-v1:0",
BedrockModels.ANTROPHIC_CLAUDE_OPUS_V4.model);
+ assertEquals("anthropic.claude-sonnet-4-20250514-v1:0",
BedrockModels.ANTROPHIC_CLAUDE_SONNET_V4.model);
+ }
+
+ @Test
+ void testCohereModels() {
+ assertEquals("cohere.command-r-plus-v1:0",
BedrockModels.COHERE_COMMAND_R_PLUS.model);
+ assertEquals("cohere.command-r-v1:0",
BedrockModels.COHERE_COMMAND_R.model);
+ assertEquals("cohere.embed-english-v3",
BedrockModels.COHERE_EMBED_ENGLISH_V3.model);
+ assertEquals("cohere.embed-multilingual-v3",
BedrockModels.COHERE_EMBED_MULTILINGUAL_V3.model);
+ assertEquals("cohere.rerank-v3-5:0",
BedrockModels.COHERE_RERANK_V3_5.model);
+ }
+
+ @Test
+ void testMetaLlamaModels() {
+ assertEquals("meta.llama3-8b-instruct-v1:0",
BedrockModels.LLAMA3_8B_INSTRUCT.model);
+ assertEquals("meta.llama3-70b-instruct-v1:0",
BedrockModels.LLAMA3_70B_INSTRUCT.model);
+ assertEquals("meta.llama3-1-8b-instruct-v1:0",
BedrockModels.LLAMA3_1_8B_INSTRUCT.model);
+ assertEquals("meta.llama3-1-70b-instruct-v1:0",
BedrockModels.LLAMA3_1_70B_INSTRUCT.model);
+ assertEquals("meta.llama3-1-405b-instruct-v1:0",
BedrockModels.LLAMA3_1_405B_INSTRUCT.model);
+ assertEquals("meta.llama3-2-1b-instruct-v1:0",
BedrockModels.LLAMA3_2_1B_INSTRUCT.model);
+ assertEquals("meta.llama3-2-3b-instruct-v1:0",
BedrockModels.LLAMA3_2_3B_INSTRUCT.model);
+ assertEquals("meta.llama3-2-11b-instruct-v1:0",
BedrockModels.LLAMA3_2_11B_INSTRUCT.model);
+ assertEquals("meta.llama3-2-90b-instruct-v1:0",
BedrockModels.LLAMA3_2_90B_INSTRUCT.model);
+ assertEquals("meta.llama3-3-70b-instruct-v1:0",
BedrockModels.LLAMA3_3_70B_INSTRUCT.model);
+ assertEquals("meta.llama4-maverick-17b-instruct-v1:0",
BedrockModels.LLAMA4_MAVERICK_17B_INSTRUCT.model);
+ assertEquals("meta.llama4-scout-17b-instruct-v1:0",
BedrockModels.LLAMA4_SCOUT_17B_INSTRUCT.model);
+ }
+
+ @Test
+ void testMistralAIModels() {
+ assertEquals("mistral.mistral-7b-instruct-v0:2",
BedrockModels.MISTRAL_7B_INSTRUCT.model);
+ assertEquals("mistral.mixtral-8x7b-instruct-v0:1",
BedrockModels.MISTRAL_8x7B_INSTRUCT.model);
+ assertEquals("mistral.mistral-large-2402-v1:0",
BedrockModels.MISTRAL_LARGE.model);
+ assertEquals("mistral.mistral-large-2407-v1:0",
BedrockModels.MISTRAL_LARGE_2407.model);
+ assertEquals("mistral.mistral-small-2402-v1:0",
BedrockModels.MISTRAL_SMALL_2402.model);
+ assertEquals("mistral.pixtral-large-2502-v1:0",
BedrockModels.PIXTRAL_LARGE.model);
+ }
+
+ @Test
+ void testStabilityAIModels() {
+ assertEquals("stability.sd3-5-large-v1:0",
BedrockModels.STABLE_DIFFUSION_3_5_LARGE.model);
+ assertEquals("stability.stable-image-control-sketch-v1:0",
BedrockModels.STABLE_IMAGE_CONTROL_SKETCH.model);
+ assertEquals("stability.stable-image-control-structure-v1:0",
BedrockModels.STABLE_IMAGE_CONTROL_STRUCTURE.model);
+ assertEquals("stability.stable-image-core-v1:1",
BedrockModels.STABLE_IMAGE_CORE.model);
+ }
+
+ @Test
+ void testModelCategorization() {
+
assertTrue(BedrockModels.TITAN_TEXT_EXPRESS_V1.model.startsWith("amazon."));
+ assertTrue(BedrockModels.JAMBA_1_5_LARGE.model.startsWith("ai21."));
+
assertTrue(BedrockModels.ANTROPHIC_CLAUDE_V3.model.startsWith("anthropic."));
+ assertTrue(BedrockModels.COHERE_COMMAND_R.model.startsWith("cohere."));
+ assertTrue(BedrockModels.LLAMA3_8B_INSTRUCT.model.startsWith("meta."));
+
assertTrue(BedrockModels.MISTRAL_7B_INSTRUCT.model.startsWith("mistral."));
+
assertTrue(BedrockModels.STABLE_DIFFUSION_3_5_LARGE.model.startsWith("stability."));
+ }
+
+ @Test
+ void testEnumCountAndNewModels() {
+ BedrockModels[] allModels = BedrockModels.values();
+ assertEquals(60, allModels.length,
+ "Should have exactly 60 models (including deprecated models
with @Deprecated annotations)");
+
+ boolean hasNovaModels = false;
+ boolean hasJambaModels = false;
+ boolean hasLlamaModels = false;
+ boolean hasCohereModels = false;
+ boolean hasStabilityModels = false;
+
+ for (BedrockModels model : allModels) {
+ if (model.model.contains("nova")) {
+ hasNovaModels = true;
+ }
+ if (model.model.contains("jamba")) {
+ hasJambaModels = true;
+ }
+ if (model.model.contains("llama")) {
+ hasLlamaModels = true;
+ }
+ if (model.model.startsWith("cohere.")) {
+ hasCohereModels = true;
+ }
+ if (model.model.startsWith("stability.")) {
+ hasStabilityModels = true;
+ }
+ }
+
+ assertTrue(hasNovaModels, "Should include Amazon Nova models");
+ assertTrue(hasJambaModels, "Should include AI21 Jamba models");
+ assertTrue(hasLlamaModels, "Should include Meta Llama models");
+ assertTrue(hasCohereModels, "Should include Cohere models");
+ assertTrue(hasStabilityModels, "Should include Stability AI models");
+ }
+}
diff --git
a/components/camel-aws/camel-aws-bedrock/src/test/java/org/apache/camel/component/aws2/bedrock/runtime/integration/BedrockProducerIT.java
b/components/camel-aws/camel-aws-bedrock/src/test/java/org/apache/camel/component/aws2/bedrock/runtime/integration/BedrockProducerIT.java
index 8a7bc51730a..ce51d3f7ef1 100644
---
a/components/camel-aws/camel-aws-bedrock/src/test/java/org/apache/camel/component/aws2/bedrock/runtime/integration/BedrockProducerIT.java
+++
b/components/camel-aws/camel-aws-bedrock/src/test/java/org/apache/camel/component/aws2/bedrock/runtime/integration/BedrockProducerIT.java
@@ -149,40 +149,6 @@ class BedrockProducerIT extends CamelTestSupport {
MockEndpoint.assertIsSatisfied(context);
}
- @Test
- public void testInvokeJurassic2UltraModel() throws InterruptedException {
-
- result.expectedMessageCount(1);
- final Exchange result = template.send("direct:send_jurassic2_model",
exchange -> {
- ObjectMapper mapper = new ObjectMapper();
- ObjectNode rootNode = mapper.createObjectNode();
- rootNode.putIfAbsent("prompt",
- new TextNode(
- "\"Apple Inc. (NASDAQ:AAPL) Q3 2023 Earnings
Conference Call August 3, 2023 5:00 PM ET Operator\\\\nGood day, and welcome to
the Apple Q3 Fiscal Year 2023 Earnings Conference Call. Today's call is being
recorded. At this time, for opening remarks and introductions, I would like to
turn the call over to Saori Casey, Vice President of Finance. Please go
ahead.\\\\nSaori Casey\\\\nThank you. Good afternoon, and thank you for joining
us. Speaking first today is Ap [...]
-
- rootNode.putIfAbsent("maxTokens", new IntNode(500));
- rootNode.putIfAbsent("temperature", new IntNode(0));
- rootNode.putIfAbsent("topP", new IntNode(1));
-
- ArrayNode stopSequences = mapper.createArrayNode();
- stopSequences.add("###");
-
- rootNode.putIfAbsent("stopSequences", stopSequences);
-
- ObjectNode childNode = mapper.createObjectNode();
- childNode.putIfAbsent("scale", new IntNode(0));
-
- rootNode.putIfAbsent("presencePenalty", childNode);
- rootNode.putIfAbsent("frequencyPenalty", childNode);
-
-
exchange.getMessage().setBody(mapper.writer().writeValueAsString(rootNode));
-
exchange.getMessage().setHeader(BedrockConstants.MODEL_CONTENT_TYPE,
"application/json");
-
exchange.getMessage().setHeader(BedrockConstants.MODEL_ACCEPT_CONTENT_TYPE,
"application/json");
- });
-
- MockEndpoint.assertIsSatisfied(context);
- }
-
@Test
public void testInvokeJurassic2MidModel() throws InterruptedException {
@@ -507,6 +473,400 @@ class BedrockProducerIT extends CamelTestSupport {
MockEndpoint.assertIsSatisfied(context);
}
+ @Test
+ public void testInvokeNovaLiteModel() throws InterruptedException {
+
+ result.expectedMessageCount(1);
+ final Exchange result = template.send("direct:send_nova_lite",
exchange -> {
+ ObjectMapper mapper = new ObjectMapper();
+ ObjectNode rootNode = mapper.createObjectNode();
+
+ ArrayNode messages = mapper.createArrayNode();
+
+ ObjectNode element = mapper.createObjectNode();
+ element.putIfAbsent("role", new TextNode("user"));
+
+ ArrayNode content = mapper.createArrayNode();
+
+ ObjectNode textContent = mapper.createObjectNode();
+
+ textContent.putIfAbsent("type", new TextNode("text"));
+ textContent.putIfAbsent("text", new TextNode("Can you tell the
history of Mayflower?"));
+
+ content.add(textContent);
+
+ element.putIfAbsent("content", content);
+
+ messages.add(element);
+
+ rootNode.putIfAbsent("messages", messages);
+ rootNode.putIfAbsent("max_tokens", new IntNode(1000));
+
+
exchange.getMessage().setBody(mapper.writer().writeValueAsString(rootNode));
+
exchange.getMessage().setHeader(BedrockConstants.MODEL_CONTENT_TYPE,
"application/json");
+
exchange.getMessage().setHeader(BedrockConstants.MODEL_ACCEPT_CONTENT_TYPE,
"application/json");
+ });
+
+ MockEndpoint.assertIsSatisfied(context);
+ }
+
+ @Test
+ public void testInvokeJamba15LargeModel() throws InterruptedException {
+
+ result.expectedMessageCount(1);
+ final Exchange result = template.send("direct:send_jamba_15_large",
exchange -> {
+ ObjectMapper mapper = new ObjectMapper();
+ ObjectNode rootNode = mapper.createObjectNode();
+
+ ArrayNode messages = mapper.createArrayNode();
+
+ ObjectNode element = mapper.createObjectNode();
+ element.putIfAbsent("role", new TextNode("user"));
+ element.putIfAbsent("content", new TextNode("Can you tell the
history of Mayflower?"));
+
+ messages.add(element);
+
+ rootNode.putIfAbsent("messages", messages);
+ rootNode.putIfAbsent("max_tokens", new IntNode(1000));
+ rootNode.putIfAbsent("temperature", new DoubleNode(0.7));
+ rootNode.putIfAbsent("top_p", new DoubleNode(0.9));
+
+
exchange.getMessage().setBody(mapper.writer().writeValueAsString(rootNode));
+
exchange.getMessage().setHeader(BedrockConstants.MODEL_CONTENT_TYPE,
"application/json");
+
exchange.getMessage().setHeader(BedrockConstants.MODEL_ACCEPT_CONTENT_TYPE,
"application/json");
+ });
+
+ MockEndpoint.assertIsSatisfied(context);
+ }
+
+ @Test
+ public void testInvokeCohereCommandRModel() throws InterruptedException {
+
+ result.expectedMessageCount(1);
+ final Exchange result = template.send("direct:send_cohere_command_r",
exchange -> {
+ ObjectMapper mapper = new ObjectMapper();
+ ObjectNode rootNode = mapper.createObjectNode();
+ rootNode.putIfAbsent("message", new TextNode("Can you tell the
history of Mayflower?"));
+ rootNode.putIfAbsent("max_tokens", new IntNode(1000));
+ rootNode.putIfAbsent("temperature", new DoubleNode(0.7));
+ rootNode.putIfAbsent("p", new DoubleNode(0.9));
+
+
exchange.getMessage().setBody(mapper.writer().writeValueAsString(rootNode));
+
exchange.getMessage().setHeader(BedrockConstants.MODEL_CONTENT_TYPE,
"application/json");
+
exchange.getMessage().setHeader(BedrockConstants.MODEL_ACCEPT_CONTENT_TYPE,
"application/json");
+ });
+
+ MockEndpoint.assertIsSatisfied(context);
+ }
+
+ @Test
+ public void testInvokeLlama38BInstructModel() throws InterruptedException {
+
+ result.expectedMessageCount(1);
+ final Exchange result =
template.send("direct:send_llama3_8b_instruct", exchange -> {
+ ObjectMapper mapper = new ObjectMapper();
+ ObjectNode rootNode = mapper.createObjectNode();
+ rootNode.putIfAbsent("prompt", new TextNode(
+
"<|begin_of_text|><|start_header_id|>user<|end_header_id|>\n\nCan you tell the
history of
Mayflower?<|eot_id|><|start_header_id|>assistant<|end_header_id|>\n\n"));
+ rootNode.putIfAbsent("max_gen_len", new IntNode(1000));
+ rootNode.putIfAbsent("temperature", new DoubleNode(0.7));
+ rootNode.putIfAbsent("top_p", new DoubleNode(0.9));
+
+
exchange.getMessage().setBody(mapper.writer().writeValueAsString(rootNode));
+
exchange.getMessage().setHeader(BedrockConstants.MODEL_CONTENT_TYPE,
"application/json");
+
exchange.getMessage().setHeader(BedrockConstants.MODEL_ACCEPT_CONTENT_TYPE,
"application/json");
+ });
+
+ MockEndpoint.assertIsSatisfied(context);
+ }
+
+ @Test
+ public void testInvokeMistralLarge2407Model() throws InterruptedException {
+
+ result.expectedMessageCount(1);
+ final Exchange result =
template.send("direct:send_mistral_large_2407", exchange -> {
+ ObjectMapper mapper = new ObjectMapper();
+ ObjectNode rootNode = mapper.createObjectNode();
+ rootNode.putIfAbsent("prompt",
+ new TextNode("\"<s>[INST] Can you tell the history of
Mayflower? [/INST]\\\""));
+
+ rootNode.putIfAbsent("max_tokens", new IntNode(300));
+ rootNode.putIfAbsent("temperature", new DoubleNode(0.5));
+ rootNode.putIfAbsent("top_p", new DoubleNode(0.9));
+ rootNode.putIfAbsent("top_k", new IntNode(50));
+
+
exchange.getMessage().setBody(mapper.writer().writeValueAsString(rootNode));
+
exchange.getMessage().setHeader(BedrockConstants.MODEL_CONTENT_TYPE,
"application/json");
+
exchange.getMessage().setHeader(BedrockConstants.MODEL_ACCEPT_CONTENT_TYPE,
"application/json");
+ });
+
+ MockEndpoint.assertIsSatisfied(context);
+ }
+
+ @Test
+ public void testInvokeNovaMicroModel() throws InterruptedException {
+
+ result.expectedMessageCount(1);
+ final Exchange result = template.send("direct:send_nova_micro",
exchange -> {
+ ObjectMapper mapper = new ObjectMapper();
+ ObjectNode rootNode = mapper.createObjectNode();
+
+ ArrayNode messages = mapper.createArrayNode();
+
+ ObjectNode element = mapper.createObjectNode();
+ element.putIfAbsent("role", new TextNode("user"));
+
+ ArrayNode content = mapper.createArrayNode();
+
+ ObjectNode textContent = mapper.createObjectNode();
+
+ textContent.putIfAbsent("type", new TextNode("text"));
+ textContent.putIfAbsent("text", new TextNode("Can you tell the
history of Mayflower?"));
+
+ content.add(textContent);
+
+ element.putIfAbsent("content", content);
+
+ messages.add(element);
+
+ rootNode.putIfAbsent("messages", messages);
+ rootNode.putIfAbsent("max_tokens", new IntNode(1000));
+
+
exchange.getMessage().setBody(mapper.writer().writeValueAsString(rootNode));
+
exchange.getMessage().setHeader(BedrockConstants.MODEL_CONTENT_TYPE,
"application/json");
+
exchange.getMessage().setHeader(BedrockConstants.MODEL_ACCEPT_CONTENT_TYPE,
"application/json");
+ });
+
+ MockEndpoint.assertIsSatisfied(context);
+ }
+
+ @Test
+ public void testInvokeNovaProModel() throws InterruptedException {
+
+ result.expectedMessageCount(1);
+ final Exchange result = template.send("direct:send_nova_pro", exchange
-> {
+ ObjectMapper mapper = new ObjectMapper();
+ ObjectNode rootNode = mapper.createObjectNode();
+
+ ArrayNode messages = mapper.createArrayNode();
+
+ ObjectNode element = mapper.createObjectNode();
+ element.putIfAbsent("role", new TextNode("user"));
+
+ ArrayNode content = mapper.createArrayNode();
+
+ ObjectNode textContent = mapper.createObjectNode();
+
+ textContent.putIfAbsent("type", new TextNode("text"));
+ textContent.putIfAbsent("text", new TextNode("Can you tell the
history of Mayflower?"));
+
+ content.add(textContent);
+
+ element.putIfAbsent("content", content);
+
+ messages.add(element);
+
+ rootNode.putIfAbsent("messages", messages);
+ rootNode.putIfAbsent("max_tokens", new IntNode(1000));
+
+
exchange.getMessage().setBody(mapper.writer().writeValueAsString(rootNode));
+
exchange.getMessage().setHeader(BedrockConstants.MODEL_CONTENT_TYPE,
"application/json");
+
exchange.getMessage().setHeader(BedrockConstants.MODEL_ACCEPT_CONTENT_TYPE,
"application/json");
+ });
+
+ MockEndpoint.assertIsSatisfied(context);
+ }
+
+ @Test
+ public void testInvokeJamba15MiniModel() throws InterruptedException {
+
+ result.expectedMessageCount(1);
+ final Exchange result = template.send("direct:send_jamba_15_mini",
exchange -> {
+ ObjectMapper mapper = new ObjectMapper();
+ ObjectNode rootNode = mapper.createObjectNode();
+
+ ArrayNode messages = mapper.createArrayNode();
+
+ ObjectNode element = mapper.createObjectNode();
+ element.putIfAbsent("role", new TextNode("user"));
+ element.putIfAbsent("content", new TextNode("Can you tell the
history of Mayflower?"));
+
+ messages.add(element);
+
+ rootNode.putIfAbsent("messages", messages);
+ rootNode.putIfAbsent("max_tokens", new IntNode(1000));
+ rootNode.putIfAbsent("temperature", new DoubleNode(0.7));
+ rootNode.putIfAbsent("top_p", new DoubleNode(0.9));
+
+
exchange.getMessage().setBody(mapper.writer().writeValueAsString(rootNode));
+
exchange.getMessage().setHeader(BedrockConstants.MODEL_CONTENT_TYPE,
"application/json");
+
exchange.getMessage().setHeader(BedrockConstants.MODEL_ACCEPT_CONTENT_TYPE,
"application/json");
+ });
+
+ MockEndpoint.assertIsSatisfied(context);
+ }
+
+ @Test
+ public void testInvokeCohereCommandRPlusModel() throws
InterruptedException {
+
+ result.expectedMessageCount(1);
+ final Exchange result =
template.send("direct:send_cohere_command_r_plus", exchange -> {
+ ObjectMapper mapper = new ObjectMapper();
+ ObjectNode rootNode = mapper.createObjectNode();
+ rootNode.putIfAbsent("message", new TextNode("Can you tell the
history of Mayflower?"));
+ rootNode.putIfAbsent("max_tokens", new IntNode(1000));
+ rootNode.putIfAbsent("temperature", new DoubleNode(0.7));
+ rootNode.putIfAbsent("p", new DoubleNode(0.9));
+
+
exchange.getMessage().setBody(mapper.writer().writeValueAsString(rootNode));
+
exchange.getMessage().setHeader(BedrockConstants.MODEL_CONTENT_TYPE,
"application/json");
+
exchange.getMessage().setHeader(BedrockConstants.MODEL_ACCEPT_CONTENT_TYPE,
"application/json");
+ });
+
+ MockEndpoint.assertIsSatisfied(context);
+ }
+
+ @Test
+ public void testInvokeLlama31_70BInstructModel() throws
InterruptedException {
+
+ result.expectedMessageCount(1);
+ final Exchange result =
template.send("direct:send_llama31_70b_instruct", exchange -> {
+ ObjectMapper mapper = new ObjectMapper();
+ ObjectNode rootNode = mapper.createObjectNode();
+ rootNode.putIfAbsent("prompt", new TextNode(
+
"<|begin_of_text|><|start_header_id|>user<|end_header_id|>\n\nCan you tell the
history of
Mayflower?<|eot_id|><|start_header_id|>assistant<|end_header_id|>\n\n"));
+ rootNode.putIfAbsent("max_gen_len", new IntNode(1000));
+ rootNode.putIfAbsent("temperature", new DoubleNode(0.7));
+ rootNode.putIfAbsent("top_p", new DoubleNode(0.9));
+
+
exchange.getMessage().setBody(mapper.writer().writeValueAsString(rootNode));
+
exchange.getMessage().setHeader(BedrockConstants.MODEL_CONTENT_TYPE,
"application/json");
+
exchange.getMessage().setHeader(BedrockConstants.MODEL_ACCEPT_CONTENT_TYPE,
"application/json");
+ });
+
+ MockEndpoint.assertIsSatisfied(context);
+ }
+
+ @Test
+ public void testInvokeLlama32_11BInstructModel() throws
InterruptedException {
+
+ result.expectedMessageCount(1);
+ final Exchange result =
template.send("direct:send_llama32_11b_instruct", exchange -> {
+ ObjectMapper mapper = new ObjectMapper();
+ ObjectNode rootNode = mapper.createObjectNode();
+ rootNode.putIfAbsent("prompt", new TextNode(
+
"<|begin_of_text|><|start_header_id|>user<|end_header_id|>\n\nCan you tell the
history of
Mayflower?<|eot_id|><|start_header_id|>assistant<|end_header_id|>\n\n"));
+ rootNode.putIfAbsent("max_gen_len", new IntNode(1000));
+ rootNode.putIfAbsent("temperature", new DoubleNode(0.7));
+ rootNode.putIfAbsent("top_p", new DoubleNode(0.9));
+
+
exchange.getMessage().setBody(mapper.writer().writeValueAsString(rootNode));
+
exchange.getMessage().setHeader(BedrockConstants.MODEL_CONTENT_TYPE,
"application/json");
+
exchange.getMessage().setHeader(BedrockConstants.MODEL_ACCEPT_CONTENT_TYPE,
"application/json");
+ });
+
+ MockEndpoint.assertIsSatisfied(context);
+ }
+
+ @Test
+ public void testInvokeAnthropicClaude35Sonnet2Model() throws
InterruptedException {
+
+ result.expectedMessageCount(1);
+ final Exchange result =
template.send("direct:send_anthropic_claude_35_sonnet_2", exchange -> {
+ ObjectMapper mapper = new ObjectMapper();
+ ObjectNode rootNode = mapper.createObjectNode();
+
+ ArrayNode messages = mapper.createArrayNode();
+
+ ObjectNode element = mapper.createObjectNode();
+ element.putIfAbsent("role", new TextNode("user"));
+
+ ArrayNode content = mapper.createArrayNode();
+
+ ObjectNode textContent = mapper.createObjectNode();
+
+ textContent.putIfAbsent("type", new TextNode("text"));
+ textContent.putIfAbsent("text", new TextNode("Can you tell the
history of Mayflower?"));
+
+ content.add(textContent);
+
+ element.putIfAbsent("content", content);
+
+ messages.add(element);
+
+ rootNode.putIfAbsent("messages", messages);
+ rootNode.putIfAbsent("max_tokens", new IntNode(1000));
+ rootNode.putIfAbsent("anthropic_version", new
TextNode("bedrock-2023-05-31"));
+
+
exchange.getMessage().setBody(mapper.writer().writeValueAsString(rootNode));
+
exchange.getMessage().setHeader(BedrockConstants.MODEL_CONTENT_TYPE,
"application/json");
+
exchange.getMessage().setHeader(BedrockConstants.MODEL_ACCEPT_CONTENT_TYPE,
"application/json");
+ });
+
+ MockEndpoint.assertIsSatisfied(context);
+ }
+
+ @Test
+ public void testInvokeAnthropicClaude35HaikuModel() throws
InterruptedException {
+
+ result.expectedMessageCount(1);
+ final Exchange result =
template.send("direct:send_anthropic_claude_35_haiku", exchange -> {
+ ObjectMapper mapper = new ObjectMapper();
+ ObjectNode rootNode = mapper.createObjectNode();
+
+ ArrayNode messages = mapper.createArrayNode();
+
+ ObjectNode element = mapper.createObjectNode();
+ element.putIfAbsent("role", new TextNode("user"));
+
+ ArrayNode content = mapper.createArrayNode();
+
+ ObjectNode textContent = mapper.createObjectNode();
+
+ textContent.putIfAbsent("type", new TextNode("text"));
+ textContent.putIfAbsent("text", new TextNode("Can you tell the
history of Mayflower?"));
+
+ content.add(textContent);
+
+ element.putIfAbsent("content", content);
+
+ messages.add(element);
+
+ rootNode.putIfAbsent("messages", messages);
+ rootNode.putIfAbsent("max_tokens", new IntNode(1000));
+ rootNode.putIfAbsent("anthropic_version", new
TextNode("bedrock-2023-05-31"));
+
+
exchange.getMessage().setBody(mapper.writer().writeValueAsString(rootNode));
+
exchange.getMessage().setHeader(BedrockConstants.MODEL_CONTENT_TYPE,
"application/json");
+
exchange.getMessage().setHeader(BedrockConstants.MODEL_ACCEPT_CONTENT_TYPE,
"application/json");
+ });
+
+ MockEndpoint.assertIsSatisfied(context);
+ }
+
+ @Test
+ public void testInvokeMistralSmall2402Model() throws InterruptedException {
+
+ result.expectedMessageCount(1);
+ final Exchange result =
template.send("direct:send_mistral_small_2402", exchange -> {
+ ObjectMapper mapper = new ObjectMapper();
+ ObjectNode rootNode = mapper.createObjectNode();
+ rootNode.putIfAbsent("prompt",
+ new TextNode("\"<s>[INST] Can you tell the history of
Mayflower? [/INST]\\\""));
+
+ rootNode.putIfAbsent("max_tokens", new IntNode(300));
+ rootNode.putIfAbsent("temperature", new DoubleNode(0.5));
+ rootNode.putIfAbsent("top_p", new DoubleNode(0.9));
+ rootNode.putIfAbsent("top_k", new IntNode(50));
+
+
exchange.getMessage().setBody(mapper.writer().writeValueAsString(rootNode));
+
exchange.getMessage().setHeader(BedrockConstants.MODEL_CONTENT_TYPE,
"application/json");
+
exchange.getMessage().setHeader(BedrockConstants.MODEL_ACCEPT_CONTENT_TYPE,
"application/json");
+ });
+
+ MockEndpoint.assertIsSatisfied(context);
+ }
+
@Override
protected RouteBuilder createRouteBuilder() {
return new RouteBuilder() {
@@ -613,6 +973,90 @@ class BedrockProducerIT extends CamelTestSupport {
+ BedrockModels.MISTRAL_LARGE.model)
.log("Completions: ${body}")
.to(result);
+
+ from("direct:send_nova_lite")
+
.to("aws-bedrock:label?accessKey=RAW({{aws.manual.access.key}})&secretKey=RAW({{aws.manual.secret.key}})®ion=us-east-1&operation=invokeTextModel&modelId="
+ + BedrockModels.NOVA_LITE_V1.model)
+ .log("Completions: ${body}")
+ .to(result);
+
+ from("direct:send_jamba_15_large")
+
.to("aws-bedrock:label?accessKey=RAW({{aws.manual.access.key}})&secretKey=RAW({{aws.manual.secret.key}})®ion=us-east-1&operation=invokeTextModel&modelId="
+ + BedrockModels.JAMBA_1_5_LARGE.model)
+ .log("Completions: ${body}")
+ .to(result);
+
+ from("direct:send_cohere_command_r")
+
.to("aws-bedrock:label?accessKey=RAW({{aws.manual.access.key}})&secretKey=RAW({{aws.manual.secret.key}})®ion=us-east-1&operation=invokeTextModel&modelId="
+ + BedrockModels.COHERE_COMMAND_R.model)
+ .log("Completions: ${body}")
+ .to(result);
+
+ from("direct:send_llama3_8b_instruct")
+
.to("aws-bedrock:label?accessKey=RAW({{aws.manual.access.key}})&secretKey=RAW({{aws.manual.secret.key}})®ion=us-east-1&operation=invokeTextModel&modelId="
+ + BedrockModels.LLAMA3_8B_INSTRUCT.model)
+ .log("Completions: ${body}")
+ .to(result);
+
+ from("direct:send_mistral_large_2407")
+
.to("aws-bedrock:label?accessKey=RAW({{aws.manual.access.key}})&secretKey=RAW({{aws.manual.secret.key}})®ion=us-east-1&operation=invokeTextModel&modelId="
+ + BedrockModels.MISTRAL_LARGE_2407.model)
+ .log("Completions: ${body}")
+ .to(result);
+
+ from("direct:send_nova_micro")
+
.to("aws-bedrock:label?accessKey=RAW({{aws.manual.access.key}})&secretKey=RAW({{aws.manual.secret.key}})®ion=us-east-1&operation=invokeTextModel&modelId="
+ + BedrockModels.NOVA_MICRO_V1.model)
+ .log("Completions: ${body}")
+ .to(result);
+
+ from("direct:send_nova_pro")
+
.to("aws-bedrock:label?accessKey=RAW({{aws.manual.access.key}})&secretKey=RAW({{aws.manual.secret.key}})®ion=us-east-1&operation=invokeTextModel&modelId="
+ + BedrockModels.NOVA_PRO_V1.model)
+ .log("Completions: ${body}")
+ .to(result);
+
+ from("direct:send_jamba_15_mini")
+
.to("aws-bedrock:label?accessKey=RAW({{aws.manual.access.key}})&secretKey=RAW({{aws.manual.secret.key}})®ion=us-east-1&operation=invokeTextModel&modelId="
+ + BedrockModels.JAMBA_1_5_MINI.model)
+ .log("Completions: ${body}")
+ .to(result);
+
+ from("direct:send_cohere_command_r_plus")
+
.to("aws-bedrock:label?accessKey=RAW({{aws.manual.access.key}})&secretKey=RAW({{aws.manual.secret.key}})®ion=us-east-1&operation=invokeTextModel&modelId="
+ + BedrockModels.COHERE_COMMAND_R_PLUS.model)
+ .log("Completions: ${body}")
+ .to(result);
+
+ from("direct:send_llama31_70b_instruct")
+
.to("aws-bedrock:label?accessKey=RAW({{aws.manual.access.key}})&secretKey=RAW({{aws.manual.secret.key}})®ion=us-east-1&operation=invokeTextModel&modelId="
+ + BedrockModels.LLAMA3_1_70B_INSTRUCT.model)
+ .log("Completions: ${body}")
+ .to(result);
+
+ from("direct:send_llama32_11b_instruct")
+
.to("aws-bedrock:label?accessKey=RAW({{aws.manual.access.key}})&secretKey=RAW({{aws.manual.secret.key}})®ion=us-east-1&operation=invokeTextModel&modelId="
+ + BedrockModels.LLAMA3_2_11B_INSTRUCT.model)
+ .log("Completions: ${body}")
+ .to(result);
+
+ from("direct:send_anthropic_claude_35_sonnet_2")
+
.to("aws-bedrock:label?accessKey=RAW({{aws.manual.access.key}})&secretKey=RAW({{aws.manual.secret.key}})®ion=us-east-1&operation=invokeTextModel&modelId="
+ + BedrockModels.ANTROPHIC_CLAUDE_V35_2.model)
+ .log("Completions: ${body}")
+ .to(result);
+
+ from("direct:send_anthropic_claude_35_haiku")
+
.to("aws-bedrock:label?accessKey=RAW({{aws.manual.access.key}})&secretKey=RAW({{aws.manual.secret.key}})®ion=us-east-1&operation=invokeTextModel&modelId="
+ + BedrockModels.ANTROPHIC_CLAUDE_HAIKU_V35.model)
+ .log("Completions: ${body}")
+ .to(result);
+
+ from("direct:send_mistral_small_2402")
+
.to("aws-bedrock:label?accessKey=RAW({{aws.manual.access.key}})&secretKey=RAW({{aws.manual.secret.key}})®ion=us-east-1&operation=invokeTextModel&modelId="
+ + BedrockModels.MISTRAL_SMALL_2402.model)
+ .log("Completions: ${body}")
+ .to(result);
}
};
}