Skip to content

Commit 8527ee6

Browse files
authored
E2E Different Resource Group (#222)
1 parent 81b5036 commit 8527ee6

File tree

8 files changed

+83
-4
lines changed

8 files changed

+83
-4
lines changed

foundation-models/openai/src/main/java/com/sap/ai/sdk/foundationmodels/openai/OpenAiClient.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,13 @@ public OpenAiClient withApiVersion(@Nonnull final String apiVersion) {
9494
@Beta
9595
@Nonnull
9696
public static OpenAiClient withCustomDestination(@Nonnull final Destination destination) {
97-
return new OpenAiClient(destination);
97+
final OpenAiClient client = new OpenAiClient(destination);
98+
99+
if (destination.get("URL.queries.api-version").isDefined()) {
100+
return client;
101+
}
102+
103+
return client.withApiVersion(DEFAULT_API_VERSION);
98104
}
99105

100106
/**

foundation-models/openai/src/test/java/com/sap/ai/sdk/foundationmodels/openai/OpenAiClientTest.java

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,9 @@ void apiVersion() {
7474
stubFor(post(anyUrl()).willReturn(okJson("{}")));
7575
Try.of(() -> client.chatCompletion(new OpenAiChatCompletionParameters()));
7676

77-
verify(exactly(1), postRequestedFor(anyUrl()).withoutQueryParam("api-version"));
77+
verify(
78+
exactly(1),
79+
postRequestedFor(anyUrl()).withQueryParam("api-version", equalTo("2024-02-01")));
7880

7981
Try.of(
8082
() -> client.withApiVersion("fooBar").chatCompletion(new OpenAiChatCompletionParameters()));
@@ -85,7 +87,9 @@ void apiVersion() {
8587
"withApiVersion should return a new object, the sut object should remain unchanged")
8688
.isNotSameAs(client.withApiVersion("fooBar"));
8789
Try.of(() -> client.chatCompletion(new OpenAiChatCompletionParameters()));
88-
verify(exactly(2), postRequestedFor(anyUrl()).withoutQueryParam("api-version"));
90+
verify(
91+
exactly(2),
92+
postRequestedFor(anyUrl()).withQueryParam("api-version", equalTo("2024-02-01")));
8993
}
9094

9195
private static Runnable[] errorHandlingCalls() {
@@ -197,7 +201,11 @@ void chatCompletion(@Nonnull final Callable<OpenAiChatCompletionOutput> request)
197201
try (var inputStream = fileLoader.apply("__files/chatCompletionResponse.json")) {
198202

199203
final String response = new String(inputStream.readAllBytes());
200-
stubFor(post("/chat/completions").willReturn(okJson(response)));
204+
// with query parameter api-version=2024-02-01
205+
stubFor(
206+
post(urlPathEqualTo("/chat/completions"))
207+
.withQueryParam("api-version", equalTo("2024-02-01"))
208+
.willReturn(okJson(response)));
201209

202210
final OpenAiChatCompletionOutput result = request.call();
203211

@@ -264,6 +272,7 @@ void chatCompletion(@Nonnull final Callable<OpenAiChatCompletionOutput> request)
264272

265273
verify(
266274
postRequestedFor(urlPathEqualTo("/chat/completions"))
275+
.withQueryParam("api-version", equalTo("2024-02-01"))
267276
.withRequestBody(
268277
equalToJson(
269278
"""

sample-code/spring-app/pom.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,10 @@
157157
<artifactId>assertj-core</artifactId>
158158
<scope>test</scope>
159159
</dependency>
160+
<dependency>
161+
<groupId>com.sap.cloud.sdk.cloudplatform</groupId>
162+
<artifactId>cloudplatform-connectivity</artifactId>
163+
</dependency>
160164
</dependencies>
161165

162166
<build>

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

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
import com.fasterxml.jackson.core.JsonProcessingException;
99
import com.fasterxml.jackson.databind.ObjectMapper;
10+
import com.sap.ai.sdk.core.AiCoreService;
1011
import com.sap.ai.sdk.foundationmodels.openai.OpenAiClient;
1112
import com.sap.ai.sdk.foundationmodels.openai.model.OpenAiChatCompletionFunction;
1213
import com.sap.ai.sdk.foundationmodels.openai.model.OpenAiChatCompletionOutput;
@@ -26,6 +27,7 @@
2627
import org.springframework.http.MediaType;
2728
import org.springframework.http.ResponseEntity;
2829
import org.springframework.web.bind.annotation.GetMapping;
30+
import org.springframework.web.bind.annotation.PathVariable;
2931
import org.springframework.web.bind.annotation.RestController;
3032
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyEmitter;
3133

@@ -189,4 +191,22 @@ OpenAiEmbeddingOutput embedding() {
189191

190192
return OpenAiClient.forModel(TEXT_EMBEDDING_ADA_002).embedding(request);
191193
}
194+
195+
/**
196+
* Chat request to OpenAI filtering by resource group
197+
*
198+
* @param resourceGroup The resource group to use
199+
* @return the assistant message response
200+
*/
201+
@GetMapping("/chatCompletion/{resourceGroup}")
202+
@Nonnull
203+
public static OpenAiChatCompletionOutput chatCompletionWithResource(
204+
@Nonnull @PathVariable("resourceGroup") final String resourceGroup) {
205+
206+
final var destination =
207+
new AiCoreService().getInferenceDestination(resourceGroup).forModel(GPT_4O);
208+
209+
return OpenAiClient.withCustomDestination(destination)
210+
.chatCompletion("Where is the nearest coffee shop?");
211+
}
192212
}

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

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import static com.sap.ai.sdk.orchestration.OrchestrationAiModel.GPT_35_TURBO;
44
import static com.sap.ai.sdk.orchestration.OrchestrationAiModel.Parameter.TEMPERATURE;
55

6+
import com.sap.ai.sdk.core.AiCoreService;
67
import com.sap.ai.sdk.orchestration.AzureContentFilter;
78
import com.sap.ai.sdk.orchestration.AzureFilterThreshold;
89
import com.sap.ai.sdk.orchestration.DpiMasking;
@@ -151,6 +152,25 @@ OrchestrationChatResponse maskingAnonymization() {
151152
return client.chatCompletion(prompt, configWithMasking);
152153
}
153154

155+
/**
156+
* Chat request to OpenAI through the Orchestration deployment under a specific resource group.
157+
*
158+
* @return the result object
159+
*/
160+
@GetMapping("/completion/{resourceGroup}")
161+
@Nonnull
162+
public OrchestrationChatResponse completionWithResourceGroup(
163+
@PathVariable("resourceGroup") @Nonnull final String resourceGroup) {
164+
165+
final var destination =
166+
new AiCoreService().getInferenceDestination(resourceGroup).forScenario("orchestration");
167+
final var clientWithResourceGroup = new OrchestrationClient(destination);
168+
169+
final var prompt = new OrchestrationPrompt("Hello world! Why is this phrase so famous?");
170+
171+
return clientWithResourceGroup.chatCompletion(prompt, config);
172+
}
173+
154174
/**
155175
* Let the orchestration service a response to a hypothetical user who provided feedback on the AI
156176
* SDK. Pseudonymize the user's name and location to protect their privacy.

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ <h2>Endpoints</h2>
8585
<li><a href="/chatCompletionTool">/chatCompletionTool</a></li>
8686
<li><a href="/chatCompletionImage">/chatCompletionImage</a></li>
8787
<li><a href="/embedding">/embedding</a></li>
88+
<li><a href="/chatCompletion/ai-sdk-java-e2e">/chatCompletion/resourceGroup</a></li>
8889
</ul>
8990
</ul>
9091
</li>

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,4 +88,13 @@ void embedding() {
8888
assertThat(embedding.getModel()).isEqualTo("ada");
8989
assertThat(embedding.getObject()).isEqualTo("list");
9090
}
91+
92+
@Test
93+
void chatCompletionWithResource() {
94+
final var completion = OpenAiController.chatCompletionWithResource("ai-sdk-java-e2e");
95+
96+
final var message = completion.getChoices().get(0).getMessage();
97+
assertThat(message.getRole()).isEqualTo("assistant");
98+
assertThat(message.getContent()).isNotEmpty();
99+
}
91100
}

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,4 +157,14 @@ void testGrounding() {
157157
// Placeholder for grounding test
158158
assertThat(System.getProperty("aicore.landscape")).isNotEqualTo("production");
159159
}
160+
161+
@Test
162+
void testCompletionWithResourceGroup() {
163+
var response = controller.completionWithResourceGroup("ai-sdk-java-e2e");
164+
var result = response.getOriginalResponse();
165+
var llmChoice =
166+
((LLMModuleResultSynchronous) result.getOrchestrationResult()).getChoices().get(0);
167+
assertThat(llmChoice.getFinishReason()).isEqualTo("stop");
168+
assertThat(llmChoice.getMessage().getContent()).isNotEmpty();
169+
}
160170
}

0 commit comments

Comments
 (0)