| 
 | 1 | +/* eslint-disable no-console */  | 
 | 2 | +import { openai } from '@ai-sdk/openai';  | 
 | 3 | +import { generateText, streamText } from 'ai';  | 
 | 4 | + | 
 | 5 | +import { init, type LDClient, type LDContext } from '@launchdarkly/node-server-sdk';  | 
 | 6 | +import { initAi } from '@launchdarkly/server-sdk-ai';  | 
 | 7 | + | 
 | 8 | +// Environment variables  | 
 | 9 | +const sdkKey = process.env.LAUNCHDARKLY_SDK_KEY ?? '';  | 
 | 10 | +const aiConfigKey = process.env.LAUNCHDARKLY_AI_CONFIG_KEY || 'sample-ai-config';  | 
 | 11 | + | 
 | 12 | +// Validate required environment variables  | 
 | 13 | +if (!sdkKey) {  | 
 | 14 | +  console.error('*** Please set the LAUNCHDARKLY_SDK_KEY env first');  | 
 | 15 | +  process.exit(1);  | 
 | 16 | +}  | 
 | 17 | + | 
 | 18 | +let client: LDClient | undefined;  | 
 | 19 | + | 
 | 20 | +async function main() {  | 
 | 21 | +  // Initialize LaunchDarkly client  | 
 | 22 | +  client = init(sdkKey);  | 
 | 23 | + | 
 | 24 | +  // Set up the context properties. This context should appear on your LaunchDarkly contexts dashboard  | 
 | 25 | +  const context: LDContext = {  | 
 | 26 | +    kind: 'user',  | 
 | 27 | +    key: 'example-user-key',  | 
 | 28 | +    name: 'Sandy',  | 
 | 29 | +  };  | 
 | 30 | + | 
 | 31 | +  try {  | 
 | 32 | +    await client.waitForInitialization({ timeout: 10 });  | 
 | 33 | +    console.log('*** SDK successfully initialized');  | 
 | 34 | +  } catch (error) {  | 
 | 35 | +    console.log(`*** SDK failed to initialize: ${error}`);  | 
 | 36 | +    process.exit(1);  | 
 | 37 | +  }  | 
 | 38 | + | 
 | 39 | +  const aiClient = initAi(client);  | 
 | 40 | + | 
 | 41 | +  // Get AI configuration from LaunchDarkly  | 
 | 42 | +  const aiConfig = await aiClient.config(aiConfigKey, context, { model: { name: 'gpt-4' } });  | 
 | 43 | + | 
 | 44 | +  if (!aiConfig.enabled) {  | 
 | 45 | +    console.log('*** AI configuration is not enabled');  | 
 | 46 | +    process.exit(0);  | 
 | 47 | +  }  | 
 | 48 | + | 
 | 49 | +  console.log('Using model:', aiConfig.model?.name);  | 
 | 50 | + | 
 | 51 | +  // Example of using generateText (non-streaming)  | 
 | 52 | +  console.log('\n*** Generating text:');  | 
 | 53 | +  try {  | 
 | 54 | +    const userMessage = {  | 
 | 55 | +      role: 'user' as const,  | 
 | 56 | +      content: 'What can you help me with?',  | 
 | 57 | +    };  | 
 | 58 | + | 
 | 59 | +    const result = await aiConfig.tracker.trackVercelAISDKGenerateTextMetrics(() =>  | 
 | 60 | +      generateText(aiConfig.toVercelAISDK(openai, { nonInterpolatedMessages: [userMessage] })),  | 
 | 61 | +    );  | 
 | 62 | +    console.log('Response:', result.text);  | 
 | 63 | + | 
 | 64 | +    process.stdout.write('Streaming Response: ');  | 
 | 65 | +    const streamResult = aiConfig.tracker.trackVercelAISDKStreamTextMetrics(() =>  | 
 | 66 | +      streamText(aiConfig.toVercelAISDK(openai, { nonInterpolatedMessages: [userMessage] })),  | 
 | 67 | +    );  | 
 | 68 | + | 
 | 69 | +    // eslint-disable-next-line no-restricted-syntax  | 
 | 70 | +    for await (const textPart of streamResult.textStream) {  | 
 | 71 | +      process.stdout.write(textPart);  | 
 | 72 | +    }  | 
 | 73 | + | 
 | 74 | +    console.log('\nSuccess.');  | 
 | 75 | +  } catch (err) {  | 
 | 76 | +    console.error('Error:', err);  | 
 | 77 | +  }  | 
 | 78 | +}  | 
 | 79 | + | 
 | 80 | +main()  | 
 | 81 | +  .catch((e) => console.error(e))  | 
 | 82 | +  .finally(async () => {  | 
 | 83 | +    await client?.flush();  | 
 | 84 | +    client?.close();  | 
 | 85 | +  });  | 
0 commit comments