Skip to content

Commit 869e83a

Browse files
committed
Merge branch 'main' into orchestration-llm-config
# Conflicts: # orchestration/src/test/java/com/sap/ai/sdk/orchestration/OrchestrationUnitTest.java # sample-code/spring-app/src/main/java/com/sap/ai/sdk/app/controllers/OrchestrationController.java # sample-code/spring-app/src/test/java/com/sap/ai/sdk/app/controllers/OrchestrationTest.java
2 parents f8fb1de + a71d721 commit 869e83a

File tree

70 files changed

+3432
-9944
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

70 files changed

+3432
-9944
lines changed

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,6 @@
2626
.java-version
2727

2828
### Environment ###
29-
*.env
29+
*.env
30+
31+
.openapi-generator

.pipeline/sdk_specific_pmd_rules.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@
131131
<property name="xpath">
132132
<value>
133133
<![CDATA[
134-
//MethodDeclaration[@EffectiveVisibility='public' and @Void=false() and ClassType and not(
134+
//MethodDeclaration[(@EffectiveVisibility='public' or @EffectiveVisibility='protected') and @Void=false() and ClassType and not(
135135
./ModifierList/Annotation[@SimpleName='Nullable'] or
136136
./ModifierList/Annotation[@SimpleName='Nonnull']
137137
)]
@@ -185,7 +185,7 @@
185185
<value>
186186
<![CDATA[
187187
//ClassBody
188-
/*[@EffectiveVisibility='public']
188+
/*[(@EffectiveVisibility='public' or @EffectiveVisibility='protected')]
189189
/FormalParameters
190190
/FormalParameter[
191191
ClassType and

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ Additional methods (not recommended for production):
8484
**1. Obtain Service Credentials:**
8585

8686
- Log into the **SAP BTP Cockpit**
87-
- Navigate to **Instances and Subscriptions** -> **Instances** -> **AI Core**
87+
- Navigate to **Services** -> **Instances and Subscriptions** -> **Instances** -> **AI Core**
8888
- Click **View Credentials** and copy the JSON content
8989

9090
**2. Create `.env` file:**
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# OpenAPI Generator Ignore
2+
3+
.github/
4+
gradle/
5+
.gitignore
6+
.travis.yml
7+
build.gradle
8+
build.sbt
9+
git_push.sh
10+
gradle.properties
11+
gradlew
12+
gradlew.bat
13+
pom.xml
14+
README.md
15+
settings.gradle
16+
src/main/AndroidManifest.xml
17+
api/
18+
.openapi-generator/

orchestration/pom.xml

Lines changed: 59 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,14 @@
8585
<groupId>org.slf4j</groupId>
8686
<artifactId>slf4j-api</artifactId>
8787
</dependency>
88+
<dependency>
89+
<groupId>javax.annotation</groupId>
90+
<artifactId>javax.annotation-api</artifactId>
91+
</dependency>
92+
<dependency>
93+
<groupId>com.google.guava</groupId>
94+
<artifactId>guava</artifactId>
95+
</dependency>
8896

8997
<!-- TODO: only needed for JsonObjectMapperBuilder, maybe we can use Jackson natively to avoid this dependency -->
9098
<dependency>
@@ -132,38 +140,72 @@
132140
<build>
133141
<plugins>
134142
<plugin>
135-
<groupId>com.sap.cloud.sdk.datamodel</groupId>
143+
<groupId>org.openapitools</groupId>
136144
<artifactId>openapi-generator-maven-plugin</artifactId>
137-
<configuration>
138-
<skip>true</skip>
139-
<!-- skip automatic generation until we can omit API classes from code generation -->
140-
<outputDirectory>${project.basedir}/src/main/java</outputDirectory>
141-
<apiMaturity>beta</apiMaturity>
142-
<enableOneOfAnyOfGeneration>true</enableOneOfAnyOfGeneration>
143-
<compileScope>COMPILE</compileScope>
144-
<deleteOutputDirectory>true</deleteOutputDirectory>
145-
</configuration>
146145
<executions>
147146
<execution>
148-
<id>orchestration</id>
149147
<goals>
150148
<goal>generate</goal>
151149
</goals>
152150
<phase>generate-sources</phase>
153151
<configuration>
152+
<!-- Specify the input OpenAPI spec file -->
154153
<inputSpec>${project.basedir}/src/main/resources/spec/orchestration.yaml</inputSpec>
155-
<apiPackage>com.sap.ai.sdk.orchestration.client</apiPackage>
154+
<output>${project.basedir}</output>
155+
<!-- Specify the generator to use, e.g., java, spring, kotlin, etc. -->
156+
<generatorName>java</generatorName>
157+
<!-- Specify the package names for models, APIs, and invokers -->
156158
<modelPackage>com.sap.ai.sdk.orchestration.client.model</modelPackage>
157-
<additionalProperties>
158-
<pojoBuilderMethodName>create</pojoBuilderMethodName>
159-
<pojoBuildMethodName/>
160-
<pojoConstructorVisibility>protected</pojoConstructorVisibility>
159+
<apiPackage>com.sap.ai.sdk.orchestration.client.api</apiPackage>
160+
<invokerPackage>com.sap.ai.sdk.orchestration.client.invoker</invokerPackage>
161+
162+
<!-- Global properties level; can be unpacked with 'generate' prefix-->
163+
<globalProperties>
164+
<apiDocs>false</apiDocs>
165+
<modelDocs>false</modelDocs>
166+
<modelTests>false</modelTests>
167+
<apiTests>false</apiTests>
168+
<minimalUpdate>true</minimalUpdate>
169+
</globalProperties>
170+
171+
<!-- Generator Specific properties level; some can be unpacked-->
172+
<configOptions>
173+
<generateBuilders>true</generateBuilders>
174+
<failOnUnknownProperties>false</failOnUnknownProperties>
175+
<hideGenerationTimestamp>true</hideGenerationTimestamp>
176+
<disallowAdditionalPropertiesIfNotPresent>false</disallowAdditionalPropertiesIfNotPresent>
161177
<enumUnknownDefaultCase>true</enumUnknownDefaultCase>
162-
</additionalProperties>
178+
<useBeanValidation>false</useBeanValidation>
179+
<useOneOfInterfaces>true</useOneOfInterfaces>
180+
<additionalModelTypeAnnotations>@com.google.common.annotations.Beta</additionalModelTypeAnnotations>
181+
</configOptions>
182+
<generateModels>true</generateModels>
183+
<generateSupportingFiles>false</generateSupportingFiles>
184+
<generateApis>false</generateApis>
185+
<library>resttemplate</library>
186+
<!--<configHelp>true</configHelp>-->
163187
</configuration>
164188
</execution>
165189
</executions>
166190
</plugin>
191+
<plugin>
192+
<artifactId>maven-clean-plugin</artifactId>
193+
<configuration>
194+
<filesets>
195+
<fileset>
196+
<directory>${project.basedir}/src/main/java/com/sap/ai/sdk/orchestration/client</directory>
197+
<includes>
198+
<include>**/*</include>
199+
</includes>
200+
</fileset>
201+
</filesets>
202+
</configuration>
203+
<executions>
204+
<execution>
205+
<id>delete-orchestration-generated-client</id>
206+
</execution>
207+
</executions>
208+
</plugin>
167209
</plugins>
168210
</build>
169211
</profile>

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

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

3+
import com.sap.ai.sdk.orchestration.client.model.ChatMessage;
34
import com.sap.ai.sdk.orchestration.client.model.CompletionPostRequest;
45
import com.sap.ai.sdk.orchestration.client.model.ModuleConfigs;
56
import com.sap.ai.sdk.orchestration.client.model.OrchestrationConfig;
7+
import com.sap.ai.sdk.orchestration.client.model.Template;
68
import com.sap.ai.sdk.orchestration.client.model.TemplatingModuleConfig;
79
import io.vavr.control.Option;
810
import java.util.ArrayList;
@@ -25,9 +27,9 @@ static CompletionPostRequest toCompletionPostRequest(
2527
// subsequent requests
2628
val configCopy = config.withTemplateConfig(template);
2729

28-
return CompletionPostRequest.create()
30+
return new CompletionPostRequest()
2931
.orchestrationConfig(
30-
OrchestrationConfig.create().moduleConfigurations(toModuleConfigs(configCopy)))
32+
new OrchestrationConfig().moduleConfigurations(toModuleConfigs(configCopy)))
3133
.inputParams(prompt.getTemplateParameters())
3234
.messagesHistory(prompt.getMessagesHistory());
3335
}
@@ -42,14 +44,14 @@ static TemplatingModuleConfig toTemplateModuleConfig(
4244
* In this case, the request will fail, since the templating module will try to resolve the parameter.
4345
* To be fixed with https://github.tools.sap/AI/llm-orchestration/issues/662
4446
*/
45-
val messages = Option.of(template).map(TemplatingModuleConfig::getTemplate).getOrElse(List::of);
47+
val messages = template instanceof Template t ? t.getTemplate() : List.<ChatMessage>of();
4648
val messagesWithPrompt = new ArrayList<>(messages);
4749
messagesWithPrompt.addAll(prompt.getMessages());
4850
if (messagesWithPrompt.isEmpty()) {
4951
throw new IllegalStateException(
5052
"A prompt is required. Pass at least one message or configure a template with messages or a template reference.");
5153
}
52-
return TemplatingModuleConfig.create().template(messagesWithPrompt);
54+
return new Template().template(messagesWithPrompt);
5355
}
5456

5557
@Nonnull
@@ -60,7 +62,7 @@ static ModuleConfigs toModuleConfigs(@Nonnull final OrchestrationModuleConfig co
6062

6163
//noinspection DataFlowIssue the template is always non-null here
6264
val moduleConfig =
63-
ModuleConfigs.create()
65+
new ModuleConfigs()
6466
.llmModuleConfig(llmConfig)
6567
.templatingModuleConfig(config.getTemplateConfig());
6668

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package com.sap.ai.sdk.orchestration;
2+
3+
import com.fasterxml.jackson.annotation.JsonTypeInfo;
4+
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
5+
import com.sap.ai.sdk.orchestration.client.model.LLMModuleResultSynchronous;
6+
7+
/** Mixin to enforce a specific subtype to be deserialized always. */
8+
@JsonTypeInfo(use = JsonTypeInfo.Id.NONE)
9+
@JsonDeserialize(as = LLMModuleResultSynchronous.class)
10+
interface LLMModuleResultMixIn {}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package com.sap.ai.sdk.orchestration;
2+
3+
import com.fasterxml.jackson.annotation.JsonTypeInfo;
4+
5+
/** Mixin to suppress @JsonTypeInfo for oneOf interfaces. */
6+
@JsonTypeInfo(use = JsonTypeInfo.Id.NONE)
7+
interface NoTypeInfoMixin {}

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

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,13 @@
1010
import com.sap.ai.sdk.core.AiCoreService;
1111
import com.sap.ai.sdk.orchestration.client.model.CompletionPostRequest;
1212
import com.sap.ai.sdk.orchestration.client.model.CompletionPostResponse;
13+
import com.sap.ai.sdk.orchestration.client.model.FilterConfig;
14+
import com.sap.ai.sdk.orchestration.client.model.LLMModuleResult;
15+
import com.sap.ai.sdk.orchestration.client.model.MaskingProviderConfig;
1316
import com.sap.ai.sdk.orchestration.client.model.ModuleConfigs;
17+
import com.sap.ai.sdk.orchestration.client.model.ModuleResultsOutputUnmaskingInner;
1418
import com.sap.ai.sdk.orchestration.client.model.OrchestrationConfig;
19+
import com.sap.ai.sdk.orchestration.client.model.TemplatingModuleConfig;
1520
import com.sap.cloud.sdk.cloudplatform.connectivity.ApacheHttpClient5Accessor;
1621
import com.sap.cloud.sdk.cloudplatform.connectivity.exception.DestinationAccessException;
1722
import com.sap.cloud.sdk.cloudplatform.connectivity.exception.DestinationNotFoundException;
@@ -40,6 +45,11 @@ public class OrchestrationClient {
4045
.visibility(PropertyAccessor.GETTER, JsonAutoDetect.Visibility.NONE)
4146
.visibility(PropertyAccessor.SETTER, JsonAutoDetect.Visibility.NONE)
4247
.serializationInclusion(JsonInclude.Include.NON_NULL)
48+
.mixIn(LLMModuleResult.class, LLMModuleResultMixIn.class)
49+
.mixIn(ModuleResultsOutputUnmaskingInner.class, NoTypeInfoMixin.class)
50+
.mixIn(FilterConfig.class, NoTypeInfoMixin.class)
51+
.mixIn(MaskingProviderConfig.class, NoTypeInfoMixin.class)
52+
.mixIn(TemplatingModuleConfig.class, NoTypeInfoMixin.class)
4353
.build();
4454
}
4555

@@ -66,6 +76,20 @@ public OrchestrationClient(@Nonnull final AiCoreDeployment deployment) {
6676
this.deployment = () -> deployment;
6777
}
6878

79+
/**
80+
* Convert the given prompt and config into a low-level request data object. The data object
81+
* allows for further customization before sending the request.
82+
*
83+
* @param prompt The {@link OrchestrationPrompt} to generate a completion for.
84+
* @param config The {@link OrchestrationConfig } configuration to use for the completion.
85+
* @return The low-level request data object to send to orchestration.
86+
*/
87+
@Nonnull
88+
public static CompletionPostRequest toCompletionPostRequest(
89+
@Nonnull final OrchestrationPrompt prompt, @Nonnull final OrchestrationModuleConfig config) {
90+
return ConfigToRequestTransformer.toCompletionPostRequest(prompt, config);
91+
}
92+
6993
/**
7094
* Generate a completion for the given prompt.
7195
*
@@ -118,20 +142,6 @@ public CompletionPostResponse executeRequest(@Nonnull final CompletionPostReques
118142
return executeRequest(postRequest);
119143
}
120144

121-
/**
122-
* Convert the given prompt and config into a low-level request data object. The data object
123-
* allows for further customization before sending the request.
124-
*
125-
* @param prompt The {@link OrchestrationPrompt} to generate a completion for.
126-
* @param config The {@link OrchestrationConfig } configuration to use for the completion.
127-
* @return The low-level request data object to send to orchestration.
128-
*/
129-
@Nonnull
130-
public static CompletionPostRequest toCompletionPostRequest(
131-
@Nonnull final OrchestrationPrompt prompt, @Nonnull final OrchestrationModuleConfig config) {
132-
return ConfigToRequestTransformer.toCompletionPostRequest(prompt, config);
133-
}
134-
135145
@Nonnull
136146
CompletionPostResponse executeRequest(@Nonnull final BasicClassicHttpRequest request) {
137147
try {

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public class OrchestrationPrompt {
3232
* @param message A user message.
3333
*/
3434
public OrchestrationPrompt(@Nonnull final String message) {
35-
messages.add(ChatMessage.create().role("user").content(message));
35+
messages.add(new ChatMessage().role("user").content(message));
3636
}
3737

3838
/**

0 commit comments

Comments
 (0)