Skip to content

Commit 20a106a

Browse files
Added e2e test
1 parent 444833d commit 20a106a

File tree

4 files changed

+95
-20
lines changed

4 files changed

+95
-20
lines changed

sample-code/spring-app/src/main/java/com/sap/ai/sdk/app/controllers/OrchestrationController.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,28 @@ ResponseEntity<String> outputFiltering(
188188
}
189189
}
190190

191+
@GetMapping("/llamaGuardFilter/{enabled}")
192+
@Nonnull
193+
ResponseEntity<String> llamaGuardInputFiltering(
194+
@Nullable @RequestHeader(value = "accept", required = false) final String accept,
195+
@PathVariable("enabled") final boolean enabled)
196+
throws JsonProcessingException {
197+
198+
final OrchestrationChatResponse response;
199+
try {
200+
response = service.llamaGuardInputFilter(enabled);
201+
} catch (OrchestrationClientException e) {
202+
final var msg = "Failed to obtain a response as the content was flagged by input filter.";
203+
log.debug(msg, e);
204+
return ResponseEntity.internalServerError().body(msg);
205+
}
206+
207+
if (accept.equals("application/json")) {
208+
return ResponseEntity.ok().body(MAPPER.writeValueAsString(response));
209+
}
210+
return ResponseEntity.ok().body(response.getContent());
211+
}
212+
191213
/**
192214
* Let the orchestration service evaluate the feedback on the AI SDK provided by a hypothetical
193215
* user. Anonymize any names given as they are not relevant for judging the sentiment of the

sample-code/spring-app/src/main/java/com/sap/ai/sdk/app/services/OrchestrationService.java

Lines changed: 44 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -117,26 +117,10 @@ public OrchestrationChatResponse messagesHistory(@Nonnull final String prevMessa
117117
@Nonnull
118118
public OrchestrationChatResponse inputFiltering(@Nonnull final AzureFilterThreshold policy)
119119
throws OrchestrationClientException {
120-
val prompt = new OrchestrationPrompt("'We shall spill blood tonight', said the operation in-charge.");
121-
val filter = true;
122-
val b =
123-
LlamaGuard38b.create()
124-
.violentCrimes(filter)
125-
.nonViolentCrimes(filter)
126-
.sexCrimes(filter)
127-
.childExploitation(filter)
128-
.defamation(filter)
129-
.specializedAdvice(filter)
130-
.privacy(filter)
131-
.intellectualProperty(filter)
132-
.indiscriminateWeapons(filter)
133-
.hate(filter)
134-
.selfHarm(filter)
135-
.sexualContent(filter)
136-
.elections(filter)
137-
.codeInterpreterAbuse(filter);
138-
139-
val filterConfig = new LlamaGuardFilter().config(b);
120+
val prompt =
121+
new OrchestrationPrompt("'We shall spill blood tonight', said the operation in-charge.");
122+
val filterConfig =
123+
new AzureContentFilter().hate(policy).selfHarm(policy).sexual(policy).violence(policy);
140124

141125
val configWithFilter = config.withInputFiltering(filterConfig);
142126

@@ -168,6 +152,46 @@ public OrchestrationChatResponse outputFiltering(@Nonnull final AzureFilterThres
168152
return client.chatCompletion(prompt, configWithFilter);
169153
}
170154

155+
/**
156+
* Apply the Llama Guard filter.
157+
*
158+
* @link <a
159+
* href="https://help.sap.com/docs/sap-ai-core/sap-ai-core-service-guide/input-filtering">SAP
160+
* AI Core: Orchestration - Input Filtering</a>
161+
* @throws OrchestrationClientException if input filter filters the prompt
162+
* @param filter enable or disable the filter
163+
* @return the assistant response object
164+
*/
165+
@Nonnull
166+
public OrchestrationChatResponse llamaGuardInputFilter(final boolean filter)
167+
throws OrchestrationClientException {
168+
val prompt = new OrchestrationPrompt("'We shall spill blood tonight', said the operation in-charge.");
169+
170+
// values not set are disabled by default
171+
val config =
172+
LlamaGuard38b.create()
173+
.violentCrimes(filter)
174+
.nonViolentCrimes(filter)
175+
.sexCrimes(filter)
176+
.childExploitation(filter)
177+
.defamation(filter)
178+
.specializedAdvice(filter)
179+
.privacy(filter)
180+
.intellectualProperty(filter)
181+
.indiscriminateWeapons(filter)
182+
.hate(filter)
183+
.selfHarm(filter)
184+
.sexualContent(filter)
185+
.elections(filter)
186+
.codeInterpreterAbuse(filter);
187+
188+
val filterConfig = new LlamaGuardFilter().config(config);
189+
190+
val configWithFilter = this.config.withInputFiltering(filterConfig);
191+
192+
return client.chatCompletion(prompt, configWithFilter);
193+
}
194+
171195
/**
172196
* Let the orchestration service evaluate the feedback on the AI SDK provided by a hypothetical
173197
* user. Anonymize any names given as they are not relevant for judging the sentiment of the

sample-code/spring-app/src/main/resources/static/index.html

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,15 @@ <h2>Orchestration</h2>
310310
</div>
311311
</div>
312312
</li>
313+
<li class="list-group-item">
314+
<div class="info-tooltip">
315+
<a class="link-offset-2-hover link-underline link-underline-opacity-0 link-underline-opacity-75-hover endpoint"
316+
href="/orchestration/llamaGuardFilter/false"><code>/orchestration/llamaGuardFilter/false</code></a>
317+
<div class="tooltip-content">
318+
Apply lenient input filtering for a request to orchestration.
319+
</div>
320+
</div>
321+
</li>
313322
<li class="list-group-item">
314323
<div class="info-tooltip">
315324
<a class="link-offset-2-hover link-underline link-underline-opacity-0 link-underline-opacity-75-hover endpoint"

sample-code/spring-app/src/test/java/com/sap/ai/sdk/app/controllers/OrchestrationTest.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,4 +228,24 @@ void testOutputFilteringLenient() {
228228
var filterResult = response.getOriginalResponse().getModuleResults().getOutputFiltering();
229229
assertThat(filterResult.getMessage()).containsPattern("0 of \\d+ choices failed");
230230
}
231+
232+
@Test
233+
void testLlamaGuardEnabled() {
234+
assertThatThrownBy(() -> service.llamaGuardInputFilter(true))
235+
.isInstanceOf(OrchestrationClientException.class)
236+
.hasMessageContaining(
237+
"Content filtered due to safety violations. Please modify the prompt and try again.")
238+
.hasMessageContaining("400 Bad Request");
239+
}
240+
241+
@Test
242+
void testLlamaGuardDisabled() {
243+
var response = service.llamaGuardInputFilter(false);
244+
245+
assertThat(response.getChoice().getFinishReason()).isEqualTo("stop");
246+
assertThat(response.getContent()).isNotEmpty();
247+
248+
var filterResult = response.getOriginalResponse().getModuleResults().getInputFiltering();
249+
assertThat(filterResult.getMessage()).contains("passed");
250+
}
231251
}

0 commit comments

Comments
 (0)