@mymediset/sap-ai-provider
Version:
SAP AI Core provider for AI SDK (powered by @sap-ai-sdk/orchestration)
652 lines (646 loc) • 21.4 kB
text/typescript
import { LanguageModelV2, LanguageModelV2CallOptions, LanguageModelV2Content, LanguageModelV2FinishReason, LanguageModelV2Usage, LanguageModelV2CallWarning, LanguageModelV2StreamPart, ProviderV2 } from '@ai-sdk/provider';
import { HttpDestinationOrFetchOptions } from '@sap-cloud-sdk/connectivity';
import { ResourceGroupConfig, DeploymentIdConfig } from '@sap-ai-sdk/ai-api/internal.js';
import { MaskingModule, FilteringModule, ChatCompletionTool, ChatModel, OrchestrationErrorResponse } from '@sap-ai-sdk/orchestration';
export { AssistantChatMessage, ChatCompletionRequest, ChatCompletionTool, ChatMessage, DeveloperChatMessage, FilteringModule, FunctionObject, GroundingModule, LlmModelDetails, LlmModelParams, MaskingModule, OrchestrationClient, OrchestrationErrorResponse, OrchestrationModuleConfig, OrchestrationResponse, OrchestrationStreamChunkResponse, OrchestrationStreamResponse, PromptTemplatingModule, SystemChatMessage, ToolChatMessage, TranslationModule, UserChatMessage, buildAzureContentSafetyFilter, buildDocumentGroundingConfig, buildDpiMaskingProvider, buildLlamaGuard38BFilter, buildTranslationConfig } from '@sap-ai-sdk/orchestration';
/**
* Settings for configuring SAP AI Core model behavior.
*/
interface SAPAISettings {
/**
* Specific version of the model to use.
* If not provided, the latest version will be used.
*/
modelVersion?: string;
/**
* Model generation parameters that control the output.
*/
modelParams?: {
/**
* Maximum number of tokens to generate.
* Higher values allow for longer responses but increase latency and cost.
*/
maxTokens?: number;
/**
* Sampling temperature between 0 and 2.
* Higher values make output more random, lower values more deterministic.
* No default; omitted when unspecified or unsupported by the target model.
*/
temperature?: number;
/**
* Nucleus sampling parameter between 0 and 1.
* Controls diversity via cumulative probability cutoff.
* @default 1
*/
topP?: number;
/**
* Frequency penalty between -2.0 and 2.0.
* Positive values penalize tokens based on their frequency.
* @default 0
*/
frequencyPenalty?: number;
/**
* Presence penalty between -2.0 and 2.0.
* Positive values penalize tokens that have appeared in the text.
* @default 0
*/
presencePenalty?: number;
/**
* Number of completions to generate.
* Multiple completions provide alternative responses.
* Note: Not supported by Amazon and Anthropic models.
* @default 1
*/
n?: number;
/**
* Whether to enable parallel tool calls.
* When enabled, the model can call multiple tools in parallel.
*/
parallel_tool_calls?: boolean;
};
/**
* Masking configuration for SAP AI Core orchestration.
* When provided, sensitive information in prompts can be anonymized or
* pseudonymized by SAP Data Privacy Integration (DPI).
*
* @example
* ```typescript
* import { buildDpiMaskingProvider } from '@sap-ai-sdk/orchestration';
*
* const model = provider('gpt-4o', {
* masking: {
* masking_providers: [
* buildDpiMaskingProvider({
* method: 'anonymization',
* entities: ['profile-email', 'profile-phone']
* })
* ]
* }
* });
* ```
*/
masking?: MaskingModule;
/**
* Filtering configuration for input and output content safety.
* Supports Azure Content Safety and Llama Guard filters.
*
* @example
* ```typescript
* import { buildAzureContentSafetyFilter } from '@sap-ai-sdk/orchestration';
*
* const model = provider('gpt-4o', {
* filtering: {
* input: {
* filters: [
* buildAzureContentSafetyFilter('input', {
* hate: 'ALLOW_SAFE',
* violence: 'ALLOW_SAFE_LOW_MEDIUM'
* })
* ]
* }
* }
* });
* ```
*/
filtering?: FilteringModule;
/**
* Response format for templating prompt (OpenAI-compatible).
* Allows specifying structured output formats.
*
* @example
* ```typescript
* const model = provider('gpt-4o', {
* responseFormat: {
* type: 'json_schema',
* json_schema: {
* name: 'response',
* schema: { type: 'object', properties: { answer: { type: 'string' } } }
* }
* }
* });
* ```
*/
responseFormat?: {
type: "text";
} | {
type: "json_object";
} | {
type: "json_schema";
json_schema: {
name: string;
description?: string;
schema?: unknown;
strict?: boolean | null;
};
};
/**
* Tool definitions in SAP AI SDK format.
*
* Use this to pass tools directly with proper JSON Schema definitions.
* This bypasses the AI SDK's Zod conversion which may have issues.
*
* Note: This should be used in conjunction with AI SDK's tool handling
* to provide the actual tool implementations (execute functions).
*
* @example
* ```typescript
* const model = provider('gpt-4o', {
* tools: [
* {
* type: 'function',
* function: {
* name: 'get_weather',
* description: 'Get weather for a location',
* parameters: {
* type: 'object',
* properties: {
* location: { type: 'string', description: 'City name' }
* },
* required: ['location']
* }
* }
* }
* ]
* });
* ```
*/
tools?: ChatCompletionTool[];
}
/**
* Supported model IDs in SAP AI Core.
*
* These models are available through the SAP AI Core Orchestration service.
* Model availability depends on your subscription and region.
*
* **Azure OpenAI Models:**
* - gpt-4o, gpt-4o-mini
* - gpt-4.1, gpt-4.1-mini, gpt-4.1-nano
* - o1, o3, o3-mini, o4-mini
*
* **Google Vertex AI Models:**
* - gemini-2.0-flash, gemini-2.0-flash-lite
* - gemini-2.5-flash, gemini-2.5-pro
*
* **AWS Bedrock Models:**
* - anthropic--claude-3-haiku, anthropic--claude-3-sonnet, anthropic--claude-3-opus
* - anthropic--claude-3.5-sonnet, anthropic--claude-3.7-sonnet
* - anthropic--claude-4-sonnet, anthropic--claude-4-opus
* - amazon--nova-pro, amazon--nova-lite, amazon--nova-micro, amazon--nova-premier
*
* **AI Core Open Source Models:**
* - mistralai--mistral-large-instruct, mistralai--mistral-medium-instruct, mistralai--mistral-small-instruct
* - cohere--command-a-reasoning
*/
type SAPAIModelId = ChatModel;
/**
* Internal configuration for the SAP AI Chat Language Model.
* @internal
*/
interface SAPAIConfig {
/** Provider identifier */
provider: string;
/** Deployment configuration for SAP AI SDK */
deploymentConfig: ResourceGroupConfig | DeploymentIdConfig;
/** Optional custom destination */
destination?: HttpDestinationOrFetchOptions;
}
/**
* SAP AI Chat Language Model implementation.
*
* This class implements the Vercel AI SDK's `LanguageModelV2` interface,
* providing a bridge between the AI SDK and SAP AI Core's Orchestration API
* using the official SAP AI SDK (@sap-ai-sdk/orchestration).
*
* **Features:**
* - Text generation (streaming and non-streaming)
* - Tool calling (function calling)
* - Multi-modal input (text + images)
* - Data masking (SAP DPI)
* - Content filtering
*
* **Model Support:**
* - Azure OpenAI models (gpt-4o, gpt-4o-mini, o1, o3, etc.)
* - Google Vertex AI models (gemini-2.0-flash, gemini-2.5-pro, etc.)
* - AWS Bedrock models (anthropic--claude-*, amazon--nova-*, etc.)
* - AI Core open source models (mistralai--, cohere--, etc.)
*
* @example
* ```typescript
* // Create via provider
* const provider = createSAPAIProvider();
* const model = provider('gpt-4o');
*
* // Use with AI SDK
* const result = await generateText({
* model,
* prompt: 'Hello, world!'
* });
* ```
*
* @implements {LanguageModelV2}
*/
declare class SAPAIChatLanguageModel implements LanguageModelV2 {
/** AI SDK specification version */
readonly specificationVersion = "v2";
/** Default object generation mode */
readonly defaultObjectGenerationMode = "json";
/** Whether the model supports image URLs */
readonly supportsImageUrls = true;
/** The model identifier (e.g., 'gpt-4o', 'anthropic--claude-3.5-sonnet') */
readonly modelId: SAPAIModelId;
/** Whether the model supports structured outputs */
readonly supportsStructuredOutputs = true;
/** Internal configuration */
private readonly config;
/** Model-specific settings */
private readonly settings;
/**
* Creates a new SAP AI Chat Language Model instance.
*
* @param modelId - The model identifier
* @param settings - Model-specific configuration settings
* @param config - Internal configuration (deployment config, destination, etc.)
*
* @internal This constructor is not meant to be called directly.
* Use the provider function instead.
*/
constructor(modelId: SAPAIModelId, settings: SAPAISettings, config: SAPAIConfig);
/**
* Checks if a URL is supported for file/image uploads.
*
* @param url - The URL to check
* @returns True if the URL protocol is HTTPS
*/
supportsUrl(url: URL): boolean;
/**
* Returns supported URL patterns for different content types.
*
* @returns Record of content types to regex patterns
*/
get supportedUrls(): Record<string, RegExp[]>;
/**
* Gets the provider identifier.
*
* @returns The provider name ('sap-ai')
*/
get provider(): string;
/**
* Builds orchestration module config for SAP AI SDK.
*
* @param options - Call options from the AI SDK
* @returns Object containing orchestration config and warnings
*
* @internal
*/
private buildOrchestrationConfig;
/**
* Creates an OrchestrationClient instance.
*
* @param config - Orchestration module configuration
* @returns OrchestrationClient instance
*
* @internal
*/
private createClient;
/**
* Generates a single completion (non-streaming).
*
* This method implements the `LanguageModelV2.doGenerate` interface,
* sending a request to SAP AI Core and returning the complete response.
*
* **Features:**
* - Tool calling support
* - Multi-modal input (text + images)
* - Data masking (if configured)
* - Content filtering (if configured)
*
* @param options - Generation options including prompt, tools, and settings
* @returns Promise resolving to the generation result with content, usage, and metadata
*
* @example
* ```typescript
* const result = await model.doGenerate({
* prompt: [
* { role: 'user', content: [{ type: 'text', text: 'Hello!' }] }
* ]
* });
*
* console.log(result.content); // Generated content
* console.log(result.usage); // Token usage
* ```
*/
doGenerate(options: LanguageModelV2CallOptions): Promise<{
content: LanguageModelV2Content[];
finishReason: LanguageModelV2FinishReason;
usage: LanguageModelV2Usage;
rawCall: {
rawPrompt: unknown;
rawSettings: Record<string, unknown>;
};
warnings: LanguageModelV2CallWarning[];
}>;
/**
* Generates a streaming completion.
*
* This method implements the `LanguageModelV2.doStream` interface,
* sending a streaming request to SAP AI Core and returning a stream of response parts.
*
* **Stream Events:**
* - `stream-start` - Stream initialization
* - `response-metadata` - Response metadata (model, timestamp)
* - `text-start` - Text generation starts
* - `text-delta` - Incremental text chunks
* - `text-end` - Text generation completes
* - `tool-call` - Tool call detected
* - `finish` - Stream completes with usage and finish reason
* - `error` - Error occurred
*
* @param options - Streaming options including prompt, tools, and settings
* @returns Promise resolving to stream and raw call metadata
*
* @example
* ```typescript
* const { stream } = await model.doStream({
* prompt: [
* { role: 'user', content: [{ type: 'text', text: 'Write a story' }] }
* ]
* });
*
* for await (const part of stream) {
* if (part.type === 'text-delta') {
* process.stdout.write(part.delta);
* }
* }
* ```
*/
doStream(options: LanguageModelV2CallOptions): Promise<{
stream: ReadableStream<LanguageModelV2StreamPart>;
rawCall: {
rawPrompt: unknown;
rawSettings: Record<string, unknown>;
};
}>;
}
/**
* SAP AI Provider interface.
*
* This is the main interface for creating and configuring SAP AI Core models.
* It extends the standard Vercel AI SDK ProviderV2 interface with SAP-specific functionality.
*
* @example
* ```typescript
* const provider = createSAPAIProvider({
* resourceGroup: 'default'
* });
*
* // Create a model instance
* const model = provider('gpt-4o', {
* modelParams: {
* temperature: 0.7,
* maxTokens: 1000
* }
* });
*
* // Or use the explicit chat method
* const chatModel = provider.chat('gpt-4o');
* ```
*/
interface SAPAIProvider extends ProviderV2 {
/**
* Create a language model instance.
*
* @param modelId - The SAP AI Core model identifier (e.g., 'gpt-4o', 'anthropic--claude-3.5-sonnet')
* @param settings - Optional model configuration settings
* @returns Configured SAP AI chat language model instance
*/
(modelId: SAPAIModelId, settings?: SAPAISettings): SAPAIChatLanguageModel;
/**
* Explicit method for creating chat models.
*
* This method is equivalent to calling the provider function directly,
* but provides a more explicit API for chat-based interactions.
*
* @param modelId - The SAP AI Core model identifier
* @param settings - Optional model configuration settings
* @returns Configured SAP AI chat language model instance
*/
chat(modelId: SAPAIModelId, settings?: SAPAISettings): SAPAIChatLanguageModel;
}
/**
* Configuration settings for the SAP AI Provider.
*
* This interface defines all available options for configuring the SAP AI Core connection
* using the official SAP AI SDK. The SDK handles authentication automatically when
* running on SAP BTP (via service binding) or locally (via AICORE_SERVICE_KEY env var).
*
* @example
* ```typescript
* // Using default configuration (auto-detects service binding or env var)
* const provider = createSAPAIProvider();
*
* // With specific resource group
* const provider = createSAPAIProvider({
* resourceGroup: 'production'
* });
*
* // With custom destination
* const provider = createSAPAIProvider({
* destination: {
* url: 'https://my-ai-core-instance.cfapps.eu10.hana.ondemand.com'
* }
* });
* ```
*/
interface SAPAIProviderSettings {
/**
* SAP AI Core resource group.
*
* Logical grouping of AI resources in SAP AI Core.
* Used for resource isolation and access control.
* Different resource groups can have different permissions and quotas.
*
* @default 'default'
* @example
* ```typescript
* resourceGroup: 'default' // Default resource group
* resourceGroup: 'production' // Production environment
* resourceGroup: 'development' // Development environment
* ```
*/
resourceGroup?: string;
/**
* SAP AI Core deployment ID.
*
* A specific deployment ID to use for orchestration requests.
* If not provided, the SDK will resolve the deployment automatically.
*
* @example
* ```typescript
* deploymentId: 'd65d81e7c077e583'
* ```
*/
deploymentId?: string;
/**
* Custom destination configuration for SAP AI Core.
*
* Override the default destination detection. Useful for:
* - Custom proxy configurations
* - Non-standard SAP AI Core setups
* - Testing environments
*
* @example
* ```typescript
* destination: {
* url: 'https://api.ai.prod.eu-central-1.aws.ml.hana.ondemand.com'
* }
* ```
*/
destination?: HttpDestinationOrFetchOptions;
/**
* Default model settings applied to every model instance created by this provider.
* Per-call settings provided to the model will override these.
*/
defaultSettings?: SAPAISettings;
}
/**
* Deployment configuration type used by SAP AI SDK.
*/
type DeploymentConfig = ResourceGroupConfig | DeploymentIdConfig;
/**
* Creates a SAP AI Core provider instance for use with Vercel AI SDK.
*
* This is the main entry point for integrating SAP AI Core with the Vercel AI SDK.
* It uses the official SAP AI SDK (@sap-ai-sdk/orchestration) under the hood,
* which handles authentication and API communication automatically.
*
* **Authentication:**
* The SAP AI SDK automatically handles authentication:
* 1. On SAP BTP: Uses service binding (VCAP_SERVICES)
* 2. Locally: Uses AICORE_SERVICE_KEY environment variable
*
* **Key Features:**
* - Automatic authentication via SAP AI SDK
* - Support for all SAP AI Core orchestration models
* - Streaming and non-streaming responses
* - Tool calling support
* - Data masking (DPI)
* - Content filtering
*
* @param options - Configuration options for the provider
* @returns A configured SAP AI provider
*
* @example
* **Basic Usage**
* ```typescript
* import { createSAPAIProvider } from '@mymediset/sap-ai-provider';
* import { generateText } from 'ai';
*
* const provider = createSAPAIProvider();
*
* const result = await generateText({
* model: provider('gpt-4o'),
* prompt: 'Hello, world!'
* });
* ```
*
* @example
* **With Resource Group**
* ```typescript
* const provider = createSAPAIProvider({
* resourceGroup: 'production'
* });
*
* const model = provider('anthropic--claude-3.5-sonnet', {
* modelParams: {
* temperature: 0.3,
* maxTokens: 2000
* }
* });
* ```
*
* @example
* **With Default Settings**
* ```typescript
* const provider = createSAPAIProvider({
* defaultSettings: {
* modelParams: {
* temperature: 0.7
* }
* }
* });
* ```
*/
declare function createSAPAIProvider(options?: SAPAIProviderSettings): SAPAIProvider;
/**
* Default SAP AI provider instance.
*
* Uses the default configuration which auto-detects authentication
* from service binding (SAP BTP) or AICORE_SERVICE_KEY environment variable.
*
* @example
* ```typescript
* import { sapai } from '@mymediset/sap-ai-provider';
* import { generateText } from 'ai';
*
* const result = await generateText({
* model: sapai('gpt-4o'),
* prompt: 'Hello!'
* });
* ```
*/
declare const sapai: SAPAIProvider;
/**
* Custom error class for SAP AI Core errors.
* Provides structured access to error details returned by the API.
*
* The SAP AI SDK handles most error responses internally, but this class
* can be used to wrap and provide additional context for errors.
*
* @example
* ```typescript
* try {
* await model.doGenerate({ prompt });
* } catch (error) {
* if (error instanceof SAPAIError) {
* console.error('Error Code:', error.code);
* console.error('Request ID:', error.requestId);
* console.error('Location:', error.location);
* }
* }
* ```
*/
declare class SAPAIError extends Error {
/** HTTP status code or custom error code */
readonly code?: number;
/** Where the error occurred (e.g., module name) */
readonly location?: string;
/** Unique identifier for tracking the request */
readonly requestId?: string;
/** Additional error context or debugging information */
readonly details?: string;
/** Original cause of the error */
readonly cause?: unknown;
constructor(message: string, options?: {
code?: number;
location?: string;
requestId?: string;
details?: string;
cause?: unknown;
});
/**
* Creates a SAPAIError from an OrchestrationErrorResponse.
*
* @param errorResponse - The error response from SAP AI SDK
* @returns A new SAPAIError instance
*/
static fromOrchestrationError(errorResponse: OrchestrationErrorResponse): SAPAIError;
/**
* Creates a SAPAIError from a generic error.
*
* @param error - The original error
* @param context - Optional context about where the error occurred
* @returns A new SAPAIError instance
*/
static fromError(error: unknown, context?: string): SAPAIError;
}
export { type DeploymentConfig, SAPAIError, type SAPAIModelId, type SAPAIProvider, type SAPAIProviderSettings, type SAPAISettings, createSAPAIProvider, sapai };