From d81bde9ac199a034aca60b68487a1b1805527186 Mon Sep 17 00:00:00 2001 From: Benjoyo Date: Tue, 15 Aug 2023 16:09:48 +0200 Subject: [PATCH] change task type and cleanup --- .editorconfig | 7 +- .../connector-gpt-compose.json | 2 +- .../connector-gpt-database.json | 2 +- .../connector-gpt-decide.json | 2 +- .../connector-gpt-executor.json | 2 +- .../connector-gpt-extract.json | 2 +- .../connector-gpt-generic.json | 2 +- .../connector-gpt-openapi.json | 2 +- .../connector-gpt-planner.json | 2 +- .../connector-gpt-process.json | 2 +- .../connector-gpt-retrieval.json | 2 +- .../connector-gpt-translate.json | 2 +- .../io/holunda/connector/common/JsonUtil.kt | 12 +- .../connector/common/LLMServiceClient.kt | 50 +-- .../connector/compose/ComposeFunction.kt | 88 ++--- .../connector/compose/ComposeRequest.kt | 26 +- .../holunda/connector/compose/ComposeTask.kt | 38 +++ .../database/DatabaseAgentFunction.kt | 66 ++-- .../database/DatabaseAgentRequest.kt | 12 +- .../connector/database/DatabaseAgentResult.kt | 2 +- .../connector/database/DatabaseAgentTask.kt | 24 ++ .../connector/decide/DecideFunction.kt | 67 ++-- .../holunda/connector/decide/DecideRequest.kt | 10 +- .../io/holunda/connector/decide/DecideTask.kt | 22 ++ .../connector/executor/ExecutorFunction.kt | 87 ++--- .../connector/executor/ExecutorRequest.kt | 8 +- .../connector/executor/ExecutorResult.kt | 2 +- .../connector/executor/ExecutorTask.kt | 28 ++ .../connector/extract/ExtractFunction.kt | 88 ++--- .../connector/extract/ExtractRequest.kt | 18 +- .../holunda/connector/extract/ExtractTask.kt | 24 ++ .../connector/generic/GenericFunction.kt | 63 ++-- .../connector/generic/GenericRequest.kt | 8 +- .../holunda/connector/generic/GenericTask.kt | 20 ++ .../connector/openapi/OpenApiAgentFunction.kt | 67 ++-- .../connector/openapi/OpenApiAgentRequest.kt | 12 +- .../connector/openapi/OpenApiAgentResult.kt | 2 +- .../connector/openapi/OpenApiAgentTask.kt | 24 ++ .../connector/planner/PlannerFunction.kt | 78 ++--- .../connector/planner/PlannerRequest.kt | 8 +- .../connector/planner/PlannerResult.kt | 14 +- .../holunda/connector/planner/PlannerTask.kt | 21 ++ .../connector/process/FormGenerator.kt | 8 +- .../connector/process/ProcessAgentFunction.kt | 78 ++--- .../connector/process/ProcessAgentRequest.kt | 8 +- .../connector/process/ProcessAgentResult.kt | 2 +- .../connector/process/ProcessAgentTask.kt | 20 ++ .../connector/process/ProcessModelCreator.kt | 311 +++++++++--------- .../io/holunda/connector/process/Types.kt | 26 +- .../connector/retrieval/RetrievalFunction.kt | 73 ++-- .../connector/retrieval/RetrievalRequest.kt | 18 +- .../connector/retrieval/RetrievalResult.kt | 2 +- .../connector/retrieval/RetrievalTask.kt | 28 ++ .../connector/translate/TranslateFunction.kt | 61 ++-- .../connector/translate/TranslateRequest.kt | 6 +- .../connector/translate/TranslateTask.kt | 18 + element-templates/connector-gpt-compose.json | 2 +- element-templates/connector-gpt-database.json | 2 +- element-templates/connector-gpt-decide.json | 2 +- element-templates/connector-gpt-executor.json | 2 +- element-templates/connector-gpt-extract.json | 2 +- element-templates/connector-gpt-generic.json | 2 +- element-templates/connector-gpt-openapi.json | 2 +- element-templates/connector-gpt-planner.json | 2 +- element-templates/connector-gpt-process.json | 2 +- .../connector-gpt-retrieval.json | 2 +- .../connector-gpt-translate.json | 2 +- 67 files changed, 862 insertions(+), 837 deletions(-) create mode 100644 core/src/main/kotlin/io/holunda/connector/compose/ComposeTask.kt create mode 100644 core/src/main/kotlin/io/holunda/connector/database/DatabaseAgentTask.kt create mode 100644 core/src/main/kotlin/io/holunda/connector/decide/DecideTask.kt create mode 100644 core/src/main/kotlin/io/holunda/connector/executor/ExecutorTask.kt create mode 100644 core/src/main/kotlin/io/holunda/connector/extract/ExtractTask.kt create mode 100644 core/src/main/kotlin/io/holunda/connector/generic/GenericTask.kt create mode 100644 core/src/main/kotlin/io/holunda/connector/openapi/OpenApiAgentTask.kt create mode 100644 core/src/main/kotlin/io/holunda/connector/planner/PlannerTask.kt create mode 100644 core/src/main/kotlin/io/holunda/connector/process/ProcessAgentTask.kt create mode 100644 core/src/main/kotlin/io/holunda/connector/retrieval/RetrievalTask.kt create mode 100644 core/src/main/kotlin/io/holunda/connector/translate/TranslateTask.kt diff --git a/.editorconfig b/.editorconfig index aa08fa5..e062e2c 100755 --- a/.editorconfig +++ b/.editorconfig @@ -4,7 +4,7 @@ root = true -[*] +[*.kt] # We recommend you to keep these unchanged end_of_line = lf insert_final_newline = true @@ -12,13 +12,14 @@ charset = utf-8 trim_trailing_whitespace = true max_line_length = 160 -# camunda uses 2 spaces for indention +# camunda uses 2 spaces for indention but I honestly hate it too much +indent_size = 4 indent_style = space -indent_size = 2 # in markdown, we might want trailing whitespaces [*.md] trim_trailing_whitespace = false [*.py] +indent_style = space indent_size = 4 diff --git a/bpmn/.camunda/element-templates/connector-gpt-compose.json b/bpmn/.camunda/element-templates/connector-gpt-compose.json index f6b7c44..ee6f1e4 100644 --- a/bpmn/.camunda/element-templates/connector-gpt-compose.json +++ b/bpmn/.camunda/element-templates/connector-gpt-compose.json @@ -37,7 +37,7 @@ "properties": [ { "type": "Hidden", - "value": "io.holunda.connector.compose:1", + "value": "io.holunda:connector-compose:1", "binding": { "type": "zeebe:taskDefinition:type" } diff --git a/bpmn/.camunda/element-templates/connector-gpt-database.json b/bpmn/.camunda/element-templates/connector-gpt-database.json index 53cdaf0..c33b57d 100644 --- a/bpmn/.camunda/element-templates/connector-gpt-database.json +++ b/bpmn/.camunda/element-templates/connector-gpt-database.json @@ -45,7 +45,7 @@ "properties": [ { "type": "Hidden", - "value": "io.holunda.connector.database:1", + "value": "io.holunda:connector-database:1", "binding": { "type": "zeebe:taskDefinition:type" } diff --git a/bpmn/.camunda/element-templates/connector-gpt-decide.json b/bpmn/.camunda/element-templates/connector-gpt-decide.json index d07942e..6dc752c 100644 --- a/bpmn/.camunda/element-templates/connector-gpt-decide.json +++ b/bpmn/.camunda/element-templates/connector-gpt-decide.json @@ -37,7 +37,7 @@ "properties": [ { "type": "Hidden", - "value": "io.holunda.connector.decide:1", + "value": "io.holunda:connector-decide:1", "binding": { "type": "zeebe:taskDefinition:type" } diff --git a/bpmn/.camunda/element-templates/connector-gpt-executor.json b/bpmn/.camunda/element-templates/connector-gpt-executor.json index 9b1a427..6bd237e 100644 --- a/bpmn/.camunda/element-templates/connector-gpt-executor.json +++ b/bpmn/.camunda/element-templates/connector-gpt-executor.json @@ -41,7 +41,7 @@ "properties": [ { "type": "Hidden", - "value": "io.holunda.connector.executor:1", + "value": "io.holunda:connector-executor:1", "binding": { "type": "zeebe:taskDefinition:type" } diff --git a/bpmn/.camunda/element-templates/connector-gpt-extract.json b/bpmn/.camunda/element-templates/connector-gpt-extract.json index 7736ce1..a13bde7 100644 --- a/bpmn/.camunda/element-templates/connector-gpt-extract.json +++ b/bpmn/.camunda/element-templates/connector-gpt-extract.json @@ -41,7 +41,7 @@ "properties": [ { "type": "Hidden", - "value": "io.holunda.connector.extract:1", + "value": "io.holunda:connector-extract:1", "binding": { "type": "zeebe:taskDefinition:type" } diff --git a/bpmn/.camunda/element-templates/connector-gpt-generic.json b/bpmn/.camunda/element-templates/connector-gpt-generic.json index daf6e05..735d849 100644 --- a/bpmn/.camunda/element-templates/connector-gpt-generic.json +++ b/bpmn/.camunda/element-templates/connector-gpt-generic.json @@ -37,7 +37,7 @@ "properties": [ { "type": "Hidden", - "value": "io.holunda.connector.generic:1", + "value": "io.holunda:connector-generic:1", "binding": { "type": "zeebe:taskDefinition:type" } diff --git a/bpmn/.camunda/element-templates/connector-gpt-openapi.json b/bpmn/.camunda/element-templates/connector-gpt-openapi.json index bd6c120..6f2945b 100644 --- a/bpmn/.camunda/element-templates/connector-gpt-openapi.json +++ b/bpmn/.camunda/element-templates/connector-gpt-openapi.json @@ -45,7 +45,7 @@ "properties": [ { "type": "Hidden", - "value": "io.holunda.connector.openapi:1", + "value": "io.holunda:connector-openapi:1", "binding": { "type": "zeebe:taskDefinition:type" } diff --git a/bpmn/.camunda/element-templates/connector-gpt-planner.json b/bpmn/.camunda/element-templates/connector-gpt-planner.json index 6165e83..1c6585f 100644 --- a/bpmn/.camunda/element-templates/connector-gpt-planner.json +++ b/bpmn/.camunda/element-templates/connector-gpt-planner.json @@ -41,7 +41,7 @@ "properties": [ { "type": "Hidden", - "value": "io.holunda.connector.planner:1", + "value": "io.holunda:connector-planner:1", "binding": { "type": "zeebe:taskDefinition:type" } diff --git a/bpmn/.camunda/element-templates/connector-gpt-process.json b/bpmn/.camunda/element-templates/connector-gpt-process.json index 08b2a32..e25a08b 100644 --- a/bpmn/.camunda/element-templates/connector-gpt-process.json +++ b/bpmn/.camunda/element-templates/connector-gpt-process.json @@ -41,7 +41,7 @@ "properties": [ { "type": "Hidden", - "value": "io.holunda.connector.process:1", + "value": "io.holunda:connector-process:1", "binding": { "type": "zeebe:taskDefinition:type" } diff --git a/bpmn/.camunda/element-templates/connector-gpt-retrieval.json b/bpmn/.camunda/element-templates/connector-gpt-retrieval.json index 1cf66ad..b81b27a 100644 --- a/bpmn/.camunda/element-templates/connector-gpt-retrieval.json +++ b/bpmn/.camunda/element-templates/connector-gpt-retrieval.json @@ -41,7 +41,7 @@ "properties": [ { "type": "Hidden", - "value": "io.holunda.connector.retrieval:1", + "value": "io.holunda:connector-retrieval:1", "binding": { "type": "zeebe:taskDefinition:type" } diff --git a/bpmn/.camunda/element-templates/connector-gpt-translate.json b/bpmn/.camunda/element-templates/connector-gpt-translate.json index 641aabb..d14564b 100644 --- a/bpmn/.camunda/element-templates/connector-gpt-translate.json +++ b/bpmn/.camunda/element-templates/connector-gpt-translate.json @@ -37,7 +37,7 @@ "properties": [ { "type": "Hidden", - "value": "io.holunda.connector.translate:1", + "value": "io.holunda:connector-translate:1", "binding": { "type": "zeebe:taskDefinition:type" } diff --git a/core/src/main/kotlin/io/holunda/connector/common/JsonUtil.kt b/core/src/main/kotlin/io/holunda/connector/common/JsonUtil.kt index 6fd7483..7db6b39 100644 --- a/core/src/main/kotlin/io/holunda/connector/common/JsonUtil.kt +++ b/core/src/main/kotlin/io/holunda/connector/common/JsonUtil.kt @@ -7,18 +7,18 @@ import com.fasterxml.jackson.module.kotlin.* private val mapper = jacksonObjectMapper() fun JsonNode.toMap(): Map { - val typeRef = object : TypeReference>() {} - return mapper.convertValue(this, typeRef) + val typeRef = object : TypeReference>() {} + return mapper.convertValue(this, typeRef) } fun JsonNode.toStringMap(): Map { - val typeRef = object : TypeReference>() {} - return mapper.convertValue(this, typeRef) + val typeRef = object : TypeReference>() {} + return mapper.convertValue(this, typeRef) } fun JsonNode.toStringList(): List { - val typeRef = object : TypeReference>() {} - return mapper.convertValue(this, typeRef) + val typeRef = object : TypeReference>() {} + return mapper.convertValue(this, typeRef) } inline fun String.readFromJson() = jacksonObjectMapper().readValue(this) diff --git a/core/src/main/kotlin/io/holunda/connector/common/LLMServiceClient.kt b/core/src/main/kotlin/io/holunda/connector/common/LLMServiceClient.kt index ad61ba4..88a6a2e 100644 --- a/core/src/main/kotlin/io/holunda/connector/common/LLMServiceClient.kt +++ b/core/src/main/kotlin/io/holunda/connector/common/LLMServiceClient.kt @@ -14,34 +14,34 @@ import kotlinx.coroutines.* object LLMServiceClient { - val llmServiceUrl = System.getenv("LLM_SERVICE_URL") ?: "http://localhost:9999" + val llmServiceUrl = System.getenv("LLM_SERVICE_URL") ?: "http://localhost:9999" - val client = HttpClient { - install(ContentNegotiation) { - jackson { - configure(SerializationFeature.INDENT_OUTPUT, true) - setDefaultPrettyPrinter(DefaultPrettyPrinter().apply { - indentArraysWith(DefaultPrettyPrinter.FixedSpaceIndenter.instance) - indentObjectsWith(DefaultIndenter(" ", "\n")) - }) - } - expectSuccess = true + val client = HttpClient { + install(ContentNegotiation) { + jackson { + configure(SerializationFeature.INDENT_OUTPUT, true) + setDefaultPrettyPrinter(DefaultPrettyPrinter().apply { + indentArraysWith(DefaultPrettyPrinter.FixedSpaceIndenter.instance) + indentObjectsWith(DefaultIndenter(" ", "\n")) + }) + } + expectSuccess = true + } + install(HttpTimeout) { + requestTimeoutMillis = HttpTimeout.INFINITE_TIMEOUT_MS + connectTimeoutMillis = HttpTimeout.INFINITE_TIMEOUT_MS + socketTimeoutMillis = HttpTimeout.INFINITE_TIMEOUT_MS + } } - install(HttpTimeout) { - requestTimeoutMillis = HttpTimeout.INFINITE_TIMEOUT_MS - connectTimeoutMillis = HttpTimeout.INFINITE_TIMEOUT_MS - socketTimeoutMillis = HttpTimeout.INFINITE_TIMEOUT_MS - } - } - val jsonMapper = jacksonObjectMapper() + val jsonMapper = jacksonObjectMapper() - inline fun run(task: String, request: T): JsonNode = runBlocking { - val response: String = client.post("${llmServiceUrl}/$task") { - contentType(ContentType.Application.Json) - setBody(jsonMapper.writeValueAsString(request)) - }.body() - jsonMapper.readTree(response) - } + inline fun run(task: String, request: T): JsonNode = runBlocking { + val response: String = client.post("${llmServiceUrl}/$task") { + contentType(ContentType.Application.Json) + setBody(jsonMapper.writeValueAsString(request)) + }.body() + jsonMapper.readTree(response) + } } diff --git a/core/src/main/kotlin/io/holunda/connector/compose/ComposeFunction.kt b/core/src/main/kotlin/io/holunda/connector/compose/ComposeFunction.kt index 489ae63..05ac163 100644 --- a/core/src/main/kotlin/io/holunda/connector/compose/ComposeFunction.kt +++ b/core/src/main/kotlin/io/holunda/connector/compose/ComposeFunction.kt @@ -1,74 +1,44 @@ package io.holunda.connector.compose -import com.fasterxml.jackson.databind.* import io.camunda.connector.api.annotation.* import io.camunda.connector.api.outbound.* import io.holunda.connector.common.* -import io.holunda.connector.generic.* +import mu.* import org.apache.commons.text.* -import org.slf4j.* -import java.util.* @OutboundConnector( - name = "gpt-compose", - inputVariables = ["inputJson", "description", "temperature", "type", "style", "tone", "length", "language", "sender", "customPrinciple", "constitutionalPrinciple", "model"], - type = "io.holunda.connector.compose:1" + name = "gpt-compose", + inputVariables = [ + "inputJson", + "description", + "temperature", + "type", + "style", + "tone", + "length", + "language", + "sender", + "customPrinciple", + "constitutionalPrinciple", + "model" + ], + type = "io.holunda:connector-compose:1" ) class ComposeFunction : OutboundConnectorFunction { - @Throws(Exception::class) - override fun execute(context: OutboundConnectorContext): Any { - LOG.info("Executing ComposeFunction") - val unescapedVariables = StringEscapeUtils.unescapeJson(context.variables) // TODO remove when Camunda fixes this in zeebe :P zeebe/issues/9859 - val connectorRequest = unescapedVariables.readFromJson() - //val connectorRequest = context.bindVariables(ComposeRequest::class.java) - LOG.info("Request: {}", connectorRequest) - return executeConnector(connectorRequest) - } - - private fun executeConnector(request: ComposeRequest): ComposeResult { - val constitutionalPrinciple = when (request.constitutionalPrinciple) { - null, "none" -> null - "custom" -> request.customPrinciple - else -> request.constitutionalPrinciple + override fun execute(context: OutboundConnectorContext): Any { + logger.info("Executing ComposeFunction") + val unescapedVariables = StringEscapeUtils.unescapeJson(context.variables) // TODO remove when Camunda fixes this in zeebe :P zeebe/issues/9859 + val connectorRequest = unescapedVariables.readFromJson() + logger.info("ComposeFunction request: $connectorRequest") + return executeRequest(ComposeTask.fromRequest(connectorRequest)) } - val result = LLMServiceClient.run("compose", - ComposeTask( - request.model.modelId, - request.inputJson, - request.description, - request.type, - request.style, - request.tone, - request.length, - request.language, - request.temperature, - request.sender, - constitutionalPrinciple - ) - ) - - LOG.info("ComposeFunction result: $result") - - return ComposeResult(result) - } - - data class ComposeTask( - val model: String, - val context: JsonNode, - val instructions: String, - val type: String, - val style: String, - val tone: String, - val length: String, - val language: String, - val temperature: Double, - val sender: String?, - val constitutional_principle: String?, - ) + private fun executeRequest(composeTask: ComposeTask): ComposeResult { + val result = LLMServiceClient.run("compose", composeTask) + logger.info("ComposeFunction result: $result") + return ComposeResult(result) + } - companion object { - private val LOG = LoggerFactory.getLogger(ComposeFunction::class.java) - } + companion object : KLogging() } diff --git a/core/src/main/kotlin/io/holunda/connector/compose/ComposeRequest.kt b/core/src/main/kotlin/io/holunda/connector/compose/ComposeRequest.kt index 7db02df..9cc621b 100644 --- a/core/src/main/kotlin/io/holunda/connector/compose/ComposeRequest.kt +++ b/core/src/main/kotlin/io/holunda/connector/compose/ComposeRequest.kt @@ -4,17 +4,17 @@ import com.fasterxml.jackson.databind.* import io.holunda.connector.common.* data class ComposeRequest( - val inputJson: JsonNode, - val description: String, - val style: String, - val type: String, - val tone: String, - val length: String, - val language: String, - val temperature: Double = 0.0, - val sender: String?, - val template: String?, - val constitutionalPrinciple: String?, - val customPrinciple: String?, - val model: Model + val inputJson: JsonNode, + val description: String, + val style: String, + val type: String, + val tone: String, + val length: String, + val language: String, + val temperature: Double = 0.0, + val sender: String?, + val template: String?, + val constitutionalPrinciple: String?, + val customPrinciple: String?, + val model: Model ) diff --git a/core/src/main/kotlin/io/holunda/connector/compose/ComposeTask.kt b/core/src/main/kotlin/io/holunda/connector/compose/ComposeTask.kt new file mode 100644 index 0000000..5ebd37b --- /dev/null +++ b/core/src/main/kotlin/io/holunda/connector/compose/ComposeTask.kt @@ -0,0 +1,38 @@ +package io.holunda.connector.compose + +import com.fasterxml.jackson.databind.* + +data class ComposeTask( + val model: String, + val context: JsonNode, + val instructions: String, + val type: String, + val style: String, + val tone: String, + val length: String, + val language: String, + val temperature: Double, + val sender: String?, + val constitutional_principle: String?, +) { + companion object { + fun fromRequest(request: ComposeRequest) = + ComposeTask( + request.model.modelId, + request.inputJson, + request.description, + request.type, + request.style, + request.tone, + request.length, + request.language, + request.temperature, + request.sender, + when (request.constitutionalPrinciple) { + null, "none" -> null + "custom" -> request.customPrinciple + else -> request.constitutionalPrinciple + } + ) + } +} diff --git a/core/src/main/kotlin/io/holunda/connector/database/DatabaseAgentFunction.kt b/core/src/main/kotlin/io/holunda/connector/database/DatabaseAgentFunction.kt index 7b6694e..789aefb 100644 --- a/core/src/main/kotlin/io/holunda/connector/database/DatabaseAgentFunction.kt +++ b/core/src/main/kotlin/io/holunda/connector/database/DatabaseAgentFunction.kt @@ -1,58 +1,36 @@ package io.holunda.connector.database -import com.fasterxml.jackson.databind.* import io.camunda.connector.api.annotation.* import io.camunda.connector.api.outbound.* import io.holunda.connector.common.* -import io.holunda.connector.compose.* -import io.holunda.connector.openapi.* import mu.* -import org.apache.commons.text.* -import org.slf4j.* -import java.util.* - @OutboundConnector( - name = "gpt-database", - inputVariables = ["inputJson", "taskDescription", "databaseUrl", "outputSchema", "skillStoreUrl", "model"], - type = "io.holunda.connector.database:1" + name = "gpt-database", + inputVariables = [ + "inputJson", + "taskDescription", + "databaseUrl", + "outputSchema", + "skillStoreUrl", + "model" + ], + type = "io.holunda:connector-database:1" ) class DatabaseAgentFunction : OutboundConnectorFunction { - @Throws(Exception::class) - override fun execute(context: OutboundConnectorContext): Any { - logger.info("Executing DatabaseAgentFunction") - val connectorRequest = context.variables.readFromJson() - //val connectorRequest = context.bindVariables(DatabaseAgentRequest::class.java) - logger.info("Request: {}", connectorRequest) - return executeConnector(connectorRequest) - } - - private fun executeConnector(request: DatabaseAgentRequest): DatabaseAgentResult { - val result = LLMServiceClient.run("database", - DatabaseAgentTask( - request.model.modelId, - request.query, - request.inputJson, - request.databaseUrl, - request.outputSchema, - request.skillStoreUrl - ) - ) - - logger.info("DatabaseAgentFunction result: $result") - - return DatabaseAgentResult(result) - } + override fun execute(context: OutboundConnectorContext): Any { + logger.info("Executing DatabaseAgentFunction") + val connectorRequest = context.variables.readFromJson() + logger.info("DatabaseAgentFunction request: $connectorRequest") + return executeRequest(DatabaseAgentTask.fromRequest(connectorRequest)) + } - data class DatabaseAgentTask( - val model: String, - val task: String, - val context: JsonNode, - val database_url: String, - val output_schema: JsonNode, - val skill_store_url: String?, - ) + private fun executeRequest(databaseAgentTask: DatabaseAgentTask): DatabaseAgentResult { + val result = LLMServiceClient.run("database", databaseAgentTask) + logger.info("DatabaseAgentFunction result: $result") + return DatabaseAgentResult(result) + } - companion object : KLogging() + companion object : KLogging() } diff --git a/core/src/main/kotlin/io/holunda/connector/database/DatabaseAgentRequest.kt b/core/src/main/kotlin/io/holunda/connector/database/DatabaseAgentRequest.kt index 56479fe..0d33909 100644 --- a/core/src/main/kotlin/io/holunda/connector/database/DatabaseAgentRequest.kt +++ b/core/src/main/kotlin/io/holunda/connector/database/DatabaseAgentRequest.kt @@ -4,10 +4,10 @@ import com.fasterxml.jackson.databind.* import io.holunda.connector.common.* data class DatabaseAgentRequest( - val inputJson: JsonNode, - val query: String, - val databaseUrl: String, - val skillStoreUrl: String?, - val outputSchema: JsonNode, - val model: Model + val inputJson: JsonNode, + val query: String, + val databaseUrl: String, + val skillStoreUrl: String?, + val outputSchema: JsonNode, + val model: Model ) diff --git a/core/src/main/kotlin/io/holunda/connector/database/DatabaseAgentResult.kt b/core/src/main/kotlin/io/holunda/connector/database/DatabaseAgentResult.kt index c261817..6a420e9 100644 --- a/core/src/main/kotlin/io/holunda/connector/database/DatabaseAgentResult.kt +++ b/core/src/main/kotlin/io/holunda/connector/database/DatabaseAgentResult.kt @@ -1,5 +1,5 @@ package io.holunda.connector.database data class DatabaseAgentResult( - val result: Any + val result: Any ) diff --git a/core/src/main/kotlin/io/holunda/connector/database/DatabaseAgentTask.kt b/core/src/main/kotlin/io/holunda/connector/database/DatabaseAgentTask.kt new file mode 100644 index 0000000..9e4526b --- /dev/null +++ b/core/src/main/kotlin/io/holunda/connector/database/DatabaseAgentTask.kt @@ -0,0 +1,24 @@ +package io.holunda.connector.database + +import com.fasterxml.jackson.databind.* + +data class DatabaseAgentTask( + val model: String, + val task: String, + val context: JsonNode, + val database_url: String, + val output_schema: JsonNode, + val skill_store_url: String?, +) { + companion object { + fun fromRequest(request: DatabaseAgentRequest) = + DatabaseAgentTask( + request.model.modelId, + request.query, + request.inputJson, + request.databaseUrl, + request.outputSchema, + request.skillStoreUrl + ) + } +} diff --git a/core/src/main/kotlin/io/holunda/connector/decide/DecideFunction.kt b/core/src/main/kotlin/io/holunda/connector/decide/DecideFunction.kt index 1136dc9..c996f0e 100644 --- a/core/src/main/kotlin/io/holunda/connector/decide/DecideFunction.kt +++ b/core/src/main/kotlin/io/holunda/connector/decide/DecideFunction.kt @@ -1,58 +1,35 @@ package io.holunda.connector.decide -import com.fasterxml.jackson.databind.* import io.camunda.connector.api.annotation.* -import io.camunda.connector.api.error.* import io.camunda.connector.api.outbound.* import io.holunda.connector.common.* -import io.holunda.connector.compose.* -import io.holunda.connector.decide.DecisionOutputType.* -import io.holunda.connector.generic.* -import org.apache.commons.text.* -import org.slf4j.* -import java.util.* +import mu.* @OutboundConnector( - name = "gpt-decide", - inputVariables = ["inputJson", "instructions", "outputType", "possibleValues", "model"], - type = "io.holunda.connector.decide:1" + name = "gpt-decide", + inputVariables = [ + "inputJson", + "instructions", + "outputType", + "possibleValues", + "model" + ], + type = "io.holunda:connector-decide:1" ) class DecideFunction : OutboundConnectorFunction { - @Throws(Exception::class) - override fun execute(context: OutboundConnectorContext): Any { - LOG.info("Executing DecideFunction") - val connectorRequest = context.variables.readFromJson() - //val connectorRequest = context.bindVariables(DecideRequest::class.java) - LOG.info("Request: {}", connectorRequest) - return executeConnector(connectorRequest) - } + override fun execute(context: OutboundConnectorContext): Any { + logger.info("Executing DecideFunction") + val connectorRequest = context.variables.readFromJson() + logger.info("DecideFunction request: $connectorRequest") + return executeRequest(DecideTask.fromRequest(connectorRequest)) + } - private fun executeConnector(request: DecideRequest): DecideResult { - val result = LLMServiceClient.run("decide", - DecideTask( - request.model.modelId, - request.inputJson, - request.instructions, - request.outputType.name.lowercase(), - request.possibleValues - ) - ) + private fun executeRequest(decideTask: DecideTask): DecideResult { + val result = LLMServiceClient.run("decide", decideTask) + logger.info("DecideFunction result: $result") + return DecideResult(result) + } - LOG.info("DecideFunction result: $result") - - return DecideResult(result) - } - - data class DecideTask( - val model: String, - val context: JsonNode, - val instructions: String, - val output_type: String, - val possible_values: List? - ) - - companion object { - private val LOG = LoggerFactory.getLogger(DecideFunction::class.java) - } + companion object : KLogging() } diff --git a/core/src/main/kotlin/io/holunda/connector/decide/DecideRequest.kt b/core/src/main/kotlin/io/holunda/connector/decide/DecideRequest.kt index 7d6392e..981449f 100644 --- a/core/src/main/kotlin/io/holunda/connector/decide/DecideRequest.kt +++ b/core/src/main/kotlin/io/holunda/connector/decide/DecideRequest.kt @@ -4,11 +4,11 @@ import com.fasterxml.jackson.databind.* import io.holunda.connector.common.* data class DecideRequest( - val inputJson: JsonNode, - val instructions: String, - val outputType: DecisionOutputType, - val possibleValues: List?, - val model: Model + val inputJson: JsonNode, + val instructions: String, + val outputType: DecisionOutputType, + val possibleValues: List?, + val model: Model ) enum class DecisionOutputType(name: String) { diff --git a/core/src/main/kotlin/io/holunda/connector/decide/DecideTask.kt b/core/src/main/kotlin/io/holunda/connector/decide/DecideTask.kt new file mode 100644 index 0000000..6c76593 --- /dev/null +++ b/core/src/main/kotlin/io/holunda/connector/decide/DecideTask.kt @@ -0,0 +1,22 @@ +package io.holunda.connector.decide + +import com.fasterxml.jackson.databind.* + +data class DecideTask( + val model: String, + val context: JsonNode, + val instructions: String, + val output_type: String, + val possible_values: List? +) { + companion object { + fun fromRequest(request: DecideRequest) = + DecideTask( + request.model.modelId, + request.inputJson, + request.instructions, + request.outputType.name.lowercase(), + request.possibleValues + ) + } +} diff --git a/core/src/main/kotlin/io/holunda/connector/executor/ExecutorFunction.kt b/core/src/main/kotlin/io/holunda/connector/executor/ExecutorFunction.kt index 4772ec6..49217cb 100644 --- a/core/src/main/kotlin/io/holunda/connector/executor/ExecutorFunction.kt +++ b/core/src/main/kotlin/io/holunda/connector/executor/ExecutorFunction.kt @@ -1,73 +1,52 @@ package io.holunda.connector.executor -import com.fasterxml.jackson.databind.* import io.camunda.connector.api.annotation.* import io.camunda.connector.api.outbound.* import io.holunda.connector.common.* -import io.holunda.connector.compose.* import mu.* -import org.apache.commons.text.* -import org.slf4j.* -import java.util.* - @OutboundConnector( - name = "gpt-executor", - inputVariables = ["inputJson", "taskObject", "result", "model"], - type = "io.holunda.connector.executor:1" + name = "gpt-executor", + inputVariables = [ + "inputJson", + "taskObject", + "result", + "model" + ], + type = "io.holunda:connector-executor:1" ) class ExecutorFunction : OutboundConnectorFunction { - @Throws(Exception::class) - override fun execute(context: OutboundConnectorContext): Any { - logger.info("Executing ExecutorFunction") - val connectorRequest = context.variables.readFromJson() - //val connectorRequest = context.bindVariables(ExecutorRequest::class.java) - logger.info("Request: {}", connectorRequest) - return executeConnector(connectorRequest) - } - - private fun executeConnector(request: ExecutorRequest): ExecutorResult { - val task = if (request.result != null) { - request.taskObject.copy( - results = request.taskObject.results + listOf(request.result) - ) - } else request.taskObject - - val previousStepsAndResults = task.pastSteps.zip(task.results).toString() - val currentPlanStep = task.plan.getOrElse(task.results.size) { _ -> "" } + override fun execute(context: OutboundConnectorContext): Any { + logger.info("Executing ExecutorFunction") + val connectorRequest = context.variables.readFromJson() + logger.info("ExecutorFunction request: $connectorRequest") + return executeRequest(connectorRequest) + } - val currentStep = LLMServiceClient.run("executor", - ExecutorTask( - request.model.modelId, - task.task, - request.inputJson, - task.tools, - previousStepsAndResults, - currentPlanStep - ) - ).toStringMap() + private fun executeRequest(request: ExecutorRequest): ExecutorResult { + val task = if (request.result != null) { + request.taskObject.copy( + results = request.taskObject.results + listOf(request.result) + ) + } else request.taskObject - val currentStepSummary = "${currentStep["action"]}: ${currentStep["input"]}" + val currentStep = LLMServiceClient.run( + "executor", + ExecutorTask.fromRequestAndTaskObject(request, task) + ).toStringMap() - val updatedTask = task.copy( - currentStep = currentStep, - pastSteps = task.pastSteps + listOf(currentStepSummary) - ) + val currentStepSummary = "${currentStep["action"]}: ${currentStep["input"]}" - logger.info("ExecutorFunction result: $updatedTask") + val updatedTask = task.copy( + currentStep = currentStep, + pastSteps = task.pastSteps + listOf(currentStepSummary) + ) - return ExecutorResult(updatedTask) - } + logger.info("ExecutorFunction result: $updatedTask") - data class ExecutorTask( - val model: String, - val task: String, - val context: JsonNode, - val tools: Map, - val previous_steps: String, - val current_step: String - ) + return ExecutorResult(updatedTask) + } - companion object : KLogging() + companion object : KLogging() } diff --git a/core/src/main/kotlin/io/holunda/connector/executor/ExecutorRequest.kt b/core/src/main/kotlin/io/holunda/connector/executor/ExecutorRequest.kt index d900fb6..96244ee 100644 --- a/core/src/main/kotlin/io/holunda/connector/executor/ExecutorRequest.kt +++ b/core/src/main/kotlin/io/holunda/connector/executor/ExecutorRequest.kt @@ -5,8 +5,8 @@ import io.holunda.connector.common.* import io.holunda.connector.planner.* data class ExecutorRequest( - val inputJson: JsonNode, - val taskObject: Task, - val result: String?, - val model: Model + val inputJson: JsonNode, + val taskObject: Task, + val result: String?, + val model: Model ) diff --git a/core/src/main/kotlin/io/holunda/connector/executor/ExecutorResult.kt b/core/src/main/kotlin/io/holunda/connector/executor/ExecutorResult.kt index 49f3ff9..1570c27 100644 --- a/core/src/main/kotlin/io/holunda/connector/executor/ExecutorResult.kt +++ b/core/src/main/kotlin/io/holunda/connector/executor/ExecutorResult.kt @@ -1,5 +1,5 @@ package io.holunda.connector.executor data class ExecutorResult( - val result: Any + val result: Any ) diff --git a/core/src/main/kotlin/io/holunda/connector/executor/ExecutorTask.kt b/core/src/main/kotlin/io/holunda/connector/executor/ExecutorTask.kt new file mode 100644 index 0000000..b81e99f --- /dev/null +++ b/core/src/main/kotlin/io/holunda/connector/executor/ExecutorTask.kt @@ -0,0 +1,28 @@ +package io.holunda.connector.executor + +import com.fasterxml.jackson.databind.* +import io.holunda.connector.planner.* + +data class ExecutorTask( + val model: String, + val task: String, + val context: JsonNode, + val tools: Map, + val previous_steps: String, + val current_step: String +) { + companion object { + fun fromRequestAndTaskObject(request: ExecutorRequest, task: Task): ExecutorTask { + val previousStepsAndResults = task.pastSteps.zip(task.results).toString() + val currentPlanStep = task.plan.getOrElse(task.results.size) { _ -> "" } + return ExecutorTask( + request.model.modelId, + task.task, + request.inputJson, + task.tools, + previousStepsAndResults, + currentPlanStep + ) + } + } +} diff --git a/core/src/main/kotlin/io/holunda/connector/extract/ExtractFunction.kt b/core/src/main/kotlin/io/holunda/connector/extract/ExtractFunction.kt index 43768c8..b7e98a6 100644 --- a/core/src/main/kotlin/io/holunda/connector/extract/ExtractFunction.kt +++ b/core/src/main/kotlin/io/holunda/connector/extract/ExtractFunction.kt @@ -1,73 +1,53 @@ package io.holunda.connector.extract import com.fasterxml.jackson.databind.* -import com.fasterxml.jackson.module.kotlin.* import io.camunda.connector.api.annotation.* import io.camunda.connector.api.error.* import io.camunda.connector.api.outbound.* import io.holunda.connector.common.* -import io.holunda.connector.compose.* -import io.holunda.connector.database.* -import org.apache.commons.text.* -import org.slf4j.* -import java.util.* +import mu.* @OutboundConnector( - name = "gpt-extract", - inputVariables = ["inputJson", "instructions", "extractionJson", "missingDataBehavior", "mode", "entitiesDescription", "model"], - type = "io.holunda.connector.extract:1" + name = "gpt-extract", + inputVariables = [ + "inputJson", + "instructions", + "extractionJson", + "missingDataBehavior", + "mode", + "entitiesDescription", + "model" + ], + type = "io.holunda:connector-extract:1" ) class ExtractFunction : OutboundConnectorFunction { - @Throws(Exception::class) - override fun execute(context: OutboundConnectorContext): Any { - LOG.info("Executing ExtractDataFunction") - val connectorRequest = context.variables.readFromJson() - //val connectorRequest = context.bindVariables(ExtractDataRequest::class.java) - LOG.info("Request: {}", connectorRequest) - return executeConnector(connectorRequest) - } - - private fun executeConnector(request: ExtractDataRequest): ExtractResult { - val result = LLMServiceClient.run( - "extract", - ExtractTask( - request.model.modelId, - request.inputJson, - request.instructions, - request.extractionJson, - request.mode == Mode.REPEATED, - request.entitiesDescription - ) - ) - - fun checkNode(node: JsonNode) { - if (request.missingDataBehavior == MissingDataBehavior.ERROR && node.toMap().values.any { it == null }) { - throw ConnectorException("MISSING_DATA", "One or more result values are null") - } + override fun execute(context: OutboundConnectorContext): Any { + logger.info("Executing ExtractFunction") + val connectorRequest = context.variables.readFromJson() + logger.info("ExtractFunction request: $connectorRequest") + return executeRequest(connectorRequest) } - when { - result.isArray -> result.forEach(::checkNode) - result.isObject -> checkNode(result) - else -> throw IllegalArgumentException("The result must be a JSON object or a JSON array") - } + private fun executeRequest(request: ExtractRequest): ExtractResult { + val result = LLMServiceClient.run("extract", ExtractTask.fromRequest(request)) - LOG.info("ExtractDataFunction result: $result") + fun checkNode(node: JsonNode) { + if (request.missingDataBehavior == MissingDataBehavior.ERROR && node.toMap().values.any { it == null }) { + throw ConnectorException("MISSING_DATA", "One or more result values are null") + } + } - return ExtractResult(result) - } + when { + result.isArray -> result.forEach(::checkNode) + result.isObject -> checkNode(result) + else -> throw IllegalArgumentException("The result must be a JSON object or a JSON array") + } - data class ExtractTask( - val model: String, - val context: JsonNode, - val instructions: String?, - val extraction_schema: JsonNode, - val repeated: Boolean, - val repeated_description: String?, - ) + logger.info("ExtractFunction result: $result") + + return ExtractResult(result) + } - companion object { - private val LOG = LoggerFactory.getLogger(ExtractFunction::class.java) - } + companion object : KLogging() } diff --git a/core/src/main/kotlin/io/holunda/connector/extract/ExtractRequest.kt b/core/src/main/kotlin/io/holunda/connector/extract/ExtractRequest.kt index a252018..43e0a50 100644 --- a/core/src/main/kotlin/io/holunda/connector/extract/ExtractRequest.kt +++ b/core/src/main/kotlin/io/holunda/connector/extract/ExtractRequest.kt @@ -3,18 +3,18 @@ package io.holunda.connector.extract import com.fasterxml.jackson.databind.* import io.holunda.connector.common.* -data class ExtractDataRequest( - val inputJson: JsonNode, - val instructions: String?, - val extractionJson: JsonNode, - val mode: Mode, - val entitiesDescription: String?, - val missingDataBehavior: MissingDataBehavior, - val model: Model +data class ExtractRequest( + val inputJson: JsonNode, + val instructions: String?, + val extractionJson: JsonNode, + val mode: Mode, + val entitiesDescription: String?, + val missingDataBehavior: MissingDataBehavior, + val model: Model ) enum class Mode { - SINGLE, REPEATED + SINGLE, REPEATED } enum class MissingDataBehavior { diff --git a/core/src/main/kotlin/io/holunda/connector/extract/ExtractTask.kt b/core/src/main/kotlin/io/holunda/connector/extract/ExtractTask.kt new file mode 100644 index 0000000..d3958fb --- /dev/null +++ b/core/src/main/kotlin/io/holunda/connector/extract/ExtractTask.kt @@ -0,0 +1,24 @@ +package io.holunda.connector.extract + +import com.fasterxml.jackson.databind.* + +data class ExtractTask( + val model: String, + val context: JsonNode, + val instructions: String?, + val extraction_schema: JsonNode, + val repeated: Boolean, + val repeated_description: String?, +) { + companion object { + fun fromRequest(request: ExtractRequest) = + ExtractTask( + request.model.modelId, + request.inputJson, + request.instructions, + request.extractionJson, + request.mode == Mode.REPEATED, + request.entitiesDescription + ) + } +} diff --git a/core/src/main/kotlin/io/holunda/connector/generic/GenericFunction.kt b/core/src/main/kotlin/io/holunda/connector/generic/GenericFunction.kt index d07f05a..a849782 100644 --- a/core/src/main/kotlin/io/holunda/connector/generic/GenericFunction.kt +++ b/core/src/main/kotlin/io/holunda/connector/generic/GenericFunction.kt @@ -1,55 +1,34 @@ package io.holunda.connector.generic -import com.fasterxml.jackson.databind.* -import com.fasterxml.jackson.module.kotlin.* import io.camunda.connector.api.annotation.* import io.camunda.connector.api.outbound.* import io.holunda.connector.common.* -import io.holunda.connector.compose.* -import io.holunda.connector.translate.* -import org.apache.commons.text.* -import org.slf4j.* -import java.util.* +import mu.* @OutboundConnector( - name = "gpt-generic", - inputVariables = ["inputJson", "taskDescription", "outputFormat", "model"], - type = "io.holunda.connector.generic:1" + name = "gpt-generic", + inputVariables = [ + "inputJson", + "taskDescription", + "outputFormat", + "model" + ], + type = "io.holunda:connector-generic:1" ) class GenericFunction : OutboundConnectorFunction { - @Throws(Exception::class) - override fun execute(context: OutboundConnectorContext): Any { - LOG.info("Executing GenericFunction") - val connectorRequest = context.variables.readFromJson() - //val connectorRequest = context.bindVariables(GenericRequest::class.java) - LOG.info("Request: {}", connectorRequest) - return executeConnector(connectorRequest) - } + override fun execute(context: OutboundConnectorContext): Any { + logger.info("Executing GenericFunction") + val connectorRequest = context.variables.readFromJson() + logger.info("GenericFunction request $connectorRequest") + return executeRequest(connectorRequest) + } - private fun executeConnector(request: GenericRequest): GenericResult { - val result = LLMServiceClient.run("generic", - GenericTask( - request.model.modelId, - request.inputJson, - request.taskDescription, - request.outputFormat - ) - ) + private fun executeRequest(request: GenericRequest): GenericResult { + val result = LLMServiceClient.run("generic", GenericTask.fromRequest(request)) + logger.info("GenericFunction result: $result") + return GenericResult(result) + } - LOG.info("GenericFunction result: $result") - - return GenericResult(result) - } - - data class GenericTask( - val model: String, - val context: JsonNode, - val instructions: String, - val output_schema: JsonNode, - ) - - companion object { - private val LOG = LoggerFactory.getLogger(GenericFunction::class.java) - } + companion object : KLogging() } diff --git a/core/src/main/kotlin/io/holunda/connector/generic/GenericRequest.kt b/core/src/main/kotlin/io/holunda/connector/generic/GenericRequest.kt index 9d8afb2..a2ceafd 100644 --- a/core/src/main/kotlin/io/holunda/connector/generic/GenericRequest.kt +++ b/core/src/main/kotlin/io/holunda/connector/generic/GenericRequest.kt @@ -4,8 +4,8 @@ import com.fasterxml.jackson.databind.* import io.holunda.connector.common.* data class GenericRequest( - val inputJson: JsonNode, - val outputFormat: JsonNode, - val taskDescription: String, - val model: Model + val inputJson: JsonNode, + val outputFormat: JsonNode, + val taskDescription: String, + val model: Model ) diff --git a/core/src/main/kotlin/io/holunda/connector/generic/GenericTask.kt b/core/src/main/kotlin/io/holunda/connector/generic/GenericTask.kt new file mode 100644 index 0000000..c072bc7 --- /dev/null +++ b/core/src/main/kotlin/io/holunda/connector/generic/GenericTask.kt @@ -0,0 +1,20 @@ +package io.holunda.connector.generic + +import com.fasterxml.jackson.databind.* + +data class GenericTask( + val model: String, + val context: JsonNode, + val instructions: String, + val output_schema: JsonNode, +) { + companion object { + fun fromRequest(request: GenericRequest) = + GenericTask( + request.model.modelId, + request.inputJson, + request.taskDescription, + request.outputFormat + ) + } +} diff --git a/core/src/main/kotlin/io/holunda/connector/openapi/OpenApiAgentFunction.kt b/core/src/main/kotlin/io/holunda/connector/openapi/OpenApiAgentFunction.kt index 7143dc9..18b256a 100644 --- a/core/src/main/kotlin/io/holunda/connector/openapi/OpenApiAgentFunction.kt +++ b/core/src/main/kotlin/io/holunda/connector/openapi/OpenApiAgentFunction.kt @@ -1,59 +1,36 @@ package io.holunda.connector.openapi -import com.fasterxml.jackson.databind.* import io.camunda.connector.api.annotation.* import io.camunda.connector.api.outbound.* import io.holunda.connector.common.* -import io.holunda.connector.compose.* -import io.holunda.connector.planner.* import mu.* -import org.apache.commons.text.* -import org.slf4j.* -import java.util.* @OutboundConnector( - name = "gpt-openapi", - inputVariables = ["inputJson", "taskDescription", "specUrl", "outputSchema", "skillStoreUrl", "model"], - type = "io.holunda.connector.openapi:1" + name = "gpt-openapi", + inputVariables = [ + "inputJson", + "taskDescription", + "specUrl", + "outputSchema", + "skillStoreUrl", + "model" + ], + type = "io.holunda:connector-openapi:1" ) class OpenApiAgentFunction : OutboundConnectorFunction { - @Throws(Exception::class) - override fun execute(context: OutboundConnectorContext): Any { - logger.info("Executing OpenApiAgentFunction") - val connectorRequest = context.variables.readFromJson() - //val connectorRequest = context.bindVariables(OpenApiAgentRequest::class.java) - logger.info("Request: {}", connectorRequest) - return executeConnector(connectorRequest) - } + override fun execute(context: OutboundConnectorContext): Any { + logger.info("Executing OpenApiAgentFunction") + val connectorRequest = context.variables.readFromJson() + logger.info("OpenApiAgentFunction request: $connectorRequest") + return executeRequest(connectorRequest) + } - private fun executeConnector(request: OpenApiAgentRequest): OpenApiAgentResult { - val result = LLMServiceClient.run("openapi", - OpenApiAgentTask( - request.model.modelId, - request.query, - request.inputJson, - request.specUrl, - request.outputSchema, - request.skillStoreUrl - ) - ) + private fun executeRequest(request: OpenApiAgentRequest): OpenApiAgentResult { + val result = LLMServiceClient.run("openapi", OpenApiAgentTask.fromRequest(request)) + logger.info("OpenApiAgentFunction result: $request") + return OpenApiAgentResult(result) + } - val json = result.toMap() - - logger.info("OpenApiAgentFunction result: $json") - - return OpenApiAgentResult(json) - } - - data class OpenApiAgentTask( - val model: String, - val task: String, - val context: JsonNode, - val spec_url: String, - val output_schema: JsonNode, - val skill_store_url: String?, - ) - - companion object : KLogging() + companion object : KLogging() } diff --git a/core/src/main/kotlin/io/holunda/connector/openapi/OpenApiAgentRequest.kt b/core/src/main/kotlin/io/holunda/connector/openapi/OpenApiAgentRequest.kt index 1fb1a7f..aafad3b 100644 --- a/core/src/main/kotlin/io/holunda/connector/openapi/OpenApiAgentRequest.kt +++ b/core/src/main/kotlin/io/holunda/connector/openapi/OpenApiAgentRequest.kt @@ -4,10 +4,10 @@ import com.fasterxml.jackson.databind.* import io.holunda.connector.common.* data class OpenApiAgentRequest( - val inputJson: JsonNode, - val query: String, - val specUrl: String, - val skillStoreUrl: String?, - val outputSchema: JsonNode, - val model: Model + val inputJson: JsonNode, + val query: String, + val specUrl: String, + val skillStoreUrl: String?, + val outputSchema: JsonNode, + val model: Model ) diff --git a/core/src/main/kotlin/io/holunda/connector/openapi/OpenApiAgentResult.kt b/core/src/main/kotlin/io/holunda/connector/openapi/OpenApiAgentResult.kt index 5026abd..8a0c5d2 100644 --- a/core/src/main/kotlin/io/holunda/connector/openapi/OpenApiAgentResult.kt +++ b/core/src/main/kotlin/io/holunda/connector/openapi/OpenApiAgentResult.kt @@ -1,5 +1,5 @@ package io.holunda.connector.openapi data class OpenApiAgentResult( - val result: Any + val result: Any ) diff --git a/core/src/main/kotlin/io/holunda/connector/openapi/OpenApiAgentTask.kt b/core/src/main/kotlin/io/holunda/connector/openapi/OpenApiAgentTask.kt new file mode 100644 index 0000000..3d6fbbd --- /dev/null +++ b/core/src/main/kotlin/io/holunda/connector/openapi/OpenApiAgentTask.kt @@ -0,0 +1,24 @@ +package io.holunda.connector.openapi + +import com.fasterxml.jackson.databind.* + +data class OpenApiAgentTask( + val model: String, + val task: String, + val context: JsonNode, + val spec_url: String, + val output_schema: JsonNode, + val skill_store_url: String?, +) { + companion object { + fun fromRequest(request: OpenApiAgentRequest) = + OpenApiAgentTask( + request.model.modelId, + request.query, + request.inputJson, + request.specUrl, + request.outputSchema, + request.skillStoreUrl + ) + } +} diff --git a/core/src/main/kotlin/io/holunda/connector/planner/PlannerFunction.kt b/core/src/main/kotlin/io/holunda/connector/planner/PlannerFunction.kt index b4cedfd..8a8c0d7 100644 --- a/core/src/main/kotlin/io/holunda/connector/planner/PlannerFunction.kt +++ b/core/src/main/kotlin/io/holunda/connector/planner/PlannerFunction.kt @@ -1,61 +1,41 @@ package io.holunda.connector.planner -import com.fasterxml.jackson.databind.* import io.camunda.connector.api.annotation.* import io.camunda.connector.api.outbound.* import io.holunda.connector.common.* -import io.holunda.connector.compose.* -import io.holunda.connector.openapi.* -import io.holunda.connector.planner.* import mu.* -import org.apache.commons.text.* -import org.slf4j.* -import java.util.* @OutboundConnector( - name = "gpt-planner", - inputVariables = ["inputJson", "taskDescription", "tools", "model"], - type = "io.holunda.connector.planner:1" + name = "gpt-planner", + inputVariables = [ + "inputJson", + "taskDescription", + "tools", + "model" + ], + type = "io.holunda:connector-planner:1" ) class PlannerFunction : OutboundConnectorFunction { - @Throws(Exception::class) - override fun execute(context: OutboundConnectorContext): Any { - logger.info("Executing PlannerFunction") - val connectorRequest = context.variables.readFromJson() - //val connectorRequest = context.bindVariables(PlannerRequest::class.java) - logger.info("Request: {}", connectorRequest) - return executeConnector(connectorRequest) - } - - private fun executeConnector(request: PlannerRequest): PlannerResult { - val result = LLMServiceClient.run("planner", PlannerTask( - request.model.modelId, - request.taskDescription, - request.inputJson, - request.tools.toStringMap(), - ) - ) - - val plan = result.toStringList() - - logger.info("PlannerFunction result: $plan") - - return PlannerResult( - Task( - task = request.taskDescription, - tools = request.tools.toStringMap(), - plan = plan, - ) - ) - } - - data class PlannerTask( - val model: String, - val task: String, - val context: JsonNode, - val tools: Map - ) - - companion object : KLogging() + override fun execute(context: OutboundConnectorContext): Any { + logger.info("Executing PlannerFunction") + val connectorRequest = context.variables.readFromJson() + logger.info("PlannerFunction request: $connectorRequest") + return executeRequest(connectorRequest) + } + + private fun executeRequest(request: PlannerRequest): PlannerResult { + val result = LLMServiceClient.run("planner", PlannerTask.fromRequest(request)) + val plan = result.toStringList() + logger.info("PlannerFunction result: $plan") + return PlannerResult( + Task( + task = request.taskDescription, + tools = request.tools.toStringMap(), + plan = plan, + ) + ) + } + + companion object : KLogging() } diff --git a/core/src/main/kotlin/io/holunda/connector/planner/PlannerRequest.kt b/core/src/main/kotlin/io/holunda/connector/planner/PlannerRequest.kt index 4d92cab..d1123fd 100644 --- a/core/src/main/kotlin/io/holunda/connector/planner/PlannerRequest.kt +++ b/core/src/main/kotlin/io/holunda/connector/planner/PlannerRequest.kt @@ -4,8 +4,8 @@ import com.fasterxml.jackson.databind.* import io.holunda.connector.common.* data class PlannerRequest( - val inputJson: JsonNode, - val taskDescription: String, - val tools: JsonNode, - val model: Model + val inputJson: JsonNode, + val taskDescription: String, + val tools: JsonNode, + val model: Model ) diff --git a/core/src/main/kotlin/io/holunda/connector/planner/PlannerResult.kt b/core/src/main/kotlin/io/holunda/connector/planner/PlannerResult.kt index 316efec..74418d8 100644 --- a/core/src/main/kotlin/io/holunda/connector/planner/PlannerResult.kt +++ b/core/src/main/kotlin/io/holunda/connector/planner/PlannerResult.kt @@ -1,14 +1,14 @@ package io.holunda.connector.planner data class PlannerResult( - val result: Any + val result: Any ) data class Task( - val task: String, - val tools: Map, - val plan: List, - val currentStep: Map? = null, - val pastSteps: List = emptyList(), - val results: List = emptyList(), + val task: String, + val tools: Map, + val plan: List, + val currentStep: Map? = null, + val pastSteps: List = emptyList(), + val results: List = emptyList(), ) diff --git a/core/src/main/kotlin/io/holunda/connector/planner/PlannerTask.kt b/core/src/main/kotlin/io/holunda/connector/planner/PlannerTask.kt new file mode 100644 index 0000000..2e17d09 --- /dev/null +++ b/core/src/main/kotlin/io/holunda/connector/planner/PlannerTask.kt @@ -0,0 +1,21 @@ +package io.holunda.connector.planner + +import com.fasterxml.jackson.databind.* +import io.holunda.connector.common.* + +data class PlannerTask( + val model: String, + val task: String, + val context: JsonNode, + val tools: Map +) { + companion object { + fun fromRequest(request: PlannerRequest) = + PlannerTask( + request.model.modelId, + request.taskDescription, + request.inputJson, + request.tools.toStringMap(), + ) + } +} diff --git a/core/src/main/kotlin/io/holunda/connector/process/FormGenerator.kt b/core/src/main/kotlin/io/holunda/connector/process/FormGenerator.kt index f9e3029..5aca83d 100644 --- a/core/src/main/kotlin/io/holunda/connector/process/FormGenerator.kt +++ b/core/src/main/kotlin/io/holunda/connector/process/FormGenerator.kt @@ -4,9 +4,9 @@ import java.util.* object FormGenerator { - fun generate(task: String, variables: List): String { + fun generate(task: String, variables: List): String { - fun getField(name: String) = """ + fun getField(name: String) = """ { "text": "=\"$name: \" + string($name)", "type": "text", @@ -14,7 +14,7 @@ object FormGenerator { } """.trimIndent() - return """ + return """ { "components": [ { @@ -51,6 +51,6 @@ object FormGenerator { "schemaVersion": 7 } """.trimIndent() - } + } } diff --git a/core/src/main/kotlin/io/holunda/connector/process/ProcessAgentFunction.kt b/core/src/main/kotlin/io/holunda/connector/process/ProcessAgentFunction.kt index cf165c7..7fbd4fa 100644 --- a/core/src/main/kotlin/io/holunda/connector/process/ProcessAgentFunction.kt +++ b/core/src/main/kotlin/io/holunda/connector/process/ProcessAgentFunction.kt @@ -1,61 +1,43 @@ package io.holunda.connector.process -import com.fasterxml.jackson.databind.* import com.fasterxml.jackson.module.kotlin.* import io.camunda.connector.api.annotation.* import io.camunda.connector.api.outbound.* import io.holunda.connector.common.* -import io.holunda.connector.compose.* -import io.holunda.connector.openapi.* import mu.* -import org.apache.commons.text.* -import org.slf4j.* -import java.util.* - @OutboundConnector( - name = "gpt-process", - inputVariables = ["inputJson", "taskDescription", "activities", "model"], - type = "io.holunda.connector.process:1" + name = "gpt-process", + inputVariables = [ + "inputJson", + "taskDescription", + "activities", + "model" + ], + type = "io.holunda:connector-process:1" ) class ProcessAgentFunction : OutboundConnectorFunction { - @Throws(Exception::class) - override fun execute(context: OutboundConnectorContext): Any { - logger.info("Executing ProcessAgentFunction") - val connectorRequest = context.variables.readFromJson() - //val connectorRequest = context.bindVariables(ProcessAgentRequest::class.java) - logger.info("Request: {}", connectorRequest) - return executeConnector(connectorRequest) - } - - private fun executeConnector(request: ProcessAgentRequest): ProcessAgentResult { - val result = LLMServiceClient.run("process", - ProcessAgentTask( - request.model.modelId, - request.taskDescription, - request.inputJson, - request.activities.mapValues { it.value.description } - ) - ) - - val elements = jacksonObjectMapper().treeToValue>(result.get("elements")) - val flows = jacksonObjectMapper().treeToValue>(result.get("flows")) - - val creator = ProcessModelCreator(request.activities) - val processId = creator.createProcess(elements, flows) - - logger.info("ProcessAgentFunction result: $processId") - - return ProcessAgentResult(processId ?: "") - } - - data class ProcessAgentTask( - val model: String, - val task: String, - val context: JsonNode, - val activities: Map, - ) - - companion object : KLogging() + override fun execute(context: OutboundConnectorContext): Any { + logger.info("Executing ProcessAgentFunction") + val connectorRequest = context.variables.readFromJson() + logger.info("ProcessAgentFunction request: $connectorRequest") + return executeRequest(connectorRequest) + } + + private fun executeRequest(request: ProcessAgentRequest): ProcessAgentResult { + val result = LLMServiceClient.run("process", ProcessAgentTask.fromRequest(request)) + + val elements = jacksonObjectMapper().treeToValue>(result.get("elements")) + val flows = jacksonObjectMapper().treeToValue>(result.get("flows")) + + val creator = ProcessModelCreator(request.activities) + val processId = creator.createProcess(elements, flows) + + logger.info("ProcessAgentFunction result: $processId") + + return ProcessAgentResult(processId ?: "") + } + + companion object : KLogging() } diff --git a/core/src/main/kotlin/io/holunda/connector/process/ProcessAgentRequest.kt b/core/src/main/kotlin/io/holunda/connector/process/ProcessAgentRequest.kt index 5b1c2ed..fb18e8c 100644 --- a/core/src/main/kotlin/io/holunda/connector/process/ProcessAgentRequest.kt +++ b/core/src/main/kotlin/io/holunda/connector/process/ProcessAgentRequest.kt @@ -4,8 +4,8 @@ import com.fasterxml.jackson.databind.* import io.holunda.connector.common.* data class ProcessAgentRequest( - val inputJson: JsonNode, - val taskDescription: String, - val activities: Map, - val model: Model + val inputJson: JsonNode, + val taskDescription: String, + val activities: Map, + val model: Model ) diff --git a/core/src/main/kotlin/io/holunda/connector/process/ProcessAgentResult.kt b/core/src/main/kotlin/io/holunda/connector/process/ProcessAgentResult.kt index 950475e..9e5ee4b 100644 --- a/core/src/main/kotlin/io/holunda/connector/process/ProcessAgentResult.kt +++ b/core/src/main/kotlin/io/holunda/connector/process/ProcessAgentResult.kt @@ -1,5 +1,5 @@ package io.holunda.connector.process data class ProcessAgentResult( - val result: Any + val result: Any ) diff --git a/core/src/main/kotlin/io/holunda/connector/process/ProcessAgentTask.kt b/core/src/main/kotlin/io/holunda/connector/process/ProcessAgentTask.kt new file mode 100644 index 0000000..b32a9d6 --- /dev/null +++ b/core/src/main/kotlin/io/holunda/connector/process/ProcessAgentTask.kt @@ -0,0 +1,20 @@ +package io.holunda.connector.process + +import com.fasterxml.jackson.databind.* + +data class ProcessAgentTask( + val model: String, + val task: String, + val context: JsonNode, + val activities: Map, +) { + companion object { + fun fromRequest(request: ProcessAgentRequest) = + ProcessAgentTask( + request.model.modelId, + request.taskDescription, + request.inputJson, + request.activities.mapValues { it.value.description } + ) + } +} diff --git a/core/src/main/kotlin/io/holunda/connector/process/ProcessModelCreator.kt b/core/src/main/kotlin/io/holunda/connector/process/ProcessModelCreator.kt index e728771..9336b29 100644 --- a/core/src/main/kotlin/io/holunda/connector/process/ProcessModelCreator.kt +++ b/core/src/main/kotlin/io/holunda/connector/process/ProcessModelCreator.kt @@ -13,183 +13,184 @@ private const val MODELER_SCHEMA = "http://camunda.org/schema/modeler/1.0" class ProcessModelCreator(val activityDefinitions: Map) { - private val nodeBuilders = mutableMapOf>() - private val adjacencyList = mutableMapOf>() - - companion object { - val objectMapper = jacksonObjectMapper().enable(SerializationFeature.INDENT_OUTPUT) - - val templates = mapOf( - "gpt-database" to "io.holunda.connector.database.v1", - "gpt-openapi" to "io.holunda.connector.openapi.v1", - "gpt-retrieval" to "io.holunda.connector.retrieval.v1", - ) - val icons = mapOf( - "gpt-database" to "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48IS0tIFVwbG9hZGVkIHRvOiBTVkcgUmVwbywgd3d3LnN2Z3JlcG8uY29tLCBHZW5lcmF0b3I6IFNWRyBSZXBvIE1peGVyIFRvb2xzIC0tPg0KPHN2ZyB3aWR0aD0iODAwcHgiIGhlaWdodD0iODAwcHgiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4NCjxwYXRoIGQ9Ik0zLjE3MDA0IDcuNDM5OTRMMTIgMTIuNTQ5OUwyMC43NyA3LjQ2OTkxIiBzdHJva2U9IiMyOTJEMzIiIHN0cm9rZS13aWR0aD0iMS41IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiLz4NCjxwYXRoIGQ9Ik0xMiAyMS42MDk5VjEyLjUzOTkiIHN0cm9rZT0iIzI5MkQzMiIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIvPg0KPHBhdGggZD0iTTIxLjYxIDEyLjgzVjkuMTdDMjEuNjEgNy43OSAyMC42MiA2LjExMDAyIDE5LjQxIDUuNDQwMDJMMTQuMDcgMi40OEMxMi45MyAxLjg0IDExLjA3IDEuODQgOS45Mjk5OSAyLjQ4TDQuNTkgNS40NDAwMkMzLjM4IDYuMTEwMDIgMi4zOTAwMSA3Ljc5IDIuMzkwMDEgOS4xN1YxNC44M0MyLjM5MDAxIDE2LjIxIDMuMzggMTcuODkgNC41OSAxOC41Nkw5LjkyOTk5IDIxLjUyQzEwLjUgMjEuODQgMTEuMjUgMjIgMTIgMjJDMTIuNzUgMjIgMTMuNSAyMS44NCAxNC4wNyAyMS41MiIgc3Ryb2tlPSIjMjkyRDMyIiBzdHJva2Utd2lkdGg9IjEuNSIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIi8+DQo8cGF0aCBkPSJNMTkuMiAyMS40QzIwLjk2NzMgMjEuNCAyMi40IDE5Ljk2NzMgMjIuNCAxOC4yQzIyLjQgMTYuNDMyNyAyMC45NjczIDE1IDE5LjIgMTVDMTcuNDMyNyAxNSAxNiAxNi40MzI3IDE2IDE4LjJDMTYgMTkuOTY3MyAxNy40MzI3IDIxLjQgMTkuMiAyMS40WiIgc3Ryb2tlPSIjMjkyRDMyIiBzdHJva2Utd2lkdGg9IjEuNSIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIi8+DQo8cGF0aCBkPSJNMjMgMjJMMjIgMjEiIHN0cm9rZT0iIzI5MkQzMiIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIvPg0KPC9zdmc+", - "gpt-openapi" to "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48IS0tIFVwbG9hZGVkIHRvOiBTVkcgUmVwbywgd3d3LnN2Z3JlcG8uY29tLCBHZW5lcmF0b3I6IFNWRyBSZXBvIE1peGVyIFRvb2xzIC0tPg0KPHN2ZyB3aWR0aD0iODAwcHgiIGhlaWdodD0iODAwcHgiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4NCjxwYXRoIGQ9Ik0xMiAyMkMxNy41MjI4IDIyIDIyIDE3LjUyMjggMjIgMTJDMjIgNi40NzcxNSAxNy41MjI4IDIgMTIgMkM2LjQ3NzE1IDIgMiA2LjQ3NzE1IDIgMTJDMiAxNy41MjI4IDYuNDc3MTUgMjIgMTIgMjJaIiBzdHJva2U9IiMyOTJEMzIiIHN0cm9rZS13aWR0aD0iMS41IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiLz4NCjxwYXRoIGQ9Ik03Ljk5OTk4IDNIOC45OTk5OEM3LjA0OTk4IDguODQgNy4wNDk5OCAxNS4xNiA4Ljk5OTk4IDIxSDcuOTk5OTgiIHN0cm9rZT0iIzI5MkQzMiIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIvPg0KPHBhdGggZD0iTTE1IDNDMTYuOTUgOC44NCAxNi45NSAxNS4xNiAxNSAyMSIgc3Ryb2tlPSIjMjkyRDMyIiBzdHJva2Utd2lkdGg9IjEuNSIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIi8+DQo8cGF0aCBkPSJNMyAxNlYxNUM4Ljg0IDE2Ljk1IDE1LjE2IDE2Ljk1IDIxIDE1VjE2IiBzdHJva2U9IiMyOTJEMzIiIHN0cm9rZS13aWR0aD0iMS41IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiLz4NCjxwYXRoIGQ9Ik0zIDkuMDAwMUM4Ljg0IDcuMDUwMSAxNS4xNiA3LjA1MDEgMjEgOS4wMDAxIiBzdHJva2U9IiMyOTJEMzIiIHN0cm9rZS13aWR0aD0iMS41IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiLz4NCjwvc3ZnPg==", - "gpt-retrieval" to "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48IS0tIFVwbG9hZGVkIHRvOiBTVkcgUmVwbywgd3d3LnN2Z3JlcG8uY29tLCBHZW5lcmF0b3I6IFNWRyBSZXBvIE1peGVyIFRvb2xzIC0tPg0KPHN2ZyB3aWR0aD0iODAwcHgiIGhlaWdodD0iODAwcHgiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4NCjxwYXRoIGQ9Ik0xNyAxOC40MzAxSDEzTDguNTQ5OTkgMjEuMzlDNy44ODk5OSAyMS44MyA3IDIxLjM2MDEgNyAyMC41NjAxVjE4LjQzMDFDNCAxOC40MzAxIDIgMTYuNDMwMSAyIDEzLjQzMDFWNy40Mjk5OUMyIDQuNDI5OTkgNCAyLjQyOTk5IDcgMi40Mjk5OUgxN0MyMCAyLjQyOTk5IDIyIDQuNDI5OTkgMjIgNy40Mjk5OVYxMy40MzAxQzIyIDE2LjQzMDEgMjAgMTguNDMwMSAxNyAxOC40MzAxWiIgc3Ryb2tlPSIjMjkyRDMyIiBzdHJva2Utd2lkdGg9IjEuNSIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiLz4NCjxwYXRoIGQ9Ik0xMi4wMDAxIDExLjM2VjExLjE1QzEyLjAwMDEgMTAuNDcgMTIuNDIwMSAxMC4xMSAxMi44NDAxIDkuODIwMDFDMTMuMjUwMSA5LjU0MDAxIDEzLjY2IDkuMTgwMDIgMTMuNjYgOC41MjAwMkMxMy42NiA3LjYwMDAyIDEyLjkyMDEgNi44NTk5OSAxMi4wMDAxIDYuODU5OTlDMTEuMDgwMSA2Ljg1OTk5IDEwLjM0MDEgNy42MDAwMiAxMC4zNDAxIDguNTIwMDIiIHN0cm9rZT0iIzI5MkQzMiIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIvPg0KPHBhdGggZD0iTTExLjk5NTUgMTMuNzVIMTIuMDA0NSIgc3Ryb2tlPSIjMjkyRDMyIiBzdHJva2Utd2lkdGg9IjEuNSIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIi8+DQo8L3N2Zz4=" - ) - } - - fun createProcess( - elementDefinitions: List, - flowDefinitions: List, - ): String? { - // Create adjacency list for depth-first creation of process - for (flowDefinition in flowDefinitions) { - val from = flowDefinition.from - adjacencyList.getOrPut(from) { mutableListOf() }.add(flowDefinition) - } + private val nodeBuilders = mutableMapOf>() + private val adjacencyList = mutableMapOf>() - val nodeStack = Stack() + companion object { + val objectMapper = jacksonObjectMapper().enable(SerializationFeature.INDENT_OUTPUT) - val processBuilder = Bpmn.createExecutableProcess() - registerNamespaces(processBuilder) + val templates = mapOf( + "gpt-database" to "io.holunda.connector.database.v1", + "gpt-openapi" to "io.holunda.connector.openapi.v1", + "gpt-retrieval" to "io.holunda.connector.retrieval.v1", + ) + val icons = mapOf( + "gpt-database" to "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48IS0tIFVwbG9hZGVkIHRvOiBTVkcgUmVwbywgd3d3LnN2Z3JlcG8uY29tLCBHZW5lcmF0b3I6IFNWRyBSZXBvIE1peGVyIFRvb2xzIC0tPg0KPHN2ZyB3aWR0aD0iODAwcHgiIGhlaWdodD0iODAwcHgiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4NCjxwYXRoIGQ9Ik0zLjE3MDA0IDcuNDM5OTRMMTIgMTIuNTQ5OUwyMC43NyA3LjQ2OTkxIiBzdHJva2U9IiMyOTJEMzIiIHN0cm9rZS13aWR0aD0iMS41IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiLz4NCjxwYXRoIGQ9Ik0xMiAyMS42MDk5VjEyLjUzOTkiIHN0cm9rZT0iIzI5MkQzMiIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIvPg0KPHBhdGggZD0iTTIxLjYxIDEyLjgzVjkuMTdDMjEuNjEgNy43OSAyMC42MiA2LjExMDAyIDE5LjQxIDUuNDQwMDJMMTQuMDcgMi40OEMxMi45MyAxLjg0IDExLjA3IDEuODQgOS45Mjk5OSAyLjQ4TDQuNTkgNS40NDAwMkMzLjM4IDYuMTEwMDIgMi4zOTAwMSA3Ljc5IDIuMzkwMDEgOS4xN1YxNC44M0MyLjM5MDAxIDE2LjIxIDMuMzggMTcuODkgNC41OSAxOC41Nkw5LjkyOTk5IDIxLjUyQzEwLjUgMjEuODQgMTEuMjUgMjIgMTIgMjJDMTIuNzUgMjIgMTMuNSAyMS44NCAxNC4wNyAyMS41MiIgc3Ryb2tlPSIjMjkyRDMyIiBzdHJva2Utd2lkdGg9IjEuNSIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIi8+DQo8cGF0aCBkPSJNMTkuMiAyMS40QzIwLjk2NzMgMjEuNCAyMi40IDE5Ljk2NzMgMjIuNCAxOC4yQzIyLjQgMTYuNDMyNyAyMC45NjczIDE1IDE5LjIgMTVDMTcuNDMyNyAxNSAxNiAxNi40MzI3IDE2IDE4LjJDMTYgMTkuOTY3MyAxNy40MzI3IDIxLjQgMTkuMiAyMS40WiIgc3Ryb2tlPSIjMjkyRDMyIiBzdHJva2Utd2lkdGg9IjEuNSIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIi8+DQo8cGF0aCBkPSJNMjMgMjJMMjIgMjEiIHN0cm9rZT0iIzI5MkQzMiIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIvPg0KPC9zdmc+", + "gpt-openapi" to "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48IS0tIFVwbG9hZGVkIHRvOiBTVkcgUmVwbywgd3d3LnN2Z3JlcG8uY29tLCBHZW5lcmF0b3I6IFNWRyBSZXBvIE1peGVyIFRvb2xzIC0tPg0KPHN2ZyB3aWR0aD0iODAwcHgiIGhlaWdodD0iODAwcHgiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4NCjxwYXRoIGQ9Ik0xMiAyMkMxNy41MjI4IDIyIDIyIDE3LjUyMjggMjIgMTJDMjIgNi40NzcxNSAxNy41MjI4IDIgMTIgMkM2LjQ3NzE1IDIgMiA2LjQ3NzE1IDIgMTJDMiAxNy41MjI4IDYuNDc3MTUgMjIgMTIgMjJaIiBzdHJva2U9IiMyOTJEMzIiIHN0cm9rZS13aWR0aD0iMS41IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiLz4NCjxwYXRoIGQ9Ik03Ljk5OTk4IDNIOC45OTk5OEM3LjA0OTk4IDguODQgNy4wNDk5OCAxNS4xNiA4Ljk5OTk4IDIxSDcuOTk5OTgiIHN0cm9rZT0iIzI5MkQzMiIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIvPg0KPHBhdGggZD0iTTE1IDNDMTYuOTUgOC44NCAxNi45NSAxNS4xNiAxNSAyMSIgc3Ryb2tlPSIjMjkyRDMyIiBzdHJva2Utd2lkdGg9IjEuNSIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIi8+DQo8cGF0aCBkPSJNMyAxNlYxNUM4Ljg0IDE2Ljk1IDE1LjE2IDE2Ljk1IDIxIDE1VjE2IiBzdHJva2U9IiMyOTJEMzIiIHN0cm9rZS13aWR0aD0iMS41IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiLz4NCjxwYXRoIGQ9Ik0zIDkuMDAwMUM4Ljg0IDcuMDUwMSAxNS4xNiA3LjA1MDEgMjEgOS4wMDAxIiBzdHJva2U9IiMyOTJEMzIiIHN0cm9rZS13aWR0aD0iMS41IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiLz4NCjwvc3ZnPg==", + "gpt-retrieval" to "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48IS0tIFVwbG9hZGVkIHRvOiBTVkcgUmVwbywgd3d3LnN2Z3JlcG8uY29tLCBHZW5lcmF0b3I6IFNWRyBSZXBvIE1peGVyIFRvb2xzIC0tPg0KPHN2ZyB3aWR0aD0iODAwcHgiIGhlaWdodD0iODAwcHgiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4NCjxwYXRoIGQ9Ik0xNyAxOC40MzAxSDEzTDguNTQ5OTkgMjEuMzlDNy44ODk5OSAyMS44MyA3IDIxLjM2MDEgNyAyMC41NjAxVjE4LjQzMDFDNCAxOC40MzAxIDIgMTYuNDMwMSAyIDEzLjQzMDFWNy40Mjk5OUMyIDQuNDI5OTkgNCAyLjQyOTk5IDcgMi40Mjk5OUgxN0MyMCAyLjQyOTk5IDIyIDQuNDI5OTkgMjIgNy40Mjk5OVYxMy40MzAxQzIyIDE2LjQzMDEgMjAgMTguNDMwMSAxNyAxOC40MzAxWiIgc3Ryb2tlPSIjMjkyRDMyIiBzdHJva2Utd2lkdGg9IjEuNSIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiLz4NCjxwYXRoIGQ9Ik0xMi4wMDAxIDExLjM2VjExLjE1QzEyLjAwMDEgMTAuNDcgMTIuNDIwMSAxMC4xMSAxMi44NDAxIDkuODIwMDFDMTMuMjUwMSA5LjU0MDAxIDEzLjY2IDkuMTgwMDIgMTMuNjYgOC41MjAwMkMxMy42NiA3LjYwMDAyIDEyLjkyMDEgNi44NTk5OSAxMi4wMDAxIDYuODU5OTlDMTEuMDgwMSA2Ljg1OTk5IDEwLjM0MDEgNy42MDAwMiAxMC4zNDAxIDguNTIwMDIiIHN0cm9rZT0iIzI5MkQzMiIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIvPg0KPHBhdGggZD0iTTExLjk5NTUgMTMuNzVIMTIuMDA0NSIgc3Ryb2tlPSIjMjkyRDMyIiBzdHJva2Utd2lkdGg9IjEuNSIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIi8+DQo8L3N2Zz4=" + ) + } - nodeStack.push( - createStartEvent(elementDefinitions, processBuilder) - ) + fun createProcess( + elementDefinitions: List, + flowDefinitions: List, + ): String? { + // Create adjacency list for depth-first creation of process + for (flowDefinition in flowDefinitions) { + val from = flowDefinition.from + adjacencyList.getOrPut(from) { mutableListOf() }.add(flowDefinition) + } - // Create process depth-first - while (!nodeStack.isEmpty()) { - val fromNodeName = nodeStack.pop() + val nodeStack = Stack() - adjacencyList[fromNodeName]?.forEach { outgoingFlowDefinition -> - val toNodeName = outgoingFlowDefinition.to - val fromNode = nodeBuilders[fromNodeName]!! - val condition = outgoingFlowDefinition.condition + val processBuilder = Bpmn.createExecutableProcess() + registerNamespaces(processBuilder) - if (!condition.isNullOrEmpty()) { - fromNode.condition(condition.toFeelExpression()) - } + nodeStack.push( + createStartEvent(elementDefinitions, processBuilder) + ) - // Create the 'to' node if it has not been created yet - if (!nodeBuilders.containsKey(toNodeName)) { - // flow is automatically added by builder method - createNode(elementDefinitions, toNodeName, fromNodeName) - } else { - // If node already exists, we need to manually add the flow to it - val toNode = nodeBuilders[toNodeName]!! - fromNode.connectTo(toNode.element.id) + // Create process depth-first + while (!nodeStack.isEmpty()) { + val fromNodeName = nodeStack.pop() + + adjacencyList[fromNodeName]?.forEach { outgoingFlowDefinition -> + val toNodeName = outgoingFlowDefinition.to + val fromNode = nodeBuilders[fromNodeName]!! + val condition = outgoingFlowDefinition.condition + + if (!condition.isNullOrEmpty()) { + fromNode.condition(condition.toFeelExpression()) + } + + // Create the 'to' node if it has not been created yet + if (!nodeBuilders.containsKey(toNodeName)) { + // flow is automatically added by builder method + createNode(elementDefinitions, toNodeName, fromNodeName) + } else { + // If node already exists, we need to manually add the flow to it + val toNode = nodeBuilders[toNodeName]!! + fromNode.connectTo(toNode.element.id) + } + + nodeStack.push(toNodeName) + } } - nodeStack.push(toNodeName) - } + val modelInstance = processBuilder.done() + + val client = ZeebeClient.newClientBuilder().usePlaintext().build() + + val res = client.newDeployResourceCommand() + .addProcessModel(modelInstance, UUID.randomUUID().toString() + ".bpmn") + .send().join() + + return res.processes.first().bpmnProcessId } - val modelInstance = processBuilder.done() + private fun createNode(elementDefinitions: List, toNodeName: String, nodeName: String) { + val toNodeDefinition = elementDefinitions.findByName(toNodeName) + ?: throw IllegalStateException("Flow target $toNodeName not found.") - val client = ZeebeClient.newClientBuilder().usePlaintext().build() + val type = toNodeDefinition.type + val name = toNodeDefinition.name + var builder = nodeBuilders[nodeName]!! - val res = client.newDeployResourceCommand() - .addProcessModel(modelInstance, UUID.randomUUID().toString() + ".bpmn") - .send().join() + builder = when (type) { + "user_task" -> builder + .userTask(toNodeDefinition.name) + .zeebeUserTaskForm( + FormGenerator.generate(toNodeDefinition.instruction ?: "", toNodeDefinition.input_variables) + ) - return res.processes.first().bpmnProcessId - } + "end" -> builder.endEvent(name) + "gateway" -> builder.exclusiveGateway(name) + else -> createServiceTask(builder, toNodeDefinition) + } + nodeBuilders[name] = builder + } - private fun createNode(elementDefinitions: List, toNodeName: String, nodeName: String) { - val toNodeDefinition = elementDefinitions.findByName(toNodeName) - ?: throw IllegalStateException("Flow target $toNodeName not found.") + private fun createStartEvent(elementDefinitions: List, processBuilder: ProcessBuilder) = + elementDefinitions.findStartEvent() + ?.let { startDefinition -> + val name = startDefinition.name + val startEventBuilder = processBuilder.startEvent(name) + nodeBuilders[name] = startEventBuilder + name + } ?: throw IllegalArgumentException("No start event found") + + private fun createServiceTask(builder: AbstractFlowNodeBuilder<*, *>, elementDefinition: Element): ServiceTaskBuilder { + val activityDefinition = activityDefinitions[elementDefinition.type] + ?: throw IllegalStateException("No activity definition for element type ${elementDefinition.type}.") + + val serviceTaskBuilder = builder + .serviceTask(elementDefinition.name) + .zeebeJobType(activityDefinition.task) + + // is connector? + if (activityDefinition.task in templates.keys) { + addDefaultInputs(serviceTaskBuilder, elementDefinition) + addInputsFromAttributes(serviceTaskBuilder, activityDefinition.attributes) + addConnectorTemplate(serviceTaskBuilder, elementDefinition) + } + return serviceTaskBuilder + } - val type = toNodeDefinition.type - val name = toNodeDefinition.name - var builder = nodeBuilders[nodeName]!! + private fun addInputsFromAttributes(serviceTaskBuilder: ServiceTaskBuilder, attributes: Map) { + attributes.entries.forEach { + serviceTaskBuilder.zeebeInput(it.value, it.key) + } + } - builder = when (type) { - "user_task" -> builder - .userTask(toNodeDefinition.name) - .zeebeUserTaskForm( - FormGenerator.generate(toNodeDefinition.instruction ?: "", toNodeDefinition.input_variables) - ) - "end" -> builder.endEvent(name) - "gateway" -> builder.exclusiveGateway(name) - else -> createServiceTask(builder, toNodeDefinition) + private fun addDefaultInputs(serviceTaskBuilder: ServiceTaskBuilder, elementDefinition: Element) { + val inputVarMap = elementDefinition.input_variables.associateBy({ it }) { it } + serviceTaskBuilder + .zeebeInput("secrets.OPENAI_API_KEY", "apiKey") + .zeebeInput("GPT_4", "model") + .zeebeInput("=" + objectMapper.writeValueAsString(inputVarMap).replace("\"", ""), "inputJson") + .zeebeInput(elementDefinition.instruction, "query") + + if (elementDefinition.output_variable != null && elementDefinition.output_schema != null) { + serviceTaskBuilder.zeebeTaskHeader("resultExpression", "={" + elementDefinition.output_variable + ": result}") + serviceTaskBuilder.zeebeInput("=" + objectMapper.writeValueAsString(elementDefinition.output_schema), "outputSchema") + } + } + + private fun addDatabaseConnectorAttributes(serviceTaskBuilder: ServiceTaskBuilder, elementDefinition: Element, activity: ActivityDefinition) { + serviceTaskBuilder + .zeebeInput(activity.attributes["databaseUrl"], "databaseUrl") + .zeebeInput("NULL", "missingDataBehavior") } - nodeBuilders[name] = builder - } - - private fun createStartEvent(elementDefinitions: List, processBuilder: ProcessBuilder) = - elementDefinitions.findStartEvent() - ?.let { startDefinition -> - val name = startDefinition.name - val startEventBuilder = processBuilder.startEvent(name) - nodeBuilders[name] = startEventBuilder - name - } ?: throw IllegalArgumentException("No start event found") - - private fun createServiceTask(builder: AbstractFlowNodeBuilder<*, *>, elementDefinition: Element): ServiceTaskBuilder { - val activityDefinition = activityDefinitions[elementDefinition.type] - ?: throw IllegalStateException("No activity definition for element type ${elementDefinition.type}.") - - val serviceTaskBuilder = builder - .serviceTask(elementDefinition.name) - .zeebeJobType(activityDefinition.task) - - // is connector? - if (activityDefinition.task in templates.keys) { - addDefaultInputs(serviceTaskBuilder, elementDefinition) - addInputsFromAttributes(serviceTaskBuilder, activityDefinition.attributes) - addConnectorTemplate(serviceTaskBuilder, elementDefinition) + + private fun registerNamespaces(processBuilder: ProcessBuilder) { + val root = processBuilder.element.modelInstance.document.rootElement + root.registerNamespace("zeebe", ZEEBE_SCHEMA) + root.registerNamespace("modeler", MODELER_SCHEMA) } - return serviceTaskBuilder - } - private fun addInputsFromAttributes(serviceTaskBuilder: ServiceTaskBuilder, attributes: Map) { - attributes.entries.forEach { - serviceTaskBuilder.zeebeInput(it.value, it.key) + private fun addConnectorTemplate(builder: AbstractFlowNodeBuilder<*, *>, elementDefinition: Element) { + val dom = builder.element.domElement + dom.setAttribute(ZEEBE_SCHEMA, "modelerTemplate", templates[activityDefinitions[elementDefinition.type]!!.task!!]!!) + dom.setAttribute(ZEEBE_SCHEMA, "modelerTemplateVersion", "1") + dom.setAttribute(ZEEBE_SCHEMA, "modelerTemplateIcon", icons[activityDefinitions[elementDefinition.type]!!.task!!]!!) } - } - - private fun addDefaultInputs(serviceTaskBuilder: ServiceTaskBuilder, elementDefinition: Element) { - val inputVarMap = elementDefinition.input_variables.associateBy({it}) { it } - serviceTaskBuilder - .zeebeInput("secrets.OPENAI_API_KEY", "apiKey") - .zeebeInput("GPT_4", "model") - .zeebeInput("=" + objectMapper.writeValueAsString(inputVarMap).replace("\"", ""), "inputJson") - .zeebeInput(elementDefinition.instruction, "query") - - if (elementDefinition.output_variable != null && elementDefinition.output_schema != null) { - serviceTaskBuilder.zeebeTaskHeader("resultExpression", "={" + elementDefinition.output_variable + ": result}") - serviceTaskBuilder.zeebeInput("=" + objectMapper.writeValueAsString(elementDefinition.output_schema), "outputSchema") + + private fun String.toFeelExpression(): String { + val feel = if (startsWith("!")) { + this.drop(1) + " = false" + } else this + return "=$feel" } - } - - private fun addDatabaseConnectorAttributes(serviceTaskBuilder: ServiceTaskBuilder, elementDefinition: Element, activity: ActivityDefinition) { - serviceTaskBuilder - .zeebeInput(activity.attributes["databaseUrl"], "databaseUrl") - .zeebeInput("NULL", "missingDataBehavior") - } - - private fun registerNamespaces(processBuilder: ProcessBuilder) { - val root = processBuilder.element.modelInstance.document.rootElement - root.registerNamespace("zeebe", ZEEBE_SCHEMA) - root.registerNamespace("modeler", MODELER_SCHEMA) - } - - private fun addConnectorTemplate(builder: AbstractFlowNodeBuilder<*, *>, elementDefinition: Element) { - val dom = builder.element.domElement - dom.setAttribute(ZEEBE_SCHEMA, "modelerTemplate", templates[activityDefinitions[elementDefinition.type]!!.task!!]!!) - dom.setAttribute(ZEEBE_SCHEMA, "modelerTemplateVersion", "1") - dom.setAttribute(ZEEBE_SCHEMA, "modelerTemplateIcon", icons[activityDefinitions[elementDefinition.type]!!.task!!]!!) - } - - private fun String.toFeelExpression(): String { - val feel = if (startsWith("!")) { - this.drop(1) + " = false" - } else this - return "=$feel" - } - - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - private fun writeModelToFile(modelInstance: BpmnModelInstance?, filePath: String) { - try { - val file = File(filePath) - Bpmn.writeModelToFile(file, modelInstance) - } catch (e: Exception) { - throw RuntimeException("Failed to write BPMN model to file: $filePath", e) + + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + private fun writeModelToFile(modelInstance: BpmnModelInstance?, filePath: String) { + try { + val file = File(filePath) + Bpmn.writeModelToFile(file, modelInstance) + } catch (e: Exception) { + throw RuntimeException("Failed to write BPMN model to file: $filePath", e) + } } - } } diff --git a/core/src/main/kotlin/io/holunda/connector/process/Types.kt b/core/src/main/kotlin/io/holunda/connector/process/Types.kt index e8a343d..95096b9 100644 --- a/core/src/main/kotlin/io/holunda/connector/process/Types.kt +++ b/core/src/main/kotlin/io/holunda/connector/process/Types.kt @@ -3,27 +3,27 @@ package io.holunda.connector.process import com.fasterxml.jackson.databind.* data class ActivityDefinition( - val task: String?, - val description: String, - val attributes: Map = mapOf() + val task: String?, + val description: String, + val attributes: Map = mapOf() ) data class Element( - val type: String, - val name: String, - val instruction: String?, - val input_variables: List = emptyList(), - val output_variable: String?, - val output_schema: JsonNode? + val type: String, + val name: String, + val instruction: String?, + val input_variables: List = emptyList(), + val output_variable: String?, + val output_schema: JsonNode? ) { - fun isStartEvent() = (type == "start") + fun isStartEvent() = (type == "start") } fun List.findStartEvent() = firstOrNull { it.isStartEvent() } fun List.findByName(name: String) = firstOrNull { it.name == name } data class Flow( - val from: String, - val to: String, - val condition: String?, + val from: String, + val to: String, + val condition: String?, ) diff --git a/core/src/main/kotlin/io/holunda/connector/retrieval/RetrievalFunction.kt b/core/src/main/kotlin/io/holunda/connector/retrieval/RetrievalFunction.kt index ede1d77..557ac19 100644 --- a/core/src/main/kotlin/io/holunda/connector/retrieval/RetrievalFunction.kt +++ b/core/src/main/kotlin/io/holunda/connector/retrieval/RetrievalFunction.kt @@ -1,63 +1,38 @@ package io.holunda.connector.retrieval -import com.fasterxml.jackson.databind.* import io.camunda.connector.api.annotation.* import io.camunda.connector.api.outbound.* import io.holunda.connector.common.* -import io.holunda.connector.compose.* -import io.holunda.connector.database.* -import io.holunda.connector.openapi.* import mu.* -import org.apache.commons.text.* -import org.slf4j.* -import java.util.* - @OutboundConnector( - name = "gpt-retrieval", - inputVariables = ["query", "outputSchema", "database", "databaseUrl", "embeddingProvider", "embeddingModel", "mode", "model"], - type = "io.holunda.connector.retrieval:1" + name = "gpt-retrieval", + inputVariables = [ + "query", + "outputSchema", + "database", + "databaseUrl", + "embeddingProvider", + "embeddingModel", + "mode", + "model" + ], + type = "io.holunda:connector-retrieval:1" ) class RetrievalFunction : OutboundConnectorFunction { - @Throws(Exception::class) - override fun execute(context: OutboundConnectorContext): Any { - logger.info("Executing RetrievalFunction") - val connectorRequest = context.variables.readFromJson() - //val connectorRequest = context.bindVariables(RetrievalRequest::class.java) - logger.info("Request: {}", connectorRequest) - return executeConnector(connectorRequest) - } - - private fun executeConnector(request: RetrievalRequest): RetrievalResult { - val result = LLMServiceClient.run("retrieval", - RetrievalTask( - request.model.modelId, - request.query, - request.database, - request.databaseUrl, - request.embeddingProvider, - request.embeddingModel, - request.mode, - request.outputSchema - ) - ) - - logger.info("RetrievalFunction result: $result") - - return RetrievalResult(result) - } + override fun execute(context: OutboundConnectorContext): Any { + logger.info("Executing RetrievalFunction") + val connectorRequest = context.variables.readFromJson() + logger.info("RetrievalFunction request: $connectorRequest") + return executeRequest(connectorRequest) + } - data class RetrievalTask( - val model: String, - val query: String, - val database: String, - val database_url: String, - val embedding_provider: String, - val embedding_model: String, - val mode: String, - val output_schema: JsonNode?, - ) + private fun executeRequest(request: RetrievalRequest): RetrievalResult { + val result = LLMServiceClient.run("retrieval", RetrievalTask.fromRequest(request)) + logger.info("RetrievalFunction result: $result") + return RetrievalResult(result) + } - companion object : KLogging() + companion object : KLogging() } diff --git a/core/src/main/kotlin/io/holunda/connector/retrieval/RetrievalRequest.kt b/core/src/main/kotlin/io/holunda/connector/retrieval/RetrievalRequest.kt index 64ce1b5..da9cfeb 100644 --- a/core/src/main/kotlin/io/holunda/connector/retrieval/RetrievalRequest.kt +++ b/core/src/main/kotlin/io/holunda/connector/retrieval/RetrievalRequest.kt @@ -1,15 +1,15 @@ package io.holunda.connector.retrieval -import com.fasterxml.jackson.databind.JsonNode +import com.fasterxml.jackson.databind.* import io.holunda.connector.common.* data class RetrievalRequest( - val query: String, - val database: String, - val databaseUrl: String, - val embeddingProvider: String, - val embeddingModel: String, - val mode: String, - val outputSchema: JsonNode?, - val model: Model + val query: String, + val database: String, + val databaseUrl: String, + val embeddingProvider: String, + val embeddingModel: String, + val mode: String, + val outputSchema: JsonNode?, + val model: Model ) diff --git a/core/src/main/kotlin/io/holunda/connector/retrieval/RetrievalResult.kt b/core/src/main/kotlin/io/holunda/connector/retrieval/RetrievalResult.kt index 053d611..33a099a 100644 --- a/core/src/main/kotlin/io/holunda/connector/retrieval/RetrievalResult.kt +++ b/core/src/main/kotlin/io/holunda/connector/retrieval/RetrievalResult.kt @@ -1,5 +1,5 @@ package io.holunda.connector.retrieval data class RetrievalResult( - val result: Any + val result: Any ) diff --git a/core/src/main/kotlin/io/holunda/connector/retrieval/RetrievalTask.kt b/core/src/main/kotlin/io/holunda/connector/retrieval/RetrievalTask.kt new file mode 100644 index 0000000..0e7c9f2 --- /dev/null +++ b/core/src/main/kotlin/io/holunda/connector/retrieval/RetrievalTask.kt @@ -0,0 +1,28 @@ +package io.holunda.connector.retrieval + +import com.fasterxml.jackson.databind.* + +data class RetrievalTask( + val model: String, + val query: String, + val database: String, + val database_url: String, + val embedding_provider: String, + val embedding_model: String, + val mode: String, + val output_schema: JsonNode?, +) { + companion object { + fun fromRequest(request: RetrievalRequest) = + RetrievalTask( + request.model.modelId, + request.query, + request.database, + request.databaseUrl, + request.embeddingProvider, + request.embeddingModel, + request.mode, + request.outputSchema + ) + } +} diff --git a/core/src/main/kotlin/io/holunda/connector/translate/TranslateFunction.kt b/core/src/main/kotlin/io/holunda/connector/translate/TranslateFunction.kt index 46a9989..c6892c3 100644 --- a/core/src/main/kotlin/io/holunda/connector/translate/TranslateFunction.kt +++ b/core/src/main/kotlin/io/holunda/connector/translate/TranslateFunction.kt @@ -1,54 +1,33 @@ package io.holunda.connector.translate -import com.fasterxml.jackson.databind.* -import com.fasterxml.jackson.module.kotlin.* import io.camunda.connector.api.annotation.* -import io.camunda.connector.api.error.* import io.camunda.connector.api.outbound.* import io.holunda.connector.common.* -import io.holunda.connector.compose.* -import io.holunda.connector.extract.* -import org.apache.commons.text.* -import org.slf4j.* -import java.util.* +import mu.* @OutboundConnector( - name = "gpt-translate", - inputVariables = ["inputJson", "language", "model"], - type = "io.holunda.connector.translate:1" + name = "gpt-translate", + inputVariables = [ + "inputJson", + "language", + "model" + ], + type = "io.holunda.connector.translate:1" ) class TranslateFunction : OutboundConnectorFunction { - @Throws(Exception::class) - override fun execute(context: OutboundConnectorContext): Any { - LOG.info("Executing TranslateFunction") - val connectorRequest = context.variables.readFromJson() - //val connectorRequest = context.bindVariables(TranslateRequest::class.java) - LOG.info("Request: {}", connectorRequest) - return executeConnector(connectorRequest) - } + override fun execute(context: OutboundConnectorContext): Any { + logger.info("Executing TranslateFunction") + val connectorRequest = context.variables.readFromJson() + logger.info("TranslateFunction request: $connectorRequest") + return executeRequest(connectorRequest) + } - private fun executeConnector(request: TranslateRequest): TranslateResult { - val result = LLMServiceClient.run("translate", - TranslateTask( - request.model.modelId, - request.inputJson, - request.language - ) - ) + private fun executeRequest(request: TranslateRequest): TranslateResult { + val result = LLMServiceClient.run("translate", TranslateTask.fromRequest(request)) + logger.info("TranslateFunction result: $result") + return TranslateResult(result) + } - LOG.info("TranslateFunction result: $result") - - return TranslateResult(result) - } - - data class TranslateTask( - val model: String, - val input: JsonNode, - val target_language: String, - ) - - companion object { - private val LOG = LoggerFactory.getLogger(TranslateFunction::class.java) - } + companion object : KLogging() } diff --git a/core/src/main/kotlin/io/holunda/connector/translate/TranslateRequest.kt b/core/src/main/kotlin/io/holunda/connector/translate/TranslateRequest.kt index bbe73a8..684bc79 100644 --- a/core/src/main/kotlin/io/holunda/connector/translate/TranslateRequest.kt +++ b/core/src/main/kotlin/io/holunda/connector/translate/TranslateRequest.kt @@ -4,7 +4,7 @@ import com.fasterxml.jackson.databind.* import io.holunda.connector.common.* data class TranslateRequest( - val inputJson: JsonNode, - val language: String, - val model: Model + val inputJson: JsonNode, + val language: String, + val model: Model ) diff --git a/core/src/main/kotlin/io/holunda/connector/translate/TranslateTask.kt b/core/src/main/kotlin/io/holunda/connector/translate/TranslateTask.kt new file mode 100644 index 0000000..241e7e6 --- /dev/null +++ b/core/src/main/kotlin/io/holunda/connector/translate/TranslateTask.kt @@ -0,0 +1,18 @@ +package io.holunda.connector.translate + +import com.fasterxml.jackson.databind.* + +data class TranslateTask( + val model: String, + val input: JsonNode, + val target_language: String, +) { + companion object { + fun fromRequest(request: TranslateRequest) = + TranslateTask( + request.model.modelId, + request.inputJson, + request.language + ) + } +} diff --git a/element-templates/connector-gpt-compose.json b/element-templates/connector-gpt-compose.json index f6b7c44..ee6f1e4 100644 --- a/element-templates/connector-gpt-compose.json +++ b/element-templates/connector-gpt-compose.json @@ -37,7 +37,7 @@ "properties": [ { "type": "Hidden", - "value": "io.holunda.connector.compose:1", + "value": "io.holunda:connector-compose:1", "binding": { "type": "zeebe:taskDefinition:type" } diff --git a/element-templates/connector-gpt-database.json b/element-templates/connector-gpt-database.json index 53cdaf0..c33b57d 100644 --- a/element-templates/connector-gpt-database.json +++ b/element-templates/connector-gpt-database.json @@ -45,7 +45,7 @@ "properties": [ { "type": "Hidden", - "value": "io.holunda.connector.database:1", + "value": "io.holunda:connector-database:1", "binding": { "type": "zeebe:taskDefinition:type" } diff --git a/element-templates/connector-gpt-decide.json b/element-templates/connector-gpt-decide.json index d07942e..6dc752c 100644 --- a/element-templates/connector-gpt-decide.json +++ b/element-templates/connector-gpt-decide.json @@ -37,7 +37,7 @@ "properties": [ { "type": "Hidden", - "value": "io.holunda.connector.decide:1", + "value": "io.holunda:connector-decide:1", "binding": { "type": "zeebe:taskDefinition:type" } diff --git a/element-templates/connector-gpt-executor.json b/element-templates/connector-gpt-executor.json index 9b1a427..6bd237e 100644 --- a/element-templates/connector-gpt-executor.json +++ b/element-templates/connector-gpt-executor.json @@ -41,7 +41,7 @@ "properties": [ { "type": "Hidden", - "value": "io.holunda.connector.executor:1", + "value": "io.holunda:connector-executor:1", "binding": { "type": "zeebe:taskDefinition:type" } diff --git a/element-templates/connector-gpt-extract.json b/element-templates/connector-gpt-extract.json index 7736ce1..a13bde7 100644 --- a/element-templates/connector-gpt-extract.json +++ b/element-templates/connector-gpt-extract.json @@ -41,7 +41,7 @@ "properties": [ { "type": "Hidden", - "value": "io.holunda.connector.extract:1", + "value": "io.holunda:connector-extract:1", "binding": { "type": "zeebe:taskDefinition:type" } diff --git a/element-templates/connector-gpt-generic.json b/element-templates/connector-gpt-generic.json index daf6e05..735d849 100644 --- a/element-templates/connector-gpt-generic.json +++ b/element-templates/connector-gpt-generic.json @@ -37,7 +37,7 @@ "properties": [ { "type": "Hidden", - "value": "io.holunda.connector.generic:1", + "value": "io.holunda:connector-generic:1", "binding": { "type": "zeebe:taskDefinition:type" } diff --git a/element-templates/connector-gpt-openapi.json b/element-templates/connector-gpt-openapi.json index bd6c120..6f2945b 100644 --- a/element-templates/connector-gpt-openapi.json +++ b/element-templates/connector-gpt-openapi.json @@ -45,7 +45,7 @@ "properties": [ { "type": "Hidden", - "value": "io.holunda.connector.openapi:1", + "value": "io.holunda:connector-openapi:1", "binding": { "type": "zeebe:taskDefinition:type" } diff --git a/element-templates/connector-gpt-planner.json b/element-templates/connector-gpt-planner.json index 6165e83..1c6585f 100644 --- a/element-templates/connector-gpt-planner.json +++ b/element-templates/connector-gpt-planner.json @@ -41,7 +41,7 @@ "properties": [ { "type": "Hidden", - "value": "io.holunda.connector.planner:1", + "value": "io.holunda:connector-planner:1", "binding": { "type": "zeebe:taskDefinition:type" } diff --git a/element-templates/connector-gpt-process.json b/element-templates/connector-gpt-process.json index 08b2a32..e25a08b 100644 --- a/element-templates/connector-gpt-process.json +++ b/element-templates/connector-gpt-process.json @@ -41,7 +41,7 @@ "properties": [ { "type": "Hidden", - "value": "io.holunda.connector.process:1", + "value": "io.holunda:connector-process:1", "binding": { "type": "zeebe:taskDefinition:type" } diff --git a/element-templates/connector-gpt-retrieval.json b/element-templates/connector-gpt-retrieval.json index 1cf66ad..b81b27a 100644 --- a/element-templates/connector-gpt-retrieval.json +++ b/element-templates/connector-gpt-retrieval.json @@ -41,7 +41,7 @@ "properties": [ { "type": "Hidden", - "value": "io.holunda.connector.retrieval:1", + "value": "io.holunda:connector-retrieval:1", "binding": { "type": "zeebe:taskDefinition:type" } diff --git a/element-templates/connector-gpt-translate.json b/element-templates/connector-gpt-translate.json index 641aabb..d14564b 100644 --- a/element-templates/connector-gpt-translate.json +++ b/element-templates/connector-gpt-translate.json @@ -37,7 +37,7 @@ "properties": [ { "type": "Hidden", - "value": "io.holunda.connector.translate:1", + "value": "io.holunda:connector-translate:1", "binding": { "type": "zeebe:taskDefinition:type" }