Skip to content

Commit 0845245

Browse files
chore: [OpenAI] [Orchestration] Added new models
1 parent e366acb commit 0845245

File tree

8 files changed

+111
-25
lines changed

8 files changed

+111
-25
lines changed

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,15 @@ public record OpenAiModel(@Nonnull String name, @Nullable String version) implem
9595
/** Azure OpenAI GPT-4.1-mini model */
9696
public static final OpenAiModel GPT_41_MINI = new OpenAiModel("gpt-4.1-mini", null);
9797

98+
/** Azure OpenAI GPT-5 model */
99+
public static final OpenAiModel GPT_5 = new OpenAiModel("gpt-5", null);
100+
101+
/** Azure OpenAI GPT-5-mini model */
102+
public static final OpenAiModel GPT_5_MINI = new OpenAiModel("gpt-5-mini", null);
103+
104+
/** Azure OpenAI GPT-5-nano model */
105+
public static final OpenAiModel GPT_5_NANO = new OpenAiModel("gpt-5-nano", null);
106+
98107
/**
99108
* Azure OpenAI Text Embedding ADA 002 model
100109
*

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,13 @@ class OpenAiClientGeneratedTest extends BaseOpenAiClientTest {
4949

5050
@Test
5151
void openAiModels() {
52-
var model = OpenAiModel.GPT_4;
52+
var model = OpenAiModel.GPT_5;
5353
var newModel = model.withVersion("v1");
5454

55-
assertThat(model.name()).isEqualTo("gpt-4");
55+
assertThat(model.name()).isEqualTo("gpt-5");
5656
assertThat(model.version()).isNull();
5757

58-
assertThat(newModel.name()).isEqualTo("gpt-4");
58+
assertThat(newModel.name()).isEqualTo("gpt-5");
5959
assertThat(newModel.version()).isEqualTo("v1");
6060

6161
assertThat(model).isNotSameAs(newModel);

orchestration/src/main/java/com/sap/ai/sdk/orchestration/OrchestrationAiModel.java

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,13 @@ public class OrchestrationAiModel {
4444
/** The version of the model, defaults to "latest". */
4545
String version;
4646

47-
/** IBM Granite 13B Chat model */
47+
/**
48+
* IBM Granite 13B Chat model
49+
*
50+
* @deprecated This model is deprecated on AI Core with a planned retirement not earlier than
51+
* 2025-09-30.
52+
*/
53+
@Deprecated
4854
public static final OrchestrationAiModel IBM_GRANITE_13B_CHAT =
4955
new OrchestrationAiModel("ibm--granite-13b-chat");
5056

@@ -228,6 +234,15 @@ public class OrchestrationAiModel {
228234
/** Azure OpenAI o3 model */
229235
public static final OrchestrationAiModel OPENAI_O3 = new OrchestrationAiModel("o3");
230236

237+
/** Azure OpenAI GPT-5 model */
238+
public static final OrchestrationAiModel GPT_5 = new OrchestrationAiModel("gpt-5");
239+
240+
/** Azure OpenAI GPT-5-mini model */
241+
public static final OrchestrationAiModel GPT_5_MINI = new OrchestrationAiModel("gpt-5-mini");
242+
243+
/** Azure OpenAI GPT-5-nano model */
244+
public static final OrchestrationAiModel GPT_5_NANO = new OrchestrationAiModel("gpt-5-nano");
245+
231246
/**
232247
* Google Cloud Platform Gemini 1.0 Pro model
233248
*
@@ -239,11 +254,23 @@ public class OrchestrationAiModel {
239254
public static final OrchestrationAiModel GEMINI_1_0_PRO =
240255
new OrchestrationAiModel("gemini-1.0-pro");
241256

242-
/** Google Cloud Platform Gemini 1.5 Pro model */
257+
/**
258+
* Google Cloud Platform Gemini 1.5 Pro model
259+
*
260+
* @deprecated This model is deprecated on AI Core with a planned retirement on 2025-09-24. The
261+
* suggested replacement model is {@link OrchestrationAiModel#GEMINI_2_5_PRO}.
262+
*/
263+
@Deprecated
243264
public static final OrchestrationAiModel GEMINI_1_5_PRO =
244265
new OrchestrationAiModel("gemini-1.5-pro");
245266

246-
/** Google Cloud Platform Gemini 1.5 Flash model */
267+
/**
268+
* Google Cloud Platform Gemini 1.5 Flash model
269+
*
270+
* @deprecated This model is deprecated on AI Core with a planned retirement on 2025-09-24. The
271+
* suggested replacement model is {@link OrchestrationAiModel#GEMINI_2_5_FLASH}.
272+
*/
273+
@Deprecated
247274
public static final OrchestrationAiModel GEMINI_1_5_FLASH =
248275
new OrchestrationAiModel("gemini-1.5-flash");
249276

orchestration/src/test/java/com/sap/ai/sdk/orchestration/spring/OrchestrationChatOptionsTest.java

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package com.sap.ai.sdk.orchestration.spring;
22

3-
import static com.sap.ai.sdk.orchestration.OrchestrationAiModel.GEMINI_1_5_FLASH;
3+
import static com.sap.ai.sdk.orchestration.OrchestrationAiModel.GEMINI_2_5_FLASH;
44
import static com.sap.ai.sdk.orchestration.OrchestrationAiModel.Parameter.FREQUENCY_PENALTY;
55
import static com.sap.ai.sdk.orchestration.OrchestrationAiModel.Parameter.MAX_TOKENS;
66
import static com.sap.ai.sdk.orchestration.OrchestrationAiModel.Parameter.PRESENCE_PENALTY;
@@ -16,7 +16,7 @@
1616
class OrchestrationChatOptionsTest {
1717

1818
static final OrchestrationAiModel CUSTOM_LLM =
19-
GEMINI_1_5_FLASH
19+
GEMINI_2_5_FLASH
2020
.withParam(FREQUENCY_PENALTY, 0.5)
2121
.withParam(MAX_TOKENS, 100)
2222
.withParam(PRESENCE_PENALTY, 0.5)
@@ -26,8 +26,8 @@ class OrchestrationChatOptionsTest {
2626
.withParam(TOP_P, 0.5);
2727

2828
private static void assertCustomLLM(OrchestrationChatOptions opts) {
29-
assertThat(opts.getModel()).isEqualTo(GEMINI_1_5_FLASH.getName());
30-
assertThat(opts.getModelVersion()).isEqualTo(GEMINI_1_5_FLASH.getVersion());
29+
assertThat(opts.getModel()).isEqualTo(GEMINI_2_5_FLASH.getName());
30+
assertThat(opts.getModelVersion()).isEqualTo(GEMINI_2_5_FLASH.getVersion());
3131
assertThat(opts.getFrequencyPenalty()).isEqualTo(0.5);
3232
assertThat(opts.getMaxTokens()).isEqualTo(100);
3333
assertThat(opts.getPresencePenalty()).isEqualTo(0.5);
@@ -41,10 +41,10 @@ private static void assertCustomLLM(OrchestrationChatOptions opts) {
4141
void testParametersAreInherited() {
4242
var opts =
4343
new OrchestrationChatOptions(
44-
new OrchestrationModuleConfig().withLlmConfig(GEMINI_1_5_FLASH));
44+
new OrchestrationModuleConfig().withLlmConfig(GEMINI_2_5_FLASH));
4545

46-
assertThat(opts.getModel()).isEqualTo(GEMINI_1_5_FLASH.getName());
47-
assertThat(opts.getModelVersion()).isEqualTo(GEMINI_1_5_FLASH.getVersion());
46+
assertThat(opts.getModel()).isEqualTo(GEMINI_2_5_FLASH.getName());
47+
assertThat(opts.getModelVersion()).isEqualTo(GEMINI_2_5_FLASH.getVersion());
4848
}
4949

5050
@Test
@@ -59,11 +59,11 @@ void testCustomParametersAreInherited() {
5959
void testCopy() {
6060
var opts =
6161
new OrchestrationChatOptions(
62-
new OrchestrationModuleConfig().withLlmConfig(GEMINI_1_5_FLASH));
62+
new OrchestrationModuleConfig().withLlmConfig(GEMINI_2_5_FLASH));
6363

6464
var copy = (OrchestrationChatOptions) opts.copy();
65-
assertThat(copy.getModel()).isEqualTo(GEMINI_1_5_FLASH.getName());
66-
assertThat(copy.getModelVersion()).isEqualTo(GEMINI_1_5_FLASH.getVersion());
65+
assertThat(copy.getModel()).isEqualTo(GEMINI_2_5_FLASH.getName());
66+
assertThat(copy.getModelVersion()).isEqualTo(GEMINI_2_5_FLASH.getVersion());
6767
}
6868

6969
@Test

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package com.sap.ai.sdk.app.services;
22

3-
import static com.sap.ai.sdk.orchestration.OrchestrationAiModel.GEMINI_1_5_FLASH;
3+
import static com.sap.ai.sdk.orchestration.OrchestrationAiModel.GEMINI_2_5_FLASH;
44
import static com.sap.ai.sdk.orchestration.OrchestrationAiModel.GPT_4O_MINI;
55
import static com.sap.ai.sdk.orchestration.OrchestrationAiModel.Parameter.TEMPERATURE;
66
import static com.sap.ai.sdk.orchestration.model.SAPDocumentTranslation.TypeEnum.SAP_DOCUMENT_TRANSLATION;
@@ -50,7 +50,7 @@ public class OrchestrationService {
5050

5151
@Getter
5252
private final OrchestrationModuleConfig config =
53-
new OrchestrationModuleConfig().withLlmConfig(GEMINI_1_5_FLASH.withParam(TEMPERATURE, 0.0));
53+
new OrchestrationModuleConfig().withLlmConfig(GEMINI_2_5_FLASH.withParam(TEMPERATURE, 0.0));
5454

5555
/**
5656
* Chat request to OpenAI through the Orchestration service with a simple prompt.

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package com.sap.ai.sdk.app.services;
22

3-
import static com.sap.ai.sdk.orchestration.OrchestrationAiModel.GEMINI_1_5_FLASH;
3+
import static com.sap.ai.sdk.orchestration.OrchestrationAiModel.GEMINI_2_5_FLASH;
44
import static com.sap.ai.sdk.orchestration.OrchestrationAiModel.GPT_4O;
55
import static com.sap.ai.sdk.orchestration.OrchestrationAiModel.GPT_4O_MINI;
66

@@ -132,7 +132,7 @@ public ChatResponse inputFiltering(@Nonnull final AzureFilterThreshold policy)
132132
new AzureContentFilter().hate(policy).selfHarm(policy).sexual(policy).violence(policy);
133133
val opts =
134134
new OrchestrationChatOptions(
135-
config.withLlmConfig(GEMINI_1_5_FLASH).withInputFiltering(filterConfig));
135+
config.withLlmConfig(GEMINI_2_5_FLASH).withInputFiltering(filterConfig));
136136

137137
val prompt =
138138
new Prompt(
@@ -157,7 +157,7 @@ public ChatResponse outputFiltering(@Nonnull final AzureFilterThreshold policy)
157157
new AzureContentFilter().hate(policy).selfHarm(policy).sexual(policy).violence(policy);
158158
val opts =
159159
new OrchestrationChatOptions(
160-
config.withLlmConfig(GEMINI_1_5_FLASH).withOutputFiltering(filterConfig));
160+
config.withLlmConfig(GEMINI_2_5_FLASH).withOutputFiltering(filterConfig));
161161

162162
val prompt =
163163
new Prompt(

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package com.sap.ai.sdk.app.controllers;
22

3-
import static com.sap.ai.sdk.orchestration.OrchestrationAiModel.GEMINI_1_5_FLASH;
3+
import static com.sap.ai.sdk.orchestration.OrchestrationAiModel.GEMINI_2_5_FLASH;
44
import static com.sap.ai.sdk.orchestration.OrchestrationAiModel.Parameter.TEMPERATURE;
55
import static com.sap.ai.sdk.orchestration.model.AzureThreshold.*;
66
import static com.sap.ai.sdk.orchestration.model.ResponseChatMessage.RoleEnum.ASSISTANT;
@@ -42,7 +42,7 @@
4242
class OrchestrationTest {
4343
private final OrchestrationClient client = new OrchestrationClient();
4444
private final OrchestrationModuleConfig config =
45-
new OrchestrationModuleConfig().withLlmConfig(GEMINI_1_5_FLASH.withParam(TEMPERATURE, 0.0));
45+
new OrchestrationModuleConfig().withLlmConfig(GEMINI_2_5_FLASH.withParam(TEMPERATURE, 0.0));
4646
OrchestrationService service;
4747

4848
@BeforeEach

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

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,17 @@
55
import com.sap.ai.sdk.core.model.AiModelBaseData;
66
import com.sap.ai.sdk.core.model.AiModelVersion;
77
import com.sap.ai.sdk.foundationmodels.openai.OpenAiModel;
8+
import com.sap.ai.sdk.orchestration.OrchestrationAiModel;
89
import java.lang.reflect.Field;
910
import java.util.HashMap;
1011
import java.util.Optional;
1112
import lombok.SneakyThrows;
1213
import org.assertj.core.api.SoftAssertions;
13-
import org.junit.jupiter.api.Disabled;
1414
import org.junit.jupiter.api.DisplayName;
1515
import org.junit.jupiter.api.Test;
1616

1717
class ScenarioTest {
1818

19-
@Disabled("https://github.com/SAP/ai-sdk-java-backlog/issues/306")
2019
@Test
2120
@DisplayName(
2221
"Declared OpenAI models must be superset of our AI Core account's available OpenAI models")
@@ -62,6 +61,57 @@ void openAiModelAvailability() {
6261
softly.assertAll();
6362
}
6463

64+
@Test
65+
@DisplayName(
66+
"Declared Orchestration models must be superset of our AI Core account's available Orchestration models")
67+
@SneakyThrows
68+
void orchestrationAiModelAvailability() {
69+
70+
// Gather AI Core's list of available Orchestration models
71+
final var aiModelList = new ScenarioController().getModels().getResources();
72+
73+
final var availableOrchestrationModels =
74+
aiModelList.stream()
75+
.filter(
76+
model ->
77+
model.getAllowedScenarios().stream()
78+
.anyMatch(scenario -> scenario.getScenarioId().equals("orchestration")))
79+
.filter(model -> !model.getModel().contains("embed"))
80+
.collect(
81+
() -> new HashMap<String, Boolean>(),
82+
(list, model) -> list.put(model.getModel(), isDeprecated(model)),
83+
HashMap::putAll);
84+
85+
// Gather our declared Orchestration models
86+
Field[] declaredFields = OrchestrationAiModel.class.getFields();
87+
88+
// get the models from the OrchestrationAiModel class
89+
HashMap<String, Boolean> declaredOrchestrationModelList = new HashMap<>();
90+
for (Field field : declaredFields) {
91+
if (field.getType().equals(OrchestrationAiModel.class)) {
92+
declaredOrchestrationModelList.put(
93+
((OrchestrationAiModel) field.get(null)).getName(),
94+
field.isAnnotationPresent(Deprecated.class));
95+
}
96+
}
97+
98+
// Assert that the declared Orchestration models match the expected list
99+
assertThat(declaredOrchestrationModelList.keySet())
100+
.containsAll(availableOrchestrationModels.keySet());
101+
102+
SoftAssertions softly = new SoftAssertions();
103+
for (var model : availableOrchestrationModels.entrySet()) {
104+
Boolean declaredDeprecated = declaredOrchestrationModelList.get(model.getKey());
105+
softly
106+
.assertThat(declaredDeprecated)
107+
.withFailMessage(
108+
"%s is deprecated:%s on AI Core but deprecated:%s in AI SDK",
109+
model.getKey(), model.getValue(), declaredDeprecated)
110+
.isEqualTo(model.getValue());
111+
}
112+
softly.assertAll();
113+
}
114+
65115
private static boolean isDeprecated(AiModelBaseData model) {
66116
Optional<AiModelVersion> version =
67117
model.getVersions().stream().filter(AiModelVersion::isIsLatest).findFirst();

0 commit comments

Comments
 (0)