33import static com .sap .ai .sdk .orchestration .OrchestrationAiModel .GEMINI_1_5_FLASH ;
44import static com .sap .ai .sdk .orchestration .OrchestrationAiModel .GPT_4O_MINI ;
55
6+ import com .fasterxml .jackson .annotation .JsonProperty ;
67import com .sap .ai .sdk .orchestration .AzureContentFilter ;
78import com .sap .ai .sdk .orchestration .AzureFilterThreshold ;
89import com .sap .ai .sdk .orchestration .DpiMasking ;
910import com .sap .ai .sdk .orchestration .OrchestrationClientException ;
1011import com .sap .ai .sdk .orchestration .OrchestrationModuleConfig ;
12+ import com .sap .ai .sdk .orchestration .ResponseJsonSchema ;
13+ import com .sap .ai .sdk .orchestration .TemplateConfig ;
1114import com .sap .ai .sdk .orchestration .model .DPIEntities ;
1215import com .sap .ai .sdk .orchestration .spring .OrchestrationChatModel ;
1316import com .sap .ai .sdk .orchestration .spring .OrchestrationChatOptions ;
1417import java .util .List ;
1518import java .util .Map ;
1619import java .util .Objects ;
1720import javax .annotation .Nonnull ;
21+ import javax .annotation .Nullable ;
1822import lombok .val ;
1923import org .springframework .ai .chat .client .ChatClient ;
2024import org .springframework .ai .chat .client .advisor .MessageChatMemoryAdvisor ;
@@ -159,7 +163,7 @@ public ChatResponse outputFiltering(@Nonnull final AzureFilterThreshold policy)
159163 */
160164 @ Nonnull
161165 public ChatResponse toolCalling (final boolean internalToolExecutionEnabled ) {
162- final OrchestrationChatOptions options = new OrchestrationChatOptions (config );
166+ val options = new OrchestrationChatOptions (config );
163167 options .setToolCallbacks (List .of (ToolCallbacks .from (new WeatherMethod ())));
164168 options .setInternalToolExecutionEnabled (internalToolExecutionEnabled );
165169
@@ -184,4 +188,36 @@ public ChatResponse chatMemory() {
184188 return Objects .requireNonNull (
185189 cl .prompt (prompt2 ).call ().chatResponse (), "Chat response is null" );
186190 }
191+
192+ /**
193+ * A simple record to demonstrate the response format feature of the orchestration service.
194+ *
195+ * @param translation the translated text
196+ * @param language the language of the translation
197+ */
198+ public record Translation (
199+ @ JsonProperty (required = true ) String translation ,
200+ @ JsonProperty (required = true ) String language ) {}
201+
202+ /**
203+ * Perform a chat completion where the LLM response adheres to a JSON schema. Use a Java record or
204+ * class to define the expected format and automatically parse the response into it.
205+ *
206+ * <p>In this case, we expect a {@code Translation} of the input text into Dutch.
207+ *
208+ * @return The translated text.
209+ */
210+ @ Nullable
211+ public Translation responseFormat () {
212+ val cl = ChatClient .builder (new OrchestrationChatModel ()).build ();
213+
214+ var schema = ResponseJsonSchema .fromType (Translation .class );
215+ var template = TemplateConfig .create ().withJsonSchemaResponse (schema );
216+
217+ val options = new OrchestrationChatOptions (config .withTemplateConfig (template ));
218+ val prompt =
219+ new Prompt ("How do I say 'AI is going to revolutionize the world' in dutch?" , options );
220+
221+ return cl .prompt (prompt ).call ().entity (Translation .class );
222+ }
187223}
0 commit comments