AI rule node: use ObjectNode instead of more general JsonNode for JSON Schema config field

This commit is contained in:
Dmytro Skarzhynets 2025-06-11 17:51:38 +03:00
parent cb106760c1
commit 2e5aab3fd6
No known key found for this signature in database
GPG Key ID: 2B51652F224037DF
3 changed files with 9 additions and 7 deletions

View File

@ -16,6 +16,7 @@
package org.thingsboard.rule.engine.ai; package org.thingsboard.rule.engine.ai;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import dev.langchain4j.model.chat.request.json.JsonArraySchema; import dev.langchain4j.model.chat.request.json.JsonArraySchema;
import dev.langchain4j.model.chat.request.json.JsonBooleanSchema; import dev.langchain4j.model.chat.request.json.JsonBooleanSchema;
import dev.langchain4j.model.chat.request.json.JsonEnumSchema; import dev.langchain4j.model.chat.request.json.JsonEnumSchema;
@ -42,10 +43,10 @@ final class Langchain4jJsonSchemaAdapter {
/** /**
* Creates a Langchain4j {@link JsonSchema} from the given root JSON Schema node. * Creates a Langchain4j {@link JsonSchema} from the given root JSON Schema node.
* *
* @param rootSchemaNode a valid JSON Schema as a Jackson {@link JsonNode} * @param rootSchemaNode a valid JSON Schema as a Jackson {@link ObjectNode}
* @return the corresponding Langchain4j {@link JsonSchema} * @return the corresponding Langchain4j {@link JsonSchema}
*/ */
public static JsonSchema fromJsonNode(JsonNode rootSchemaNode) { public static JsonSchema fromJsonNode(ObjectNode rootSchemaNode) {
return JsonSchema.builder() return JsonSchema.builder()
.name(rootSchemaNode.get("title").textValue()) .name(rootSchemaNode.get("title").textValue())
.rootElement(parse(rootSchemaNode)) .rootElement(parse(rootSchemaNode))

View File

@ -16,6 +16,7 @@
package org.thingsboard.rule.engine.ai; package org.thingsboard.rule.engine.ai;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.common.util.concurrent.FutureCallback; import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListenableFuture;
import dev.langchain4j.data.message.SystemMessage; import dev.langchain4j.data.message.SystemMessage;
@ -97,11 +98,11 @@ public final class TbAiNode extends TbAbstractExternalNode implements TbNode {
aiSettingsId = config.getAiSettingsId(); aiSettingsId = config.getAiSettingsId();
} }
private static JsonSchema getJsonSchema(ResponseFormatType responseFormatType, JsonNode jsonSchema) { private static JsonSchema getJsonSchema(ResponseFormatType responseFormatType, ObjectNode jsonSchema) {
if (responseFormatType == ResponseFormatType.TEXT) { if (responseFormatType == ResponseFormatType.TEXT) {
return null; return null;
} }
return responseFormatType == ResponseFormatType.JSON && jsonSchema != null && !jsonSchema.isNull() ? Langchain4jJsonSchemaAdapter.fromJsonNode(jsonSchema) : null; return responseFormatType == ResponseFormatType.JSON && jsonSchema != null ? Langchain4jJsonSchemaAdapter.fromJsonNode(jsonSchema) : null;
} }
@Override @Override

View File

@ -16,7 +16,7 @@
package org.thingsboard.rule.engine.ai; package org.thingsboard.rule.engine.ai;
import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ObjectNode;
import dev.langchain4j.model.chat.request.ResponseFormatType; import dev.langchain4j.model.chat.request.ResponseFormatType;
import jakarta.validation.constraints.AssertTrue; import jakarta.validation.constraints.AssertTrue;
import jakarta.validation.constraints.Max; import jakarta.validation.constraints.Max;
@ -46,7 +46,7 @@ public class TbAiNodeConfiguration implements NodeConfiguration<TbAiNodeConfigur
@NotNull @NotNull
private ResponseFormatType responseFormatType; private ResponseFormatType responseFormatType;
private JsonNode jsonSchema; private ObjectNode jsonSchema;
@Min(value = 1, message = "must be at least 1 second") @Min(value = 1, message = "must be at least 1 second")
@Max(value = 600, message = "cannot exceed 600 seconds (10 minutes)") @Max(value = 600, message = "cannot exceed 600 seconds (10 minutes)")
@ -55,7 +55,7 @@ public class TbAiNodeConfiguration implements NodeConfiguration<TbAiNodeConfigur
@JsonIgnore @JsonIgnore
@AssertTrue(message = "provided JSON Schema must conform to the Draft 2020-12 meta-schema") @AssertTrue(message = "provided JSON Schema must conform to the Draft 2020-12 meta-schema")
public boolean isJsonSchemaValid() { public boolean isJsonSchemaValid() {
return jsonSchema == null || jsonSchema.isNull() || JsonSchemaUtils.isValidJsonSchema(jsonSchema); return jsonSchema == null || JsonSchemaUtils.isValidJsonSchema(jsonSchema);
} }
@Override @Override