From ad0161e3dfddd60b50f1ed02b5db4f9562eaf710 Mon Sep 17 00:00:00 2001 From: Dmytro Skarzhynets Date: Fri, 16 May 2025 16:46:00 +0300 Subject: [PATCH] AI rule node: add AiProvider enum --- .../server/service/ai/AiServiceImpl.java | 7 +++--- .../server/common/data/ai/AiProvider.java | 24 +++++++++++++++++++ .../server/common/data/ai/AiSettings.java | 12 ++++++---- .../dao/model/sql/AiSettingsEntity.java | 6 ++++- .../thingsboard/rule/engine/ai/TbAiNode.java | 2 +- 5 files changed, 40 insertions(+), 11 deletions(-) create mode 100644 common/data/src/main/java/org/thingsboard/server/common/data/ai/AiProvider.java diff --git a/application/src/main/java/org/thingsboard/server/service/ai/AiServiceImpl.java b/application/src/main/java/org/thingsboard/server/service/ai/AiServiceImpl.java index b7c91de260..9306ce5c71 100644 --- a/application/src/main/java/org/thingsboard/server/service/ai/AiServiceImpl.java +++ b/application/src/main/java/org/thingsboard/server/service/ai/AiServiceImpl.java @@ -45,19 +45,18 @@ class AiServiceImpl implements RuleEngineAiService { var aiSettings = aiSettingsOpt.get(); return switch (aiSettings.getProvider()) { - case "openai" -> OpenAiChatModel.builder() + case OPENAI -> OpenAiChatModel.builder() .apiKey(aiSettings.getApiKey()) .modelName(aiSettings.getModel()) .build(); - case "mistral-ai" -> MistralAiChatModel.builder() + case MISTRAL_AI -> MistralAiChatModel.builder() .apiKey(aiSettings.getApiKey()) .modelName(aiSettings.getModel()) .build(); - case "google-ai-gemini" -> GoogleAiGeminiChatModel.builder() + case GOOGLE_AI_GEMINI -> GoogleAiGeminiChatModel.builder() .apiKey(aiSettings.getApiKey()) .modelName(aiSettings.getModel()) .build(); - default -> throw new IllegalArgumentException("Unsupported AI provider: " + aiSettings.getProvider()); }; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/ai/AiProvider.java b/common/data/src/main/java/org/thingsboard/server/common/data/ai/AiProvider.java new file mode 100644 index 0000000000..e2938cdddc --- /dev/null +++ b/common/data/src/main/java/org/thingsboard/server/common/data/ai/AiProvider.java @@ -0,0 +1,24 @@ +/** + * Copyright © 2016-2025 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.common.data.ai; + +public enum AiProvider { + + OPENAI, + GOOGLE_AI_GEMINI, + MISTRAL_AI + +} diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/ai/AiSettings.java b/common/data/src/main/java/org/thingsboard/server/common/data/ai/AiSettings.java index 0c5b9c1a63..81a27ae914 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/ai/AiSettings.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/ai/AiSettings.java @@ -66,15 +66,17 @@ public final class AiSettings extends BaseData implements HasTenan @Schema( requiredMode = Schema.RequiredMode.REQUIRED, accessMode = Schema.AccessMode.READ_WRITE, - description = "Name of the LLM provider", - example = "openai" + description = "Name of the AI provider", + example = "OPENAI", + allowableValues = {"OPENAI", "GOOGLE_AI_GEMINI", "MISTRAL_AI"}, + type = "string" ) - String provider; + AiProvider provider; @Schema( requiredMode = Schema.RequiredMode.REQUIRED, accessMode = Schema.AccessMode.READ_WRITE, - description = "Identifier of the LLM model to use", + description = "Identifier of the AI model to use", example = "gpt-4o-mini" ) String model; @@ -82,7 +84,7 @@ public final class AiSettings extends BaseData implements HasTenan @Schema( requiredMode = Schema.RequiredMode.REQUIRED, accessMode = Schema.AccessMode.WRITE_ONLY, - description = "API key for authenticating with the selected LLM provider", + description = "API key for authenticating with the selected AI provider", example = "sk-********************************" ) String apiKey; diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/AiSettingsEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/AiSettingsEntity.java index f238f57d4b..f473fe6acb 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/AiSettingsEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/AiSettingsEntity.java @@ -17,11 +17,14 @@ package org.thingsboard.server.dao.model.sql; import jakarta.persistence.Column; import jakarta.persistence.Entity; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; import jakarta.persistence.Table; import lombok.Getter; import lombok.Setter; import lombok.ToString; import org.hibernate.proxy.HibernateProxy; +import org.thingsboard.server.common.data.ai.AiProvider; import org.thingsboard.server.common.data.ai.AiSettings; import org.thingsboard.server.common.data.id.AiSettingsId; import org.thingsboard.server.common.data.id.TenantId; @@ -44,8 +47,9 @@ public class AiSettingsEntity extends BaseVersionedEntity { @Column(name = ModelConstants.AI_SETTINGS_NAME_COLUMN_NAME, nullable = false) private String name; + @Enumerated(EnumType.STRING) @Column(name = ModelConstants.AI_SETTINGS_PROVIDER_COLUMN_NAME, nullable = false) - private String provider; + private AiProvider provider; @Column(name = ModelConstants.AI_SETTINGS_MODEL_COLUMN_NAME, nullable = false) private String model; diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/ai/TbAiNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/ai/TbAiNode.java index 5682529224..8810e20599 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/ai/TbAiNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/ai/TbAiNode.java @@ -48,7 +48,7 @@ import static org.thingsboard.server.dao.service.ConstraintValidator.validateFie type = ComponentType.EXTERNAL, name = "AI", nodeDescription = "Interact with AI", - nodeDetails = "This node makes requests to LLM based on a prompt and a input message and returns a response in a form of output message", + nodeDetails = "This node makes requests to AI based on a prompt and a input message and returns a response in a form of output message", configClazz = TbAiNodeConfiguration.class ) public final class TbAiNode extends TbAbstractExternalNode implements TbNode {