diff --git a/packages/sdk/server-ai/src/LDAIConfigMapper.ts b/packages/sdk/server-ai/src/LDAIConfigMapper.ts index f7ed111152..827f4d01e4 100644 --- a/packages/sdk/server-ai/src/LDAIConfigMapper.ts +++ b/packages/sdk/server-ai/src/LDAIConfigMapper.ts @@ -27,6 +27,10 @@ export class LDAIConfigMapper { return undefined; } + /** + * @deprecated Use `VercelProvider.toVercelAISDK()` from the `@launchdarkly/server-sdk-ai-vercel` package instead. + * This method will be removed in a future version. + */ toVercelAISDK( provider: VercelAISDKProvider | Record>, options?: VercelAISDKMapOptions | undefined, diff --git a/packages/sdk/server-ai/src/LDAIConfigTrackerImpl.ts b/packages/sdk/server-ai/src/LDAIConfigTrackerImpl.ts index 8830cee4ea..578ef1f8da 100644 --- a/packages/sdk/server-ai/src/LDAIConfigTrackerImpl.ts +++ b/packages/sdk/server-ai/src/LDAIConfigTrackerImpl.ts @@ -119,6 +119,58 @@ export class LDAIConfigTrackerImpl implements LDAIConfigTracker { return result; } + trackStreamMetricsOf( + streamCreator: () => TStream, + metricsExtractor: (stream: TStream) => Promise, + ): TStream { + const startTime = Date.now(); + + try { + // Create the stream synchronously + const stream = streamCreator(); + + // Start background metrics tracking (fire and forget) + this._trackStreamMetricsInBackground(stream, metricsExtractor, startTime); + + // Return stream immediately for consumption + return stream; + } catch (error) { + // Track error if stream creation fails + this.trackDuration(Date.now() - startTime); + this.trackError(); + throw error; + } + } + + private async _trackStreamMetricsInBackground( + stream: TStream, + metricsExtractor: (stream: TStream) => Promise, + startTime: number, + ): Promise { + try { + // Wait for metrics to be available + const metrics = await metricsExtractor(stream); + + // Track success/error based on metrics + if (metrics.success) { + this.trackSuccess(); + } else { + this.trackError(); + } + + // Track token usage if available + if (metrics.usage) { + this.trackTokens(metrics.usage); + } + } catch (error) { + // If metrics extraction fails, track error + this.trackError(); + } finally { + // Track duration regardless of success/error + this.trackDuration(Date.now() - startTime); + } + } + async trackOpenAIMetrics< TRes extends { usage?: { diff --git a/packages/sdk/server-ai/src/api/config/LDAIConfig.ts b/packages/sdk/server-ai/src/api/config/LDAIConfig.ts index c5071a6d59..4f958f3d3a 100644 --- a/packages/sdk/server-ai/src/api/config/LDAIConfig.ts +++ b/packages/sdk/server-ai/src/api/config/LDAIConfig.ts @@ -76,6 +76,9 @@ export interface LDAIConfig { * * WARNING: this method can throw an exception if a Vercel AI SDK model cannot be determined. * + * @deprecated Use `VercelProvider.toVercelAISDK()` from the `@launchdarkly/server-sdk-ai-vercel` package instead. + * This method will be removed in a future version. + * * @param provider A Vercel AI SDK Provider or a map of provider names to Vercel AI SDK Providers. * @param options Optional mapping options. * @returns A configuration directly usable in Vercel AI SDK generateText() and streamText() diff --git a/packages/sdk/server-ai/src/api/config/LDAIConfigTracker.ts b/packages/sdk/server-ai/src/api/config/LDAIConfigTracker.ts index 7f0b3f5797..491315e02b 100644 --- a/packages/sdk/server-ai/src/api/config/LDAIConfigTracker.ts +++ b/packages/sdk/server-ai/src/api/config/LDAIConfigTracker.ts @@ -106,6 +106,32 @@ export interface LDAIConfigTracker { func: () => Promise, ): Promise; + /** + * Track metrics for a streaming AI operation. + * + * This function will track the duration of the operation, extract metrics using the provided + * metrics extractor function, and track success or error status accordingly. + * + * Unlike trackMetricsOf, this method is designed for streaming operations where: + * - The stream is created and returned immediately (synchronously) + * - Metrics are extracted asynchronously in the background once the stream completes + * - Duration is tracked from stream creation to metrics extraction completion + * + * The stream is returned immediately so the caller can begin consuming it without waiting. + * Metrics extraction happens in the background and does not block stream consumption. + * + * If the stream creator throws, then this method will also throw and record an error. + * If metrics extraction fails, the error is logged but does not affect stream consumption. + * + * @param streamCreator Function that creates and returns the stream (synchronous) + * @param metricsExtractor Function that asynchronously extracts metrics from the stream + * @returns The stream result (returned immediately, not a Promise) + */ + trackStreamMetricsOf( + streamCreator: () => TStream, + metricsExtractor: (stream: TStream) => Promise, + ): TStream; + /** * Track an OpenAI operation. * @@ -187,6 +213,9 @@ export interface LDAIConfigTracker { * In the case the provided function throws, this function will record the duration and an error. * A failed operation will not have any token usage data. * + * @deprecated Use `trackStreamMetricsOf()` with `VercelProvider.createStreamMetricsExtractor()` from the + * `@launchdarkly/server-sdk-ai-vercel` package instead. This method will be removed in a future version. + * * @param func Function which executes the operation. * @returns The result of the operation. */ diff --git a/packages/sdk/server-ai/src/api/config/VercelAISDK.ts b/packages/sdk/server-ai/src/api/config/VercelAISDK.ts index 8796eb5c95..d8491a6810 100644 --- a/packages/sdk/server-ai/src/api/config/VercelAISDK.ts +++ b/packages/sdk/server-ai/src/api/config/VercelAISDK.ts @@ -1,11 +1,23 @@ import { type LDMessage } from './LDAIConfig'; +/** + * @deprecated Use `VercelAISDKProvider` from the `@launchdarkly/server-sdk-ai-vercel` package instead. + * This type will be removed in a future version. + */ export type VercelAISDKProvider = (modelName: string) => TMod; +/** + * @deprecated Use `VercelAISDKMapOptions` from the `@launchdarkly/server-sdk-ai-vercel` package instead. + * This type will be removed in a future version. + */ export interface VercelAISDKMapOptions { nonInterpolatedMessages?: LDMessage[] | undefined; } +/** + * @deprecated Use `VercelAISDKConfig` from the `@launchdarkly/server-sdk-ai-vercel` package instead. + * This type will be removed in a future version. + */ export interface VercelAISDKConfig { model: TMod; messages?: LDMessage[] | undefined;