Skip to content

Commit 05e3d8c

Browse files
committed
Migrate to the JsonSchemaElement API
Closes #1054
1 parent 2103f07 commit 05e3d8c

12 files changed

+532
-76
lines changed

core/deployment/src/main/java/io/quarkiverse/langchain4j/deployment/ToolProcessor.java

+114-73
Large diffs are not rendered by default.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package io.quarkiverse.langchain4j.runtime.tool;
2+
3+
import dev.langchain4j.model.chat.request.json.JsonArraySchema;
4+
import dev.langchain4j.model.chat.request.json.JsonSchemaElement;
5+
import io.quarkus.runtime.annotations.RecordableConstructor;
6+
7+
public final class JsonArraySchemaObjectSubstitution extends JsonSchemaElementObjectSubstitution {
8+
@Override
9+
public JsonArraySchemaObjectSubstitution.Serialized serialize(JsonSchemaElement obj) {
10+
var a = (JsonArraySchema) obj;
11+
return new Serialized(a.description(), a.items());
12+
}
13+
14+
@Override
15+
public JsonArraySchema deserialize(JsonSchemaElementObjectSubstitution.Serialized obj) {
16+
var a = (JsonArraySchemaObjectSubstitution.Serialized) obj;
17+
return JsonArraySchema.builder()
18+
.description(a.description)
19+
.items(a.items)
20+
.build();
21+
}
22+
23+
public static final class Serialized extends JsonSchemaElementObjectSubstitution.Serialized {
24+
private final String description;
25+
private final JsonSchemaElement items;
26+
27+
@RecordableConstructor
28+
public Serialized(String description, JsonSchemaElement items) {
29+
this.description = description;
30+
this.items = items;
31+
}
32+
33+
public String getDescription() {
34+
return description;
35+
}
36+
37+
public JsonSchemaElement getItems() {
38+
return items;
39+
}
40+
}
41+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package io.quarkiverse.langchain4j.runtime.tool;
2+
3+
import dev.langchain4j.model.chat.request.json.JsonBooleanSchema;
4+
import dev.langchain4j.model.chat.request.json.JsonSchemaElement;
5+
import io.quarkus.runtime.annotations.RecordableConstructor;
6+
7+
public final class JsonBooleanSchemaObjectSubstitution extends JsonSchemaElementObjectSubstitution {
8+
@Override
9+
public JsonBooleanSchemaObjectSubstitution.Serialized serialize(JsonSchemaElement obj) {
10+
var b = (JsonBooleanSchema) obj;
11+
return new Serialized(b.description());
12+
}
13+
14+
@Override
15+
public JsonBooleanSchema deserialize(JsonSchemaElementObjectSubstitution.Serialized obj) {
16+
var b = (JsonBooleanSchemaObjectSubstitution.Serialized) obj;
17+
return JsonBooleanSchema.builder()
18+
.description(b.description)
19+
.build();
20+
}
21+
22+
public static final class Serialized extends JsonSchemaElementObjectSubstitution.Serialized {
23+
private final String description;
24+
25+
@RecordableConstructor
26+
public Serialized(String description) {
27+
this.description = description;
28+
}
29+
30+
public String getDescription() {
31+
return description;
32+
}
33+
}
34+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package io.quarkiverse.langchain4j.runtime.tool;
2+
3+
import java.util.List;
4+
5+
import dev.langchain4j.model.chat.request.json.JsonEnumSchema;
6+
import dev.langchain4j.model.chat.request.json.JsonSchemaElement;
7+
import io.quarkus.runtime.annotations.RecordableConstructor;
8+
9+
public final class JsonEnumSchemaObjectSubstitution extends JsonSchemaElementObjectSubstitution {
10+
@Override
11+
public JsonEnumSchemaObjectSubstitution.Serialized serialize(JsonSchemaElement obj) {
12+
var e = (JsonEnumSchema) obj;
13+
return new Serialized(e.description(), e.enumValues());
14+
}
15+
16+
@Override
17+
public JsonEnumSchema deserialize(JsonSchemaElementObjectSubstitution.Serialized obj) {
18+
var e = (JsonEnumSchemaObjectSubstitution.Serialized) obj;
19+
return JsonEnumSchema.builder()
20+
.description(e.description)
21+
.enumValues(e.enumValues)
22+
.build();
23+
}
24+
25+
public static final class Serialized extends JsonSchemaElementObjectSubstitution.Serialized {
26+
private final String description;
27+
private final List<String> enumValues;
28+
29+
@RecordableConstructor
30+
public Serialized(String description, List<String> enumValues) {
31+
this.description = description;
32+
this.enumValues = enumValues;
33+
}
34+
35+
public String getDescription() {
36+
return description;
37+
}
38+
39+
public List<String> getEnumValues() {
40+
return enumValues;
41+
}
42+
}
43+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package io.quarkiverse.langchain4j.runtime.tool;
2+
3+
import dev.langchain4j.model.chat.request.json.JsonIntegerSchema;
4+
import dev.langchain4j.model.chat.request.json.JsonSchemaElement;
5+
import io.quarkus.runtime.annotations.RecordableConstructor;
6+
7+
public final class JsonIntegerSchemaObjectSubstitution extends JsonSchemaElementObjectSubstitution {
8+
@Override
9+
public JsonIntegerSchemaObjectSubstitution.Serialized serialize(JsonSchemaElement obj) {
10+
var i = (JsonIntegerSchema) obj;
11+
return new Serialized(i.description());
12+
}
13+
14+
@Override
15+
public JsonIntegerSchema deserialize(JsonSchemaElementObjectSubstitution.Serialized obj) {
16+
var i = (JsonIntegerSchemaObjectSubstitution.Serialized) obj;
17+
return JsonIntegerSchema.builder()
18+
.description(i.description)
19+
.build();
20+
}
21+
22+
public static final class Serialized extends JsonSchemaElementObjectSubstitution.Serialized {
23+
private final String description;
24+
25+
@RecordableConstructor
26+
public Serialized(String description) {
27+
this.description = description;
28+
}
29+
30+
public String getDescription() {
31+
return description;
32+
}
33+
}
34+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package io.quarkiverse.langchain4j.runtime.tool;
2+
3+
import dev.langchain4j.model.chat.request.json.JsonNumberSchema;
4+
import dev.langchain4j.model.chat.request.json.JsonSchemaElement;
5+
import io.quarkus.runtime.annotations.RecordableConstructor;
6+
7+
public final class JsonNumberSchemaObjectSubstitution extends JsonSchemaElementObjectSubstitution {
8+
@Override
9+
public JsonNumberSchemaObjectSubstitution.Serialized serialize(JsonSchemaElement obj) {
10+
var n = (JsonNumberSchema) obj;
11+
return new Serialized(n.description());
12+
}
13+
14+
@Override
15+
public JsonNumberSchema deserialize(JsonSchemaElementObjectSubstitution.Serialized obj) {
16+
var n = (JsonNumberSchemaObjectSubstitution.Serialized) obj;
17+
return JsonNumberSchema.builder()
18+
.description(n.description)
19+
.build();
20+
}
21+
22+
public static final class Serialized extends JsonSchemaElementObjectSubstitution.Serialized {
23+
private final String description;
24+
25+
@RecordableConstructor
26+
public Serialized(String description) {
27+
this.description = description;
28+
}
29+
30+
public String getDescription() {
31+
return description;
32+
}
33+
}
34+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package io.quarkiverse.langchain4j.runtime.tool;
2+
3+
import java.util.List;
4+
import java.util.Map;
5+
6+
import dev.langchain4j.model.chat.request.json.JsonObjectSchema;
7+
import dev.langchain4j.model.chat.request.json.JsonSchemaElement;
8+
import io.quarkus.runtime.annotations.RecordableConstructor;
9+
10+
public final class JsonObjectSchemaObjectSubstitution extends JsonSchemaElementObjectSubstitution {
11+
@Override
12+
public JsonObjectSchemaObjectSubstitution.Serialized serialize(JsonSchemaElement obj) {
13+
var o = (JsonObjectSchema) obj;
14+
return new Serialized(o.description(), o.properties(), o.required(), o.additionalProperties(), o.definitions());
15+
}
16+
17+
@Override
18+
public JsonObjectSchema deserialize(JsonSchemaElementObjectSubstitution.Serialized obj) {
19+
var o = (JsonObjectSchemaObjectSubstitution.Serialized) obj;
20+
return JsonObjectSchema.builder()
21+
.description(o.description)
22+
.properties(o.properties)
23+
.required(o.required)
24+
.additionalProperties(o.additionalProperties)
25+
.definitions(o.definitions)
26+
.build();
27+
}
28+
29+
public static final class Serialized extends JsonSchemaElementObjectSubstitution.Serialized {
30+
private final String description;
31+
private final Map<String, JsonSchemaElement> properties;
32+
private final List<String> required;
33+
private final Boolean additionalProperties;
34+
private final Map<String, JsonSchemaElement> definitions;
35+
36+
@RecordableConstructor
37+
public Serialized(String description, Map<String, JsonSchemaElement> properties, List<String> required,
38+
Boolean additionalProperties, Map<String, JsonSchemaElement> definitions) {
39+
this.description = description;
40+
this.properties = properties;
41+
this.required = required;
42+
this.additionalProperties = additionalProperties;
43+
this.definitions = definitions;
44+
}
45+
46+
public String getDescription() {
47+
return description;
48+
}
49+
50+
public Map<String, JsonSchemaElement> getProperties() {
51+
return properties;
52+
}
53+
54+
public List<String> getRequired() {
55+
return required;
56+
}
57+
58+
public Boolean getAdditionalProperties() {
59+
return additionalProperties;
60+
}
61+
62+
public Map<String, JsonSchemaElement> getDefinitions() {
63+
return definitions;
64+
}
65+
}
66+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package io.quarkiverse.langchain4j.runtime.tool;
2+
3+
import dev.langchain4j.model.chat.request.json.JsonReferenceSchema;
4+
import dev.langchain4j.model.chat.request.json.JsonSchemaElement;
5+
import io.quarkus.runtime.annotations.RecordableConstructor;
6+
7+
public final class JsonReferenceSchemaObjectSubstitution extends JsonSchemaElementObjectSubstitution {
8+
public JsonReferenceSchemaObjectSubstitution.Serialized serialize(JsonSchemaElement obj) {
9+
var r = (JsonReferenceSchema) obj;
10+
return new Serialized(r.reference());
11+
}
12+
13+
public JsonReferenceSchema deserialize(JsonSchemaElementObjectSubstitution.Serialized obj) {
14+
var r = (JsonReferenceSchemaObjectSubstitution.Serialized) obj;
15+
return JsonReferenceSchema.builder()
16+
.reference(r.reference)
17+
.build();
18+
}
19+
20+
public static final class Serialized extends JsonSchemaElementObjectSubstitution.Serialized {
21+
private final String reference;
22+
23+
@RecordableConstructor
24+
public Serialized(String reference) {
25+
this.reference = reference;
26+
}
27+
28+
public String getReference() {
29+
return reference;
30+
}
31+
}
32+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
package io.quarkiverse.langchain4j.runtime.tool;
2+
3+
import java.util.Map;
4+
import java.util.concurrent.ConcurrentHashMap;
5+
6+
import dev.langchain4j.model.chat.request.json.JsonArraySchema;
7+
import dev.langchain4j.model.chat.request.json.JsonBooleanSchema;
8+
import dev.langchain4j.model.chat.request.json.JsonEnumSchema;
9+
import dev.langchain4j.model.chat.request.json.JsonIntegerSchema;
10+
import dev.langchain4j.model.chat.request.json.JsonNumberSchema;
11+
import dev.langchain4j.model.chat.request.json.JsonObjectSchema;
12+
import dev.langchain4j.model.chat.request.json.JsonReferenceSchema;
13+
import dev.langchain4j.model.chat.request.json.JsonSchemaElement;
14+
import dev.langchain4j.model.chat.request.json.JsonStringSchema;
15+
import io.quarkus.runtime.ObjectSubstitution;
16+
17+
public sealed class JsonSchemaElementObjectSubstitution
18+
implements ObjectSubstitution<JsonSchemaElement, JsonSchemaElementObjectSubstitution.Serialized>
19+
permits JsonArraySchemaObjectSubstitution,
20+
JsonBooleanSchemaObjectSubstitution,
21+
JsonEnumSchemaObjectSubstitution,
22+
JsonIntegerSchemaObjectSubstitution,
23+
JsonNumberSchemaObjectSubstitution,
24+
JsonObjectSchemaObjectSubstitution,
25+
JsonReferenceSchemaObjectSubstitution,
26+
JsonStringSchemaObjectSubstitution {
27+
28+
// Using ConcurrentHashMap in case multiple threads are using this class at the same time
29+
// Not sure if this will ever happen
30+
private final Map<Class<?>, JsonSchemaElementObjectSubstitution> substitutions = new ConcurrentHashMap<>(8);
31+
32+
@Override
33+
public JsonSchemaElementObjectSubstitution.Serialized serialize(JsonSchemaElement obj) {
34+
return getSubstitution(obj.getClass()).serialize(obj);
35+
}
36+
37+
@Override
38+
public JsonSchemaElement deserialize(JsonSchemaElementObjectSubstitution.Serialized obj) {
39+
return getSubstitution(obj.getClass()).deserialize(obj);
40+
}
41+
42+
private JsonSchemaElementObjectSubstitution getSubstitution(Class<?> clazz) {
43+
return this.substitutions.computeIfAbsent(clazz, c -> {
44+
if (JsonArraySchema.class.isAssignableFrom(c)
45+
|| JsonArraySchemaObjectSubstitution.Serialized.class.isAssignableFrom(c)) {
46+
return new JsonArraySchemaObjectSubstitution();
47+
} else if (JsonBooleanSchema.class.isAssignableFrom(c)
48+
|| JsonBooleanSchemaObjectSubstitution.Serialized.class.isAssignableFrom(c)) {
49+
return new JsonBooleanSchemaObjectSubstitution();
50+
} else if (JsonEnumSchema.class.isAssignableFrom(c)
51+
|| JsonEnumSchemaObjectSubstitution.Serialized.class.isAssignableFrom(c)) {
52+
return new JsonEnumSchemaObjectSubstitution();
53+
} else if (JsonIntegerSchema.class.isAssignableFrom(c)
54+
|| JsonIntegerSchemaObjectSubstitution.Serialized.class.isAssignableFrom(c)) {
55+
return new JsonIntegerSchemaObjectSubstitution();
56+
} else if (JsonNumberSchema.class.isAssignableFrom(c)
57+
|| JsonNumberSchemaObjectSubstitution.Serialized.class.isAssignableFrom(c)) {
58+
return new JsonNumberSchemaObjectSubstitution();
59+
} else if (JsonObjectSchema.class.isAssignableFrom(c)
60+
|| JsonObjectSchemaObjectSubstitution.Serialized.class.isAssignableFrom(c)) {
61+
return new JsonObjectSchemaObjectSubstitution();
62+
} else if (JsonReferenceSchema.class.isAssignableFrom(c)
63+
|| JsonReferenceSchemaObjectSubstitution.Serialized.class.isAssignableFrom(c)) {
64+
return new JsonReferenceSchemaObjectSubstitution();
65+
} else if (JsonStringSchema.class.isAssignableFrom(c)
66+
|| JsonStringSchemaObjectSubstitution.Serialized.class.isAssignableFrom(c)) {
67+
return new JsonStringSchemaObjectSubstitution();
68+
}
69+
70+
// Handle unsupported types
71+
throw new IllegalArgumentException("Unsupported type: %s".formatted(c.getName()));
72+
});
73+
}
74+
75+
public static sealed class Serialized
76+
permits JsonArraySchemaObjectSubstitution.Serialized,
77+
JsonBooleanSchemaObjectSubstitution.Serialized,
78+
JsonEnumSchemaObjectSubstitution.Serialized,
79+
JsonIntegerSchemaObjectSubstitution.Serialized,
80+
JsonNumberSchemaObjectSubstitution.Serialized,
81+
JsonObjectSchemaObjectSubstitution.Serialized,
82+
JsonReferenceSchemaObjectSubstitution.Serialized,
83+
JsonStringSchemaObjectSubstitution.Serialized {
84+
85+
}
86+
}

0 commit comments

Comments
 (0)