|
8 | 8 | import com.fasterxml.jackson.databind.ObjectMapper; |
9 | 9 | import com.sap.ai.sdk.app.services.OrchestrationService; |
10 | 10 | import com.sap.ai.sdk.orchestration.AzureFilterThreshold; |
| 11 | +import com.sap.ai.sdk.orchestration.OrchestrationChatResponse; |
| 12 | +import com.sap.ai.sdk.orchestration.OrchestrationClientException; |
11 | 13 | import com.sap.ai.sdk.orchestration.model.DPIEntities; |
12 | 14 | import com.sap.cloud.sdk.cloudplatform.thread.ThreadContextExecutors; |
13 | 15 | import javax.annotation.Nonnull; |
@@ -121,30 +123,78 @@ ResponseEntity<String> messagesHistory( |
121 | 123 | } |
122 | 124 |
|
123 | 125 | /** |
124 | | - * Apply both input and output filtering for a request to orchestration. |
| 126 | + * Send an HTTP GET request for input filtering to the Orchestration service. |
125 | 127 | * |
126 | 128 | * @link <a |
127 | 129 | * href="https://help.sap.com/docs/sap-ai-core/sap-ai-core-service-guide/input-filtering">SAP |
128 | | - * AI Core: Orchestration - Input Filtering</a> |
129 | | - * @link <a |
130 | | - * href="https://help.sap.com/docs/sap-ai-core/sap-ai-core-service-guide/output-filtering">SAP |
131 | | - * AI Core: Orchestration - Output Filtering</a> |
132 | | - * @param policy A high threshold is a loose filter, a low threshold is a strict filter |
133 | | - * @return a ResponseEntity with the response content |
| 130 | + * * AI Core: Orchestration - Input Filtering</a> |
| 131 | + * @param accept an optional HTTP header specifying the desired content type for the response. |
| 132 | + * @param policy path variable specifying the {@link AzureFilterThreshold} the explicitness of |
| 133 | + * content that should be allowed through the filter |
| 134 | + * @return a {@link ResponseEntity} containing the filtered input. The response is either in JSON |
| 135 | + * format if the "accept" header specifies "application/json" or in plain content format |
| 136 | + * otherwise. |
| 137 | + * @throws JsonProcessingException if an error occurs while converting the response to JSON. |
134 | 138 | */ |
135 | | - @GetMapping("/filter/{policy}") |
| 139 | + @GetMapping("/inputFiltering/{policy}") |
136 | 140 | @Nonnull |
137 | | - ResponseEntity<String> filter( |
| 141 | + ResponseEntity<String> inputFiltering( |
138 | 142 | @RequestHeader(value = "accept", required = false) final String accept, |
139 | 143 | @Nonnull @PathVariable("policy") final AzureFilterThreshold policy) |
140 | 144 | throws JsonProcessingException { |
141 | | - final var response = service.filter(policy, "the downtown area"); |
142 | | - if ("application/json".equals(accept)) { |
| 145 | + |
| 146 | + final OrchestrationChatResponse response; |
| 147 | + try { |
| 148 | + response = service.inputFiltering(policy); |
| 149 | + } catch (OrchestrationClientException e) { |
| 150 | + final var msg = "Failed to obtain a response as the content was flagged by input filter."; |
| 151 | + log.debug(msg, e); |
| 152 | + return ResponseEntity.internalServerError().body(msg); |
| 153 | + } |
| 154 | + |
| 155 | + if (accept.equals("application/json")) { |
143 | 156 | return ResponseEntity.ok() |
144 | 157 | .contentType(MediaType.APPLICATION_JSON) |
145 | 158 | .body(mapper.writeValueAsString(response)); |
146 | 159 | } |
147 | | - return ResponseEntity.ok(response.getContent()); |
| 160 | + return ResponseEntity.ok().body(response.getContent()); |
| 161 | + } |
| 162 | + |
| 163 | + /** |
| 164 | + * Send an HTTP GET request for output filtering to the Orchestration service. |
| 165 | + * |
| 166 | + * @link <a |
| 167 | + * href="https://help.sap.com/docs/sap-ai-core/sap-ai-core-service-guide/output-filtering">SAP |
| 168 | + * AI Core: Orchestration - Output Filtering</a> |
| 169 | + * @param accept an optional HTTP header specifying the desired content type for the response. |
| 170 | + * @param policy a mandatory path variable specifying the {@link AzureFilterThreshold} the |
| 171 | + * explicitness of content that should be allowed through the filter |
| 172 | + * @return a {@link ResponseEntity} containing the filtered output. The response is either in JSON |
| 173 | + * format if the "accept" header specifies "application/json" or in plain content format |
| 174 | + * otherwise. |
| 175 | + * @throws OrchestrationClientException if the output filter filtered the LLM response. |
| 176 | + * @throws JsonProcessingException if an error occurs while converting the response to JSON. |
| 177 | + */ |
| 178 | + @GetMapping("/outputFiltering/{policy}") |
| 179 | + @Nonnull |
| 180 | + ResponseEntity<String> outputFiltering( |
| 181 | + @RequestHeader(value = "accept", required = false) final String accept, |
| 182 | + @Nonnull @PathVariable("policy") final AzureFilterThreshold policy) |
| 183 | + throws JsonProcessingException, OrchestrationClientException { |
| 184 | + |
| 185 | + final var response = service.outputFiltering(policy); |
| 186 | + try { |
| 187 | + if (accept.equals("application/json")) { |
| 188 | + return ResponseEntity.ok() |
| 189 | + .contentType(MediaType.APPLICATION_JSON) |
| 190 | + .body(mapper.writeValueAsString(response)); |
| 191 | + } |
| 192 | + return ResponseEntity.ok().body(response.getContent()); |
| 193 | + } catch (OrchestrationClientException e) { |
| 194 | + final var msg = "Failed to obtain a response as the content was flagged by output filter."; |
| 195 | + log.debug(msg, e); |
| 196 | + return ResponseEntity.internalServerError().body(msg); |
| 197 | + } |
148 | 198 | } |
149 | 199 |
|
150 | 200 | /** |
|
0 commit comments