All skills
secondsky avatar

/sap-cloud-sdk-ai

@620a19a
by Eddiesecondsky/sap-skills456 stars
120

Integrates SAP Cloud SDK for AI into JavaScript/TypeScript and Java applications. Use when building applications with SAP AI Core, Generative AI Hub, or Orchestration Service. Covers chat completion, embedding, streaming, function calling, content filtering, data masking, document grounding, prompt registry, and LangChain/Spring AI integration. Supports OpenAI GPT-4o, Llama, Gemini, Amazon Nova, and other foundation models via SAP BTP.

Use this Skill: https://skilld.dev/gh/secondsky/sap-skills/sap-cloud-sdk-ai

This session only. Nothing lands on disk.

referencesfoundation-models-guide.md

≈3k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Foundation Models Guide

Direct access to OpenAI models via SAP AI Core without orchestration layer.

Table of Contents

  1. Overview
  2. Installation
  3. JavaScript Client
  4. Java Client
  5. Chat Completion
  6. Streaming
  7. Function Calling
  8. Embedding
  9. Model Versioning
  10. Custom Configuration

Overview

The Foundation Models package provides direct access to Azure OpenAI models deployed on SAP AI Core. Use this when you need:

  • Direct model access without orchestration features
  • Specific OpenAI API compatibility
  • Lower latency (no orchestration overhead)

When to use Orchestration instead:

  • Need content filtering, data masking, or grounding
  • Want harmonized API across multiple model providers
  • Need prompt templating or translation

Installation

JavaScript/TypeScript

npm install @sap-ai-sdk/foundation-models

Java (Maven)

<dependency>
  <groupId>com.sap.ai.sdk.foundationmodels</groupId>
  <artifactId>openai</artifactId>
  <version>${ai-sdk.version}</version>
</dependency>

JavaScript Client

Client Initialization

import { AzureOpenAiChatClient } from '@sap-ai-sdk/foundation-models';

// Basic initialization
const client = new AzureOpenAiChatClient('gpt-4o');

// With model version
const client = new AzureOpenAiChatClient({
  modelName: 'gpt-4o',
  modelVersion: '2024-05-13'
});

// With resource group
const client = new AzureOpenAiChatClient({
  modelName: 'gpt-4o',
  resourceGroup: 'my-resource-group'
});

// With deployment ID (bypasses model lookup)
const client = new AzureOpenAiChatClient({
  deploymentId: 'd1234567'
});

API Version

The client uses Azure OpenAI API version 2024-10-21 by default. Override via CustomRequestConfig:

const response = await client.run(
  { messages: [...] },
  {
    params: { 'api-version': '2024-08-01-preview' }
  }
);

Available Clients

Client Purpose
AzureOpenAiChatClient Chat completions
AzureOpenAiEmbeddingClient Text embeddings

Java Client

Client Initialization

import com.sap.ai.sdk.foundationmodels.openai.*;

// Basic initialization
var client = OpenAiClient.forModel(OpenAiModel.GPT_4O);

// With system prompt
var client = OpenAiClient.forModel(OpenAiModel.GPT_4O)
    .withSystemPrompt("You are a helpful assistant");

// With custom resource group
var destination = new AiCoreService()
    .getInferenceDestination("my-resource-group");
var client = OpenAiClient.forModel(OpenAiModel.GPT_4O)
    .withDestination(destination);

Version History

Version Features
v1.8.0+ Tool calling with OpenAiTool
v1.4.0+ New interface with OpenAiChatCompletionRequest, OpenAiMessage
v1.0.0 Deprecated interface (still available)

v1.4.0+ Interface (Recommended)

// Using new interface
var request = OpenAiChatCompletionRequest.create()
    .addMessage(OpenAiMessage.system("You are helpful"))
    .addMessage(OpenAiMessage.user("What is SAP?"));

var response = client.chatCompletion(request);
String content = response.getContent();

v1.0.0 Interface (Deprecated)

// Legacy interface - avoid for new code
var params = new OpenAiChatCompletionParameters()
    .addMessages(new OpenAiChatSystemMessage().setContent("System prompt"))
    .addMessages(new OpenAiChatUserMessage().setContent("User message"));

var response = client.chatCompletion(params);

Chat Completion

JavaScript

// Basic request
const response = await client.run({
  messages: [
    { role: 'user', content: 'What is SAP CAP?' }
  ]
});

console.log(response.getContent());

// With parameters
const response = await client.run({
  messages: [
    { role: 'system', content: 'You are a helpful assistant' },
    { role: 'user', content: 'Explain briefly' }
  ],
  max_tokens: 500,
  temperature: 0.7
});

// Token usage
const usage = response.getTokenUsage();
console.log('Prompt tokens:', usage.prompt_tokens);
console.log('Completion tokens:', usage.completion_tokens);
console.log('Total tokens:', usage.total_tokens);

Java

// Simple request
var response = client.chatCompletion("What is SAP CAP?");
System.out.println(response.getContent());

// With message history
var request = OpenAiChatCompletionRequest.create()
    .addMessage(OpenAiMessage.system("You are a SAP expert"))
    .addMessage(OpenAiMessage.user("What is CAP?"))
    .addMessage(OpenAiMessage.assistant("CAP is..."))
    .addMessage(OpenAiMessage.user("Tell me more"));

var response = client.chatCompletion(request);

Streaming

JavaScript

// Basic streaming
const stream = client.stream({
  messages: [{ role: 'user', content: 'Explain SAP in detail' }]
});

for await (const chunk of stream.toContentStream()) {
  process.stdout.write(chunk);
}

// Get metadata after streaming
console.log('Finish reason:', stream.getFinishReason());
console.log('Token usage:', stream.getTokenUsage());

// With abort controller
const controller = new AbortController();
const stream = client.stream(config, controller.signal);

setTimeout(() => controller.abort(), 5000);

try {
  for await (const chunk of stream.toContentStream()) {
    process.stdout.write(chunk);
  }
} catch (e) {
  if (e.name === 'AbortError') {
    console.log('Stream cancelled');
  }
}

Java

// Blocking stream
client.streamChatCompletion("Explain SAP")
    .forEach(chunk -> System.out.print(chunk.getDeltaContent()));

// Non-blocking with deltas (v1.4.0+)
client.streamChatCompletionDeltas(request)
    .forEach(delta -> {
        if (delta.getDeltaContent() != null) {
            System.out.print(delta.getDeltaContent());
        }
    });

// With AtomicReference for result collection
AtomicReference<String> result = new AtomicReference<>("");
client.streamChatCompletion("Query")
    .forEach(chunk -> result.updateAndGet(s -> s + chunk.getDeltaContent()));

System.out.println("Full response: " + result.get());

Function Calling

JavaScript

const tools = [{
  type: 'function',
  function: {
    name: 'get_weather',
    description: 'Get weather for a location',
    parameters: {
      type: 'object',
      properties: {
        location: { type: 'string' },
        unit: { type: 'string', enum: ['celsius', 'fahrenheit'] }
      },
      required: ['location']
    },
    strict: true  // Enforce schema compliance
  }
}];

const response = await client.run({
  messages: [{ role: 'user', content: 'Weather in Berlin?' }],
  tools
});

const toolCalls = response.getToolCalls();
if (toolCalls?.length) {
  for (const call of toolCalls) {
    const { name, arguments: args } = call.function;
    const parsedArgs = JSON.parse(args);

    // Execute function
    const result = await executeWeatherLookup(parsedArgs.location);

    // Continue conversation with result
    const followUp = await client.run({
      messages: [
        { role: 'user', content: 'Weather in Berlin?' },
        response.getAssistantMessage(),
        { role: 'tool', tool_call_id: call.id, content: result }
      ],
      tools
    });
  }
}

Java (v1.8.0+)

// Define tool
var weatherTool = OpenAiTool.builder()
    .function(OpenAiFunction.builder()
        .name("get_weather")
        .description("Get weather for a location")
        .parameters(Map.of(
            "type", "object",
            "properties", Map.of(
                "location", Map.of("type", "string"),
                "unit", Map.of("type", "string", "enum", List.of("celsius", "fahrenheit"))
            ),
            "required", List.of("location")
        ))
        .build())
    .build();

// Request with tools
var request = OpenAiChatCompletionRequest.create()
    .addMessage(OpenAiMessage.user("Weather in Berlin?"))
    .withTools(List.of(weatherTool));

var response = client.chatCompletion(request);
var toolCalls = response.getToolCalls();

// Process tool calls
if (toolCalls != null && !toolCalls.isEmpty()) {
    for (var call : toolCalls) {
        String functionName = call.getFunction().getName();
        String arguments = call.getFunction().getArguments();
        // Execute and continue...
    }
}

Embedding

JavaScript

import { AzureOpenAiEmbeddingClient } from '@sap-ai-sdk/foundation-models';

const client = new AzureOpenAiEmbeddingClient('text-embedding-3-small');

// Single embedding
const response = await client.run({
  input: 'SAP is an enterprise software company'
});
const embedding = response.getEmbedding();
console.log('Dimensions:', embedding.length);

// Batch embeddings
const response = await client.run({
  input: ['First text', 'Second text', 'Third text']
});
const embeddings = response.getEmbeddings();

Java

// v1.4.0+ interface (recommended)
var client = OpenAiClient.forModel(OpenAiModel.TEXT_EMBEDDING_3_SMALL);

var request = new OpenAiEmbeddingRequest(List.of("SAP is an enterprise software company"));
var response = client.embedding(request);
float[] embedding = response.getEmbeddingVectors().get(0);
// v1.0.0 interface (legacy, deprecated)
var request = new OpenAiEmbeddingParameters().setInput("Hello World");
var response = OpenAiClient.forModel(OpenAiModel.TEXT_EMBEDDING_3_SMALL)
    .embedding(request);
float[] embedding = response.getData().get(0).getEmbedding();

Model Versioning

JavaScript

// Specify version at initialization
const client = new AzureOpenAiChatClient({
  modelName: 'gpt-4o',
  modelVersion: '2024-05-13'
});

Java

// Using withVersion()
var model = OpenAiModel.GPT_4O.withVersion("2024-05-13");
var client = OpenAiClient.forModel(model);

// Custom model
var customModel = new OpenAiModel("gpt-4o-custom", "2024-05-13");
var client = OpenAiClient.forModel(customModel);

Available Models

Model Constant Description
GPT_4O GPT-4o latest
GPT_4O_MINI GPT-4o mini
TEXT_EMBEDDING_3_SMALL Small embedding model
TEXT_EMBEDDING_3_LARGE Large embedding model

Custom Configuration

Custom Headers

// Java
var response = client.withHeader("X-Custom-Header", "value")
    .chatCompletion("Query");

Custom Destination

// JavaScript
const client = new AzureOpenAiChatClient({
  modelName: 'gpt-4o',
  destinationName: 'my-aicore-destination',
  useCache: false  // Disable destination caching
});
// Java
var destination = DestinationAccessor.getDestination("my-aicore-destination").asHttp();
var client = OpenAiClient.forModel(OpenAiModel.GPT_4O)
    .withDestination(destination);

Response Format (JSON Schema)

// JavaScript
const response = await client.run({
  messages: [...],
  response_format: {
    type: 'json_schema',
    json_schema: {
      name: 'response_schema',
      strict: true,
      schema: {
        type: 'object',
        properties: {
          answer: { type: 'string' },
          confidence: { type: 'number' }
        },
        required: ['answer', 'confidence']
      }
    }
  }
});

Important Notes

  1. Deployment Cache: Deployment information (ID, model name, version) is cached for 5 minutes by default
  2. API Version: Default is 2024-10-21, can be overridden
  3. Generated Classes: Model classes in ...model packages may change in minor releases
  4. No Filtering: Foundation models don't include content filtering - use Orchestration if needed

Documentation Links

Source: SKILL.md on GitHub

1 warning16d5 checks · Risk SAFE
  • Gen Agent Trust Hub16d

    The skill is a comprehensive documentation and integration guide for the SAP Cloud SDK for AI. It follows security best practices for credential management, emphasizing environment variables and service bindings over hardcoded secrets. It also provides extensive guidance on implementing security controls like content filtering and data masking to mitigate risks inherent in AI integrations.

  • Socket16d

    No alerts

  • Snyk16d

    Risk: LOW · No issues

  • Runlayer6mo

    8/12 files flagged

  • ZeroLeaks5mo

    Score: 93/100 · 2 sections analyzed

Signed by skilld at 620a19a. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 2 weeks ago.

Activeupdated 2 months ago
Other metadata
metadata
{
  "maintainer": "Eduard Jiglau",
  "maintainer_email": "hello@sap-ai-skills.com",
  "website": "https://sap-ai-skills.com",
  "version": "2.4.1",
  "last_verified": "2026-06-15",
  "package_evidence": "docs/project/package-evidence/2026-06-15.json"
}

README badge

README badge for secondsky/sap-skills/sap-cloud-sdk-ai