-
Notifications
You must be signed in to change notification settings - Fork 30
feat: Add Vercel example for AI SDK #927
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
fa245b2
feat: Add vercel example for AI SDK
jsonbailey b0f8e8d
fix lint error and ignore the second
jsonbailey a3c8aca
resolve cursorbot comments
jsonbailey c1e9bef
show how a user message can be sent into the model
jsonbailey 8651a44
add missing eslint file
jsonbailey 505214b
address cursorbot comment
jsonbailey d6b16a9
clean up dependencies
jsonbailey 066cb23
match dev packages with other examples
jsonbailey File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,5 @@ | ||
| { | ||
| "extends": "./tsconfig.json", | ||
| "include": ["/**/*.ts", "/**/*.tsx"], | ||
| "include": ["**/*.ts", "**/*.tsx"], | ||
| "exclude": ["node_modules"] | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,5 @@ | ||
| { | ||
| "extends": "./tsconfig.json", | ||
| "include": ["/**/*.ts", "/**/*.tsx"], | ||
| "include": ["**/*.ts", "**/*.tsx"], | ||
| "exclude": ["node_modules"] | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,49 @@ | ||
| # LaunchDarkly AI SDK for OpenAI Example | ||
|
|
||
| This package demonstrates the integration of LaunchDarkly's AI SDK with OpenAI via Vercel AI, allowing you to leverage LaunchDarkly's AI Config capabilities in AI-powered applications using Vercel's services. | ||
|
|
||
| ## Installation and Build | ||
|
|
||
| When running as part of the js-core mono-repo the project will use local dependencies. | ||
| As such those dependencies need built. | ||
|
|
||
| In the root of the repository run: | ||
|
|
||
| ```bash | ||
| yarn | ||
| ``` | ||
|
|
||
| And then | ||
|
|
||
| ```bash | ||
| yarn build | ||
| ``` | ||
|
|
||
| ## Configuration | ||
|
|
||
| Before running the example, make sure to set the following environment variables: | ||
|
|
||
| - `LAUNCHDARKLY_SDK_KEY`: Your LaunchDarkly SDK key | ||
| - `LAUNCHDARKLY_AI_CONFIG_KEY`: Your LaunchDarkly AI Config key (defaults to 'sample-ai-config' if not set) | ||
| - `OPENAI_API_KEY`: Your OpenAI API key | ||
|
|
||
| ## Usage | ||
|
|
||
| The main script (`index.js`) demonstrates how to: | ||
|
|
||
| 1. Initialize the LaunchDarkly SDK | ||
| 2. Set up a user context | ||
| 3. Initialize the LaunchDarkly AI client | ||
| 4. Retrieve an AI model configuration | ||
| 5. Send a prompt to a Vercel AI Model (OpenAI) | ||
| 6. Track token usage | ||
|
|
||
| To run the example (in the vercel-ai directory): | ||
|
|
||
| ```bash | ||
| yarn start | ||
| ``` | ||
|
|
||
| ## Note | ||
|
|
||
| This example uses OpenAI's chat completions API. Make sure your LaunchDarkly AI Config is set up correctly to work with OpenAI's models and API structure. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,55 @@ | ||
| { | ||
| "name": "@launchdarkly/hello-vercel-ai", | ||
| "version": "0.1.0", | ||
| "description": "LaunchDarkly AI SDK for Node.js with Vercel AI", | ||
| "private": true, | ||
| "main": "dist/index.js", | ||
| "types": "dist/index.d.ts", | ||
| "scripts": { | ||
| "build": "tsc", | ||
| "start": "yarn build && node ./dist/index.js", | ||
| "lint": "npx eslint . --ext .ts", | ||
| "prettier": "prettier --write '**/*.@(js|ts|tsx|json|css)' --ignore-path ../../../.prettierignore", | ||
| "lint:fix": "yarn run lint --fix", | ||
| "check": "yarn prettier && yarn lint && yarn build && yarn test" | ||
| }, | ||
| "keywords": [ | ||
| "launchdarkly", | ||
| "ai", | ||
| "llm" | ||
| ], | ||
| "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.11.3", | ||
| "ai": "5.0.0", | ||
| "zod": "^3.23.8" | ||
| }, | ||
| "devDependencies": { | ||
| "@trivago/prettier-plugin-sort-imports": "^4.1.1", | ||
| "@tsconfig/node20": "20.1.4", | ||
| "@typescript-eslint/eslint-plugin": "^6.20.0", | ||
| "@typescript-eslint/parser": "^6.20.0", | ||
| "eslint": "^8.45.0", | ||
| "eslint-config-airbnb-base": "^15.0.0", | ||
| "eslint-config-airbnb-typescript": "^17.1.0", | ||
| "eslint-config-prettier": "^8.8.0", | ||
| "eslint-plugin-import": "^2.27.5", | ||
| "eslint-plugin-jest": "^27.6.3", | ||
| "eslint-plugin-prettier": "^5.0.0", | ||
| "jest": "^29.7.0", | ||
| "prettier": "^3.0.0", | ||
| "rimraf": "^5.0.5", | ||
| "typedoc": "0.25.0", | ||
| "typescript": "^5.5.3" | ||
| }, | ||
| "directories": { | ||
| "example": "example" | ||
| }, | ||
| "repository": { | ||
| "type": "git", | ||
| "url": "github.com/launchdarkly/js-core" | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,85 @@ | ||
| /* eslint-disable no-console */ | ||
| import { openai } from '@ai-sdk/openai'; | ||
| import { generateText, streamText } from 'ai'; | ||
|
|
||
| import { init, type LDClient, type LDContext } from '@launchdarkly/node-server-sdk'; | ||
| import { initAi } from '@launchdarkly/server-sdk-ai'; | ||
|
|
||
| // Environment variables | ||
| const sdkKey = process.env.LAUNCHDARKLY_SDK_KEY ?? ''; | ||
| const aiConfigKey = process.env.LAUNCHDARKLY_AI_CONFIG_KEY || 'sample-ai-config'; | ||
|
|
||
| // Validate required environment variables | ||
| if (!sdkKey) { | ||
| console.error('*** Please set the LAUNCHDARKLY_SDK_KEY env first'); | ||
| process.exit(1); | ||
| } | ||
|
|
||
| let client: LDClient | undefined; | ||
|
|
||
| async function main() { | ||
| // Initialize LaunchDarkly client | ||
| client = init(sdkKey); | ||
|
|
||
| // Set up the context properties. This context should appear on your LaunchDarkly contexts dashboard | ||
| const context: LDContext = { | ||
| kind: 'user', | ||
| key: 'example-user-key', | ||
| name: 'Sandy', | ||
| }; | ||
|
|
||
| try { | ||
| await client.waitForInitialization({ timeout: 10 }); | ||
| console.log('*** SDK successfully initialized'); | ||
| } catch (error) { | ||
| console.log(`*** SDK failed to initialize: ${error}`); | ||
| process.exit(1); | ||
| } | ||
|
|
||
| const aiClient = initAi(client); | ||
|
|
||
| // Get AI configuration from LaunchDarkly | ||
| const aiConfig = await aiClient.config(aiConfigKey, context, { model: { name: 'gpt-4' } }); | ||
|
|
||
| if (!aiConfig.enabled) { | ||
| 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] })), | ||
| ); | ||
| console.log('Response:', result.text); | ||
|
|
||
| process.stdout.write('Streaming Response: '); | ||
| const streamResult = aiConfig.tracker.trackVercelAISDKStreamTextMetrics(() => | ||
| streamText(aiConfig.toVercelAISDK(openai, { nonInterpolatedMessages: [userMessage] })), | ||
| ); | ||
jsonbailey marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| // eslint-disable-next-line no-restricted-syntax | ||
jsonbailey marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| for await (const textPart of streamResult.textStream) { | ||
| process.stdout.write(textPart); | ||
| } | ||
|
|
||
| console.log('\nSuccess.'); | ||
| } catch (err) { | ||
| console.error('Error:', err); | ||
| } | ||
| } | ||
|
|
||
| main() | ||
| .catch((e) => console.error(e)) | ||
| .finally(async () => { | ||
| await client?.flush(); | ||
| client?.close(); | ||
| }); | ||
5 changes: 5 additions & 0 deletions
5
packages/sdk/server-ai/examples/vercel-ai/tsconfig.eslint.json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| { | ||
| "extends": "./tsconfig.json", | ||
| "include": ["**/*.ts", "**/*.tsx"], | ||
| "exclude": ["node_modules"] | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| { | ||
| "extends": "@tsconfig/node20/tsconfig.json", | ||
| "compilerOptions": { | ||
| "noEmit": false, | ||
| "outDir": "dist", | ||
| "baseUrl": ".", | ||
| "allowUnusedLabels": false, | ||
| "allowUnreachableCode": false, | ||
| "noFallthroughCasesInSwitch": true, | ||
| "noUncheckedIndexedAccess": true, | ||
| "noUnusedLocals": true, | ||
| "noUnusedParameters": true, | ||
| "forceConsistentCasingInFileNames": true, | ||
| "declaration": true, | ||
| "sourceMap": true, | ||
| "resolveJsonModule": true, | ||
| "module": "CommonJS", | ||
| "moduleResolution": "Node" | ||
| }, | ||
| "include": ["src"], | ||
| "exclude": ["dist", "node_modules"] | ||
| } |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.