AI rule node: split AI config into AI provider config and AI model config; add support for model temperature
This commit is contained in:
		
							parent
							
								
									d44bbe4dd8
								
							
						
					
					
						commit
						45fbbf201f
					
				@ -15,13 +15,14 @@
 | 
			
		||||
--
 | 
			
		||||
 | 
			
		||||
CREATE TABLE ai_settings (
 | 
			
		||||
    id            UUID          NOT NULL PRIMARY KEY,
 | 
			
		||||
    created_time  BIGINT        NOT NULL,
 | 
			
		||||
    tenant_id     UUID          NOT NULL,
 | 
			
		||||
    version       BIGINT        NOT NULL DEFAULT 1,
 | 
			
		||||
    name          VARCHAR(255)  NOT NULL,
 | 
			
		||||
    provider      VARCHAR(255)  NOT NULL,
 | 
			
		||||
    model         VARCHAR(255)  NOT NULL,
 | 
			
		||||
    configuration JSONB         NOT NULL,
 | 
			
		||||
    id              UUID          NOT NULL PRIMARY KEY,
 | 
			
		||||
    created_time    BIGINT        NOT NULL,
 | 
			
		||||
    tenant_id       UUID          NOT NULL,
 | 
			
		||||
    version         BIGINT        NOT NULL DEFAULT 1,
 | 
			
		||||
    name            VARCHAR(255)  NOT NULL,
 | 
			
		||||
    provider        VARCHAR(255)  NOT NULL,
 | 
			
		||||
    provider_config JSONB         NOT NULL,
 | 
			
		||||
    model           VARCHAR(255)  NOT NULL,
 | 
			
		||||
    model_config    JSONB,
 | 
			
		||||
    CONSTRAINT ai_settings_name_unq_key UNIQUE (tenant_id, name)
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
@ -23,6 +23,8 @@ import lombok.RequiredArgsConstructor;
 | 
			
		||||
import org.springframework.stereotype.Service;
 | 
			
		||||
import org.thingsboard.rule.engine.api.RuleEngineAiService;
 | 
			
		||||
import org.thingsboard.server.common.data.ai.AiSettings;
 | 
			
		||||
import org.thingsboard.server.common.data.ai.model.MistralAiChatModelConfig;
 | 
			
		||||
import org.thingsboard.server.common.data.ai.model.OpenAiChatModelConfig;
 | 
			
		||||
import org.thingsboard.server.common.data.id.AiSettingsId;
 | 
			
		||||
import org.thingsboard.server.common.data.id.TenantId;
 | 
			
		||||
import org.thingsboard.server.dao.ai.AiSettingsService;
 | 
			
		||||
@ -45,18 +47,39 @@ class AiServiceImpl implements RuleEngineAiService {
 | 
			
		||||
        var aiSettings = aiSettingsOpt.get();
 | 
			
		||||
 | 
			
		||||
        return switch (aiSettings.getProvider()) {
 | 
			
		||||
            case OPENAI -> OpenAiChatModel.builder()
 | 
			
		||||
                    .apiKey(aiSettings.getConfiguration().getApiKey())
 | 
			
		||||
                    .modelName(aiSettings.getModel())
 | 
			
		||||
                    .build();
 | 
			
		||||
            case MISTRAL_AI -> MistralAiChatModel.builder()
 | 
			
		||||
                    .apiKey(aiSettings.getConfiguration().getApiKey())
 | 
			
		||||
                    .modelName(aiSettings.getModel())
 | 
			
		||||
                    .build();
 | 
			
		||||
            case GOOGLE_AI_GEMINI -> GoogleAiGeminiChatModel.builder()
 | 
			
		||||
                    .apiKey(aiSettings.getConfiguration().getApiKey())
 | 
			
		||||
                    .modelName(aiSettings.getModel())
 | 
			
		||||
                    .build();
 | 
			
		||||
            case OPENAI -> {
 | 
			
		||||
                var modelBuilder = OpenAiChatModel.builder()
 | 
			
		||||
                        .apiKey(aiSettings.getProviderConfig().getApiKey())
 | 
			
		||||
                        .modelName(aiSettings.getModel());
 | 
			
		||||
 | 
			
		||||
                if (aiSettings.getModelConfig() instanceof OpenAiChatModelConfig config) {
 | 
			
		||||
                    modelBuilder.temperature(config.getTemperature());
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                yield modelBuilder.build();
 | 
			
		||||
            }
 | 
			
		||||
            case MISTRAL_AI -> {
 | 
			
		||||
                var modelBuilder = MistralAiChatModel.builder()
 | 
			
		||||
                        .apiKey(aiSettings.getProviderConfig().getApiKey())
 | 
			
		||||
                        .modelName(aiSettings.getModel());
 | 
			
		||||
 | 
			
		||||
                if (aiSettings.getModelConfig() instanceof MistralAiChatModelConfig config) {
 | 
			
		||||
                    modelBuilder.temperature(config.getTemperature());
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                yield modelBuilder.build();
 | 
			
		||||
            }
 | 
			
		||||
            case GOOGLE_AI_GEMINI -> {
 | 
			
		||||
                var modelBuilder = GoogleAiGeminiChatModel.builder()
 | 
			
		||||
                        .apiKey(aiSettings.getProviderConfig().getApiKey())
 | 
			
		||||
                        .modelName(aiSettings.getModel());
 | 
			
		||||
 | 
			
		||||
                if (aiSettings.getModelConfig() instanceof OpenAiChatModelConfig config) {
 | 
			
		||||
                    modelBuilder.temperature(config.getTemperature());
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                yield modelBuilder.build();
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -24,6 +24,9 @@ import org.thingsboard.server.common.data.BaseData;
 | 
			
		||||
import org.thingsboard.server.common.data.HasName;
 | 
			
		||||
import org.thingsboard.server.common.data.HasTenantId;
 | 
			
		||||
import org.thingsboard.server.common.data.HasVersion;
 | 
			
		||||
import org.thingsboard.server.common.data.ai.model.AiModelConfig;
 | 
			
		||||
import org.thingsboard.server.common.data.ai.provider.AiProvider;
 | 
			
		||||
import org.thingsboard.server.common.data.ai.provider.AiProviderConfig;
 | 
			
		||||
import org.thingsboard.server.common.data.id.AiSettingsId;
 | 
			
		||||
import org.thingsboard.server.common.data.id.TenantId;
 | 
			
		||||
 | 
			
		||||
@ -76,17 +79,27 @@ public final class AiSettings extends BaseData<AiSettingsId> implements HasTenan
 | 
			
		||||
    @Schema(
 | 
			
		||||
            requiredMode = Schema.RequiredMode.REQUIRED,
 | 
			
		||||
            accessMode = Schema.AccessMode.READ_WRITE,
 | 
			
		||||
            description = "Identifier of the AI model to use",
 | 
			
		||||
            description = "Configuration specific to the AI provider"
 | 
			
		||||
    )
 | 
			
		||||
    AiProviderConfig providerConfig;
 | 
			
		||||
 | 
			
		||||
    @Schema(
 | 
			
		||||
            requiredMode = Schema.RequiredMode.REQUIRED,
 | 
			
		||||
            accessMode = Schema.AccessMode.READ_WRITE,
 | 
			
		||||
            description = "Identifier of the AI model",
 | 
			
		||||
            example = "gpt-4o-mini"
 | 
			
		||||
    )
 | 
			
		||||
    String model;
 | 
			
		||||
 | 
			
		||||
    @Schema(
 | 
			
		||||
            requiredMode = Schema.RequiredMode.REQUIRED,
 | 
			
		||||
            requiredMode = Schema.RequiredMode.NOT_REQUIRED,
 | 
			
		||||
            accessMode = Schema.AccessMode.READ_WRITE,
 | 
			
		||||
            description = "Settings specific to the selected AI provider and model"
 | 
			
		||||
            description = """
 | 
			
		||||
                    Optional configuration specific to the AI model.
 | 
			
		||||
                    If provided, it must be one of the known AiModelConfig subtypes and any settings
 | 
			
		||||
                    you specify will override the model’s defaults; if omitted, the model will run with its built-in defaults."""
 | 
			
		||||
    )
 | 
			
		||||
    AiConfig configuration;
 | 
			
		||||
    AiModelConfig modelConfig;
 | 
			
		||||
 | 
			
		||||
    public AiSettings() {}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,47 @@
 | 
			
		||||
/**
 | 
			
		||||
 * 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.model;
 | 
			
		||||
 | 
			
		||||
import com.fasterxml.jackson.annotation.JsonSubTypes;
 | 
			
		||||
import com.fasterxml.jackson.annotation.JsonTypeInfo;
 | 
			
		||||
import io.swagger.v3.oas.annotations.media.Schema;
 | 
			
		||||
import lombok.Data;
 | 
			
		||||
import lombok.NoArgsConstructor;
 | 
			
		||||
 | 
			
		||||
@Data
 | 
			
		||||
@NoArgsConstructor
 | 
			
		||||
@JsonTypeInfo(
 | 
			
		||||
        use = JsonTypeInfo.Id.NAME,
 | 
			
		||||
        include = JsonTypeInfo.As.EXISTING_PROPERTY,
 | 
			
		||||
        property = "model",
 | 
			
		||||
        visible = true
 | 
			
		||||
)
 | 
			
		||||
@JsonSubTypes({
 | 
			
		||||
        @JsonSubTypes.Type(value = OpenAiChatModelConfig.class, name = "gpt-4o"),
 | 
			
		||||
        @JsonSubTypes.Type(value = OpenAiChatModelConfig.class, name = "gpt-4o-mini"),
 | 
			
		||||
        @JsonSubTypes.Type(value = GoogleAiGeminiChatModelConfig.class, name = "gemini-2.0-flash"),
 | 
			
		||||
        @JsonSubTypes.Type(value = MistralAiChatModelConfig.class, name = "mistral-medium-latest")
 | 
			
		||||
})
 | 
			
		||||
public abstract class AiModelConfig {
 | 
			
		||||
 | 
			
		||||
    @Schema(
 | 
			
		||||
            requiredMode = Schema.RequiredMode.REQUIRED,
 | 
			
		||||
            accessMode = Schema.AccessMode.READ_WRITE,
 | 
			
		||||
            description = "Identifier of the AI model"
 | 
			
		||||
    )
 | 
			
		||||
    private String model;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,50 @@
 | 
			
		||||
/**
 | 
			
		||||
 * 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.model;
 | 
			
		||||
 | 
			
		||||
import io.swagger.v3.oas.annotations.media.Schema;
 | 
			
		||||
import lombok.Data;
 | 
			
		||||
import lombok.EqualsAndHashCode;
 | 
			
		||||
import lombok.NoArgsConstructor;
 | 
			
		||||
 | 
			
		||||
@Data
 | 
			
		||||
@EqualsAndHashCode(callSuper = true)
 | 
			
		||||
@NoArgsConstructor
 | 
			
		||||
@Schema(
 | 
			
		||||
        name = "GoogleAiGeminiChatModelConfig",
 | 
			
		||||
        description = "Configuration for Google AI Gemini chat models"
 | 
			
		||||
)
 | 
			
		||||
public final class GoogleAiGeminiChatModelConfig extends AiModelConfig {
 | 
			
		||||
 | 
			
		||||
    @Schema(
 | 
			
		||||
            requiredMode = Schema.RequiredMode.REQUIRED,
 | 
			
		||||
            accessMode = Schema.AccessMode.READ_WRITE,
 | 
			
		||||
            description = "Identifier of the AI model",
 | 
			
		||||
            allowableValues = "gemini-2.0-flash",
 | 
			
		||||
            example = "gemini-2.0-flash"
 | 
			
		||||
    )
 | 
			
		||||
    public String getModel() {
 | 
			
		||||
        return super.getModel();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Schema(
 | 
			
		||||
            accessMode = Schema.AccessMode.READ_WRITE,
 | 
			
		||||
            description = "Sampling temperature to control randomness: 0.0 (most deterministic) to 1.0 (most creative)",
 | 
			
		||||
            example = "0.7"
 | 
			
		||||
    )
 | 
			
		||||
    private Double temperature;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,50 @@
 | 
			
		||||
/**
 | 
			
		||||
 * 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.model;
 | 
			
		||||
 | 
			
		||||
import io.swagger.v3.oas.annotations.media.Schema;
 | 
			
		||||
import lombok.Data;
 | 
			
		||||
import lombok.EqualsAndHashCode;
 | 
			
		||||
import lombok.NoArgsConstructor;
 | 
			
		||||
 | 
			
		||||
@Data
 | 
			
		||||
@EqualsAndHashCode(callSuper = true)
 | 
			
		||||
@NoArgsConstructor
 | 
			
		||||
@Schema(
 | 
			
		||||
        name = "MistralAiChatModelConfig",
 | 
			
		||||
        description = "Configuration for Mistral AI chat models"
 | 
			
		||||
)
 | 
			
		||||
public final class MistralAiChatModelConfig extends AiModelConfig {
 | 
			
		||||
 | 
			
		||||
    @Schema(
 | 
			
		||||
            requiredMode = Schema.RequiredMode.REQUIRED,
 | 
			
		||||
            accessMode = Schema.AccessMode.READ_WRITE,
 | 
			
		||||
            description = "Identifier of the AI model",
 | 
			
		||||
            allowableValues = "mistral-medium-latest",
 | 
			
		||||
            example = "mistral-medium-latest"
 | 
			
		||||
    )
 | 
			
		||||
    public String getModel() {
 | 
			
		||||
        return super.getModel();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Schema(
 | 
			
		||||
            accessMode = Schema.AccessMode.READ_WRITE,
 | 
			
		||||
            description = "Sampling temperature to control randomness: 0.0 (most deterministic) to 1.0 (most creative)",
 | 
			
		||||
            example = "0.7"
 | 
			
		||||
    )
 | 
			
		||||
    private Double temperature;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,50 @@
 | 
			
		||||
/**
 | 
			
		||||
 * 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.model;
 | 
			
		||||
 | 
			
		||||
import io.swagger.v3.oas.annotations.media.Schema;
 | 
			
		||||
import lombok.Data;
 | 
			
		||||
import lombok.EqualsAndHashCode;
 | 
			
		||||
import lombok.NoArgsConstructor;
 | 
			
		||||
 | 
			
		||||
@Data
 | 
			
		||||
@EqualsAndHashCode(callSuper = true)
 | 
			
		||||
@NoArgsConstructor
 | 
			
		||||
@Schema(
 | 
			
		||||
        name = "OpenAiChatModelConfig",
 | 
			
		||||
        description = "Configuration for OpenAI chat models"
 | 
			
		||||
)
 | 
			
		||||
public final class OpenAiChatModelConfig extends AiModelConfig {
 | 
			
		||||
 | 
			
		||||
    @Schema(
 | 
			
		||||
            requiredMode = Schema.RequiredMode.REQUIRED,
 | 
			
		||||
            accessMode = Schema.AccessMode.READ_WRITE,
 | 
			
		||||
            description = "Identifier of the AI model",
 | 
			
		||||
            allowableValues = {"gpt-4o", "gpt-4o-mini"},
 | 
			
		||||
            example = "gpt-4o"
 | 
			
		||||
    )
 | 
			
		||||
    public String getModel() {
 | 
			
		||||
        return super.getModel();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Schema(
 | 
			
		||||
            accessMode = Schema.AccessMode.READ_WRITE,
 | 
			
		||||
            description = "Sampling temperature to control randomness: 0.0 (most deterministic) to 1.0 (most creative)",
 | 
			
		||||
            example = "0.7"
 | 
			
		||||
    )
 | 
			
		||||
    private Double temperature;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -13,7 +13,7 @@
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
package org.thingsboard.server.common.data.ai;
 | 
			
		||||
package org.thingsboard.server.common.data.ai.provider;
 | 
			
		||||
 | 
			
		||||
public enum AiProvider {
 | 
			
		||||
 | 
			
		||||
@ -13,7 +13,7 @@
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
package org.thingsboard.server.common.data.ai;
 | 
			
		||||
package org.thingsboard.server.common.data.ai.provider;
 | 
			
		||||
 | 
			
		||||
import com.fasterxml.jackson.annotation.JsonSubTypes;
 | 
			
		||||
import com.fasterxml.jackson.annotation.JsonTypeInfo;
 | 
			
		||||
@ -30,17 +30,16 @@ import lombok.NoArgsConstructor;
 | 
			
		||||
        visible = true
 | 
			
		||||
)
 | 
			
		||||
@JsonSubTypes({
 | 
			
		||||
        @JsonSubTypes.Type(value = OpenAiConfig.class, name = "OPENAI"),
 | 
			
		||||
        @JsonSubTypes.Type(value = GoogleAiGeminiConfig.class, name = "GOOGLE_AI_GEMINI"),
 | 
			
		||||
        @JsonSubTypes.Type(value = MistralAiConfig.class, name = "MISTRAL_AI")
 | 
			
		||||
        @JsonSubTypes.Type(value = OpenAiProviderConfig.class, name = "OPENAI"),
 | 
			
		||||
        @JsonSubTypes.Type(value = GoogleAiGeminiProviderConfig.class, name = "GOOGLE_AI_GEMINI"),
 | 
			
		||||
        @JsonSubTypes.Type(value = MistralAiProviderConfig.class, name = "MISTRAL_AI")
 | 
			
		||||
})
 | 
			
		||||
public abstract class AiConfig {
 | 
			
		||||
public abstract class AiProviderConfig {
 | 
			
		||||
 | 
			
		||||
    @Schema(
 | 
			
		||||
            requiredMode = Schema.RequiredMode.REQUIRED,
 | 
			
		||||
            accessMode = Schema.AccessMode.READ_WRITE,
 | 
			
		||||
            description = "API key for authenticating with the AI provider",
 | 
			
		||||
            example = "sk-********************************"
 | 
			
		||||
            description = "API key for authenticating with the AI provider"
 | 
			
		||||
    )
 | 
			
		||||
    private String apiKey;
 | 
			
		||||
 | 
			
		||||
@ -13,7 +13,7 @@
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
package org.thingsboard.server.common.data.ai;
 | 
			
		||||
package org.thingsboard.server.common.data.ai.provider;
 | 
			
		||||
 | 
			
		||||
import io.swagger.v3.oas.annotations.media.Schema;
 | 
			
		||||
import lombok.Data;
 | 
			
		||||
@ -22,10 +22,10 @@ import lombok.EqualsAndHashCode;
 | 
			
		||||
@Data
 | 
			
		||||
@EqualsAndHashCode(callSuper = true)
 | 
			
		||||
@Schema(
 | 
			
		||||
        name = "GoogleAiGemini",
 | 
			
		||||
        description = "Configuration properties for the Google AI Gemini"
 | 
			
		||||
        name = "GoogleAiGeminiProviderConfig",
 | 
			
		||||
        description = "Configuration for the Google AI Gemini provider"
 | 
			
		||||
)
 | 
			
		||||
public class GoogleAiGeminiConfig extends AiConfig {
 | 
			
		||||
public final class GoogleAiGeminiProviderConfig extends AiProviderConfig {
 | 
			
		||||
 | 
			
		||||
    @Schema(
 | 
			
		||||
            requiredMode = Schema.RequiredMode.REQUIRED,
 | 
			
		||||
@ -13,7 +13,7 @@
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
package org.thingsboard.server.common.data.ai;
 | 
			
		||||
package org.thingsboard.server.common.data.ai.provider;
 | 
			
		||||
 | 
			
		||||
import io.swagger.v3.oas.annotations.media.Schema;
 | 
			
		||||
import lombok.Data;
 | 
			
		||||
@ -22,10 +22,10 @@ import lombok.EqualsAndHashCode;
 | 
			
		||||
@Data
 | 
			
		||||
@EqualsAndHashCode(callSuper = true)
 | 
			
		||||
@Schema(
 | 
			
		||||
        name = "MistralAi",
 | 
			
		||||
        description = "Configuration properties for the Mistral AI"
 | 
			
		||||
        name = "MistralAiProviderConfig",
 | 
			
		||||
        description = "Configuration for the Mistral AI provider"
 | 
			
		||||
)
 | 
			
		||||
public class MistralAiConfig extends AiConfig {
 | 
			
		||||
public final class MistralAiProviderConfig extends AiProviderConfig {
 | 
			
		||||
 | 
			
		||||
    @Schema(
 | 
			
		||||
            requiredMode = Schema.RequiredMode.REQUIRED,
 | 
			
		||||
@ -13,7 +13,7 @@
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
package org.thingsboard.server.common.data.ai;
 | 
			
		||||
package org.thingsboard.server.common.data.ai.provider;
 | 
			
		||||
 | 
			
		||||
import io.swagger.v3.oas.annotations.media.Schema;
 | 
			
		||||
import lombok.Data;
 | 
			
		||||
@ -22,10 +22,10 @@ import lombok.EqualsAndHashCode;
 | 
			
		||||
@Data
 | 
			
		||||
@EqualsAndHashCode(callSuper = true)
 | 
			
		||||
@Schema(
 | 
			
		||||
        name = "OpenAiConfig",
 | 
			
		||||
        description = "Configuration properties for the OpenAI"
 | 
			
		||||
        name = "OpenAiProviderConfig",
 | 
			
		||||
        description = "Configuration for the OpenAI provider"
 | 
			
		||||
)
 | 
			
		||||
public class OpenAiConfig extends AiConfig {
 | 
			
		||||
public final class OpenAiProviderConfig extends AiProviderConfig {
 | 
			
		||||
 | 
			
		||||
    @Schema(
 | 
			
		||||
            requiredMode = Schema.RequiredMode.REQUIRED,
 | 
			
		||||
@ -746,8 +746,9 @@ public class ModelConstants {
 | 
			
		||||
    public static final String AI_SETTINGS_TENANT_ID_COLUMN_NAME = TENANT_ID_COLUMN;
 | 
			
		||||
    public static final String AI_SETTINGS_NAME_COLUMN_NAME = NAME_PROPERTY;
 | 
			
		||||
    public static final String AI_SETTINGS_PROVIDER_COLUMN_NAME = "provider";
 | 
			
		||||
    public static final String AI_SETTINGS_PROVIDER_CONFIG_COLUMN_NAME = "provider_config";
 | 
			
		||||
    public static final String AI_SETTINGS_MODEL_COLUMN_NAME = "model";
 | 
			
		||||
    public static final String AI_SETTINGS_CONFIGURATION_COLUMN_NAME = "configuration";
 | 
			
		||||
    public static final String AI_SETTINGS_MODEL_CONFIG_COLUMN_NAME = "model_config";
 | 
			
		||||
 | 
			
		||||
    protected static final String[] NONE_AGGREGATION_COLUMNS = new String[]{LONG_VALUE_COLUMN, DOUBLE_VALUE_COLUMN, BOOLEAN_VALUE_COLUMN, STRING_VALUE_COLUMN, JSON_VALUE_COLUMN, KEY_COLUMN, TS_COLUMN};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -26,9 +26,10 @@ import lombok.Setter;
 | 
			
		||||
import lombok.ToString;
 | 
			
		||||
import org.hibernate.annotations.Type;
 | 
			
		||||
import org.hibernate.proxy.HibernateProxy;
 | 
			
		||||
import org.thingsboard.server.common.data.ai.AiConfig;
 | 
			
		||||
import org.thingsboard.server.common.data.ai.AiProvider;
 | 
			
		||||
import org.thingsboard.server.common.data.ai.AiSettings;
 | 
			
		||||
import org.thingsboard.server.common.data.ai.model.AiModelConfig;
 | 
			
		||||
import org.thingsboard.server.common.data.ai.provider.AiProvider;
 | 
			
		||||
import org.thingsboard.server.common.data.ai.provider.AiProviderConfig;
 | 
			
		||||
import org.thingsboard.server.common.data.id.AiSettingsId;
 | 
			
		||||
import org.thingsboard.server.common.data.id.TenantId;
 | 
			
		||||
import org.thingsboard.server.dao.model.BaseVersionedEntity;
 | 
			
		||||
@ -54,12 +55,16 @@ public class AiSettingsEntity extends BaseVersionedEntity<AiSettings> {
 | 
			
		||||
    @Column(name = ModelConstants.AI_SETTINGS_PROVIDER_COLUMN_NAME, nullable = false)
 | 
			
		||||
    private AiProvider provider;
 | 
			
		||||
 | 
			
		||||
    @Type(JsonBinaryType.class)
 | 
			
		||||
    @Column(name = ModelConstants.AI_SETTINGS_PROVIDER_CONFIG_COLUMN_NAME, nullable = false, columnDefinition = "JSONB")
 | 
			
		||||
    private AiProviderConfig providerConfig;
 | 
			
		||||
 | 
			
		||||
    @Column(name = ModelConstants.AI_SETTINGS_MODEL_COLUMN_NAME, nullable = false)
 | 
			
		||||
    private String model;
 | 
			
		||||
 | 
			
		||||
    @Type(JsonBinaryType.class)
 | 
			
		||||
    @Column(name = ModelConstants.AI_SETTINGS_CONFIGURATION_COLUMN_NAME, nullable = false, columnDefinition = "JSONB")
 | 
			
		||||
    private AiConfig configuration;
 | 
			
		||||
    @Column(name = ModelConstants.AI_SETTINGS_MODEL_CONFIG_COLUMN_NAME, columnDefinition = "JSONB")
 | 
			
		||||
    private AiModelConfig modelConfig;
 | 
			
		||||
 | 
			
		||||
    public AiSettingsEntity() {}
 | 
			
		||||
 | 
			
		||||
@ -68,8 +73,9 @@ public class AiSettingsEntity extends BaseVersionedEntity<AiSettings> {
 | 
			
		||||
        tenantId = getTenantUuid(aiSettings.getTenantId());
 | 
			
		||||
        name = aiSettings.getName();
 | 
			
		||||
        provider = aiSettings.getProvider();
 | 
			
		||||
        providerConfig = aiSettings.getProviderConfig();
 | 
			
		||||
        model = aiSettings.getModel();
 | 
			
		||||
        configuration = aiSettings.getConfiguration();
 | 
			
		||||
        modelConfig = aiSettings.getModelConfig();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
@ -80,8 +86,9 @@ public class AiSettingsEntity extends BaseVersionedEntity<AiSettings> {
 | 
			
		||||
        settings.setTenantId(TenantId.fromUUID(tenantId));
 | 
			
		||||
        settings.setName(name);
 | 
			
		||||
        settings.setProvider(provider);
 | 
			
		||||
        settings.setProviderConfig(providerConfig);
 | 
			
		||||
        settings.setModel(model);
 | 
			
		||||
        settings.setConfiguration(configuration);
 | 
			
		||||
        settings.setModelConfig(modelConfig);
 | 
			
		||||
        return settings;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -950,13 +950,14 @@ CREATE TABLE IF NOT EXISTS cf_debug_event (
 | 
			
		||||
) PARTITION BY RANGE (ts);
 | 
			
		||||
 | 
			
		||||
CREATE TABLE IF NOT EXISTS ai_settings (
 | 
			
		||||
    id            UUID          NOT NULL PRIMARY KEY,
 | 
			
		||||
    created_time  BIGINT        NOT NULL,
 | 
			
		||||
    tenant_id     UUID          NOT NULL,
 | 
			
		||||
    version       BIGINT        NOT NULL DEFAULT 1,
 | 
			
		||||
    name          VARCHAR(255)  NOT NULL,
 | 
			
		||||
    provider      VARCHAR(255)  NOT NULL,
 | 
			
		||||
    model         VARCHAR(255)  NOT NULL,
 | 
			
		||||
    configuration JSONB         NOT NULL,
 | 
			
		||||
    id              UUID          NOT NULL PRIMARY KEY,
 | 
			
		||||
    created_time    BIGINT        NOT NULL,
 | 
			
		||||
    tenant_id       UUID          NOT NULL,
 | 
			
		||||
    version         BIGINT        NOT NULL DEFAULT 1,
 | 
			
		||||
    name            VARCHAR(255)  NOT NULL,
 | 
			
		||||
    provider        VARCHAR(255)  NOT NULL,
 | 
			
		||||
    provider_config JSONB         NOT NULL,
 | 
			
		||||
    model           VARCHAR(255)  NOT NULL,
 | 
			
		||||
    model_config    JSONB,
 | 
			
		||||
    CONSTRAINT ai_settings_name_unq_key UNIQUE (tenant_id, name)
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user