-
Notifications
You must be signed in to change notification settings - Fork 31
openai and bedrock examples #635
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| # LaunchDarkly AI SDK for AWS Bedrock Example | ||
|
|
||
| This package demonstrates the integration of LaunchDarkly's AI SDK with AWS Bedrock, allowing you to leverage LaunchDarkly's AI Config capabilities in AI-powered applications using AWS Bedrock. | ||
|
|
||
| ## Installation | ||
|
|
||
| To install the package and its dependencies, run: | ||
|
|
||
| ```bash | ||
| npm install | ||
| ``` | ||
|
|
||
| ## 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 configuration key (defaults to 'sample-ai-config' if not set) | ||
|
|
||
| Additionally, ensure you have proper AWS credentials configured to access Bedrock services. | ||
|
|
||
| ## 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 AWS Bedrock | ||
| 6. Track token usage | ||
|
|
||
| To run the example: | ||
|
|
||
| ```bash | ||
| node index.js | ||
| ``` |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,70 @@ | ||
| const LaunchDarkly = require('@launchdarkly/node-server-sdk'); | ||
| const LaunchDarklyAI = require('@launchdarkly/ai'); | ||
| const { OpenAITokenUsage } = require('@launchdarkly/ai'); // Adjusted require | ||
| const { BedrockRuntimeClient, ConverseCommand } = require("@aws-sdk/client-bedrock-runtime"); | ||
|
|
||
| const sdkKey = process.env.LAUNCHDARKLY_SDK_KEY; | ||
| const aiConfigKey = process.env.LAUNCHDARKLY_AI_CONFIG_KEY || 'sample-ai-config'; | ||
| const ci = process.env.CI; | ||
| const awsClient = new BedrockRuntimeClient({ region: "us-east-1" }); | ||
|
|
||
| if (!sdkKey) { | ||
| console.error("*** Please set the LAUNCHDARKLY_SDK_KEY env first"); | ||
| process.exit(1); | ||
| } | ||
| if (!aiConfigKey) { | ||
| console.error("*** Please set the LAUNCHDARKLY_AI_CONFIG_KEY env first"); | ||
| process.exit(1); | ||
| } | ||
|
|
||
| const ldClient = LaunchDarkly.init(sdkKey); | ||
|
|
||
| // Set up the context properties. This context should appear on your LaunchDarkly contexts dashboard | ||
| // soon after you run the demo. | ||
| const context = { | ||
| kind: 'user', | ||
| key: 'example-user-key', | ||
| name: 'Sandy', | ||
| }; | ||
|
|
||
| console.log("*** SDK successfully initialized"); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This log is not accurate. |
||
|
|
||
| async function main() { | ||
| let tracker; | ||
| let configValue; | ||
| try { | ||
| await ldClient.waitForInitialization({timeout: 10}); | ||
| const aiClient = LaunchDarklyAI.init(ldClient); | ||
|
|
||
| configValue = await aiClient.modelConfig(aiConfigKey, context, false, { myVariable: "My User Defined Variable" }); | ||
| tracker = configValue.tracker; | ||
|
|
||
|
|
||
|
|
||
|
|
||
| } catch (error) { | ||
| console.log(`*** SDK failed to initialize: ${error}`); | ||
| process.exit(1); | ||
| } | ||
| const conversation = [ | ||
| { | ||
| role: "user", | ||
| content: [{ text: "Hello, how are you?" }], | ||
| }, | ||
| ]; | ||
|
|
||
| const completion = await tracker.trackBedrockConverse(await awsClient.send( | ||
| new ConverseCommand({modelId: configValue.config.config.modelId, messages: mapPromptToConversation(configValue.config.prompt)}) | ||
| )); | ||
| console.log("AI Response:", completion.output.message.content[0].text); | ||
| console.log("Success."); | ||
| } | ||
|
|
||
| function mapPromptToConversation(prompt) { | ||
| return prompt.map(item => ({ | ||
| role: item.role, | ||
| content: [{ text: item.content }] | ||
| })); | ||
| } | ||
|
|
||
| main(); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Make sure to end the files with a blank line. |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| { | ||
| "name": "@launchdarkly/hello-ai-bedrock", | ||
| "version": "0.1.0", | ||
| "description": "LaunchDarkly AI SDK for Node.js", | ||
| "main": "dist/index.js", | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This main/types is incorrect. |
||
| "types": "dist/index.d.ts", | ||
| "scripts": { | ||
| "build": "tsc", | ||
| "test": "jest", | ||
| "lint": "eslint . --ext .ts" | ||
| }, | ||
| "keywords": [ | ||
| "launchdarkly", | ||
| "ai", | ||
| "llm" | ||
| ], | ||
| "author": "LaunchDarkly", | ||
| "license": "Apache-2.0", | ||
| "dependencies": { | ||
| "@aws-sdk/client-bedrock-runtime": "^3.679.0", | ||
| "@launchdarkly/ai": "0.1.0" | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So, this is a big tricky. This number will not automatically update without this example being in the workspaces list. Because that is how release-please updates it. But if it does update, then it also expects to be able to install from the workspace. So you can add it to the workspace and update the instructions to build required components. Or you can make some config which instructs release-please to update this JSON file. Or you can manually update it. Or maybe renovate or dependabot could be persuaded to update it. |
||
| }, | ||
| "devDependencies": { | ||
| "eslint": "^8.45.0" | ||
| }, | ||
| "directories": { | ||
| "example": "example" | ||
| }, | ||
| "repository": { | ||
| "type": "git", | ||
| "url": "github.com/launchdarkly/js-core" | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| # LaunchDarkly AI SDK for OpenAI Example | ||
|
|
||
| This package demonstrates the integration of LaunchDarkly's AI SDK with OpenAI, allowing you to leverage LaunchDarkly's AI Config capabilities in AI-powered applications using OpenAI's services. | ||
|
|
||
| ## Installation | ||
|
|
||
| To install the package and its dependencies, run: | ||
|
|
||
| ```bash | ||
| npm install | ||
| ``` | ||
|
|
||
| ## 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 configuration 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 OpenAI | ||
| 6. Track token usage | ||
|
|
||
| To run the example: | ||
|
|
||
| ```bash | ||
| node index.js | ||
| ``` | ||
|
|
||
| ## Note | ||
|
|
||
| This example uses OpenAI's chat completions API. Make sure your LaunchDarkly AI configuration is set up correctly to work with OpenAI's models and API structure. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,59 @@ | ||
| const LaunchDarkly = require('@launchdarkly/node-server-sdk'); | ||
| const LaunchDarklyAI = require('@launchdarkly/ai'); | ||
| const { OpenAITokenUsage } = require('@launchdarkly/ai'); // Adjusted require | ||
| const OpenAI = require('openai'); | ||
|
|
||
| const sdkKey = process.env.LAUNCHDARKLY_SDK_KEY; | ||
| const aiConfigKey = process.env.LAUNCHDARKLY_AI_CONFIG_KEY || 'sample-ai-config'; | ||
| const ci = process.env.CI; | ||
|
|
||
| const client = new OpenAI({ | ||
| apiKey: process.env['OPENAI_API_KEY'], // This is the default and can be omitted | ||
| }); | ||
|
|
||
| if (!sdkKey) { | ||
| console.error("*** Please set the LAUNCHDARKLY_SDK_KEY env first"); | ||
| process.exit(1); | ||
| } | ||
| if (!aiConfigKey) { | ||
| console.error("*** Please set the LAUNCHDARKLY_AI_CONFIG_KEY env first"); | ||
| process.exit(1); | ||
| } | ||
|
|
||
| const ldClient = LaunchDarkly.init(sdkKey); | ||
|
|
||
| // Set up the context properties. This context should appear on your LaunchDarkly contexts dashboard | ||
| // soon after you run the demo. | ||
| const context = { | ||
| kind: 'user', | ||
| key: 'example-user-key', | ||
| name: 'Sandy', | ||
| }; | ||
|
|
||
| console.log("*** SDK successfully initialized"); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This log is not accurate. |
||
|
|
||
| async function main() { | ||
| try { | ||
| await ldClient.waitForInitialization({timeout: 10}); | ||
| const aiClient = LaunchDarklyAI.init(ldClient); | ||
|
|
||
| const configValue = await aiClient.modelConfig(aiConfigKey, context, false, { myVariable: "My User Defined Variable" }); | ||
| const tracker = configValue.tracker; | ||
| const completion = await tracker.trackOpenAI(async () => { | ||
| return await client.chat.completions.create({ | ||
| messages: configValue.config.prompt, | ||
| model: configValue.config.config.modelId, | ||
| }); | ||
| }); | ||
|
|
||
| console.log("AI Response:", completion.choices[0].message.content); | ||
| console.log("Success."); | ||
|
|
||
| } catch (error) { | ||
| console.log(`*** SDK failed to initialize: ${error}`); | ||
| process.exit(1); | ||
| } | ||
|
|
||
| } | ||
|
|
||
| main(); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Newline. |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| { | ||
| "name": "@launchdarkly/hello-ai", | ||
| "version": "0.1.0", | ||
| "description": "LaunchDarkly AI SDK for Node.js", | ||
| "main": "dist/index.js", | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Main/types incorrect. |
||
| "types": "dist/index.d.ts", | ||
| "scripts": { | ||
| "build": "tsc", | ||
| "test": "jest", | ||
| "lint": "eslint . --ext .ts" | ||
| }, | ||
| "keywords": [ | ||
| "launchdarkly", | ||
| "ai", | ||
| "llm" | ||
| ], | ||
| "author": "LaunchDarkly", | ||
| "license": "Apache-2.0", | ||
| "dependencies": { | ||
| "@launchdarkly/ai": "0.1.0", | ||
| "openai": "^4.58.1" | ||
| }, | ||
| "devDependencies": { | ||
| "eslint": "^8.45.0" | ||
| }, | ||
| "directories": { | ||
| "example": "example" | ||
| }, | ||
| "repository": { | ||
| "type": "git", | ||
| "url": "github.com/launchdarkly/js-core" | ||
| } | ||
| } | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add newline. |
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would recommend importing what you use instead of importing it all and using
..I am mildly concerned about JavaScript examples as they are hard to keep functional. (Also CJS instead of ESM.)
Also customers usually want TypeScript.