Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions packages/sdk/ai/examples/bedrock/README.md
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
```
70 changes: 70 additions & 0 deletions packages/sdk/ai/examples/bedrock/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
const LaunchDarkly = require('@launchdarkly/node-server-sdk');
Copy link
Member

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.

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");
Copy link
Member

Choose a reason for hiding this comment

The 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();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make sure to end the files with a blank line.

33 changes: 33 additions & 0 deletions packages/sdk/ai/examples/bedrock/package.json
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",
Copy link
Member

Choose a reason for hiding this comment

The 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"
Copy link
Member

Choose a reason for hiding this comment

The 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"
}
}
40 changes: 40 additions & 0 deletions packages/sdk/ai/examples/openai/README.md
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.
59 changes: 59 additions & 0 deletions packages/sdk/ai/examples/openai/index.js
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");
Copy link
Member

Choose a reason for hiding this comment

The 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();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Newline.

33 changes: 33 additions & 0 deletions packages/sdk/ai/examples/openai/package.json
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",
Copy link
Member

Choose a reason for hiding this comment

The 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"
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add newline.

Loading