diff --git a/bundle/default-bundle/pom.xml b/bundle/default-bundle/pom.xml
index 2732e047b7..43c871371b 100644
--- a/bundle/default-bundle/pom.xml
+++ b/bundle/default-bundle/pom.xml
@@ -33,6 +33,10 @@
io.camunda.connector
connector-aws-lambda
+
+ io.camunda.connector
+ connector-aws-bedrock
+
io.camunda.connector
connector-google-drive
diff --git a/bundle/pom.xml b/bundle/pom.xml
index 563d961086..af08c6cd8a 100644
--- a/bundle/pom.xml
+++ b/bundle/pom.xml
@@ -59,6 +59,11 @@
connector-sendgrid
${project.version}
+
+ io.camunda.connector
+ connector-aws-bedrock
+ ${project.version}
+
io.camunda.connector
connector-aws-sns
diff --git a/connectors/aws/aws-base/pom.xml b/connectors/aws/aws-base/pom.xml
index 5eaa3f4f4d..91dd145e1d 100644
--- a/connectors/aws/aws-base/pom.xml
+++ b/connectors/aws/aws-base/pom.xml
@@ -18,7 +18,9 @@
Camunda Self-Managed Free Edition license
- https://camunda.com/legal/terms/cloud-terms-and-conditions/camunda-cloud-self-managed-free-edition-terms/
+
+ https://camunda.com/legal/terms/cloud-terms-and-conditions/camunda-cloud-self-managed-free-edition-terms/
+
Camunda Self-Managed Enterprise Edition license
@@ -31,7 +33,13 @@
aws-java-sdk-core
${version.aws-java-sdk}
-
+
+
+ software.amazon.awssdk
+ auth
+ ${version.software-aws-java-sdk}
+
+
com.amazonaws
aws-java-sdk-sagemakerruntime
diff --git a/connectors/aws/aws-base/src/main/java/io/camunda/connector/aws/CredentialsProviderSupportV2.java b/connectors/aws/aws-base/src/main/java/io/camunda/connector/aws/CredentialsProviderSupportV2.java
new file mode 100644
index 0000000000..4a8e79fa8f
--- /dev/null
+++ b/connectors/aws/aws-base/src/main/java/io/camunda/connector/aws/CredentialsProviderSupportV2.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH
+ * under one or more contributor license agreements. Licensed under a proprietary license.
+ * See the License.txt file for more information. You may not use this file
+ * except in compliance with the proprietary license.
+ */
+package io.camunda.connector.aws;
+
+import io.camunda.connector.aws.model.impl.AwsAuthentication;
+import io.camunda.connector.aws.model.impl.AwsBaseRequest;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import software.amazon.awssdk.auth.credentials.*;
+
+public class CredentialsProviderSupportV2 {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(CredentialsProviderSupportV2.class);
+
+ public static AwsCredentialsProvider credentialsProvider(AwsBaseRequest request) {
+ AwsAuthentication authentication = request.getAuthentication();
+ if (authentication instanceof AwsAuthentication.AwsStaticCredentialsAuthentication sca) {
+ LOGGER.debug("Using StaticCredentialsProvider for AWS authentication (using aws sdk v2)");
+ return StaticCredentialsProvider.create(
+ AwsBasicCredentials.create(sca.accessKey(), sca.secretKey()));
+ }
+ LOGGER.debug("Falling to DefaultCredentialsProvider for AWS authentication (using aws sdk v2)");
+ return DefaultCredentialsProvider.create();
+ }
+}
diff --git a/connectors/aws/aws-bedrock/LICENSE.txt b/connectors/aws/aws-bedrock/LICENSE.txt
new file mode 100644
index 0000000000..85fdd16e79
--- /dev/null
+++ b/connectors/aws/aws-bedrock/LICENSE.txt
@@ -0,0 +1,5 @@
+Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH under one or more contributor license agreements and licensed to you under a proprietary license.
+You may not use this file except in compliance with the proprietary license.
+The proprietary license can be either the Camunda Self-Managed Free Edition license (available on Camunda’s website) or the Camunda Self-Managed Enterprise Edition license (a copy you obtain when you contact Camunda).
+The Camunda Self-Managed Free Edition comes for free but only allows for usage of the software (file) in non-production environments.
+If you want to use the software (file) in production, you need to purchase the Camunda Self-Managed Enterprise Edition.
\ No newline at end of file
diff --git a/connectors/aws/aws-bedrock/element-templates/aws-bedrock-outbound-connector.json b/connectors/aws/aws-bedrock/element-templates/aws-bedrock-outbound-connector.json
new file mode 100644
index 0000000000..26c2ba8411
--- /dev/null
+++ b/connectors/aws/aws-bedrock/element-templates/aws-bedrock-outbound-connector.json
@@ -0,0 +1,349 @@
+{
+ "$schema" : "https://unpkg.com/@camunda/zeebe-element-templates-json-schema/resources/schema.json",
+ "name" : "AWS BedRock Outbound Connector",
+ "id" : "io.camunda.connectors.aws.bedrock.v1",
+ "description" : "Execute bedrock requests",
+ "documentationRef" : "https://docs.camunda.io/docs/",
+ "version" : 1,
+ "category" : {
+ "id" : "connectors",
+ "name" : "Connectors"
+ },
+ "appliesTo" : [ "bpmn:Task" ],
+ "elementType" : {
+ "value" : "bpmn:ServiceTask"
+ },
+ "groups" : [ {
+ "id" : "authentication",
+ "label" : "Authentication"
+ }, {
+ "id" : "configuration",
+ "label" : "Configuration"
+ }, {
+ "id" : "action",
+ "label" : "Action"
+ }, {
+ "id" : "invokeModel",
+ "label" : "Invoke Model"
+ }, {
+ "id" : "converse",
+ "label" : "Converse"
+ }, {
+ "id" : "output",
+ "label" : "Output mapping"
+ }, {
+ "id" : "error",
+ "label" : "Error handling"
+ }, {
+ "id" : "retries",
+ "label" : "Retries"
+ } ],
+ "properties" : [ {
+ "value" : "io.camunda:aws-bedrock:1",
+ "binding" : {
+ "property" : "type",
+ "type" : "zeebe:taskDefinition"
+ },
+ "type" : "Hidden"
+ }, {
+ "id" : "authentication.type",
+ "label" : "Authentication",
+ "description" : "Specify AWS authentication strategy. Learn more at the documentation page",
+ "value" : "credentials",
+ "group" : "authentication",
+ "binding" : {
+ "name" : "authentication.type",
+ "type" : "zeebe:input"
+ },
+ "type" : "Dropdown",
+ "choices" : [ {
+ "name" : "Default Credentials Chain (Hybrid/Self-Managed only)",
+ "value" : "defaultCredentialsChain"
+ }, {
+ "name" : "Credentials",
+ "value" : "credentials"
+ } ]
+ }, {
+ "id" : "authentication.accessKey",
+ "label" : "Access key",
+ "description" : "Provide an IAM access key tailored to a user, equipped with the necessary permissions",
+ "optional" : false,
+ "constraints" : {
+ "notEmpty" : true
+ },
+ "feel" : "optional",
+ "group" : "authentication",
+ "binding" : {
+ "name" : "authentication.accessKey",
+ "type" : "zeebe:input"
+ },
+ "condition" : {
+ "property" : "authentication.type",
+ "equals" : "credentials",
+ "type" : "simple"
+ },
+ "type" : "String"
+ }, {
+ "id" : "authentication.secretKey",
+ "label" : "Secret key",
+ "description" : "Provide a secret key of a user with permissions to invoke specified AWS Lambda function",
+ "optional" : false,
+ "constraints" : {
+ "notEmpty" : true
+ },
+ "feel" : "optional",
+ "group" : "authentication",
+ "binding" : {
+ "name" : "authentication.secretKey",
+ "type" : "zeebe:input"
+ },
+ "condition" : {
+ "property" : "authentication.type",
+ "equals" : "credentials",
+ "type" : "simple"
+ },
+ "type" : "String"
+ }, {
+ "id" : "configuration.region",
+ "label" : "Region",
+ "description" : "Specify the AWS region",
+ "optional" : false,
+ "constraints" : {
+ "notEmpty" : true
+ },
+ "feel" : "optional",
+ "group" : "configuration",
+ "binding" : {
+ "name" : "configuration.region",
+ "type" : "zeebe:input"
+ },
+ "type" : "String"
+ }, {
+ "id" : "configuration.endpoint",
+ "label" : "Endpoint",
+ "description" : "Specify endpoint if need to use custom endpoint",
+ "optional" : true,
+ "group" : "configuration",
+ "binding" : {
+ "name" : "configuration.endpoint",
+ "type" : "zeebe:input"
+ },
+ "type" : "Hidden"
+ }, {
+ "id" : "action",
+ "label" : "Action",
+ "value" : "invokeModel",
+ "group" : "action",
+ "binding" : {
+ "name" : "action",
+ "type" : "zeebe:input"
+ },
+ "type" : "Dropdown",
+ "choices" : [ {
+ "name" : "Invoke Model",
+ "value" : "invokeModel"
+ }, {
+ "name" : "Converse",
+ "value" : "converse"
+ } ]
+ }, {
+ "id" : "data.modelId0",
+ "label" : "Model id",
+ "optional" : false,
+ "constraints" : {
+ "notEmpty" : true
+ },
+ "feel" : "optional",
+ "group" : "invokeModel",
+ "binding" : {
+ "name" : "data.modelId",
+ "type" : "zeebe:input"
+ },
+ "condition" : {
+ "property" : "action",
+ "equals" : "invokeModel",
+ "type" : "simple"
+ },
+ "type" : "String"
+ }, {
+ "id" : "data.payload",
+ "label" : "Payload",
+ "optional" : false,
+ "constraints" : {
+ "notEmpty" : true
+ },
+ "feel" : "required",
+ "group" : "invokeModel",
+ "binding" : {
+ "name" : "data.payload",
+ "type" : "zeebe:input"
+ },
+ "condition" : {
+ "property" : "action",
+ "equals" : "invokeModel",
+ "type" : "simple"
+ },
+ "type" : "String"
+ }, {
+ "id" : "data.modelId1",
+ "label" : "Model id",
+ "optional" : false,
+ "constraints" : {
+ "notEmpty" : true
+ },
+ "feel" : "optional",
+ "group" : "converse",
+ "binding" : {
+ "name" : "data.modelId",
+ "type" : "zeebe:input"
+ },
+ "condition" : {
+ "property" : "action",
+ "equals" : "converse",
+ "type" : "simple"
+ },
+ "type" : "String"
+ }, {
+ "id" : "data.nextMessage",
+ "label" : "New Message",
+ "optional" : false,
+ "constraints" : {
+ "notEmpty" : true
+ },
+ "feel" : "optional",
+ "group" : "converse",
+ "binding" : {
+ "name" : "data.nextMessage",
+ "type" : "zeebe:input"
+ },
+ "condition" : {
+ "property" : "action",
+ "equals" : "converse",
+ "type" : "simple"
+ },
+ "type" : "String"
+ }, {
+ "id" : "data.messages",
+ "label" : "Messages History",
+ "optional" : true,
+ "feel" : "optional",
+ "group" : "converse",
+ "binding" : {
+ "name" : "data.messages",
+ "type" : "zeebe:input"
+ },
+ "condition" : {
+ "property" : "action",
+ "equals" : "converse",
+ "type" : "simple"
+ },
+ "type" : "String"
+ }, {
+ "id" : "data.maxTokens",
+ "label" : "Max token returned",
+ "optional" : true,
+ "feel" : "optional",
+ "group" : "converse",
+ "binding" : {
+ "name" : "data.maxTokens",
+ "type" : "zeebe:input"
+ },
+ "condition" : {
+ "property" : "action",
+ "equals" : "converse",
+ "type" : "simple"
+ },
+ "type" : "String"
+ }, {
+ "id" : "data.temperature",
+ "label" : "Temperature",
+ "optional" : true,
+ "feel" : "optional",
+ "group" : "converse",
+ "binding" : {
+ "name" : "data.temperature",
+ "type" : "zeebe:input"
+ },
+ "condition" : {
+ "property" : "action",
+ "equals" : "converse",
+ "type" : "simple"
+ },
+ "type" : "String"
+ }, {
+ "id" : "data.topP",
+ "label" : "top P",
+ "optional" : true,
+ "feel" : "optional",
+ "group" : "converse",
+ "binding" : {
+ "name" : "data.topP",
+ "type" : "zeebe:input"
+ },
+ "condition" : {
+ "property" : "action",
+ "equals" : "converse",
+ "type" : "simple"
+ },
+ "type" : "String"
+ }, {
+ "id" : "resultVariable",
+ "label" : "Result variable",
+ "description" : "Name of variable to store the response in",
+ "group" : "output",
+ "binding" : {
+ "key" : "resultVariable",
+ "type" : "zeebe:taskHeader"
+ },
+ "type" : "String"
+ }, {
+ "id" : "resultExpression",
+ "label" : "Result expression",
+ "description" : "Expression to map the response into process variables",
+ "feel" : "required",
+ "group" : "output",
+ "binding" : {
+ "key" : "resultExpression",
+ "type" : "zeebe:taskHeader"
+ },
+ "type" : "Text"
+ }, {
+ "id" : "errorExpression",
+ "label" : "Error expression",
+ "description" : "Expression to handle errors. Details in the documentation.",
+ "feel" : "required",
+ "group" : "error",
+ "binding" : {
+ "key" : "errorExpression",
+ "type" : "zeebe:taskHeader"
+ },
+ "type" : "Text"
+ }, {
+ "id" : "retryCount",
+ "label" : "Retries",
+ "description" : "Number of retries",
+ "value" : "3",
+ "feel" : "optional",
+ "group" : "retries",
+ "binding" : {
+ "property" : "retries",
+ "type" : "zeebe:taskDefinition"
+ },
+ "type" : "String"
+ }, {
+ "id" : "retryBackoff",
+ "label" : "Retry backoff",
+ "description" : "ISO-8601 duration to wait between retries",
+ "value" : "PT0S",
+ "feel" : "optional",
+ "group" : "retries",
+ "binding" : {
+ "key" : "retryBackoff",
+ "type" : "zeebe:taskHeader"
+ },
+ "type" : "String"
+ } ],
+ "icon" : {
+ "contents" : "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iODBweCIgaGVpZ2h0PSI4MHB4IiB2aWV3Qm94PSIwIDAgODAgODAiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CiAgICA8dGl0bGU+SWNvbi1BcmNoaXRlY3R1cmUvNjQvQXJjaF9BbWF6b24tQmVkcm9ja182NDwvdGl0bGU+CiAgICA8ZyBpZD0iSWNvbi1BcmNoaXRlY3R1cmUvNjQvQXJjaF9BbWF6b24tQmVkcm9ja182NCIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjEiIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0iZXZlbm9kZCI+CiAgICAgICAgPGcgaWQ9Ikljb24tQXJjaGl0ZWN0dXJlLUJHLzY0L01hY2hpbmUtTGVhcm5pbmciIGZpbGw9IiMwMUE4OEQiPgogICAgICAgICAgICA8cmVjdCBpZD0iUmVjdGFuZ2xlIiB4PSIwIiB5PSIwIiB3aWR0aD0iODAiIGhlaWdodD0iODAiPjwvcmVjdD4KICAgICAgICA8L2c+CiAgICAgICAgPGcgaWQ9Ikljb24tU2VydmljZS82NC9BbWF6b24tQmVkcm9ja182NCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTIuMDAwMDAwLCAxMi4wMDAwMDApIiBmaWxsPSIjRkZGRkZGIj4KICAgICAgICAgICAgPHBhdGggZD0iTTUyLDI2Ljk5OTg5MTggQzUwLjg5NywyNi45OTk4OTE4IDUwLDI2LjEwMjg5MTggNTAsMjQuOTk5ODkxOCBDNTAsMjMuODk2ODkxOCA1MC44OTcsMjIuOTk5ODkxOCA1MiwyMi45OTk4OTE4IEM1My4xMDMsMjIuOTk5ODkxOCA1NCwyMy44OTY4OTE4IDU0LDI0Ljk5OTg5MTggQzU0LDI2LjEwMjg5MTggNTMuMTAzLDI2Ljk5OTg5MTggNTIsMjYuOTk5ODkxOCBMNTIsMjYuOTk5ODkxOCBaIE0yMC4xMTMsNTMuOTA3ODkxOCBMMTYuODY1LDUyLjAxMzg5MTggTDIzLjUzLDQ3Ljg0Nzg5MTggTDIyLjQ3LDQ2LjE1MTg5MTggTDE0LjkxMyw1MC44NzQ4OTE4IEw5LDQ3LjQyNTg5MTggTDksMzguNTM0ODkxOCBMMTQuNTU1LDM0LjgzMTg5MTggTDEzLjQ0NSwzMy4xNjc4OTE4IEw3Ljk1OSwzNi44MjQ4OTE4IEwyLDMzLjQxOTg5MTggTDIsMjguNTc5ODkxOCBMOC40OTYsMjQuODY3ODkxOCBMNy41MDQsMjMuMTMxODkxOCBMMiwyNi4yNzY4OTE4IEwyLDIyLjU3OTg5MTggTDgsMTkuMTUxODkxOCBMMTQsMjIuNTc5ODkxOCBMMTQsMjYuNDMzODkxOCBMOS40ODUsMjkuMTQyODkxOCBMMTAuNTE1LDMwLjg1Njg5MTggTDE1LDI4LjE2NTg5MTggTDE5LjQ4NSwzMC44NTY4OTE4IEwyMC41MTUsMjkuMTQyODkxOCBMMTYsMjYuNDMzODkxOCBMMTYsMjIuNTM0ODkxOCBMMjEuNTU1LDE4LjgzMTg5MTggQzIxLjgzMywxOC42NDU4OTE4IDIyLDE4LjMzMzg5MTggMjIsMTcuOTk5ODkxOCBMMjIsMTAuOTk5ODkxOCBMMjAsMTAuOTk5ODkxOCBMMjAsMTcuNDY0ODkxOCBMMTQuOTU5LDIwLjgyNDg5MTggTDksMTcuNDE5ODkxOCBMOSw4LjU3Mzg5MTgxIEwxNCw1LjY1Nzg5MTgxIEwxNCwxMy45OTk4OTE4IEwxNiwxMy45OTk4OTE4IEwxNiw0LjQ5MDg5MTgxIEwyMC4xMTMsMi4wOTE4OTE4MSBMMjgsNC43MjA4OTE4MSBMMjgsMzMuNDMzODkxOCBMMTMuNDg1LDQyLjE0Mjg5MTggTDE0LjUxNSw0My44NTY4OTE4IEwyOCwzNS43NjU4OTE4IEwyOCw1MS4yNzg4OTE4IEwyMC4xMTMsNTMuOTA3ODkxOCBaIE01MCwzNy45OTk4OTE4IEM1MCwzOS4xMDI4OTE4IDQ5LjEwMywzOS45OTk4OTE4IDQ4LDM5Ljk5OTg5MTggQzQ2Ljg5NywzOS45OTk4OTE4IDQ2LDM5LjEwMjg5MTggNDYsMzcuOTk5ODkxOCBDNDYsMzYuODk2ODkxOCA0Ni44OTcsMzUuOTk5ODkxOCA0OCwzNS45OTk4OTE4IEM0OS4xMDMsMzUuOTk5ODkxOCA1MCwzNi44OTY4OTE4IDUwLDM3Ljk5OTg5MTggTDUwLDM3Ljk5OTg5MTggWiBNNDAsNDcuOTk5ODkxOCBDNDAsNDkuMTAyODkxOCAzOS4xMDMsNDkuOTk5ODkxOCAzOCw0OS45OTk4OTE4IEMzNi44OTcsNDkuOTk5ODkxOCAzNiw0OS4xMDI4OTE4IDM2LDQ3Ljk5OTg5MTggQzM2LDQ2Ljg5Njg5MTggMzYuODk3LDQ1Ljk5OTg5MTggMzgsNDUuOTk5ODkxOCBDMzkuMTAzLDQ1Ljk5OTg5MTggNDAsNDYuODk2ODkxOCA0MCw0Ny45OTk4OTE4IEw0MCw0Ny45OTk4OTE4IFogTTM5LDcuOTk5ODkxODEgQzM5LDYuODk2ODkxODEgMzkuODk3LDUuOTk5ODkxODEgNDEsNS45OTk4OTE4MSBDNDIuMTAzLDUuOTk5ODkxODEgNDMsNi44OTY4OTE4MSA0Myw3Ljk5OTg5MTgxIEM0Myw5LjEwMjg5MTgxIDQyLjEwMyw5Ljk5OTg5MTgxIDQxLDkuOTk5ODkxODEgQzM5Ljg5Nyw5Ljk5OTg5MTgxIDM5LDkuMTAyODkxODEgMzksNy45OTk4OTE4MSBMMzksNy45OTk4OTE4MSBaIE01MiwyMC45OTk4OTE4IEM1MC4xNDEsMjAuOTk5ODkxOCA0OC41ODksMjIuMjc5ODkxOCA0OC4xNDIsMjMuOTk5ODkxOCBMMzAsMjMuOTk5ODkxOCBMMzAsMTguOTk5ODkxOCBMNDEsMTguOTk5ODkxOCBDNDEuNTUzLDE4Ljk5OTg5MTggNDIsMTguNTUxODkxOCA0MiwxNy45OTk4OTE4IEw0MiwxMS44NTc4OTE4IEM0My43MiwxMS40MTA4OTE4IDQ1LDkuODU3ODkxODEgNDUsNy45OTk4OTE4MSBDNDUsNS43OTM4OTE4MSA0My4yMDYsMy45OTk4OTE4MSA0MSwzLjk5OTg5MTgxIEMzOC43OTQsMy45OTk4OTE4MSAzNyw1Ljc5Mzg5MTgxIDM3LDcuOTk5ODkxODEgQzM3LDkuODU3ODkxODEgMzguMjgsMTEuNDEwODkxOCA0MCwxMS44NTc4OTE4IEw0MCwxNi45OTk4OTE4IEwzMCwxNi45OTk4OTE4IEwzMCwzLjk5OTg5MTgxIEMzMCwzLjU2ODg5MTgxIDI5LjcyNSwzLjE4Nzg5MTgxIDI5LjMxNiwzLjA1MDg5MTgxIEwyMC4zMTYsMC4wNTA4OTE4MTEgQzIwLjA0MiwtMC4wMzkxMDgxODkgMTkuNzQ0LC0wLjAwOTEwODE4OTA0IDE5LjQ5NiwwLjEzNTg5MTgxMSBMNy40OTYsNy4xMzU4OTE4MSBDNy4xODgsNy4zMTQ4OTE4MSA3LDcuNjQ0ODkxODEgNyw3Ljk5OTg5MTgxIEw3LDE3LjQxOTg5MTggTDAuNTA0LDIxLjEzMTg5MTggQzAuMTkyLDIxLjMwOTg5MTggMCwyMS42NDA4OTE4IDAsMjEuOTk5ODkxOCBMMCwzMy45OTk4OTE4IEMwLDM0LjM1ODg5MTggMC4xOTIsMzQuNjg5ODkxOCAwLjUwNCwzNC44Njc4OTE4IEw3LDM4LjU3OTg5MTggTDcsNDcuOTk5ODkxOCBDNyw0OC4zNTQ4OTE4IDcuMTg4LDQ4LjY4NDg5MTggNy40OTYsNDguODYzODkxOCBMMTkuNDk2LDU1Ljg2Mzg5MTggQzE5LjY1LDU1Ljk1Mzg5MTggMTkuODI1LDU1Ljk5OTg5MTggMjAsNTUuOTk5ODkxOCBDMjAuMTA2LDU1Ljk5OTg5MTggMjAuMjEzLDU1Ljk4Mjg5MTggMjAuMzE2LDU1Ljk0ODg5MTggTDI5LjMxNiw1Mi45NDg4OTE4IEMyOS43MjUsNTIuODExODkxOCAzMCw1Mi40MzA4OTE4IDMwLDUxLjk5OTg5MTggTDMwLDM5Ljk5OTg5MTggTDM3LDM5Ljk5OTg5MTggTDM3LDQ0LjE0MTg5MTggQzM1LjI4LDQ0LjU4ODg5MTggMzQsNDYuMTQxODkxOCAzNCw0Ny45OTk4OTE4IEMzNCw1MC4yMDU4OTE4IDM1Ljc5NCw1MS45OTk4OTE4IDM4LDUxLjk5OTg5MTggQzQwLjIwNiw1MS45OTk4OTE4IDQyLDUwLjIwNTg5MTggNDIsNDcuOTk5ODkxOCBDNDIsNDYuMTQxODkxOCA0MC43Miw0NC41ODg4OTE4IDM5LDQ0LjE0MTg5MTggTDM5LDM4Ljk5OTg5MTggQzM5LDM4LjQ0Nzg5MTggMzguNTUzLDM3Ljk5OTg5MTggMzgsMzcuOTk5ODkxOCBMMzAsMzcuOTk5ODkxOCBMMzAsMzIuOTk5ODkxOCBMNDIuNSwzMi45OTk4OTE4IEw0NC42MzgsMzUuODQ5ODkxOCBDNDQuMjM5LDM2LjQ3MTg5MTggNDQsMzcuMjA2ODkxOCA0NCwzNy45OTk4OTE4IEM0NCw0MC4yMDU4OTE4IDQ1Ljc5NCw0MS45OTk4OTE4IDQ4LDQxLjk5OTg5MTggQzUwLjIwNiw0MS45OTk4OTE4IDUyLDQwLjIwNTg5MTggNTIsMzcuOTk5ODkxOCBDNTIsMzUuNzkzODkxOCA1MC4yMDYsMzMuOTk5ODkxOCA0OCwzMy45OTk4OTE4IEM0Ny4zMTYsMzMuOTk5ODkxOCA0Ni42ODIsMzQuMTg3ODkxOCA0Ni4xMTksMzQuNDkxODkxOCBMNDMuOCwzMS4zOTk4OTE4IEM0My42MTEsMzEuMTQ3ODkxOCA0My4zMTQsMzAuOTk5ODkxOCA0MywzMC45OTk4OTE4IEwzMCwzMC45OTk4OTE4IEwzMCwyNS45OTk4OTE4IEw0OC4xNDIsMjUuOTk5ODkxOCBDNDguNTg5LDI3LjcxOTg5MTggNTAuMTQxLDI4Ljk5OTg5MTggNTIsMjguOTk5ODkxOCBDNTQuMjA2LDI4Ljk5OTg5MTggNTYsMjcuMjA1ODkxOCA1NiwyNC45OTk4OTE4IEM1NiwyMi43OTM4OTE4IDU0LjIwNiwyMC45OTk4OTE4IDUyLDIwLjk5OTg5MTggTDUyLDIwLjk5OTg5MTggWiIgaWQ9IkZpbGwtMSI+PC9wYXRoPgogICAgICAgIDwvZz4KICAgIDwvZz4KPC9zdmc+"
+ }
+}
\ No newline at end of file
diff --git a/connectors/aws/aws-bedrock/element-templates/hybrid/aws-bedrock-outbound-connector-hybrid.json b/connectors/aws/aws-bedrock/element-templates/hybrid/aws-bedrock-outbound-connector-hybrid.json
new file mode 100644
index 0000000000..e4e504572f
--- /dev/null
+++ b/connectors/aws/aws-bedrock/element-templates/hybrid/aws-bedrock-outbound-connector-hybrid.json
@@ -0,0 +1,354 @@
+{
+ "$schema" : "https://unpkg.com/@camunda/zeebe-element-templates-json-schema/resources/schema.json",
+ "name" : "Hybrid AWS BedRock Outbound Connector",
+ "id" : "io.camunda.connectors.aws.bedrock.v1-hybrid",
+ "description" : "Execute bedrock requests",
+ "documentationRef" : "https://docs.camunda.io/docs/",
+ "version" : 1,
+ "category" : {
+ "id" : "connectors",
+ "name" : "Connectors"
+ },
+ "appliesTo" : [ "bpmn:Task" ],
+ "elementType" : {
+ "value" : "bpmn:ServiceTask"
+ },
+ "groups" : [ {
+ "id" : "taskDefinitionType",
+ "label" : "Task definition type"
+ }, {
+ "id" : "authentication",
+ "label" : "Authentication"
+ }, {
+ "id" : "configuration",
+ "label" : "Configuration"
+ }, {
+ "id" : "action",
+ "label" : "Action"
+ }, {
+ "id" : "invokeModel",
+ "label" : "Invoke Model"
+ }, {
+ "id" : "converse",
+ "label" : "Converse"
+ }, {
+ "id" : "output",
+ "label" : "Output mapping"
+ }, {
+ "id" : "error",
+ "label" : "Error handling"
+ }, {
+ "id" : "retries",
+ "label" : "Retries"
+ } ],
+ "properties" : [ {
+ "id" : "taskDefinitionType",
+ "value" : "io.camunda:aws-bedrock:1",
+ "group" : "taskDefinitionType",
+ "binding" : {
+ "property" : "type",
+ "type" : "zeebe:taskDefinition"
+ },
+ "type" : "String"
+ }, {
+ "id" : "authentication.type",
+ "label" : "Authentication",
+ "description" : "Specify AWS authentication strategy. Learn more at the documentation page",
+ "value" : "credentials",
+ "group" : "authentication",
+ "binding" : {
+ "name" : "authentication.type",
+ "type" : "zeebe:input"
+ },
+ "type" : "Dropdown",
+ "choices" : [ {
+ "name" : "Default Credentials Chain (Hybrid/Self-Managed only)",
+ "value" : "defaultCredentialsChain"
+ }, {
+ "name" : "Credentials",
+ "value" : "credentials"
+ } ]
+ }, {
+ "id" : "authentication.accessKey",
+ "label" : "Access key",
+ "description" : "Provide an IAM access key tailored to a user, equipped with the necessary permissions",
+ "optional" : false,
+ "constraints" : {
+ "notEmpty" : true
+ },
+ "feel" : "optional",
+ "group" : "authentication",
+ "binding" : {
+ "name" : "authentication.accessKey",
+ "type" : "zeebe:input"
+ },
+ "condition" : {
+ "property" : "authentication.type",
+ "equals" : "credentials",
+ "type" : "simple"
+ },
+ "type" : "String"
+ }, {
+ "id" : "authentication.secretKey",
+ "label" : "Secret key",
+ "description" : "Provide a secret key of a user with permissions to invoke specified AWS Lambda function",
+ "optional" : false,
+ "constraints" : {
+ "notEmpty" : true
+ },
+ "feel" : "optional",
+ "group" : "authentication",
+ "binding" : {
+ "name" : "authentication.secretKey",
+ "type" : "zeebe:input"
+ },
+ "condition" : {
+ "property" : "authentication.type",
+ "equals" : "credentials",
+ "type" : "simple"
+ },
+ "type" : "String"
+ }, {
+ "id" : "configuration.region",
+ "label" : "Region",
+ "description" : "Specify the AWS region",
+ "optional" : false,
+ "constraints" : {
+ "notEmpty" : true
+ },
+ "feel" : "optional",
+ "group" : "configuration",
+ "binding" : {
+ "name" : "configuration.region",
+ "type" : "zeebe:input"
+ },
+ "type" : "String"
+ }, {
+ "id" : "configuration.endpoint",
+ "label" : "Endpoint",
+ "description" : "Specify endpoint if need to use custom endpoint",
+ "optional" : true,
+ "group" : "configuration",
+ "binding" : {
+ "name" : "configuration.endpoint",
+ "type" : "zeebe:input"
+ },
+ "type" : "Hidden"
+ }, {
+ "id" : "action",
+ "label" : "Action",
+ "value" : "invokeModel",
+ "group" : "action",
+ "binding" : {
+ "name" : "action",
+ "type" : "zeebe:input"
+ },
+ "type" : "Dropdown",
+ "choices" : [ {
+ "name" : "Invoke Model",
+ "value" : "invokeModel"
+ }, {
+ "name" : "Converse",
+ "value" : "converse"
+ } ]
+ }, {
+ "id" : "data.modelId0",
+ "label" : "Model id",
+ "optional" : false,
+ "constraints" : {
+ "notEmpty" : true
+ },
+ "feel" : "optional",
+ "group" : "invokeModel",
+ "binding" : {
+ "name" : "data.modelId",
+ "type" : "zeebe:input"
+ },
+ "condition" : {
+ "property" : "action",
+ "equals" : "invokeModel",
+ "type" : "simple"
+ },
+ "type" : "String"
+ }, {
+ "id" : "data.payload",
+ "label" : "Payload",
+ "optional" : false,
+ "constraints" : {
+ "notEmpty" : true
+ },
+ "feel" : "required",
+ "group" : "invokeModel",
+ "binding" : {
+ "name" : "data.payload",
+ "type" : "zeebe:input"
+ },
+ "condition" : {
+ "property" : "action",
+ "equals" : "invokeModel",
+ "type" : "simple"
+ },
+ "type" : "String"
+ }, {
+ "id" : "data.modelId1",
+ "label" : "Model id",
+ "optional" : false,
+ "constraints" : {
+ "notEmpty" : true
+ },
+ "feel" : "optional",
+ "group" : "converse",
+ "binding" : {
+ "name" : "data.modelId",
+ "type" : "zeebe:input"
+ },
+ "condition" : {
+ "property" : "action",
+ "equals" : "converse",
+ "type" : "simple"
+ },
+ "type" : "String"
+ }, {
+ "id" : "data.nextMessage",
+ "label" : "New Message",
+ "optional" : false,
+ "constraints" : {
+ "notEmpty" : true
+ },
+ "feel" : "optional",
+ "group" : "converse",
+ "binding" : {
+ "name" : "data.nextMessage",
+ "type" : "zeebe:input"
+ },
+ "condition" : {
+ "property" : "action",
+ "equals" : "converse",
+ "type" : "simple"
+ },
+ "type" : "String"
+ }, {
+ "id" : "data.messages",
+ "label" : "Messages History",
+ "optional" : true,
+ "feel" : "optional",
+ "group" : "converse",
+ "binding" : {
+ "name" : "data.messages",
+ "type" : "zeebe:input"
+ },
+ "condition" : {
+ "property" : "action",
+ "equals" : "converse",
+ "type" : "simple"
+ },
+ "type" : "String"
+ }, {
+ "id" : "data.maxTokens",
+ "label" : "Max token returned",
+ "optional" : true,
+ "feel" : "optional",
+ "group" : "converse",
+ "binding" : {
+ "name" : "data.maxTokens",
+ "type" : "zeebe:input"
+ },
+ "condition" : {
+ "property" : "action",
+ "equals" : "converse",
+ "type" : "simple"
+ },
+ "type" : "String"
+ }, {
+ "id" : "data.temperature",
+ "label" : "Temperature",
+ "optional" : true,
+ "feel" : "optional",
+ "group" : "converse",
+ "binding" : {
+ "name" : "data.temperature",
+ "type" : "zeebe:input"
+ },
+ "condition" : {
+ "property" : "action",
+ "equals" : "converse",
+ "type" : "simple"
+ },
+ "type" : "String"
+ }, {
+ "id" : "data.topP",
+ "label" : "top P",
+ "optional" : true,
+ "feel" : "optional",
+ "group" : "converse",
+ "binding" : {
+ "name" : "data.topP",
+ "type" : "zeebe:input"
+ },
+ "condition" : {
+ "property" : "action",
+ "equals" : "converse",
+ "type" : "simple"
+ },
+ "type" : "String"
+ }, {
+ "id" : "resultVariable",
+ "label" : "Result variable",
+ "description" : "Name of variable to store the response in",
+ "group" : "output",
+ "binding" : {
+ "key" : "resultVariable",
+ "type" : "zeebe:taskHeader"
+ },
+ "type" : "String"
+ }, {
+ "id" : "resultExpression",
+ "label" : "Result expression",
+ "description" : "Expression to map the response into process variables",
+ "feel" : "required",
+ "group" : "output",
+ "binding" : {
+ "key" : "resultExpression",
+ "type" : "zeebe:taskHeader"
+ },
+ "type" : "Text"
+ }, {
+ "id" : "errorExpression",
+ "label" : "Error expression",
+ "description" : "Expression to handle errors. Details in the documentation.",
+ "feel" : "required",
+ "group" : "error",
+ "binding" : {
+ "key" : "errorExpression",
+ "type" : "zeebe:taskHeader"
+ },
+ "type" : "Text"
+ }, {
+ "id" : "retryCount",
+ "label" : "Retries",
+ "description" : "Number of retries",
+ "value" : "3",
+ "feel" : "optional",
+ "group" : "retries",
+ "binding" : {
+ "property" : "retries",
+ "type" : "zeebe:taskDefinition"
+ },
+ "type" : "String"
+ }, {
+ "id" : "retryBackoff",
+ "label" : "Retry backoff",
+ "description" : "ISO-8601 duration to wait between retries",
+ "value" : "PT0S",
+ "feel" : "optional",
+ "group" : "retries",
+ "binding" : {
+ "key" : "retryBackoff",
+ "type" : "zeebe:taskHeader"
+ },
+ "type" : "String"
+ } ],
+ "icon" : {
+ "contents" : "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iODBweCIgaGVpZ2h0PSI4MHB4IiB2aWV3Qm94PSIwIDAgODAgODAiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CiAgICA8dGl0bGU+SWNvbi1BcmNoaXRlY3R1cmUvNjQvQXJjaF9BbWF6b24tQmVkcm9ja182NDwvdGl0bGU+CiAgICA8ZyBpZD0iSWNvbi1BcmNoaXRlY3R1cmUvNjQvQXJjaF9BbWF6b24tQmVkcm9ja182NCIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjEiIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0iZXZlbm9kZCI+CiAgICAgICAgPGcgaWQ9Ikljb24tQXJjaGl0ZWN0dXJlLUJHLzY0L01hY2hpbmUtTGVhcm5pbmciIGZpbGw9IiMwMUE4OEQiPgogICAgICAgICAgICA8cmVjdCBpZD0iUmVjdGFuZ2xlIiB4PSIwIiB5PSIwIiB3aWR0aD0iODAiIGhlaWdodD0iODAiPjwvcmVjdD4KICAgICAgICA8L2c+CiAgICAgICAgPGcgaWQ9Ikljb24tU2VydmljZS82NC9BbWF6b24tQmVkcm9ja182NCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTIuMDAwMDAwLCAxMi4wMDAwMDApIiBmaWxsPSIjRkZGRkZGIj4KICAgICAgICAgICAgPHBhdGggZD0iTTUyLDI2Ljk5OTg5MTggQzUwLjg5NywyNi45OTk4OTE4IDUwLDI2LjEwMjg5MTggNTAsMjQuOTk5ODkxOCBDNTAsMjMuODk2ODkxOCA1MC44OTcsMjIuOTk5ODkxOCA1MiwyMi45OTk4OTE4IEM1My4xMDMsMjIuOTk5ODkxOCA1NCwyMy44OTY4OTE4IDU0LDI0Ljk5OTg5MTggQzU0LDI2LjEwMjg5MTggNTMuMTAzLDI2Ljk5OTg5MTggNTIsMjYuOTk5ODkxOCBMNTIsMjYuOTk5ODkxOCBaIE0yMC4xMTMsNTMuOTA3ODkxOCBMMTYuODY1LDUyLjAxMzg5MTggTDIzLjUzLDQ3Ljg0Nzg5MTggTDIyLjQ3LDQ2LjE1MTg5MTggTDE0LjkxMyw1MC44NzQ4OTE4IEw5LDQ3LjQyNTg5MTggTDksMzguNTM0ODkxOCBMMTQuNTU1LDM0LjgzMTg5MTggTDEzLjQ0NSwzMy4xNjc4OTE4IEw3Ljk1OSwzNi44MjQ4OTE4IEwyLDMzLjQxOTg5MTggTDIsMjguNTc5ODkxOCBMOC40OTYsMjQuODY3ODkxOCBMNy41MDQsMjMuMTMxODkxOCBMMiwyNi4yNzY4OTE4IEwyLDIyLjU3OTg5MTggTDgsMTkuMTUxODkxOCBMMTQsMjIuNTc5ODkxOCBMMTQsMjYuNDMzODkxOCBMOS40ODUsMjkuMTQyODkxOCBMMTAuNTE1LDMwLjg1Njg5MTggTDE1LDI4LjE2NTg5MTggTDE5LjQ4NSwzMC44NTY4OTE4IEwyMC41MTUsMjkuMTQyODkxOCBMMTYsMjYuNDMzODkxOCBMMTYsMjIuNTM0ODkxOCBMMjEuNTU1LDE4LjgzMTg5MTggQzIxLjgzMywxOC42NDU4OTE4IDIyLDE4LjMzMzg5MTggMjIsMTcuOTk5ODkxOCBMMjIsMTAuOTk5ODkxOCBMMjAsMTAuOTk5ODkxOCBMMjAsMTcuNDY0ODkxOCBMMTQuOTU5LDIwLjgyNDg5MTggTDksMTcuNDE5ODkxOCBMOSw4LjU3Mzg5MTgxIEwxNCw1LjY1Nzg5MTgxIEwxNCwxMy45OTk4OTE4IEwxNiwxMy45OTk4OTE4IEwxNiw0LjQ5MDg5MTgxIEwyMC4xMTMsMi4wOTE4OTE4MSBMMjgsNC43MjA4OTE4MSBMMjgsMzMuNDMzODkxOCBMMTMuNDg1LDQyLjE0Mjg5MTggTDE0LjUxNSw0My44NTY4OTE4IEwyOCwzNS43NjU4OTE4IEwyOCw1MS4yNzg4OTE4IEwyMC4xMTMsNTMuOTA3ODkxOCBaIE01MCwzNy45OTk4OTE4IEM1MCwzOS4xMDI4OTE4IDQ5LjEwMywzOS45OTk4OTE4IDQ4LDM5Ljk5OTg5MTggQzQ2Ljg5NywzOS45OTk4OTE4IDQ2LDM5LjEwMjg5MTggNDYsMzcuOTk5ODkxOCBDNDYsMzYuODk2ODkxOCA0Ni44OTcsMzUuOTk5ODkxOCA0OCwzNS45OTk4OTE4IEM0OS4xMDMsMzUuOTk5ODkxOCA1MCwzNi44OTY4OTE4IDUwLDM3Ljk5OTg5MTggTDUwLDM3Ljk5OTg5MTggWiBNNDAsNDcuOTk5ODkxOCBDNDAsNDkuMTAyODkxOCAzOS4xMDMsNDkuOTk5ODkxOCAzOCw0OS45OTk4OTE4IEMzNi44OTcsNDkuOTk5ODkxOCAzNiw0OS4xMDI4OTE4IDM2LDQ3Ljk5OTg5MTggQzM2LDQ2Ljg5Njg5MTggMzYuODk3LDQ1Ljk5OTg5MTggMzgsNDUuOTk5ODkxOCBDMzkuMTAzLDQ1Ljk5OTg5MTggNDAsNDYuODk2ODkxOCA0MCw0Ny45OTk4OTE4IEw0MCw0Ny45OTk4OTE4IFogTTM5LDcuOTk5ODkxODEgQzM5LDYuODk2ODkxODEgMzkuODk3LDUuOTk5ODkxODEgNDEsNS45OTk4OTE4MSBDNDIuMTAzLDUuOTk5ODkxODEgNDMsNi44OTY4OTE4MSA0Myw3Ljk5OTg5MTgxIEM0Myw5LjEwMjg5MTgxIDQyLjEwMyw5Ljk5OTg5MTgxIDQxLDkuOTk5ODkxODEgQzM5Ljg5Nyw5Ljk5OTg5MTgxIDM5LDkuMTAyODkxODEgMzksNy45OTk4OTE4MSBMMzksNy45OTk4OTE4MSBaIE01MiwyMC45OTk4OTE4IEM1MC4xNDEsMjAuOTk5ODkxOCA0OC41ODksMjIuMjc5ODkxOCA0OC4xNDIsMjMuOTk5ODkxOCBMMzAsMjMuOTk5ODkxOCBMMzAsMTguOTk5ODkxOCBMNDEsMTguOTk5ODkxOCBDNDEuNTUzLDE4Ljk5OTg5MTggNDIsMTguNTUxODkxOCA0MiwxNy45OTk4OTE4IEw0MiwxMS44NTc4OTE4IEM0My43MiwxMS40MTA4OTE4IDQ1LDkuODU3ODkxODEgNDUsNy45OTk4OTE4MSBDNDUsNS43OTM4OTE4MSA0My4yMDYsMy45OTk4OTE4MSA0MSwzLjk5OTg5MTgxIEMzOC43OTQsMy45OTk4OTE4MSAzNyw1Ljc5Mzg5MTgxIDM3LDcuOTk5ODkxODEgQzM3LDkuODU3ODkxODEgMzguMjgsMTEuNDEwODkxOCA0MCwxMS44NTc4OTE4IEw0MCwxNi45OTk4OTE4IEwzMCwxNi45OTk4OTE4IEwzMCwzLjk5OTg5MTgxIEMzMCwzLjU2ODg5MTgxIDI5LjcyNSwzLjE4Nzg5MTgxIDI5LjMxNiwzLjA1MDg5MTgxIEwyMC4zMTYsMC4wNTA4OTE4MTEgQzIwLjA0MiwtMC4wMzkxMDgxODkgMTkuNzQ0LC0wLjAwOTEwODE4OTA0IDE5LjQ5NiwwLjEzNTg5MTgxMSBMNy40OTYsNy4xMzU4OTE4MSBDNy4xODgsNy4zMTQ4OTE4MSA3LDcuNjQ0ODkxODEgNyw3Ljk5OTg5MTgxIEw3LDE3LjQxOTg5MTggTDAuNTA0LDIxLjEzMTg5MTggQzAuMTkyLDIxLjMwOTg5MTggMCwyMS42NDA4OTE4IDAsMjEuOTk5ODkxOCBMMCwzMy45OTk4OTE4IEMwLDM0LjM1ODg5MTggMC4xOTIsMzQuNjg5ODkxOCAwLjUwNCwzNC44Njc4OTE4IEw3LDM4LjU3OTg5MTggTDcsNDcuOTk5ODkxOCBDNyw0OC4zNTQ4OTE4IDcuMTg4LDQ4LjY4NDg5MTggNy40OTYsNDguODYzODkxOCBMMTkuNDk2LDU1Ljg2Mzg5MTggQzE5LjY1LDU1Ljk1Mzg5MTggMTkuODI1LDU1Ljk5OTg5MTggMjAsNTUuOTk5ODkxOCBDMjAuMTA2LDU1Ljk5OTg5MTggMjAuMjEzLDU1Ljk4Mjg5MTggMjAuMzE2LDU1Ljk0ODg5MTggTDI5LjMxNiw1Mi45NDg4OTE4IEMyOS43MjUsNTIuODExODkxOCAzMCw1Mi40MzA4OTE4IDMwLDUxLjk5OTg5MTggTDMwLDM5Ljk5OTg5MTggTDM3LDM5Ljk5OTg5MTggTDM3LDQ0LjE0MTg5MTggQzM1LjI4LDQ0LjU4ODg5MTggMzQsNDYuMTQxODkxOCAzNCw0Ny45OTk4OTE4IEMzNCw1MC4yMDU4OTE4IDM1Ljc5NCw1MS45OTk4OTE4IDM4LDUxLjk5OTg5MTggQzQwLjIwNiw1MS45OTk4OTE4IDQyLDUwLjIwNTg5MTggNDIsNDcuOTk5ODkxOCBDNDIsNDYuMTQxODkxOCA0MC43Miw0NC41ODg4OTE4IDM5LDQ0LjE0MTg5MTggTDM5LDM4Ljk5OTg5MTggQzM5LDM4LjQ0Nzg5MTggMzguNTUzLDM3Ljk5OTg5MTggMzgsMzcuOTk5ODkxOCBMMzAsMzcuOTk5ODkxOCBMMzAsMzIuOTk5ODkxOCBMNDIuNSwzMi45OTk4OTE4IEw0NC42MzgsMzUuODQ5ODkxOCBDNDQuMjM5LDM2LjQ3MTg5MTggNDQsMzcuMjA2ODkxOCA0NCwzNy45OTk4OTE4IEM0NCw0MC4yMDU4OTE4IDQ1Ljc5NCw0MS45OTk4OTE4IDQ4LDQxLjk5OTg5MTggQzUwLjIwNiw0MS45OTk4OTE4IDUyLDQwLjIwNTg5MTggNTIsMzcuOTk5ODkxOCBDNTIsMzUuNzkzODkxOCA1MC4yMDYsMzMuOTk5ODkxOCA0OCwzMy45OTk4OTE4IEM0Ny4zMTYsMzMuOTk5ODkxOCA0Ni42ODIsMzQuMTg3ODkxOCA0Ni4xMTksMzQuNDkxODkxOCBMNDMuOCwzMS4zOTk4OTE4IEM0My42MTEsMzEuMTQ3ODkxOCA0My4zMTQsMzAuOTk5ODkxOCA0MywzMC45OTk4OTE4IEwzMCwzMC45OTk4OTE4IEwzMCwyNS45OTk4OTE4IEw0OC4xNDIsMjUuOTk5ODkxOCBDNDguNTg5LDI3LjcxOTg5MTggNTAuMTQxLDI4Ljk5OTg5MTggNTIsMjguOTk5ODkxOCBDNTQuMjA2LDI4Ljk5OTg5MTggNTYsMjcuMjA1ODkxOCA1NiwyNC45OTk4OTE4IEM1NiwyMi43OTM4OTE4IDU0LjIwNiwyMC45OTk4OTE4IDUyLDIwLjk5OTg5MTggTDUyLDIwLjk5OTg5MTggWiIgaWQ9IkZpbGwtMSI+PC9wYXRoPgogICAgICAgIDwvZz4KICAgIDwvZz4KPC9zdmc+"
+ }
+}
\ No newline at end of file
diff --git a/connectors/aws/aws-bedrock/pom.xml b/connectors/aws/aws-bedrock/pom.xml
new file mode 100644
index 0000000000..60d512493f
--- /dev/null
+++ b/connectors/aws/aws-bedrock/pom.xml
@@ -0,0 +1,70 @@
+
+
+ 4.0.0
+
+ io.camunda.connector
+ connector-aws-parent
+ 8.6.0-SNAPSHOT
+
+
+
+ connector-aws-bedrock
+ Camunda AWS Bedrock Connector
+ connector-aws-bedrock
+ jar
+
+
+
+ Camunda Self-Managed Free Edition license
+ https://camunda.com/legal/terms/cloud-terms-and-conditions/camunda-cloud-self-managed-free-edition-terms/
+
+
+ Camunda Self-Managed Enterprise Edition license
+
+
+
+
+
+ io.camunda.connector
+ connector-aws-base
+ ${project.version}
+
+
+
+ software.amazon.awssdk
+ bedrockruntime
+ ${version.software-aws-java-sdk}
+
+
+
+
+
+
+ io.camunda.connector
+ element-template-generator-maven-plugin
+ ${project.version}
+
+
+
+ io.camunda.connector.aws.bedrock.BedrockConnectorFunction
+
+
+ io.camunda.connectors.aws.bedrock.v1
+ aws-bedrock-outbound-connector.json
+
+
+ true
+
+
+
+ io.camunda.connector:connector-aws-base
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/connectors/aws/aws-bedrock/src/main/java/io/camunda/connector/aws/bedrock/BedrockConnectorFunction.java b/connectors/aws/aws-bedrock/src/main/java/io/camunda/connector/aws/bedrock/BedrockConnectorFunction.java
new file mode 100644
index 0000000000..5991241b51
--- /dev/null
+++ b/connectors/aws/aws-bedrock/src/main/java/io/camunda/connector/aws/bedrock/BedrockConnectorFunction.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH
+ * under one or more contributor license agreements. Licensed under a proprietary license.
+ * See the License.txt file for more information. You may not use this file
+ * except in compliance with the proprietary license.
+ */
+package io.camunda.connector.aws.bedrock;
+
+import io.camunda.connector.api.annotation.OutboundConnector;
+import io.camunda.connector.api.outbound.OutboundConnectorContext;
+import io.camunda.connector.api.outbound.OutboundConnectorFunction;
+import io.camunda.connector.aws.bedrock.core.BedrockExecutor;
+import io.camunda.connector.aws.bedrock.model.BedrockRequest;
+import io.camunda.connector.generator.java.annotation.ElementTemplate;
+
+@OutboundConnector(
+ name = "AWS BedRock",
+ inputVariables = {"authentication", "configuration", "action", "data"},
+ type = "io.camunda:aws-bedrock:1")
+@ElementTemplate(
+ id = "io.camunda.connectors.aws.bedrock.v1",
+ name = "AWS BedRock Outbound Connector",
+ description = "Execute bedrock requests",
+ inputDataClass = BedrockRequest.class,
+ version = 1,
+ propertyGroups = {
+ @ElementTemplate.PropertyGroup(id = "authentication", label = "Authentication"),
+ @ElementTemplate.PropertyGroup(id = "configuration", label = "Configuration"),
+ @ElementTemplate.PropertyGroup(id = "action", label = "Action"),
+ @ElementTemplate.PropertyGroup(id = "invokeModel", label = "Invoke Model"),
+ @ElementTemplate.PropertyGroup(id = "converse", label = "Converse"),
+ },
+ documentationRef = "https://docs.camunda.io/docs/",
+ icon = "icon.svg")
+public class BedrockConnectorFunction implements OutboundConnectorFunction {
+
+ public BedrockConnectorFunction() {}
+
+ @Override
+ public Object execute(OutboundConnectorContext context) {
+ BedrockRequest bedrockRequest = context.bindVariables(BedrockRequest.class);
+ return BedrockExecutor.create(bedrockRequest).execute();
+ }
+}
diff --git a/connectors/aws/aws-bedrock/src/main/java/io/camunda/connector/aws/bedrock/core/BedrockExecutor.java b/connectors/aws/aws-bedrock/src/main/java/io/camunda/connector/aws/bedrock/core/BedrockExecutor.java
new file mode 100644
index 0000000000..ddf4d4f64c
--- /dev/null
+++ b/connectors/aws/aws-bedrock/src/main/java/io/camunda/connector/aws/bedrock/core/BedrockExecutor.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH
+ * under one or more contributor license agreements. Licensed under a proprietary license.
+ * See the License.txt file for more information. You may not use this file
+ * except in compliance with the proprietary license.
+ */
+package io.camunda.connector.aws.bedrock.core;
+
+import io.camunda.connector.aws.CredentialsProviderSupportV2;
+import io.camunda.connector.aws.ObjectMapperSupplier;
+import io.camunda.connector.aws.bedrock.model.BedrockRequest;
+import io.camunda.connector.aws.bedrock.model.BedrockResponse;
+import io.camunda.connector.aws.bedrock.model.RequestData;
+import software.amazon.awssdk.regions.Region;
+import software.amazon.awssdk.services.bedrockruntime.BedrockRuntimeClient;
+
+public class BedrockExecutor {
+
+ private final BedrockRuntimeClient bedrockRuntimeClient;
+ private final RequestData requestData;
+
+ public BedrockExecutor(BedrockRuntimeClient bedrockRuntimeClient, RequestData requestData) {
+ this.bedrockRuntimeClient = bedrockRuntimeClient;
+ this.requestData = requestData;
+ }
+
+ public static BedrockExecutor create(BedrockRequest bedrockRequest) {
+ return new BedrockExecutor(
+ BedrockRuntimeClient.builder()
+ .credentialsProvider(CredentialsProviderSupportV2.credentialsProvider(bedrockRequest))
+ .region(Region.of(bedrockRequest.getConfiguration().region()))
+ .build(),
+ bedrockRequest.getData());
+ }
+
+ public BedrockResponse execute() {
+ return this.requestData.execute(bedrockRuntimeClient, ObjectMapperSupplier.getMapperInstance());
+ }
+}
diff --git a/connectors/aws/aws-bedrock/src/main/java/io/camunda/connector/aws/bedrock/model/BedrockRequest.java b/connectors/aws/aws-bedrock/src/main/java/io/camunda/connector/aws/bedrock/model/BedrockRequest.java
new file mode 100644
index 0000000000..7f7197d4db
--- /dev/null
+++ b/connectors/aws/aws-bedrock/src/main/java/io/camunda/connector/aws/bedrock/model/BedrockRequest.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH
+ * under one or more contributor license agreements. Licensed under a proprietary license.
+ * See the License.txt file for more information. You may not use this file
+ * except in compliance with the proprietary license.
+ */
+package io.camunda.connector.aws.bedrock.model;
+
+import com.fasterxml.jackson.annotation.JsonSubTypes;
+import com.fasterxml.jackson.annotation.JsonTypeInfo;
+import io.camunda.connector.aws.model.impl.AwsBaseRequest;
+import io.camunda.connector.generator.java.annotation.NestedProperties;
+import jakarta.validation.Valid;
+import jakarta.validation.constraints.NotNull;
+
+public class BedrockRequest extends AwsBaseRequest {
+ @JsonTypeInfo(
+ use = JsonTypeInfo.Id.NAME,
+ include = JsonTypeInfo.As.EXTERNAL_PROPERTY,
+ property = "action")
+ @JsonSubTypes(
+ value = {
+ @JsonSubTypes.Type(value = ConverseData.class, name = "converse"),
+ @JsonSubTypes.Type(value = InvokeModelData.class, name = "invokeModel"),
+ })
+ @Valid
+ @NotNull
+ @NestedProperties(addNestedPath = false)
+ private RequestData data;
+
+ public BedrockRequest() {}
+
+ @Valid
+ @NotNull
+ public RequestData getData() {
+ return data;
+ }
+}
diff --git a/connectors/aws/aws-bedrock/src/main/java/io/camunda/connector/aws/bedrock/model/BedrockResponse.java b/connectors/aws/aws-bedrock/src/main/java/io/camunda/connector/aws/bedrock/model/BedrockResponse.java
new file mode 100644
index 0000000000..fdd984a83b
--- /dev/null
+++ b/connectors/aws/aws-bedrock/src/main/java/io/camunda/connector/aws/bedrock/model/BedrockResponse.java
@@ -0,0 +1,9 @@
+/*
+ * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH
+ * under one or more contributor license agreements. Licensed under a proprietary license.
+ * See the License.txt file for more information. You may not use this file
+ * except in compliance with the proprietary license.
+ */
+package io.camunda.connector.aws.bedrock.model;
+
+public interface BedrockResponse {}
diff --git a/connectors/aws/aws-bedrock/src/main/java/io/camunda/connector/aws/bedrock/model/ConverseData.java b/connectors/aws/aws-bedrock/src/main/java/io/camunda/connector/aws/bedrock/model/ConverseData.java
new file mode 100644
index 0000000000..f7daeb50f4
--- /dev/null
+++ b/connectors/aws/aws-bedrock/src/main/java/io/camunda/connector/aws/bedrock/model/ConverseData.java
@@ -0,0 +1,176 @@
+/*
+ * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH
+ * under one or more contributor license agreements. Licensed under a proprietary license.
+ * See the License.txt file for more information. You may not use this file
+ * except in compliance with the proprietary license.
+ */
+package io.camunda.connector.aws.bedrock.model;
+
+import com.fasterxml.jackson.annotation.JsonSetter;
+import com.fasterxml.jackson.annotation.Nulls;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import io.camunda.connector.generator.dsl.Property;
+import io.camunda.connector.generator.java.annotation.TemplateProperty;
+import io.camunda.connector.generator.java.annotation.TemplateSubType;
+import jakarta.validation.Valid;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import software.amazon.awssdk.services.bedrockruntime.BedrockRuntimeClient;
+import software.amazon.awssdk.services.bedrockruntime.model.ContentBlock;
+import software.amazon.awssdk.services.bedrockruntime.model.ConversationRole;
+import software.amazon.awssdk.services.bedrockruntime.model.ConverseResponse;
+import software.amazon.awssdk.services.bedrockruntime.model.Message;
+
+@TemplateSubType(id = "converse", label = "Converse")
+public final class ConverseData implements RequestData {
+
+ @TemplateProperty(
+ label = "Model id",
+ group = "converse",
+ id = "data.modelId1",
+ feel = Property.FeelMode.optional,
+ binding = @TemplateProperty.PropertyBinding(name = "data.modelId"))
+ @Valid
+ @NotNull
+ private String modelId;
+
+ @TemplateProperty(
+ label = "New Message",
+ group = "converse",
+ id = "data.nextMessage",
+ feel = Property.FeelMode.optional,
+ binding = @TemplateProperty.PropertyBinding(name = "data.nextMessage"))
+ @Valid
+ @NotBlank
+ private String nextMessage;
+
+ @TemplateProperty(
+ label = "Messages History",
+ group = "converse",
+ id = "data.messages",
+ feel = Property.FeelMode.optional,
+ optional = true,
+ binding = @TemplateProperty.PropertyBinding(name = "data.messages"))
+ @Valid
+ @JsonSetter(nulls = Nulls.SKIP)
+ private List messages = new ArrayList<>();
+
+ @TemplateProperty(
+ label = "Max token returned",
+ group = "converse",
+ id = "data.maxTokens",
+ feel = Property.FeelMode.optional,
+ optional = true,
+ binding = @TemplateProperty.PropertyBinding(name = "data.maxTokens"))
+ private Integer maxTokens = 512;
+
+ @TemplateProperty(
+ label = "Temperature",
+ group = "converse",
+ id = "data.temperature",
+ feel = Property.FeelMode.optional,
+ optional = true,
+ binding = @TemplateProperty.PropertyBinding(name = "data.temperature"))
+ private Float temperature = 0.5f;
+
+ @TemplateProperty(
+ label = "top P",
+ group = "converse",
+ id = "data.topP",
+ feel = Property.FeelMode.optional,
+ optional = true,
+ binding = @TemplateProperty.PropertyBinding(name = "data.topP"))
+ private Float topP = 0.9f;
+
+ @Override
+ public BedrockResponse execute(
+ BedrockRuntimeClient bedrockRuntimeClient, ObjectMapper mapperInstance) {
+ this.messages.add(new PreviousMessage(this.nextMessage, ConversationRole.USER.name()));
+ Message.Builder messageBuilder = Message.builder();
+ List messages =
+ this.messages.stream()
+ .map(
+ message ->
+ messageBuilder
+ .role(ConversationRole.valueOf(message.role()))
+ .content(ContentBlock.fromText(message.message()))
+ .build())
+ .toList();
+ ConverseResponse converseResponse =
+ bedrockRuntimeClient.converse(
+ builder ->
+ builder
+ .modelId(this.modelId)
+ .messages(messages)
+ .inferenceConfig(
+ config ->
+ config
+ .temperature(this.temperature)
+ .maxTokens(this.maxTokens)
+ .topP(this.topP)
+ .build()));
+ String newMessage = converseResponse.output().message().content().getFirst().text();
+ this.messages.add(new PreviousMessage(newMessage, ConversationRole.ASSISTANT.name()));
+ return new ConverseWrapperResponse(this.messages, newMessage);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ ConverseData that = (ConverseData) o;
+ return Objects.equals(modelId, that.modelId)
+ && Objects.equals(nextMessage, that.nextMessage)
+ && Objects.equals(messages, that.messages)
+ && Objects.equals(maxTokens, that.maxTokens)
+ && Objects.equals(temperature, that.temperature)
+ && Objects.equals(topP, that.topP);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(modelId, nextMessage, messages, maxTokens, temperature, topP);
+ }
+
+ public void setModelId(@Valid @NotNull String modelId) {
+ this.modelId = modelId;
+ }
+
+ public void setNextMessage(@Valid @NotBlank String nextMessage) {
+ this.nextMessage = nextMessage;
+ }
+
+ public void setMessages(@Valid List messages) {
+ this.messages = messages;
+ }
+
+ public void setMaxTokens(Integer maxTokens) {
+ this.maxTokens = maxTokens;
+ }
+
+ public void setTemperature(Float temperature) {
+ this.temperature = temperature;
+ }
+
+ public void setTopP(Float topP) {
+ this.topP = topP;
+ }
+
+ @Override
+ public String toString() {
+ return "ConverseData{"
+ + "modelId='"
+ + modelId
+ + '\''
+ + ", maxTokens="
+ + maxTokens
+ + ", temperature="
+ + temperature
+ + ", topP="
+ + topP
+ + '}';
+ }
+}
diff --git a/connectors/aws/aws-bedrock/src/main/java/io/camunda/connector/aws/bedrock/model/ConverseWrapperResponse.java b/connectors/aws/aws-bedrock/src/main/java/io/camunda/connector/aws/bedrock/model/ConverseWrapperResponse.java
new file mode 100644
index 0000000000..d3f0659d83
--- /dev/null
+++ b/connectors/aws/aws-bedrock/src/main/java/io/camunda/connector/aws/bedrock/model/ConverseWrapperResponse.java
@@ -0,0 +1,12 @@
+/*
+ * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH
+ * under one or more contributor license agreements. Licensed under a proprietary license.
+ * See the License.txt file for more information. You may not use this file
+ * except in compliance with the proprietary license.
+ */
+package io.camunda.connector.aws.bedrock.model;
+
+import java.util.List;
+
+public record ConverseWrapperResponse(List messagesHistory, String newMessage)
+ implements BedrockResponse {}
diff --git a/connectors/aws/aws-bedrock/src/main/java/io/camunda/connector/aws/bedrock/model/InvokeModelData.java b/connectors/aws/aws-bedrock/src/main/java/io/camunda/connector/aws/bedrock/model/InvokeModelData.java
new file mode 100644
index 0000000000..2dcc25d620
--- /dev/null
+++ b/connectors/aws/aws-bedrock/src/main/java/io/camunda/connector/aws/bedrock/model/InvokeModelData.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH
+ * under one or more contributor license agreements. Licensed under a proprietary license.
+ * See the License.txt file for more information. You may not use this file
+ * except in compliance with the proprietary license.
+ */
+package io.camunda.connector.aws.bedrock.model;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import io.camunda.connector.generator.dsl.Property;
+import io.camunda.connector.generator.java.annotation.TemplateProperty;
+import io.camunda.connector.generator.java.annotation.TemplateSubType;
+import jakarta.validation.Valid;
+import jakarta.validation.constraints.NotNull;
+import java.util.Objects;
+import software.amazon.awssdk.core.SdkBytes;
+import software.amazon.awssdk.services.bedrockruntime.BedrockRuntimeClient;
+
+@TemplateSubType(id = "invokeModel", label = "Invoke Model")
+public final class InvokeModelData implements RequestData {
+
+ @TemplateProperty(
+ label = "Model id",
+ group = "invokeModel",
+ id = "data.modelId0",
+ feel = Property.FeelMode.optional,
+ binding = @TemplateProperty.PropertyBinding(name = "data.modelId"))
+ @Valid
+ @NotNull
+ String modelId;
+
+ @TemplateProperty(
+ label = "Payload",
+ group = "invokeModel",
+ id = "data.payload",
+ feel = Property.FeelMode.required,
+ binding = @TemplateProperty.PropertyBinding(name = "data.payload"))
+ @Valid
+ @NotNull
+ Object payload;
+
+ @Override
+ public BedrockResponse execute(
+ BedrockRuntimeClient bedrockRuntimeClient, ObjectMapper mapperInstance) {
+ try {
+ String body = mapperInstance.writeValueAsString(this.payload);
+ String response =
+ bedrockRuntimeClient
+ .invokeModel(
+ builder -> builder.body(SdkBytes.fromUtf8String(body)).modelId(this.modelId))
+ .body()
+ .asUtf8String();
+ return new InvokeModelWrappedResponse(mapperInstance.readValue(response, Object.class));
+ } catch (JsonProcessingException e) {
+ throw new RuntimeException(e.getOriginalMessage(), e);
+ }
+ }
+
+ public void setModelId(@Valid @NotNull String modelId) {
+ this.modelId = modelId;
+ }
+
+ public void setPayload(@Valid @NotNull Object payload) {
+ this.payload = payload;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ InvokeModelData that = (InvokeModelData) o;
+ return Objects.equals(modelId, that.modelId) && Objects.equals(payload, that.payload);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(modelId, payload);
+ }
+
+ @Override
+ public String toString() {
+ return "InvokeModelData{" + "modelId='" + modelId + '\'' + '}';
+ }
+}
diff --git a/connectors/aws/aws-bedrock/src/main/java/io/camunda/connector/aws/bedrock/model/InvokeModelWrappedResponse.java b/connectors/aws/aws-bedrock/src/main/java/io/camunda/connector/aws/bedrock/model/InvokeModelWrappedResponse.java
new file mode 100644
index 0000000000..10635930c7
--- /dev/null
+++ b/connectors/aws/aws-bedrock/src/main/java/io/camunda/connector/aws/bedrock/model/InvokeModelWrappedResponse.java
@@ -0,0 +1,9 @@
+/*
+ * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH
+ * under one or more contributor license agreements. Licensed under a proprietary license.
+ * See the License.txt file for more information. You may not use this file
+ * except in compliance with the proprietary license.
+ */
+package io.camunda.connector.aws.bedrock.model;
+
+public record InvokeModelWrappedResponse(Object body) implements BedrockResponse {}
diff --git a/connectors/aws/aws-bedrock/src/main/java/io/camunda/connector/aws/bedrock/model/PreviousMessage.java b/connectors/aws/aws-bedrock/src/main/java/io/camunda/connector/aws/bedrock/model/PreviousMessage.java
new file mode 100644
index 0000000000..1c6c0aacfb
--- /dev/null
+++ b/connectors/aws/aws-bedrock/src/main/java/io/camunda/connector/aws/bedrock/model/PreviousMessage.java
@@ -0,0 +1,9 @@
+/*
+ * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH
+ * under one or more contributor license agreements. Licensed under a proprietary license.
+ * See the License.txt file for more information. You may not use this file
+ * except in compliance with the proprietary license.
+ */
+package io.camunda.connector.aws.bedrock.model;
+
+public record PreviousMessage(String message, String role) {}
diff --git a/connectors/aws/aws-bedrock/src/main/java/io/camunda/connector/aws/bedrock/model/RequestData.java b/connectors/aws/aws-bedrock/src/main/java/io/camunda/connector/aws/bedrock/model/RequestData.java
new file mode 100644
index 0000000000..5b2e1edb79
--- /dev/null
+++ b/connectors/aws/aws-bedrock/src/main/java/io/camunda/connector/aws/bedrock/model/RequestData.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH
+ * under one or more contributor license agreements. Licensed under a proprietary license.
+ * See the License.txt file for more information. You may not use this file
+ * except in compliance with the proprietary license.
+ */
+package io.camunda.connector.aws.bedrock.model;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import io.camunda.connector.generator.java.annotation.TemplateDiscriminatorProperty;
+import io.camunda.connector.generator.java.annotation.TemplateSubType;
+import software.amazon.awssdk.services.bedrockruntime.BedrockRuntimeClient;
+
+@TemplateDiscriminatorProperty(
+ label = "Action",
+ group = "action",
+ name = "action",
+ defaultValue = "invokeModel")
+@TemplateSubType(id = "action", label = "Action")
+public sealed interface RequestData permits InvokeModelData, ConverseData {
+ BedrockResponse execute(BedrockRuntimeClient bedrockRuntimeClient, ObjectMapper mapperInstance);
+}
diff --git a/connectors/aws/aws-bedrock/src/main/resources/META-INF/services/io.camunda.connector.api.outbound.OutboundConnectorFunction b/connectors/aws/aws-bedrock/src/main/resources/META-INF/services/io.camunda.connector.api.outbound.OutboundConnectorFunction
new file mode 100644
index 0000000000..ae6fbf7303
--- /dev/null
+++ b/connectors/aws/aws-bedrock/src/main/resources/META-INF/services/io.camunda.connector.api.outbound.OutboundConnectorFunction
@@ -0,0 +1 @@
+io.camunda.connector.aws.bedrock.BedrockConnectorFunction
\ No newline at end of file
diff --git a/connectors/aws/aws-bedrock/src/main/resources/icon.svg b/connectors/aws/aws-bedrock/src/main/resources/icon.svg
new file mode 100644
index 0000000000..2e5077ba4e
--- /dev/null
+++ b/connectors/aws/aws-bedrock/src/main/resources/icon.svg
@@ -0,0 +1,12 @@
+
+
\ No newline at end of file
diff --git a/connectors/aws/aws-bedrock/src/test/java/io/camunda/connector/aws/bedrock/BaseTest.java b/connectors/aws/aws-bedrock/src/test/java/io/camunda/connector/aws/bedrock/BaseTest.java
new file mode 100644
index 0000000000..1a3138a855
--- /dev/null
+++ b/connectors/aws/aws-bedrock/src/test/java/io/camunda/connector/aws/bedrock/BaseTest.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH
+ * under one or more contributor license agreements. Licensed under a proprietary license.
+ * See the License.txt file for more information. You may not use this file
+ * except in compliance with the proprietary license.
+ */
+package io.camunda.connector.aws.bedrock;
+
+import static java.nio.charset.StandardCharsets.UTF_8;
+import static java.nio.file.Files.readString;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import io.camunda.connector.api.json.ConnectorsObjectMapperSupplier;
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.stream.Stream;
+import org.junit.jupiter.params.provider.Arguments;
+
+public class BaseTest {
+
+ public static Stream loadInvokeModelVariables() {
+ try {
+ return loadTestCasesFromResourceFile(
+ "src/test/resources/invokemodel/invokeModelExample.json");
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public static Stream loadConverseVariables() {
+ try {
+ return loadTestCasesFromResourceFile("src/test/resources/converse/converseExample.json");
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ protected static Stream loadTestCasesFromResourceFile(final String fileWithTestCasesUri)
+ throws IOException {
+ final String cases = readString(new File(fileWithTestCasesUri).toPath(), UTF_8);
+ final ObjectMapper mapper = ConnectorsObjectMapperSupplier.getCopy();
+ var array = mapper.readValue(cases, ArrayList.class);
+ return array.stream()
+ .map(
+ value -> {
+ try {
+ return mapper.writeValueAsString(value);
+ } catch (JsonProcessingException e) {
+ throw new RuntimeException(e);
+ }
+ })
+ .map(Arguments::of);
+ }
+}
diff --git a/connectors/aws/aws-bedrock/src/test/java/io/camunda/connector/aws/bedrock/BedrockConnectorFunctionTest.java b/connectors/aws/aws-bedrock/src/test/java/io/camunda/connector/aws/bedrock/BedrockConnectorFunctionTest.java
new file mode 100644
index 0000000000..ba2f9ebc5b
--- /dev/null
+++ b/connectors/aws/aws-bedrock/src/test/java/io/camunda/connector/aws/bedrock/BedrockConnectorFunctionTest.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH
+ * under one or more contributor license agreements. Licensed under a proprietary license.
+ * See the License.txt file for more information. You may not use this file
+ * except in compliance with the proprietary license.
+ */
+package io.camunda.connector.aws.bedrock;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.when;
+
+import io.camunda.connector.aws.bedrock.core.BedrockExecutor;
+import io.camunda.connector.aws.bedrock.model.InvokeModelWrappedResponse;
+import io.camunda.connector.test.outbound.OutboundConnectorContextBuilder;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.MethodSource;
+import org.mockito.MockedStatic;
+import org.mockito.Mockito;
+
+class BedrockConnectorFunctionTest extends BaseTest {
+
+ @ParameterizedTest
+ @MethodSource("loadInvokeModelVariables")
+ void executeInvokeModelReturnsCorrectResult(String variables) {
+
+ var bedrockConnectorFunction = new BedrockConnectorFunction();
+ var context = OutboundConnectorContextBuilder.create().variables(variables).build();
+
+ var bedrockExecutor = Mockito.mock(BedrockExecutor.class);
+
+ try (MockedStatic bedrockExecutorMockedStatic =
+ Mockito.mockStatic(BedrockExecutor.class)) {
+ bedrockExecutorMockedStatic
+ .when(() -> BedrockExecutor.create(any()))
+ .thenReturn(bedrockExecutor);
+ when(bedrockExecutor.execute()).thenReturn(new InvokeModelWrappedResponse("Hello"));
+ var response = bedrockConnectorFunction.execute(context);
+ Assertions.assertNotNull(response);
+ Assertions.assertInstanceOf(InvokeModelWrappedResponse.class, response);
+ }
+ }
+
+ @ParameterizedTest
+ @MethodSource("loadConverseVariables")
+ void executeConverseReturnsCorrectResult(String variables) {
+
+ var bedrockConnectorFunction = new BedrockConnectorFunction();
+ var context = OutboundConnectorContextBuilder.create().variables(variables).build();
+
+ var bedrockExecutor = Mockito.mock(BedrockExecutor.class);
+
+ try (MockedStatic bedrockExecutorMockedStatic =
+ Mockito.mockStatic(BedrockExecutor.class)) {
+ bedrockExecutorMockedStatic
+ .when(() -> BedrockExecutor.create(any()))
+ .thenReturn(bedrockExecutor);
+ when(bedrockExecutor.execute()).thenReturn(new InvokeModelWrappedResponse("Hello"));
+ var response = bedrockConnectorFunction.execute(context);
+ Assertions.assertNotNull(response);
+ Assertions.assertInstanceOf(InvokeModelWrappedResponse.class, response);
+ }
+ }
+}
diff --git a/connectors/aws/aws-bedrock/src/test/java/io/camunda/connector/aws/bedrock/model/ConverseDataTest.java b/connectors/aws/aws-bedrock/src/test/java/io/camunda/connector/aws/bedrock/model/ConverseDataTest.java
new file mode 100644
index 0000000000..e80ed0bbc7
--- /dev/null
+++ b/connectors/aws/aws-bedrock/src/test/java/io/camunda/connector/aws/bedrock/model/ConverseDataTest.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH
+ * under one or more contributor license agreements. Licensed under a proprietary license.
+ * See the License.txt file for more information. You may not use this file
+ * except in compliance with the proprietary license.
+ */
+package io.camunda.connector.aws.bedrock.model;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.Consumer;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.mockito.Mockito;
+import software.amazon.awssdk.services.bedrockruntime.BedrockRuntimeClient;
+import software.amazon.awssdk.services.bedrockruntime.model.ConversationRole;
+import software.amazon.awssdk.services.bedrockruntime.model.ConverseResponse;
+
+class ConverseDataTest {
+
+ ObjectMapper mapper = new ObjectMapper();
+ BedrockRuntimeClient bedrockRuntimeClient = mock(BedrockRuntimeClient.class);
+ ConverseResponse converseResponse = mock(ConverseResponse.class, Mockito.RETURNS_DEEP_STUBS);
+
+ @Test
+ void execute_success() {
+
+ ConverseData converseData = new ConverseData();
+ converseData.setModelId("random-model-id");
+
+ List previousMessages = new ArrayList<>();
+ previousMessages.add(new PreviousMessage("Hey", ConversationRole.USER.name()));
+ previousMessages.add(new PreviousMessage("How are you?", ConversationRole.ASSISTANT.name()));
+ converseData.setMessages(previousMessages);
+ converseData.setNextMessage("I am good thanks, and you?");
+
+ when(bedrockRuntimeClient.converse(any(Consumer.class))).thenReturn(converseResponse);
+ when(converseResponse.output().message().content().getFirst().text())
+ .thenReturn("I am also good");
+ BedrockResponse bedrockResponse = converseData.execute(bedrockRuntimeClient, mapper);
+
+ Assertions.assertInstanceOf(ConverseWrapperResponse.class, bedrockResponse);
+ Assertions.assertEquals(
+ "I am also good",
+ ((ConverseWrapperResponse) bedrockResponse).messagesHistory().getLast().message());
+ }
+}
diff --git a/connectors/aws/aws-bedrock/src/test/java/io/camunda/connector/aws/bedrock/model/InvokeModelDataTest.java b/connectors/aws/aws-bedrock/src/test/java/io/camunda/connector/aws/bedrock/model/InvokeModelDataTest.java
new file mode 100644
index 0000000000..ee156d85c8
--- /dev/null
+++ b/connectors/aws/aws-bedrock/src/test/java/io/camunda/connector/aws/bedrock/model/InvokeModelDataTest.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH
+ * under one or more contributor license agreements. Licensed under a proprietary license.
+ * See the License.txt file for more information. You may not use this file
+ * except in compliance with the proprietary license.
+ */
+package io.camunda.connector.aws.bedrock.model;
+
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import io.camunda.connector.aws.bedrock.BaseTest;
+import java.util.function.Consumer;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import software.amazon.awssdk.core.SdkBytes;
+import software.amazon.awssdk.services.bedrockruntime.BedrockRuntimeClient;
+import software.amazon.awssdk.services.bedrockruntime.model.InvokeModelResponse;
+
+class InvokeModelDataTest extends BaseTest {
+
+ ObjectMapper mapper = new ObjectMapper();
+ BedrockRuntimeClient bedrockRuntimeClient = mock(BedrockRuntimeClient.class);
+ InvokeModelResponse invokeModelResponse = mock(InvokeModelResponse.class);
+
+ @Test
+ void execute_success() throws JsonProcessingException {
+ String payload =
+ "{\"messages\":[{\"role\":\"user\", \"content\":\"Hello\"}], \"max_tokens\":256, \"top_p\":0.8, \"temperature\":0.7}";
+ InvokeModelData invokeModelData = new InvokeModelData();
+ invokeModelData.setModelId("random-model-id");
+ invokeModelData.setPayload(mapper.readTree(payload));
+
+ when(bedrockRuntimeClient.invokeModel(any(Consumer.class))).thenReturn(invokeModelResponse);
+ when(invokeModelResponse.body()).thenReturn(SdkBytes.fromUtf8String("{\"result\" : \"Hey\"}"));
+ BedrockResponse invokeModelWrappedResponse =
+ invokeModelData.execute(bedrockRuntimeClient, mapper);
+
+ Assertions.assertInstanceOf(InvokeModelWrappedResponse.class, invokeModelWrappedResponse);
+ }
+
+ @Test
+ void execute_wrongReturn() throws JsonProcessingException {
+ String payload =
+ "{\"messages\":[{\"role\":\"user\", \"content\":\"Hello\"}], \"max_tokens\":256, \"top_p\":0.8, \"temperature\":0.7}";
+ InvokeModelData invokeModelData = new InvokeModelData();
+ invokeModelData.setModelId("random-model-id");
+ invokeModelData.setPayload(mapper.readTree(payload));
+
+ when(bedrockRuntimeClient.invokeModel(any(Consumer.class))).thenReturn(invokeModelResponse);
+ when(invokeModelResponse.body()).thenReturn(SdkBytes.fromUtf8String("Hey"));
+
+ RuntimeException runtimeException =
+ Assertions.assertThrows(
+ RuntimeException.class, () -> invokeModelData.execute(bedrockRuntimeClient, mapper));
+
+ assertEquals(
+ "Unrecognized token 'Hey': was expecting (JSON String, Number, Array, Object or token 'null', 'true' or 'false')",
+ runtimeException.getMessage());
+ }
+}
diff --git a/connectors/aws/aws-bedrock/src/test/resources/converse/converseExample.json b/connectors/aws/aws-bedrock/src/test/resources/converse/converseExample.json
new file mode 100644
index 0000000000..b17a2a2967
--- /dev/null
+++ b/connectors/aws/aws-bedrock/src/test/resources/converse/converseExample.json
@@ -0,0 +1,20 @@
+[
+ {
+ "data":{
+ "modelId":"amazon.titan-text-premier-v1:0",
+ "nextMessage":"ok",
+ "messages":[
+ {"message":"Hey", "role":"USER"}, {"message":"Hello there! How can I assist you today?", "role":"ASSISTANT"},
+ {"message":"You feel good ?", "role":"USER"}, {
+ "message":"Thank you for asking! As an AI, I don't have personal feelings or experiences, but I'm always here to help with any questions or information you may need. How can I assist you today?",
+ "role":"ASSISTANT"
+ }
+ ]
+ },
+ "action":"converse",
+ "configuration":{"region":"us-east-1"},
+ "authentication":{
+ "type":"credentials", "accessKey":"access", "secretKey":"secret"
+ }
+ }
+]
\ No newline at end of file
diff --git a/connectors/aws/aws-bedrock/src/test/resources/invokemodel/invokeModelExample.json b/connectors/aws/aws-bedrock/src/test/resources/invokemodel/invokeModelExample.json
new file mode 100644
index 0000000000..a4883efe5f
--- /dev/null
+++ b/connectors/aws/aws-bedrock/src/test/resources/invokemodel/invokeModelExample.json
@@ -0,0 +1,10 @@
+[
+ {
+ "data":{
+ "modelId":"ai21.jamba-instruct-v1:0",
+ "payload":{"messages":[{"role":"user", "content":"Hello"}], "max_tokens":256, "top_p":0.8, "temperature":0.7}
+ }, "action":"invokeModel", "configuration":{"region":"us-east-1"}, "authentication":{
+ "type":"credentials", "accessKey":"access", "secretKey":"secret"
+ }
+ }
+]
\ No newline at end of file
diff --git a/connectors/aws/pom.xml b/connectors/aws/pom.xml
index caeca95e68..461acc64d6 100644
--- a/connectors/aws/pom.xml
+++ b/connectors/aws/pom.xml
@@ -24,6 +24,7 @@
aws-sns
aws-sqs
aws-sagemaker
+ aws-bedrock
diff --git a/parent/pom.xml b/parent/pom.xml
index 760077b5d5..49133a968e 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -91,6 +91,7 @@ limitations under the License.
1.5.6
1.12.745
+ 2.26.16
3.11.6
1.2.3