UNPKG

@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
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 };