7 changed files with 188 additions and 28 deletions
@ -0,0 +1,39 @@ |
|||
/** |
|||
* 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.validation; |
|||
|
|||
import jakarta.validation.Constraint; |
|||
import jakarta.validation.Payload; |
|||
|
|||
import java.lang.annotation.Documented; |
|||
import java.lang.annotation.ElementType; |
|||
import java.lang.annotation.Retention; |
|||
import java.lang.annotation.RetentionPolicy; |
|||
import java.lang.annotation.Target; |
|||
|
|||
@Documented |
|||
@Constraint(validatedBy = {}) |
|||
@Target({ElementType.FIELD, ElementType.PARAMETER}) |
|||
@Retention(RetentionPolicy.RUNTIME) |
|||
public @interface ValidJsonSchema { |
|||
|
|||
String message() default "must conform to the Draft 2020-12 meta-schema"; |
|||
|
|||
Class<?>[] groups() default {}; |
|||
|
|||
Class<? extends Payload>[] payload() default {}; |
|||
|
|||
} |
|||
@ -0,0 +1,31 @@ |
|||
/** |
|||
* 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.dao.service; |
|||
|
|||
import com.fasterxml.jackson.databind.node.ObjectNode; |
|||
import jakarta.validation.ConstraintValidator; |
|||
import jakarta.validation.ConstraintValidatorContext; |
|||
import org.thingsboard.common.util.JsonSchemaUtils; |
|||
import org.thingsboard.server.common.data.validation.ValidJsonSchema; |
|||
|
|||
public final class JsonSchemaValidator implements ConstraintValidator<ValidJsonSchema, ObjectNode> { |
|||
|
|||
@Override |
|||
public boolean isValid(ObjectNode schema, ConstraintValidatorContext context) { |
|||
return schema == null || JsonSchemaUtils.isValidJsonSchema(schema); |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,103 @@ |
|||
/** |
|||
* 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.rule.engine.ai; |
|||
|
|||
import com.fasterxml.jackson.annotation.JsonSubTypes; |
|||
import com.fasterxml.jackson.annotation.JsonTypeInfo; |
|||
import com.fasterxml.jackson.databind.node.ObjectNode; |
|||
import dev.langchain4j.model.chat.request.ResponseFormat; |
|||
import dev.langchain4j.model.chat.request.ResponseFormatType; |
|||
import jakarta.validation.constraints.NotNull; |
|||
import org.thingsboard.server.common.data.validation.ValidJsonSchema; |
|||
|
|||
import static org.thingsboard.rule.engine.ai.TbResponseFormat.TbJsonResponseFormat; |
|||
import static org.thingsboard.rule.engine.ai.TbResponseFormat.TbJsonSchemaResponseFormat; |
|||
import static org.thingsboard.rule.engine.ai.TbResponseFormat.TbTextResponseFormat; |
|||
|
|||
@JsonTypeInfo( |
|||
use = JsonTypeInfo.Id.NAME, |
|||
include = JsonTypeInfo.As.PROPERTY, |
|||
property = "type" |
|||
) |
|||
@JsonSubTypes({ |
|||
@JsonSubTypes.Type(value = TbTextResponseFormat.class, name = "TEXT"), |
|||
@JsonSubTypes.Type(value = TbJsonResponseFormat.class, name = "JSON"), |
|||
@JsonSubTypes.Type(value = TbJsonSchemaResponseFormat.class, name = "JSON_SCHEMA") |
|||
}) |
|||
public sealed interface TbResponseFormat permits TbTextResponseFormat, TbJsonResponseFormat, TbJsonSchemaResponseFormat { |
|||
|
|||
TbResponseFormatType type(); |
|||
|
|||
ResponseFormat toLangChainResponseFormat(); |
|||
|
|||
enum TbResponseFormatType { |
|||
|
|||
TEXT, |
|||
JSON, |
|||
JSON_SCHEMA |
|||
|
|||
} |
|||
|
|||
record TbTextResponseFormat() implements TbResponseFormat { |
|||
|
|||
@Override |
|||
public TbResponseFormatType type() { |
|||
return TbResponseFormatType.TEXT; |
|||
} |
|||
|
|||
@Override |
|||
public ResponseFormat toLangChainResponseFormat() { |
|||
return ResponseFormat.builder() |
|||
.type(ResponseFormatType.TEXT) |
|||
.build(); |
|||
} |
|||
|
|||
} |
|||
|
|||
record TbJsonResponseFormat() implements TbResponseFormat { |
|||
|
|||
@Override |
|||
public TbResponseFormatType type() { |
|||
return TbResponseFormatType.JSON; |
|||
} |
|||
|
|||
@Override |
|||
public ResponseFormat toLangChainResponseFormat() { |
|||
return ResponseFormat.builder() |
|||
.type(ResponseFormatType.JSON) |
|||
.build(); |
|||
} |
|||
|
|||
} |
|||
|
|||
record TbJsonSchemaResponseFormat(@NotNull @ValidJsonSchema ObjectNode schema) implements TbResponseFormat { |
|||
|
|||
@Override |
|||
public TbResponseFormatType type() { |
|||
return TbResponseFormatType.JSON_SCHEMA; |
|||
} |
|||
|
|||
@Override |
|||
public ResponseFormat toLangChainResponseFormat() { |
|||
return ResponseFormat.builder() |
|||
.type(ResponseFormatType.JSON) |
|||
.jsonSchema(Langchain4jJsonSchemaAdapter.fromObjectNode(schema)) |
|||
.build(); |
|||
} |
|||
|
|||
} |
|||
|
|||
} |
|||
Loading…
Reference in new issue