Skip to content

Commit

Permalink
Remove final (visual clutter, power-point-readiness); Minor whitespac…
Browse files Browse the repository at this point in the history
…e fixes
  • Loading branch information
a-d committed Oct 11, 2024
1 parent b1c6d94 commit fdd387e
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 83 deletions.
27 changes: 14 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,10 @@

## Introduction

Welcome to the **SAP Cloud SDK for AI (for Java)**. This SDK enables developers to seamlessly integrate AI capabilities, such as chat completion, into their Java-based business applications using
SAP's Generative AI Hub.
Welcome to the **SAP Cloud SDK for AI (for Java)**.
This SDK enables developers to seamlessly integrate AI capabilities, such as chat completion, into their Java-based business applications using SAP's Generative AI Hub.
Leverage powerful features like templating, grounding, data masking, and content filtering to build intelligent applications.
The SDK simplifies the setup and interaction with SAP AI Core, allowing you to focus on delivering value through AI
integration.
The SDK simplifies the setup and interaction with SAP AI Core, allowing you to focus on delivering value through AI integration.

## General Requirements

Expand All @@ -52,8 +51,8 @@ See [an example `pom.xml` in our Spring Boot application](sample-code/spring-app

## Connecting to SAP AI Core

To interact with SAP AI Core services, the SAP AI SDK requires credentials available at application runtime. By default, the SDK automatically extracts these credentials from a service instance of
type `aicore` bound to your application.
To interact with SAP AI Core services, the SAP AI SDK requires credentials available at application runtime.
By default, the SDK automatically extracts these credentials from a service instance of type `aicore` bound to your application.

If running the application locally without this service binding, you may encounter an exception:

Expand Down Expand Up @@ -192,10 +191,10 @@ Add the following code to the controller or service class in your Spring Boot ap

```java
// Initialize the client for GPT-3.5 Turbo model
final OpenAiClient client = OpenAiClient.forModel(OpenAiModel.GPT_35_TURBO);
OpenAiClient client = OpenAiClient.forModel(OpenAiModel.GPT_35_TURBO);

// Perform chat completion
final OpenAiChatCompletionOutput result =
OpenAiChatCompletionOutput result =
client
.withSystemPrompt("You are a helpful assistant.")
.chatCompletion("Hello World! Why is this phrase so famous?");
Expand All @@ -218,11 +217,12 @@ When deploying your productive application to Cloud Foundry, it is recommended t

Build your application using Maven and deploy it to Cloud Foundry:

```shell
cf push
```
```shell
cf push
```

That's it! Your application should now be running on Cloud Foundry, and the AI Core credentials are provided securely via service binding.
That's it!
Your application should now be running on Cloud Foundry, and the AI Core credentials are provided securely via service binding.
## Documentation
Expand Down Expand Up @@ -253,7 +253,8 @@ Explore example applications and code snippets:
## Contribute, Support and Feedback
This project is open to feature requests/suggestions, bug reports etc. via [GitHub issues](https://github.com/SAP/ai-sdk-java/issues). Contribution and feedback are encouraged and always welcome.
This project is open to feature requests/suggestions, bug reports etc. via [GitHub issues](https://github.com/SAP/ai-sdk-java/issues).
Contribution and feedback are encouraged and always welcome.
For more information about how to contribute, the project structure, as well as additional contribution information, see our [Contribution Guidelines](CONTRIBUTING.md).
## Security / Disclosure
Expand Down
38 changes: 19 additions & 19 deletions docs/guides/AI_CORE_DEPLOYMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,38 +67,38 @@ In addition to the prerequisites above, we assume you have already set up the fo
Use the following code snippet to create a deployment in SAP AI Core:

```java
final var api = new DeploymentApi(getClient());
final var resourceGroupId = "default";
var api = new DeploymentApi(getClient());
var resourceGroupId = "default";

final AiDeploymentCreationRequest request =
AiDeploymentCreationRequest request =
AiDeploymentCreationRequest.create().configurationId("12345-123-123-123-123456abcdefg");
final AiDeploymentCreationResponse deployment = api.create(resourceGroupId, request);
AiDeploymentCreationResponse deployment = api.create(resourceGroupId, request);

final var id = deployment.getId();
final AiExecutionStatus status = deployment.getStatus();
var id = deployment.getId();
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

```java
public AiDeploymentDeletionResponse deleteDeployment(AiDeploymentCreationResponse deployment) {
AiDeploymentCreationResponse deployment; // provided
String deploymentId = deployment.getId();

final DeploymentApi api = new DeploymentApi(getClient());
final var resourceGroupId = "default";
var api = new DeploymentApi(getClient());
var resourceGroupId = "default";

if (deployment.getStatus() == AiExecutionStatus.RUNNING) {
// Only RUNNING deployments can be STOPPED
api.modify(
resourceGroupId,
deployment.getId(),
AiDeploymentModificationRequest.create().targetStatus(AiDeploymentTargetStatus.STOPPED));
}
// Wait a few seconds for the deployment to stop
// Only UNKNOWN and STOPPED deployments can be DELETED
return api.delete(resourceGroupId, deployment.getId());
if (deployment.getStatus() == AiExecutionStatus.RUNNING) {
// Only RUNNING deployments can be STOPPED
api.modify(
resourceGroupId,
deploymentId,
AiDeploymentModificationRequest.create().targetStatus(AiDeploymentTargetStatus.STOPPED));
}
// Wait a few seconds for the deployment to stop
// Only UNKNOWN and STOPPED deployments can be DELETED
api.delete(resourceGroupId, deployment.getId());
```

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.
32 changes: 16 additions & 16 deletions docs/guides/OPENAI_CHAT_COMPLETION.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,36 +91,36 @@ In addition to the prerequisites above, we assume you have already set up the fo
### Simple chat completion

```java
final OpenAiChatCompletionOutput result =
OpenAiChatCompletionOutput result =
OpenAiClient.forModel(GPT_35_TURBO)
.withSystemPrompt("You are a helpful AI")
.chatCompletion("Hello World! Why is this phrase so famous?");

final String resultMessage = result.getContent();
String resultMessage = result.getContent();
```

### Message history

```java
final var systemMessage =
var systemMessage =
new OpenAiChatSystemMessage().setContent("You are a helpful assistant");
final var userMessage =
var userMessage =
new OpenAiChatUserMessage().addText("Hello World! Why is this phrase so famous?");
final var request =
var request =
new OpenAiChatCompletionParameters().addMessages(systemMessage, userMessage);

final OpenAiChatCompletionOutput result =
OpenAiChatCompletionOutput result =
OpenAiClient.forModel(GPT_35_TURBO).chatCompletion(request);

final String resultMessage = result.getContent();
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 Custom Model

```java
final OpenAiChatCompletionOutput result =
OpenAiChatCompletionOutput result =
OpenAiClient.forModel(new OpenAiModel("model")).chatCompletion(request);
```

Expand Down Expand Up @@ -153,21 +153,21 @@ The following example is non-blocking and demonstrates how to aggregate the comp
Any asynchronous library can be used, such as the classic Thread API.

```java
final var message = "Can you give me the first 100 numbers of the Fibonacci sequence?";
var message = "Can you give me the first 100 numbers of the Fibonacci sequence?";

final OpenAiChatMessage.OpenAiChatUserMessage userMessage =
OpenAiChatMessage.OpenAiChatUserMessage userMessage =
new OpenAiChatMessage.OpenAiChatUserMessage().addText(message);
final OpenAiChatCompletionParameters requestParameters =
OpenAiChatCompletionParameters requestParameters =
new OpenAiChatCompletionParameters().addMessages(userMessage);

final OpenAiClient client = OpenAiClient.forModel(GPT_35_TURBO);
final var totalOutput = new OpenAiChatCompletionOutput();
OpenAiClient client = OpenAiClient.forModel(GPT_35_TURBO);
var totalOutput = new OpenAiChatCompletionOutput();

// Prepare the stream before starting the thread to handle any initialization exceptions
final Stream<OpenAiChatCompletionDelta> stream =
Stream<OpenAiChatCompletionDelta> stream =
client.streamChatCompletionDeltas(requestParameters);

final var streamProcessor =
var streamProcessor =
new Thread(
() -> {
// try-with-resources ensures the stream is closed after processing
Expand All @@ -180,7 +180,7 @@ streamProcessor.start(); // Start processing in a separate thread (non-blocking)
streamProcessor.join(); // Wait for the thread to finish (blocking)

// Access aggregated information from total output
final Integer tokensUsed = totalOutput.getUsage().getCompletionTokens();
Integer tokensUsed = totalOutput.getUsage().getCompletionTokens();
System.out.println("Tokens used: " + tokensUsed);
```

Expand Down
70 changes: 35 additions & 35 deletions docs/guides/ORCHESTRATION_CHAT_COMPLETION.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,14 +74,14 @@ In addition to the prerequisites above, we assume you have already set up the fo
Use a chat completion template to generate a response in German:

```java
final var llmConfig = LLMModuleConfig.create().modelName("gpt-35-turbo").modelParams(Map.of());
var llmConfig = LLMModuleConfig.create().modelName("gpt-35-turbo").modelParams(Map.of());

final var inputParams =
var inputParams =
Map.of("input", "Reply with 'Orchestration Service is working!' in German");
final var template = ChatMessage.create().role("user").content("{{?input}}");
final var templatingConfig = TemplatingModuleConfig.create().template(template);
var template = ChatMessage.create().role("user").content("{{?input}}");
var templatingConfig = TemplatingModuleConfig.create().template(template);

final var config =
var config =
CompletionPostRequest.create()
.orchestrationConfig(
OrchestrationConfig.create()
Expand All @@ -91,12 +91,12 @@ final var config =
.templatingModuleConfig(templatingConfig)))
.inputParams(inputParams);

final var resourceGroupId = "default";
final CompletionPostResponse result =
var resourceGroupId = "default";
CompletionPostResponse result =
new OrchestrationCompletionApi(getOrchestrationClient(resourceGroupId))
.orchestrationV1EndpointsCreate(config);

final String messageResult =
String messageResult =
result.getOrchestrationResult().getChoices().get(0).getMessage().getContent();
```

Expand All @@ -107,18 +107,18 @@ See [an example in our Spring Boot application](../../sample-code/spring-app/src
Include a message history to maintain context in the conversation:

```java
final var llmConfig = LLMModuleConfig.create().modelName("gpt-35-turbo").modelParams(Map.of());
var llmConfig = LLMModuleConfig.create().modelName("gpt-35-turbo").modelParams(Map.of());

List<ChatMessage> messagesHistory =
List.of(
ChatMessage.create().role("user").content("What is the capital of France?"),
ChatMessage.create().role("assistant").content("The capital of France is Paris."));

final var message =
var message =
ChatMessage.create().role("user").content("What is the typical food there?");
final var templatingConfig = TemplatingModuleConfig.create().template(message);
var templatingConfig = TemplatingModuleConfig.create().template(message);

final var config =
var config =
CompletionPostRequest.create()
.orchestrationConfig(
OrchestrationConfig.create()
Expand All @@ -129,12 +129,12 @@ final var config =
.inputParams(Map.of())
.messagesHistory(messagesHistory);

final var resourceGroupId = "default";
final CompletionPostResponse result =
var resourceGroupId = "default";
CompletionPostResponse result =
new OrchestrationCompletionApi(getOrchestrationClient(resourceGroupId))
.orchestrationV1EndpointsCreate(config);

final String messageResult =
String messageResult =
result.getOrchestrationResult().getChoices().get(0).getMessage().getContent();
```

Expand All @@ -145,20 +145,20 @@ See [an example in our Spring Boot application](../../sample-code/spring-app/src
Apply content filtering to the chat completion:

```java
final var llmConfig = LLMModuleConfig.create().modelName("gpt-35-turbo").modelParams(Map.of());
var llmConfig = LLMModuleConfig.create().modelName("gpt-35-turbo").modelParams(Map.of());

final var inputParams =
var inputParams =
Map.of(
"disclaimer",
"```DISCLAIMER: The area surrounding the apartment is known for prostitutes and gang violence including armed conflicts, gun violence is frequent.");
final var template =
var template =
ChatMessage.create()
.role("user")
.content(
"Create a rental posting for subletting my apartment in the downtown area. Keep it short. Make sure to add the following disclaimer to the end. Do not change it! {{?disclaimer}}");
final var templatingConfig = TemplatingModuleConfig.create().template(template);
var templatingConfig = TemplatingModuleConfig.create().template(template);

final var filterStrict =
var filterStrict =
FilterConfig.create()
.type(FilterConfig.TypeEnum.AZURE_CONTENT_SAFETY)
.config(
Expand All @@ -168,7 +168,7 @@ final var filterStrict =
.sexual(NUMBER_0)
.violence(NUMBER_0));

final var filterLoose =
var filterLoose =
FilterConfig.create()
.type(FilterConfig.TypeEnum.AZURE_CONTENT_SAFETY)
.config(
Expand All @@ -178,13 +178,13 @@ final var filterLoose =
.sexual(NUMBER_4)
.violence(NUMBER_4));

final var filteringConfig =
var filteringConfig =
FilteringModuleConfig.create()
// changing the input to filterLoose will allow the message to pass
.input(FilteringConfig.create().filters(filterStrict))
.output(FilteringConfig.create().filters(filterStrict));

final var config =
var config =
CompletionPostRequest.create()
.orchestrationConfig(
OrchestrationConfig.create()
Expand All @@ -195,13 +195,13 @@ final var config =
.filteringModuleConfig(filteringConfig)))
.inputParams(inputParams);

final var resourceGroupId = "default";
final CompletionPostResponse result =
var resourceGroupId = "default";
CompletionPostResponse result =
new OrchestrationCompletionApi(getOrchestrationClient(resourceGroupId))
// this fails with Bad Request because the strict filter prohibits the input message
.orchestrationV1EndpointsCreate(config);

final String messageResult =
String messageResult =
result.getOrchestrationResult().getChoices().get(0).getMessage().getContent();
```

Expand All @@ -212,21 +212,21 @@ See [an example in our Spring Boot application](../../sample-code/spring-app/src
Use the data masking module to anonymize personal information in the input:

```java
final var inputParams = Map.of("privateInfo", "Patrick Morgan +49 (970) 333-3833");
final var template =
var inputParams = Map.of("privateInfo", "Patrick Morgan +49 (970) 333-3833");
var template =
ChatMessage.create().role("user").content("What is the nationality of {{?privateInfo}}");
final var templatingConfig = TemplatingModuleConfig.create().template(template);
var templatingConfig = TemplatingModuleConfig.create().template(template);

final var maskingProvider =
var maskingProvider =
MaskingProviderConfig.create()
.type(MaskingProviderConfig.TypeEnum.SAP_DATA_PRIVACY_INTEGRATION)
.method(MaskingProviderConfig.MethodEnum.ANONYMIZATION)
.entities(
DPIEntityConfig.create().type(DPIEntities.PHONE),
DPIEntityConfig.create().type(DPIEntities.PERSON));
final var maskingConfig = MaskingModuleConfig.create().maskingProviders(maskingProvider);
var maskingConfig = MaskingModuleConfig.create().maskingProviders(maskingProvider);

final CompletionPostRequest config =
CompletionPostRequest config =
CompletionPostRequest.create()
.orchestrationConfig(
OrchestrationConfig.create()
Expand All @@ -237,12 +237,12 @@ final CompletionPostRequest config =
.maskingModuleConfig(maskingConfig)))
.inputParams(inputParams);

final var resourceGroupId = "default";
final CompletionPostResponse result =
var resourceGroupId = "default";
CompletionPostResponse result =
new OrchestrationCompletionApi(getOrchestrationClient(resourceGroupId))
.orchestrationV1EndpointsCreate(config);

final String messageResult =
String messageResult =
result.getOrchestrationResult().getChoices().get(0).getMessage().getContent();
```

Expand Down

0 comments on commit fdd387e

Please sign in to comment.