Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
46f4ba4
WiP
CharlesDuboisSAP Jan 13, 2025
ebc21ff
WiP 2
CharlesDuboisSAP Jan 13, 2025
ed7c6e4
finito
CharlesDuboisSAP Jan 14, 2025
3cc0dd0
WiP
CharlesDuboisSAP Jan 13, 2025
c5a43a0
WiP 2
CharlesDuboisSAP Jan 13, 2025
d496c13
finito
CharlesDuboisSAP Jan 14, 2025
002f677
Merge remote-tracking branch 'origin/bean' into bean
CharlesDuboisSAP Jan 14, 2025
ccbcd64
Formatting
bot-sdk-js Jan 14, 2025
605a51d
docs
CharlesDuboisSAP Jan 14, 2025
7155ad5
Merge remote-tracking branch 'origin/bean' into bean
CharlesDuboisSAP Jan 14, 2025
d45a397
repo in parent pom
CharlesDuboisSAP Jan 14, 2025
8c751be
Formatting
bot-sdk-js Jan 14, 2025
e7e5a9d
Update docs
CharlesDuboisSAP Jan 14, 2025
ab63181
Merge remote-tracking branch 'origin/bean' into bean
CharlesDuboisSAP Jan 14, 2025
529b37e
Aligned headers
CharlesDuboisSAP Jan 14, 2025
d064734
Added no args constructor
CharlesDuboisSAP Jan 14, 2025
2d20234
Removed spring-ai-app
CharlesDuboisSAP Jan 15, 2025
15f4347
Merge branch 'refs/heads/main' into bean
CharlesDuboisSAP Jan 15, 2025
afa6f9f
Added images in index.html
CharlesDuboisSAP Jan 15, 2025
bc0f64a
Alex's review comments
CharlesDuboisSAP Jan 15, 2025
efe05e1
Shorter
CharlesDuboisSAP Jan 15, 2025
2133fc4
Added instructions
CharlesDuboisSAP Jan 15, 2025
6cdd6a7
M5
CharlesDuboisSAP Jan 15, 2025
6c5a512
fixed copy
CharlesDuboisSAP Jan 16, 2025
0fd5e10
Formatting
bot-sdk-js Jan 16, 2025
5088e7d
removed warnings
CharlesDuboisSAP Jan 16, 2025
6ade28f
green CI
CharlesDuboisSAP Jan 16, 2025
da7d72e
Fixed controller, added service
CharlesDuboisSAP Jan 16, 2025
be64b9e
Removed chat Memory
CharlesDuboisSAP Jan 16, 2025
5ffb8ec
Merge branch 'main' into bean
CharlesDuboisSAP Jan 17, 2025
5f6a163
Alex's review
CharlesDuboisSAP Jan 17, 2025
ad2b83b
Better documentation
CharlesDuboisSAP Jan 17, 2025
b94276d
Added images
CharlesDuboisSAP Jan 17, 2025
6f549d9
Better images
CharlesDuboisSAP Jan 17, 2025
46c84ca
mb
CharlesDuboisSAP Jan 17, 2025
6e49163
added note
CharlesDuboisSAP Jan 17, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,10 +131,11 @@ Please refer to [this documentation](docs/guides/ORCHESTRATION_CHAT_COMPLETION.m

For more detailed information and advanced usage, please refer to the following:

- [Connecting to AI Core](docs/guides/CONNECTING_TO_AICORE.md)
- [Orchestration Chat Completion](docs/guides/ORCHESTRATION_CHAT_COMPLETION.md)
- [OpenAI Chat Completion](docs/guides/OPENAI_CHAT_COMPLETION.md)
- [AI Core Deployment](docs/guides/AI_CORE_DEPLOYMENT.md)
- [<img src="sample-code/spring-app/src/main/resources/static/BTP-Cockpit-Logo.png"/> Connecting to AI Core](docs/guides/CONNECTING_TO_AICORE.md)
- [<img src="sample-code/spring-app/src/main/resources/static/Orchestration-Logo.png" width="16"/> Orchestration Chat Completion](docs/guides/ORCHESTRATION_CHAT_COMPLETION.md)
- [<img src="sample-code/spring-app/src/main/resources/static/Open-AI-Logo.svg" width="16"/> OpenAI Chat Completion](docs/guides/OPENAI_CHAT_COMPLETION.md)
- [<img src="https://spring.io/favicon-32x32.png" width="16"/> Spring AI Integration](docs/guides/SPRING_AI_INTEGRATION.md)
- [🧰 AI Core Deployment](docs/guides/AI_CORE_DEPLOYMENT.md)

For updating versions, please refer to the [**Release Notes**](docs/release-notes/release-notes-0-to-14.md).

Expand Down
4 changes: 2 additions & 2 deletions docs/guides/AI_CORE_DEPLOYMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ In addition to the prerequisites above, we assume you have already set up the fo
```
</details>

### Create a Deployment
## Create a Deployment

Use the following code snippet to create a deployment in SAP AI Core:

Expand All @@ -84,7 +84,7 @@ AiExecutionStatus status = deployment.getStatus();

Refer to the [DeploymentController.java](../../sample-code/spring-app/src/main/java/com/sap/ai/sdk/app/controllers/DeploymentController.java) in our Spring Boot application for a complete example.

### Delete a Deployment
## Delete a Deployment

```java
AiDeploymentCreationResponse deployment; // provided
Expand Down
20 changes: 9 additions & 11 deletions docs/guides/OPENAI_CHAT_COMPLETION.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ In addition to the prerequisites above, we assume you have already set up the fo

</details>

### Simple chat completion
## Simple chat completion

```java
var result =
Expand All @@ -98,7 +98,7 @@ var result =
String resultMessage = result.getContent();
```

### Using a Custom Resource Group
## Using a Custom Resource Group
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Comment)

Why the drive-by changes 😅

Copy link
Contributor Author

@CharlesDuboisSAP CharlesDuboisSAP Jan 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this ## adds underlines which makes it more readable because the file is super long, it also aligns with the other files.

underline


```java
var destination = new AiCoreService()
Expand All @@ -107,7 +107,7 @@ var destination = new AiCoreService()
OpenAiClient.withCustomDestination(destination);
```

### Message history
## Message history

```java
var systemMessage =
Expand All @@ -124,7 +124,7 @@ String resultMessage = result.getContent();

See [an example in our Spring Boot application](../../sample-code/spring-app/src/main/java/com/sap/ai/sdk/app/controllers/OpenAiController.java)

### Chat Completion with Specific Model Version
## Chat Completion with Specific Model Version

By default, when no version is specified, the system selects one of the available deployments of the specified model, regardless of its version.
To target a specific version, you can specify the model version along with the model.
Expand All @@ -134,7 +134,7 @@ OpenAiChatCompletionOutput result =
OpenAiClient.forModel(GPT_35_TURBO.withVersion("1106")).chatCompletion(request);
```

### Chat completion with Custom Model
## Chat completion with Custom Model

You can also use a custom OpenAI model for chat completion by creating an `OpenAiModel` object.

Expand All @@ -145,11 +145,11 @@ OpenAiChatCompletionOutput result =

Ensure that the custom model is deployed in SAP AI Core.

### Stream chat completion
## Stream chat completion

It's possible to pass a stream of chat completion delta elements, e.g. from the application backend to the frontend in real-time.

#### Asynchronous Streaming
### Asynchronous Streaming

This is a blocking example for streaming and printing directly to the console:

Expand All @@ -168,7 +168,7 @@ try (Stream<String> stream = client.streamChatCompletion(msg)) {
}
```

#### Aggregating Total Output
### Aggregating Total Output

The following example is non-blocking and demonstrates how to aggregate the complete response.
Any asynchronous library can be used, such as the classic Thread API.
Expand Down Expand Up @@ -205,12 +205,10 @@ Integer tokensUsed = totalOutput.getUsage().getCompletionTokens();
System.out.println("Tokens used: " + tokensUsed);
```

#### Spring Boot example

Please find [an example in our Spring Boot application](../../sample-code/spring-app/src/main/java/com/sap/ai/sdk/app/controllers/OpenAiController.java). It shows the usage of Spring
Boot's `ResponseBodyEmitter` to stream the chat completion delta messages to the frontend in real-time.

### Embedding
## Embedding

Get the embeddings of a text input in list of float values:

Expand Down
24 changes: 11 additions & 13 deletions docs/guides/ORCHESTRATION_CHAT_COMPLETION.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ var config = new OrchestrationModuleConfig()

Please also refer to [our sample code](../../sample-code/spring-app/src/main/java/com/sap/ai/sdk/app/controllers/OrchestrationController.java) for this and all following code examples.

### Chat Completion
## Chat Completion

Use the Orchestration service to generate a response to a user message:

Expand All @@ -100,7 +100,7 @@ String messageResult = result.getContent();
In this example, the Orchestration service generates a response to the user message "Hello world! Why is this phrase so famous?".
The LLM response is available as the first choice under the `result.getOrchestrationResult()` object.

### Chat completion with Templates
## Chat completion with Templates

Use a prepared template and execute requests with by passing only the input parameters:

Expand All @@ -117,7 +117,7 @@ var result = client.chatCompletion(prompt, configWithTemplate);

In this case the template is defined with the placeholder `{{?language}}` which is replaced by the value `German` in the input parameters.

### Message history
## Message history

Include a message history to maintain context in the conversation:

Expand All @@ -134,7 +134,7 @@ var prompt = new OrchestrationPrompt(message).messageHistory(messagesHistory);
var result = new OrchestrationClient().chatCompletion(prompt, config);
```

### Chat completion filter
## Chat completion filter

Apply content filtering to the chat completion:

Expand Down Expand Up @@ -165,7 +165,7 @@ var configWithFilter = config.withInputFiltering(filterStrict).withOutputFilteri
var result =
new OrchestrationClient().chatCompletion(prompt, configWithFilter);
```
#### Behavior of Input and Output Filters
### Behavior of Input and Output Filters

- **Input Filter**:
If the input message violates the filter policy, a `400 (Bad Request)` response will be received during the `chatCompletion` call.
Expand All @@ -178,7 +178,7 @@ var result =

You will find [some examples](../../sample-code/spring-app/src/main/java/com/sap/ai/sdk/app/controllers/OrchestrationController.java) in our Spring Boot application demonstrating response handling with filters.

### Data masking
## Data masking

Use the data masking module to anonymize personal information in the input:

Expand All @@ -201,7 +201,7 @@ var result =

In this example, the input will be masked before the call to the LLM and will remain masked in the output.

### Grounding
## Grounding

Use the grounding module to provide additional context to the AI model.

Expand Down Expand Up @@ -232,11 +232,11 @@ Use the grounding module to provide additional context to the AI model.

In this example, the AI model is provided with additional context in the form of grounding information. Note, that it is necessary to provide the grounding input via one or more input variables.

### Stream chat completion
## Stream chat completion

It's possible to pass a stream of chat completion delta elements, e.g. from the application backend to the frontend in real-time.

#### Asynchronous Streaming
### Asynchronous Streaming

This is a blocking example for streaming and printing directly to the console:

Expand All @@ -253,12 +253,10 @@ try (Stream<String> stream = client.streamChatCompletion(prompt, config)) {
}
```

#### Spring Boot example

Please find [an example in our Spring Boot application](../../sample-code/spring-app/src/main/java/com/sap/ai/sdk/app/controllers/OrchestrationController.java).
It shows the usage of Spring Boot's `ResponseBodyEmitter` to stream the chat completion delta messages to the frontend in real-time.

### Set model parameters
## Set model parameters

Change your LLM configuration to add model parameters:

Expand All @@ -272,7 +270,7 @@ OrchestrationAiModel customGPT4O =
.withVersion("2024-05-13");
```

### Using a Configuration from AI Launchpad
## Using a Configuration from AI Launchpad

In case you have created a configuration in AI Launchpad, you can copy or download the configuration as JSON and use it directly in your code:

Expand Down
52 changes: 52 additions & 0 deletions docs/guides/SPRING_AI_INTEGRATION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Spring AI Integration

## Table of Contents

- [Introduction](#introduction)
- [Orchestration Chat Completion](#orchestration-chat-completion)
- [Orchestration Masking](#orchestration-masking)

## Introduction

This guide provides examples of how to use our Spring AI integration with our clients in SAP AI Core
for chat completion tasks using the SAP AI SDK for Java.

## Orchestration Chat Completion

The Orchestration client is integrated in Spring AI classes:

```java
ChatModel client = new OrchestrationChatModel();
OrchestrationModuleConfig config = new OrchestrationModuleConfig().withLlmConfig(GPT_35_TURBO);
OrchestrationChatOptions opts = new OrchestrationChatOptions(config);

Prompt prompt = new Prompt("What is the capital of France?", opts);
ChatResponse response = client.call(prompt);
```

Please
find [an example in our Spring Boot application](../../sample-code/spring-app/src/main/java/com/sap/ai/sdk/app/controllers/SpringAiOrchestrationController.java).

## Orchestration Masking

Configure Orchestration modules withing Spring AI:

```java
ChatModel client = new OrchestrationChatModel();
OrchestrationModuleConfig config = new OrchestrationModuleConfig().withLlmConfig(GPT_35_TURBO);

val masking =
DpiMasking.anonymization()
.withEntities(DPIEntities.EMAIL, DPIEntities.ADDRESS, DPIEntities.LOCATION);

val opts = new OrchestrationChatOptions(config.withMaskingConfig(masking));
val prompt =
new Prompt(
"Please write 'Hello World!' to me via email. My email address is [email protected]",
opts);

ChatResponse response = client.call(prompt);
```

Please
find [an example in our Spring Boot application](../../sample-code/spring-app/src/main/java/com/sap/ai/sdk/app/controllers/SpringAiOrchestrationController.java).
1 change: 1 addition & 0 deletions docs/release-notes/release_notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
- Orchestration supports images as input in newly introduced `MultiChatMessage`.
- `MultiChatMessage` also allows for multiple content items (text or image) in one object.
- Grounding input can be masked with `DPIConfig`.
- [Integrate the Orchestration client in Spring AI.](../guides/ORCHESTRATION_CHAT_COMPLETION.md#spring-ai-integration)

### 📈 Improvements

Expand Down
16 changes: 10 additions & 6 deletions orchestration/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,11 @@
</developers>
<properties>
<project.rootdir>${project.basedir}/../</project.rootdir>
<coverage.complexity>70%</coverage.complexity>
<coverage.line>87%</coverage.line>
<coverage.instruction>88%</coverage.instruction>
<coverage.branch>65%</coverage.branch>
<coverage.method>65%</coverage.method>
<coverage.complexity>76%</coverage.complexity>
<coverage.line>90%</coverage.line>
<coverage.instruction>91%</coverage.instruction>
<coverage.branch>69%</coverage.branch>
<coverage.method>70%</coverage.method>
<coverage.class>100%</coverage.class>
</properties>

Expand All @@ -54,7 +54,11 @@
<groupId>com.sap.cloud.sdk.cloudplatform</groupId>
<artifactId>connectivity-apache-httpclient5</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-core</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents.core5</groupId>
<artifactId>httpcore5</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,24 +1,20 @@
package com.sap.ai.sdk.orchestration;

import static com.sap.ai.sdk.core.JacksonConfiguration.getDefaultObjectMapper;
import static com.sap.ai.sdk.orchestration.OrchestrationJacksonConfiguration.getOrchestrationObjectMapper;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.common.annotations.Beta;
import com.sap.ai.sdk.core.AiCoreService;
import com.sap.ai.sdk.core.DeploymentResolutionException;
import com.sap.ai.sdk.core.common.ClientResponseHandler;
import com.sap.ai.sdk.core.common.ClientStreamingHandler;
import com.sap.ai.sdk.core.common.StreamedDelta;
import com.sap.ai.sdk.orchestration.model.ChatMessagesInner;
import com.sap.ai.sdk.orchestration.model.CompletionPostRequest;
import com.sap.ai.sdk.orchestration.model.CompletionPostResponse;
import com.sap.ai.sdk.orchestration.model.LLMModuleResult;
import com.sap.ai.sdk.orchestration.model.ModuleConfigs;
import com.sap.ai.sdk.orchestration.model.ModuleResultsOutputUnmaskingInner;
import com.sap.ai.sdk.orchestration.model.OrchestrationConfig;
import com.sap.cloud.sdk.cloudplatform.connectivity.ApacheHttpClient5Accessor;
import com.sap.cloud.sdk.cloudplatform.connectivity.HttpDestination;
Expand All @@ -41,25 +37,7 @@
public class OrchestrationClient {
private static final String DEFAULT_SCENARIO = "orchestration";

static final ObjectMapper JACKSON;

static {
JACKSON = getDefaultObjectMapper();

// Add mix-ins
JACKSON.addMixIn(LLMModuleResult.class, JacksonMixins.LLMModuleResultMixIn.class);
JACKSON.addMixIn(
ModuleResultsOutputUnmaskingInner.class,
JacksonMixins.ModuleResultsOutputUnmaskingInnerMixIn.class);

final var module =
new SimpleModule()
.addDeserializer(
ChatMessagesInner.class,
PolymorphicFallbackDeserializer.fromJsonSubTypes(ChatMessagesInner.class))
.setMixInAnnotation(ChatMessagesInner.class, JacksonMixins.NoneTypeInfoMixin.class);
JACKSON.registerModule(module);
}
static final ObjectMapper JACKSON = getOrchestrationObjectMapper();

@Nonnull private final Supplier<HttpDestination> destinationSupplier;

Expand Down
Loading
Loading