Skip to content

Commit 5176d03

Browse files
authored
feat: Update examples for AI SDK for latest version of SDK (#26)
1 parent 78fe661 commit 5176d03

31 files changed

Lines changed: 721 additions & 258 deletions

examples/bedrock/README.md

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,25 @@ This example demonstrates how to use LaunchDarkly's AI Config with the AWS Bedro
66

77
- Python 3.10 or higher
88
- [Poetry](https://python-poetry.org/) installed
9-
- A LaunchDarkly account with an [AI Config](https://launchdarkly.com/docs/home/ai-configs/create) created
9+
- A [LaunchDarkly](https://launchdarkly.com/) account and SDK key
1010
- AWS credentials configured for Bedrock access
1111

1212
## Setup
1313

14+
1. Create the following config in your LaunchDarkly project. You can use a different key by setting the environment variable in your `.env`.
15+
16+
- [Create an AI Config](https://launchdarkly.com/docs/home/ai-configs/create) with a Bedrock model and a system message. Default key: `sample-completion-config`.
17+
1418
1. Create a `.env` file in this directory with the following variables:
1519

1620
```
1721
LAUNCHDARKLY_SDK_KEY=your-launchdarkly-sdk-key
18-
LAUNCHDARKLY_AI_CONFIG_KEY=sample-ai-config
22+
LAUNCHDARKLY_AI_CONFIG_KEY=sample-completion-config
1923
```
2024

21-
> `LAUNCHDARKLY_AI_CONFIG_KEY` defaults to `sample-ai-config` if not set.
25+
> `LAUNCHDARKLY_AI_CONFIG_KEY` defaults to `sample-completion-config` if not set.
2226
23-
2. Ensure your AWS credentials can be [auto-detected by the `boto3` library](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/credentials.html). You can set them in your `.env` file:
27+
1. Ensure your AWS credentials can be [auto-detected by the `boto3` library](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/credentials.html). You can set them in your `.env` file:
2428

2529
```
2630
AWS_ACCESS_KEY_ID=your-access-key-id
@@ -30,7 +34,7 @@ This example demonstrates how to use LaunchDarkly's AI Config with the AWS Bedro
3034

3135
Other options include role providers or shared credential files.
3236

33-
3. Install the required dependencies:
37+
1. Install the required dependencies:
3438

3539
```bash
3640
poetry install
@@ -39,5 +43,5 @@ This example demonstrates how to use LaunchDarkly's AI Config with the AWS Bedro
3943
## Run
4044

4145
```bash
42-
poetry run bedrock-example
46+
poetry run bedrock
4347
```

examples/bedrock/bedrock_example.py

Lines changed: 47 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,45 @@
11
import os
2+
import logging
23
from dotenv import load_dotenv
34
import ldclient
45
from ldclient import Context
56
from ldclient.config import Config
67
from ldai import LDAIClient
8+
from ldai.tracker import TokenUsage
9+
from ldai.providers import LDAIMetrics
710
import boto3
811

912
load_dotenv()
1013

14+
logging.basicConfig()
15+
logging.getLogger('ldclient').setLevel(logging.WARNING)
16+
1117
client = boto3.client("bedrock-runtime", region_name=os.getenv('AWS_DEFAULT_REGION', 'us-east-1'))
1218

19+
20+
def get_bedrock_metrics(response):
21+
"""Extract metrics from a Bedrock converse response."""
22+
status_code = response.get("ResponseMetadata", {}).get("HTTPStatusCode", 0)
23+
success = status_code == 200
24+
25+
usage = None
26+
if response.get("usage"):
27+
u = response["usage"]
28+
usage = TokenUsage(
29+
total=u.get("totalTokens", 0),
30+
input=u.get("inputTokens", 0),
31+
output=u.get("outputTokens", 0),
32+
)
33+
34+
duration_ms = response.get("metrics", {}).get("latencyMs")
35+
36+
return LDAIMetrics(success=success, usage=usage, duration_ms=duration_ms)
37+
1338
# Set sdk_key to your LaunchDarkly SDK key.
1439
sdk_key = os.getenv('LAUNCHDARKLY_SDK_KEY')
1540

1641
# Set config_key to the AI Config key you want to evaluate.
17-
ai_config_key = os.getenv('LAUNCHDARKLY_AI_CONFIG_KEY', 'sample-ai-config')
42+
ai_config_key = os.getenv('LAUNCHDARKLY_AI_CONFIG_KEY', 'sample-completion-config')
1843

1944
def main():
2045
if not sdk_key:
@@ -69,25 +94,35 @@ def main():
6994
chat_messages = [{'role': msg.role, 'content': [{'text': msg.content}]} for msg in config_value.messages if msg.role != 'system']
7095
system_messages = [{'text': msg.content} for msg in config_value.messages if msg.role == 'system']
7196

72-
# Add the user input to the conversation
73-
USER_INPUT = "What can you help me with?"
74-
print("User Input:\n", USER_INPUT)
75-
chat_messages.append({'role': 'user', 'content': [{'text': USER_INPUT}]})
97+
SAMPLE_QUESTION = "What can you help me with?"
98+
chat_messages.append({'role': 'user', 'content': [{'text': SAMPLE_QUESTION}]})
7699

77-
converse = tracker.track_bedrock_converse_metrics(
78-
client.converse(
100+
print(f'\nSending sample question to {config_value.model.name}: "{SAMPLE_QUESTION}"')
101+
print("Waiting for response...")
102+
103+
converse = tracker.track_metrics_of(
104+
get_bedrock_metrics,
105+
lambda: client.converse(
79106
modelId=config_value.model.name,
80107
messages=chat_messages,
81108
system=system_messages,
82-
)
109+
),
83110
)
84111

85-
# Append the AI response to the conversation history
86112
chat_messages.append(converse["output"]["message"])
87-
print("AI Response:\n", converse["output"]["message"]["content"][0]["text"])
88113

89-
# Continue the conversation by adding user input to the messages list and invoking the LLM again.
90-
print("Success.")
114+
print(f"\nModel response:\n{converse['output']['message']['content'][0]['text']}")
115+
116+
summary = tracker.get_summary()
117+
print("\nDone! The AI config was evaluated and the following metrics were tracked:")
118+
print(f" Duration: {summary.duration_ms}ms")
119+
print(f" Success: {summary.success}")
120+
if summary.usage:
121+
print(f" Input tokens: {summary.usage.input}")
122+
print(f" Output tokens: {summary.usage.output}")
123+
print(f" Total tokens: {summary.usage.total}")
124+
if summary.tool_calls:
125+
print(f" Tool calls: {', '.join(summary.tool_calls)}")
91126

92127
# Flush pending events and close the client.
93128
ldclient.get().flush()

examples/bedrock/pyproject.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@ readme = "README.md"
88
packages = [{include = "bedrock_example.py"}]
99

1010
[tool.poetry.scripts]
11-
bedrock-example = "bedrock_example:main"
11+
bedrock = "bedrock_example:main"
1212

1313
[tool.poetry.dependencies]
1414
python = "^3.10"
1515
python-dotenv = ">=1.0.0"
16-
launchdarkly-server-sdk-ai = "^0.18.0"
16+
launchdarkly-server-sdk-ai = ">=0.19.0"
1717
boto3 = ">=0.2.0"
1818

1919
[build-system]

examples/chat_observability/README.md

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,29 +13,31 @@ View your data in the LaunchDarkly dashboard under **Observability** tabs.
1313

1414
- Python 3.10 or higher
1515
- [Poetry](https://python-poetry.org/) installed
16-
- A LaunchDarkly account with an [AI Config](https://launchdarkly.com/docs/home/ai-configs/create) created
16+
- A [LaunchDarkly](https://launchdarkly.com/) account and SDK key
1717
- An API key for your AI provider (e.g., OpenAI)
1818

1919
## Setup
2020

21+
1. Create the following config in your LaunchDarkly project. You can use a different key by setting the environment variable in your `.env`.
22+
23+
- [Create an AI Config](https://launchdarkly.com/docs/home/ai-configs/create) with a model and a system message. Default key: `sample-completion-config`.
24+
2125
1. Create a `.env` file in this directory with the following variables:
2226

2327
```
2428
LAUNCHDARKLY_SDK_KEY=your-launchdarkly-sdk-key
25-
LAUNCHDARKLY_AI_CONFIG_KEY=sample-ai-config
29+
LAUNCHDARKLY_AI_CONFIG_KEY=sample-completion-config
2630
OPENAI_API_KEY=your-openai-api-key
2731
```
2832

29-
> `LAUNCHDARKLY_AI_CONFIG_KEY` defaults to `sample-ai-config` if not set.
30-
3133
Optionally, set service identification:
3234

3335
```
3436
SERVICE_NAME=my-ai-service
3537
SERVICE_VERSION=1.0.0
3638
```
3739

38-
2. Install the required dependencies:
40+
1. Install the required dependencies:
3941

4042
```bash
4143
poetry install
@@ -44,5 +46,5 @@ View your data in the LaunchDarkly dashboard under **Observability** tabs.
4446
## Run
4547

4648
```bash
47-
poetry run chat-observability-example
49+
poetry run chat
4850
```

examples/chat_observability/chat_observability_example.py

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import os
2+
import logging
23
from dotenv import load_dotenv
34
import asyncio
4-
import logging
55
import ldclient
66
from ldclient import Context
77
from ldclient.config import Config
@@ -10,13 +10,15 @@
1010

1111
load_dotenv()
1212

13+
logging.basicConfig()
1314
logging.getLogger('ldclient').setLevel(logging.WARNING)
15+
logging.getLogger('httpx').setLevel(logging.WARNING)
1416

1517
# Set sdk_key to your LaunchDarkly SDK key.
1618
sdk_key = os.getenv('LAUNCHDARKLY_SDK_KEY')
1719

1820
# Set config_key to the AI Config key you want to evaluate.
19-
ai_config_key = os.getenv('LAUNCHDARKLY_AI_CONFIG_KEY', 'sample-ai-config')
21+
ai_config_key = os.getenv('LAUNCHDARKLY_AI_CONFIG_KEY', 'sample-completion-config')
2022

2123
# Service configuration for observability
2224
service_name = os.getenv('SERVICE_NAME', 'hello-python-ai-observability')
@@ -85,27 +87,29 @@ async def async_main():
8587
print(f"*** Failed to create chat for key: {ai_config_key}")
8688
return
8789

88-
user_input_1 = "What is feature flagging in 2 sentences?"
89-
print("User Input:", user_input_1)
90-
91-
response_1 = await chat.invoke(user_input_1)
92-
print("Chat Response:", response_1.message.content)
90+
sample_question_1 = "What is feature flagging in 2 sentences?"
91+
print(f'\nSending sample question: "{sample_question_1}"')
92+
print("Waiting for response...")
93+
94+
response_1 = await chat.run(sample_question_1)
95+
print(f"\nModel response:\n{response_1.content}")
9396

94-
user_input_2 = "Give me a specific use case example."
95-
print("\nUser Input:", user_input_2)
97+
sample_question_2 = "Give me a specific use case example."
98+
print(f'\nSending follow-up question: "{sample_question_2}"')
99+
print("Waiting for response...")
96100

97-
response_2 = await chat.invoke(user_input_2)
98-
print("Chat Response:", response_2.message.content)
101+
response_2 = await chat.run(sample_question_2)
102+
print(f"\nModel response:\n{response_2.content}")
99103

100-
# Judge evaluations run asynchronously. Await them (e.g. with asyncio.gather) so they
104+
# Judge evaluations run asynchronously. Await them so they
101105
# complete before the process or request ends—even if you don't need to log or use
102106
# the results.
103-
if response_1.evaluations:
104-
await asyncio.gather(*response_1.evaluations)
105-
if response_2.evaluations:
106-
await asyncio.gather(*response_2.evaluations)
107+
if response_1.evaluations is not None:
108+
await response_1.evaluations
109+
if response_2.evaluations is not None:
110+
await response_2.evaluations
107111

108-
print("\nSuccess.")
112+
print("\nDone! The AI config was evaluated with observability enabled.")
109113

110114
except Exception as err:
111115
print("Error:", err)

examples/chat_observability/pyproject.toml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,15 @@ readme = "README.md"
88
packages = [{include = "chat_observability_example.py"}]
99

1010
[tool.poetry.scripts]
11-
chat-observability-example = "chat_observability_example:main"
11+
chat = "chat_observability_example:main"
1212

1313
[tool.poetry.dependencies]
1414
python = "^3.10"
1515
python-dotenv = ">=1.0.0"
16-
launchdarkly-server-sdk-ai = "^0.18.0"
16+
launchdarkly-server-sdk-ai = ">=0.19.0"
1717
launchdarkly-observability = ">=0.1.0"
18-
launchdarkly-server-sdk-ai-openai = ">=0.4.0"
19-
launchdarkly-server-sdk-ai-langchain = ">=0.5.0"
18+
launchdarkly-server-sdk-ai-openai = ">=0.5.0"
19+
launchdarkly-server-sdk-ai-langchain = ">=0.6.0"
2020
openai = ">=0.2.0"
2121

2222
[build-system]

examples/gemini/README.md

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,22 +6,24 @@ This example demonstrates how to use LaunchDarkly's AI Config with the Google Ge
66

77
- Python 3.10 or higher
88
- [Poetry](https://python-poetry.org/) installed
9-
- A LaunchDarkly account with an [AI Config](https://launchdarkly.com/docs/home/ai-configs/create) created
9+
- A [LaunchDarkly](https://launchdarkly.com/) account and SDK key
1010
- A [Google API key](https://aistudio.google.com/apikey)
1111

1212
## Setup
1313

14+
1. Create the following config in your LaunchDarkly project. You can use a different key by setting the environment variable in your `.env`.
15+
16+
- [Create an AI Config](https://launchdarkly.com/docs/home/ai-configs/create) with a Gemini model (e.g. `gemini-2.0-flash`) and a system message. Default key: `sample-completion-config`.
17+
1418
1. Create a `.env` file in this directory with the following variables:
1519

1620
```
1721
LAUNCHDARKLY_SDK_KEY=your-launchdarkly-sdk-key
18-
LAUNCHDARKLY_AI_CONFIG_KEY=sample-ai-config
22+
LAUNCHDARKLY_AI_CONFIG_KEY=sample-completion-config
1923
GOOGLE_API_KEY=your-google-api-key
2024
```
2125

22-
> `LAUNCHDARKLY_AI_CONFIG_KEY` defaults to `sample-ai-config` if not set.
23-
24-
2. Install the required dependencies:
26+
1. Install the required dependencies:
2527

2628
```bash
2729
poetry install
@@ -30,5 +32,5 @@ This example demonstrates how to use LaunchDarkly's AI Config with the Google Ge
3032
## Run
3133

3234
```bash
33-
poetry run gemini-example
35+
poetry run gemini
3436
```

examples/gemini/gemini_example.py

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import os
2+
import logging
23
from dotenv import load_dotenv
34
import ldclient
45
from ldclient import Context
@@ -11,11 +12,14 @@
1112

1213
load_dotenv()
1314

15+
logging.basicConfig()
16+
logging.getLogger('ldclient').setLevel(logging.WARNING)
17+
1418
# Set sdk_key to your LaunchDarkly SDK key.
1519
sdk_key = os.getenv('LAUNCHDARKLY_SDK_KEY')
1620

1721
# Set config_key to the AI Config key you want to evaluate.
18-
ai_config_key = os.getenv('LAUNCHDARKLY_AI_CONFIG_KEY', 'sample-ai-config')
22+
ai_config_key = os.getenv('LAUNCHDARKLY_AI_CONFIG_KEY', 'sample-completion-config')
1923

2024
# Set Google API key
2125
google_api_key = os.getenv('GOOGLE_API_KEY')
@@ -143,12 +147,13 @@ def main():
143147
# Convert LaunchDarkly messages to Google AI format using the helper function
144148
system_instruction, messages = map_to_google_ai_messages(config_value.messages or [])
145149

146-
# Add the user input to the conversation
147-
USER_INPUT = "What can you help me with?"
148-
print("User Input:\n", USER_INPUT)
149-
user_message = types.Content(role="user", parts=[types.Part(text=USER_INPUT)])
150+
SAMPLE_QUESTION = "What can you help me with?"
151+
user_message = types.Content(role="user", parts=[types.Part(text=SAMPLE_QUESTION)])
150152
messages.append(user_message)
151153

154+
print(f'\nSending sample question to {config_value.model.name}: "{SAMPLE_QUESTION}"')
155+
print("Waiting for response...")
156+
152157
completion = track_genai_metrics(tracker, lambda: client.models.generate_content(
153158
model=config_value.model.name,
154159
contents=messages,
@@ -158,13 +163,21 @@ def main():
158163
))
159164
ai_response = completion.text
160165

161-
# Add the AI response to the conversation history
162166
ai_message = types.Content(role="model", parts=[types.Part(text=ai_response)])
163167
messages.append(ai_message)
164-
print("AI Response:\n", ai_response)
165168

166-
# Continue the conversation by adding user input to the messages list and invoking the LLM again.
167-
print("Success.")
169+
print(f"\nModel response:\n{ai_response}")
170+
171+
summary = tracker.get_summary()
172+
print("\nDone! The AI config was evaluated and the following metrics were tracked:")
173+
print(f" Duration: {summary.duration_ms}ms")
174+
print(f" Success: {summary.success}")
175+
if summary.usage:
176+
print(f" Input tokens: {summary.usage.input}")
177+
print(f" Output tokens: {summary.usage.output}")
178+
print(f" Total tokens: {summary.usage.total}")
179+
if summary.tool_calls:
180+
print(f" Tool calls: {', '.join(summary.tool_calls)}")
168181

169182
# Flush pending events and close the client.
170183
ldclient.get().flush()

0 commit comments

Comments
 (0)