|
14 | 14 | import static io.quarkiverse.langchain4j.deployment.MethodParameterAsTemplateVariableAllowance.FORCE_ALLOW; |
15 | 15 | import static io.quarkiverse.langchain4j.deployment.MethodParameterAsTemplateVariableAllowance.IGNORE; |
16 | 16 | import static io.quarkiverse.langchain4j.deployment.MethodParameterAsTemplateVariableAllowance.OPTIONAL_DENY; |
| 17 | +import static io.quarkiverse.langchain4j.deployment.ObjectSubstitutionUtil.registerJsonSchema; |
| 18 | +import static io.quarkiverse.langchain4j.runtime.types.TypeUtil.isMulti; |
17 | 19 | import static io.quarkus.arc.processor.DotNames.NAMED; |
18 | 20 |
|
19 | 21 | import java.io.IOException; |
|
61 | 63 | import org.objectweb.asm.tree.analysis.AnalyzerException; |
62 | 64 |
|
63 | 65 | import dev.langchain4j.exception.IllegalConfigurationException; |
| 66 | +import dev.langchain4j.model.chat.request.json.JsonSchema; |
64 | 67 | import dev.langchain4j.service.Moderate; |
| 68 | +import dev.langchain4j.service.output.JsonSchemas; |
65 | 69 | import dev.langchain4j.service.output.ServiceOutputParser; |
66 | 70 | import io.quarkiverse.langchain4j.ModelName; |
67 | 71 | import io.quarkiverse.langchain4j.RegisterAiService; |
|
117 | 121 | import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem; |
118 | 122 | import io.quarkus.deployment.builditem.nativeimage.ServiceProviderBuildItem; |
119 | 123 | import io.quarkus.deployment.metrics.MetricsCapabilityBuildItem; |
| 124 | +import io.quarkus.deployment.recording.RecorderContext; |
120 | 125 | import io.quarkus.gizmo.ClassCreator; |
121 | 126 | import io.quarkus.gizmo.ClassOutput; |
122 | 127 | import io.quarkus.gizmo.FieldDescriptor; |
@@ -922,6 +927,7 @@ public void markIgnoredAnnotations(BuildProducer<MethodParameterIgnoredAnnotatio |
922 | 927 | public void handleAiServices( |
923 | 928 | LangChain4jBuildConfig config, |
924 | 929 | AiServicesRecorder recorder, |
| 930 | + RecorderContext recorderContext, |
925 | 931 | CombinedIndexBuildItem indexBuildItem, |
926 | 932 | List<DeclarativeAiServiceBuildItem> declarativeAiServiceItems, |
927 | 933 | List<MethodParameterAllowedAnnotationsBuildItem> methodParameterAllowedAnnotationsItems, |
@@ -1178,6 +1184,7 @@ public void handleAiServices( |
1178 | 1184 |
|
1179 | 1185 | } |
1180 | 1186 |
|
| 1187 | + registerJsonSchema(recorderContext); |
1181 | 1188 | recorder.setMetadata(perClassMetadata); |
1182 | 1189 | } |
1183 | 1190 |
|
@@ -1246,16 +1253,18 @@ private AiServiceMethodCreateInfo gatherMethodMetadata( |
1246 | 1253 |
|
1247 | 1254 | // TODO give user ability to provide custom OutputParser |
1248 | 1255 | String outputFormatInstructions = ""; |
1249 | | - if (generateResponseSchema && !returnType.equals(Multi.class)) |
| 1256 | + Optional<JsonSchema> structuredOutputSchema = Optional.empty(); |
| 1257 | + if (!returnType.equals(Multi.class)) { |
1250 | 1258 | outputFormatInstructions = SERVICE_OUTPUT_PARSER.outputFormatInstructions(returnType); |
| 1259 | + } |
1251 | 1260 |
|
1252 | 1261 | List<TemplateParameterInfo> templateParams = gatherTemplateParamInfo(params, allowedPredicates, ignoredPredicates); |
1253 | 1262 | Optional<AiServiceMethodCreateInfo.TemplateInfo> systemMessageInfo = gatherSystemMessageInfo(method, templateParams); |
1254 | 1263 | AiServiceMethodCreateInfo.UserMessageInfo userMessageInfo = gatherUserMessageInfo(method, templateParams); |
1255 | 1264 |
|
1256 | 1265 | AiServiceMethodCreateInfo.ResponseSchemaInfo responseSchemaInfo = ResponseSchemaInfo.of(generateResponseSchema, |
1257 | 1266 | systemMessageInfo, |
1258 | | - userMessageInfo.template(), outputFormatInstructions); |
| 1267 | + userMessageInfo.template(), outputFormatInstructions, jsonSchemaFrom(returnType)); |
1259 | 1268 |
|
1260 | 1269 | if (!generateResponseSchema && responseSchemaInfo.isInSystemMessage()) |
1261 | 1270 | throw new RuntimeException( |
@@ -1293,6 +1302,13 @@ private AiServiceMethodCreateInfo gatherMethodMetadata( |
1293 | 1302 | inputGuardrails, outputGuardrails, accumulatorClassName, responseAugmenterClassName); |
1294 | 1303 | } |
1295 | 1304 |
|
| 1305 | + private Optional<JsonSchema> jsonSchemaFrom(java.lang.reflect.Type returnType) { |
| 1306 | + if (isMulti(returnType)) { |
| 1307 | + return Optional.empty(); |
| 1308 | + } |
| 1309 | + return JsonSchemas.jsonSchemaFrom(returnType); |
| 1310 | + } |
| 1311 | + |
1296 | 1312 | private boolean detectIfToolExecutionRequiresAWorkerThread(MethodInfo method, List<ToolMethodBuildItem> tools, |
1297 | 1313 | List<String> methodToolClassNames) { |
1298 | 1314 | List<String> allTools = new ArrayList<>(methodToolClassNames); |
|
0 commit comments