From 03002ced60759f978adbbc0cb05fdd9c8f96f65c Mon Sep 17 00:00:00 2001 From: jsonbailey Date: Fri, 31 Oct 2025 02:17:38 +0000 Subject: [PATCH 1/4] chore: Update VercelAI example to use Vercel AI Provider methods --- .../server-ai/examples/vercel-ai/package.json | 1 + .../server-ai/examples/vercel-ai/src/index.ts | 50 ++++++++++++++++--- 2 files changed, 43 insertions(+), 8 deletions(-) diff --git a/packages/sdk/server-ai/examples/vercel-ai/package.json b/packages/sdk/server-ai/examples/vercel-ai/package.json index 11d7985430..cceccc9e72 100644 --- a/packages/sdk/server-ai/examples/vercel-ai/package.json +++ b/packages/sdk/server-ai/examples/vercel-ai/package.json @@ -24,6 +24,7 @@ "@ai-sdk/openai": "2.0.30", "@launchdarkly/node-server-sdk": "9.7.1", "@launchdarkly/server-sdk-ai": "0.12.3", + "@launchdarkly/server-sdk-ai-vercel": "^0.2.0", "ai": "5.0.0", "zod": "^3.23.8" }, diff --git a/packages/sdk/server-ai/examples/vercel-ai/src/index.ts b/packages/sdk/server-ai/examples/vercel-ai/src/index.ts index c4f5adff42..3f36875819 100644 --- a/packages/sdk/server-ai/examples/vercel-ai/src/index.ts +++ b/packages/sdk/server-ai/examples/vercel-ai/src/index.ts @@ -4,6 +4,7 @@ import { generateText, streamText } from 'ai'; import { init, type LDClient, type LDContext } from '@launchdarkly/node-server-sdk'; import { initAi } from '@launchdarkly/server-sdk-ai'; +import { VercelProvider } from '@launchdarkly/server-sdk-ai-vercel'; // Environment variables const sdkKey = process.env.LAUNCHDARKLY_SDK_KEY ?? ''; @@ -41,31 +42,64 @@ async function main() { // Get AI configuration from LaunchDarkly const aiConfig = await aiClient.config(aiConfigKey, context, { model: { name: 'gpt-4' } }); - if (!aiConfig.enabled) { + if (!aiConfig.enabled || !aiConfig.tracker) { console.log('*** AI configuration is not enabled'); process.exit(0); } console.log('Using model:', aiConfig.model?.name); - // Example of using generateText (non-streaming) - console.log('\n*** Generating text:'); try { const userMessage = { role: 'user' as const, content: 'What can you help me with?', }; - const result = await aiConfig.tracker.trackVercelAISDKGenerateTextMetrics(() => - generateText(aiConfig.toVercelAISDK(openai, { nonInterpolatedMessages: [userMessage] })), + // Example of using generateText (non-streaming) + console.log('\n*** Generating text:'); + + // Convert config to Vercel AI SDK format + const vercelConfig = VercelProvider.toVercelAISDK( + aiConfig, + openai, + { nonInterpolatedMessages: [userMessage] }, + ); + + // Track metrics using trackMetricsOf with VercelProvider.createAIMetrics + const result = await aiConfig.tracker.trackMetricsOf( + VercelProvider.createAIMetrics, + () => generateText(vercelConfig), ); + console.log('Response:', result.text); + } catch (err) { + console.error('Error:', err); + } - process.stdout.write('Streaming Response: '); - const streamResult = aiConfig.tracker.trackVercelAISDKStreamTextMetrics(() => - streamText(aiConfig.toVercelAISDK(openai, { nonInterpolatedMessages: [userMessage] })), + // Example 2: Using streamText with trackStreamMetricsOf (streaming) + try { + const userMessage = { + role: 'user' as const, + content: 'Count from 1 to 5.', + }; + + // Example of using generateText (non-streaming) + console.log('\n*** Streaming text:'); + // Convert config to Vercel AI SDK format + const vercelConfig = VercelProvider.toVercelAISDK( + aiConfig, + openai, + { nonInterpolatedMessages: [userMessage] }, + ); + + // Track streaming metrics using trackStreamMetricsOf with provider's extractor + // Stream is returned immediately (synchronously), metrics tracked in background + const streamResult = aiConfig.tracker.trackStreamMetricsOf( + () => streamText(vercelConfig), + VercelProvider.createStreamMetricsExtractor(), ); + // Consume the stream immediately - no await needed before this! // eslint-disable-next-line no-restricted-syntax for await (const textPart of streamResult.textStream) { process.stdout.write(textPart); From cbf83c8bee9e3ba42adb5371725e1ba7cc34d83a Mon Sep 17 00:00:00 2001 From: jsonbailey Date: Fri, 31 Oct 2025 16:59:16 +0000 Subject: [PATCH 2/4] fix lint errors in example --- .../server-ai/examples/vercel-ai/package.json | 8 +++--- .../server-ai/examples/vercel-ai/src/index.ts | 25 ++++++++----------- 2 files changed, 14 insertions(+), 19 deletions(-) diff --git a/packages/sdk/server-ai/examples/vercel-ai/package.json b/packages/sdk/server-ai/examples/vercel-ai/package.json index cceccc9e72..64dd4427c2 100644 --- a/packages/sdk/server-ai/examples/vercel-ai/package.json +++ b/packages/sdk/server-ai/examples/vercel-ai/package.json @@ -21,10 +21,10 @@ "author": "LaunchDarkly", "license": "Apache-2.0", "dependencies": { - "@ai-sdk/openai": "2.0.30", - "@launchdarkly/node-server-sdk": "9.7.1", - "@launchdarkly/server-sdk-ai": "0.12.3", - "@launchdarkly/server-sdk-ai-vercel": "^0.2.0", + "@ai-sdk/openai": "^2.0.30", + "@launchdarkly/node-server-sdk": "^9.7.1", + "@launchdarkly/server-sdk-ai": "^0.12.3", + "@launchdarkly/server-sdk-ai-vercel": "^0.1.2", "ai": "5.0.0", "zod": "^3.23.8" }, diff --git a/packages/sdk/server-ai/examples/vercel-ai/src/index.ts b/packages/sdk/server-ai/examples/vercel-ai/src/index.ts index 3f36875819..de9d623354 100644 --- a/packages/sdk/server-ai/examples/vercel-ai/src/index.ts +++ b/packages/sdk/server-ai/examples/vercel-ai/src/index.ts @@ -59,18 +59,15 @@ async function main() { console.log('\n*** Generating text:'); // Convert config to Vercel AI SDK format - const vercelConfig = VercelProvider.toVercelAISDK( - aiConfig, - openai, - { nonInterpolatedMessages: [userMessage] }, - ); + const vercelConfig = VercelProvider.toVercelAISDK(aiConfig, openai, { + nonInterpolatedMessages: [userMessage], + }); // Track metrics using trackMetricsOf with VercelProvider.createAIMetrics - const result = await aiConfig.tracker.trackMetricsOf( - VercelProvider.createAIMetrics, - () => generateText(vercelConfig), + const result = await aiConfig.tracker.trackMetricsOf(VercelProvider.createAIMetrics, () => + generateText(vercelConfig), ); - + console.log('Response:', result.text); } catch (err) { console.error('Error:', err); @@ -86,12 +83,10 @@ async function main() { // Example of using generateText (non-streaming) console.log('\n*** Streaming text:'); // Convert config to Vercel AI SDK format - const vercelConfig = VercelProvider.toVercelAISDK( - aiConfig, - openai, - { nonInterpolatedMessages: [userMessage] }, - ); - + const vercelConfig = VercelProvider.toVercelAISDK(aiConfig, openai, { + nonInterpolatedMessages: [userMessage], + }); + // Track streaming metrics using trackStreamMetricsOf with provider's extractor // Stream is returned immediately (synchronously), metrics tracked in background const streamResult = aiConfig.tracker.trackStreamMetricsOf( From 8df6785ee15e6be0d0acb606f4679351e43d5eb7 Mon Sep 17 00:00:00 2001 From: jsonbailey Date: Tue, 4 Nov 2025 14:35:07 +0000 Subject: [PATCH 3/4] update metric method name --- packages/sdk/server-ai/examples/vercel-ai/src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/sdk/server-ai/examples/vercel-ai/src/index.ts b/packages/sdk/server-ai/examples/vercel-ai/src/index.ts index de9d623354..4d4cc9ace2 100644 --- a/packages/sdk/server-ai/examples/vercel-ai/src/index.ts +++ b/packages/sdk/server-ai/examples/vercel-ai/src/index.ts @@ -91,7 +91,7 @@ async function main() { // Stream is returned immediately (synchronously), metrics tracked in background const streamResult = aiConfig.tracker.trackStreamMetricsOf( () => streamText(vercelConfig), - VercelProvider.createStreamMetricsExtractor(), + VercelProvider.createStreamMetrics, ); // Consume the stream immediately - no await needed before this! From 0a8d763ee28f103398a2b605b514d1115a106384 Mon Sep 17 00:00:00 2001 From: jsonbailey Date: Tue, 4 Nov 2025 18:48:54 +0000 Subject: [PATCH 4/4] use new method names --- packages/sdk/server-ai/examples/vercel-ai/src/index.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/sdk/server-ai/examples/vercel-ai/src/index.ts b/packages/sdk/server-ai/examples/vercel-ai/src/index.ts index 4d4cc9ace2..4d79bd3800 100644 --- a/packages/sdk/server-ai/examples/vercel-ai/src/index.ts +++ b/packages/sdk/server-ai/examples/vercel-ai/src/index.ts @@ -63,9 +63,10 @@ async function main() { nonInterpolatedMessages: [userMessage], }); - // Track metrics using trackMetricsOf with VercelProvider.createAIMetrics - const result = await aiConfig.tracker.trackMetricsOf(VercelProvider.createAIMetrics, () => - generateText(vercelConfig), + // Call the model and track metrics for the ai config + const result = await aiConfig.tracker.trackMetricsOf( + VercelProvider.getAIMetricsFromResponse, + () => generateText(vercelConfig), ); console.log('Response:', result.text); @@ -87,11 +88,10 @@ async function main() { nonInterpolatedMessages: [userMessage], }); - // Track streaming metrics using trackStreamMetricsOf with provider's extractor // Stream is returned immediately (synchronously), metrics tracked in background const streamResult = aiConfig.tracker.trackStreamMetricsOf( () => streamText(vercelConfig), - VercelProvider.createStreamMetrics, + VercelProvider.getAIMetricsFromStream, ); // Consume the stream immediately - no await needed before this!