Skip to content
Draft
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
4 changes: 3 additions & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,7 @@
"packages/openai-agents": "0.2.2",
"packages/openai-messages": "0.2.2",
"packages/langchain-agents": "0.2.2",
"packages/langchain-messages": "0.2.2"
"packages/langchain-messages": "0.2.2",
"packages/bedrock-agents": "0.0.1",
"packages/bedrock-messages": "0.0.1"
}
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ graph TD

- **Tier 0 — Core** (`launchdarkly-ai-server`): The foundation. Owns all LaunchDarkly integration, telemetry orchestration, shared data types, and the primary entry points (`config()`, `graph()`, `resolve_graph()`). Has no dependency on any other `launchdarkly-ai-*` package.
- **Tier 0 — Convenience barrel** (`launchdarkly-ai`): A pure re-export package that makes all of `launchdarkly-ai-server` available under a shorter install name. No new logic — intended as the default install for most Python applications.
- **Tier 1 — Handler packages** (`launchdarkly-ai-claude-agents`, `launchdarkly-ai-claude-messages`, `launchdarkly-ai-openai-agents`, `launchdarkly-ai-openai-messages`, `launchdarkly-ai-langchain-agents`, `launchdarkly-ai-langchain-messages`, …): Each wraps a specific AI provider SDK. Depends on `launchdarkly-ai-server` for shared types and utilities. Must not depend on other Tier 1 packages.
- **Tier 1 — Handler packages** (`launchdarkly-ai-claude-agents`, `launchdarkly-ai-claude-messages`, `launchdarkly-ai-openai-agents`, `launchdarkly-ai-openai-messages`, `launchdarkly-ai-langchain-agents`, `launchdarkly-ai-langchain-messages`, `launchdarkly-ai-bedrock-agents`, `launchdarkly-ai-bedrock-messages`, …): Each wraps a specific AI provider SDK. Depends on `launchdarkly-ai-server` for shared types and utilities. Must not depend on other Tier 1 packages.
- **Tier 2 — Consumer applications** (e.g. `main.py`, downstream projects): Imports from one or more handler packages and either `launchdarkly-ai` or `launchdarkly-ai-server`. Owns tool implementations and orchestration logic. No `launchdarkly-ai-*` package should ever depend on Tier 2 code.

### Rules
Expand Down
12 changes: 9 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ That call is the whole integration. Everything it does is configured in LaunchDa
- Run agents and multi-step graphs, where each step can use a different provider
- Score output quality with judges, including scoring that stays off the request path
- See cost, latency, token usage, errors, and full conversations with no instrumentation code
- Keep the providers and frameworks you already run: OpenAI, Anthropic, LangChain, or your own handler
- Keep the providers and frameworks you already run: OpenAI, Anthropic, Amazon Bedrock, LangChain, or your own handler

- [What you get](#what-you-get)
- [How It Works](#how-it-works)
Expand Down Expand Up @@ -85,6 +85,8 @@ Tier 0 — Core Client (launchdarkly-ai-server)
| [`launchdarkly-ai-claude-agents`](packages/claude-agents/README.md) | Anthropic | `agent` | Claude Agent SDK — agentic loop with MCP tool support |
| [`launchdarkly-ai-langchain-messages`](packages/langchain-messages/README.md) | `*` (any) | `messages` | Any `BaseChatModel` via LangChain `bind_tools` loop |
| [`launchdarkly-ai-langchain-agents`](packages/langchain-agents/README.md) | `*` (any) | `agent` | LangGraph `StateGraph` — managed ReAct loop |
| [`launchdarkly-ai-bedrock-messages`](packages/bedrock-messages/README.md) | Bedrock | `messages` | Bedrock Runtime Converse with manual tool-call loop |
| [`launchdarkly-ai-bedrock-agents`](packages/bedrock-agents/README.md) | Bedrock | `agent` | Strands Agent backed by BedrockModel |

## Quick Start

Expand Down Expand Up @@ -149,6 +151,8 @@ asyncio.run(main())
| `claude_agents` | `launchdarkly-ai-claude-agents` | `claude-agent-sdk` | Claude Agent SDK (MCP) |
| `langchain_messages` | `launchdarkly-ai-langchain-messages` | `langchain-core` | LangChain `bind_tools` loop |
| `langchain_agents` | `launchdarkly-ai-langchain-agents` | `langgraph` | LangGraph `StateGraph` |
| `bedrock_messages` | `launchdarkly-ai-bedrock-messages` | `aioboto3` | Bedrock Runtime Converse |
| `bedrock_agents` | `launchdarkly-ai-bedrock-agents` | `strands-agents` | Strands Agent + BedrockModel |

---

Expand Down Expand Up @@ -250,7 +254,7 @@ async def main():
asyncio.run(main())
```

Provider packages also export single-provider conveniences (`claude_graph`, `openai_graph`, `langchain_graph`) that pre-bind their handler.
Provider packages also export single-provider conveniences (`claude_graph`, `openai_graph`, `langchain_graph`, `bedrock_graph`) that pre-bind their handler.

---

Expand Down Expand Up @@ -635,7 +639,9 @@ python-ai-sdk/
│ ├── openai-agents/ # launchdarkly-ai-openai-agents
│ ├── openai-messages/ # launchdarkly-ai-openai-messages
│ ├── langchain-agents/ # launchdarkly-ai-langchain-agents
│ └── langchain-messages/ # launchdarkly-ai-langchain-messages
│ ├── langchain-messages/ # launchdarkly-ai-langchain-messages
│ ├── bedrock-agents/ # launchdarkly-ai-bedrock-agents
│ └── bedrock-messages/ # launchdarkly-ai-bedrock-messages
├── .env.example # Template — copy to .env and fill in your values
└── agents.md # Architecture reference for AI agents and contributors
```
Expand Down
21 changes: 21 additions & 0 deletions examples/bedrock_agents_example.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
"""Example: Amazon Bedrock with Strands Agent."""

from __future__ import annotations

import json

from examples.tools import get_preferences
from examples.utils import new_context, write_output
from launchdarkly_ai_bedrock_agents import bedrock_agents


async def run(key: str, user_input: str) -> None:
response = await bedrock_agents(
key,
user_input,
new_context(),
tool_handlers={"get-user-preferences": get_preferences},
variables={"user_input": user_input},
)
print(json.dumps(response, indent=2, default=str))
write_output(response)
21 changes: 21 additions & 0 deletions examples/bedrock_messages_example.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
"""Example: Amazon Bedrock Runtime Converse."""

from __future__ import annotations

import json

from examples.tools import get_preferences
from examples.utils import new_context, write_output
from launchdarkly_ai_bedrock_messages import bedrock_messages


async def run(key: str, user_input: str) -> None:
response = await bedrock_messages(
key,
user_input,
new_context(),
tool_handlers={"get-user-preferences": get_preferences},
variables={"user_input": user_input},
)
print(json.dumps(response, indent=2, default=str))
write_output(response)
4 changes: 4 additions & 0 deletions examples/register.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
search_ld_documentation,
web_search,
)
from launchdarkly_ai_bedrock_agents import create_bedrock_agents_handler
from launchdarkly_ai_bedrock_messages import create_bedrock_messages_handler
from launchdarkly_ai_claude_agents import ClaudeWebSearch, create_claude_agents_handler
from launchdarkly_ai_claude_messages import create_claude_messages_handler
from launchdarkly_ai_openai_agents import create_openai_agent_handler
Expand All @@ -27,6 +29,8 @@
create_openai_agent_handler(),
create_claude_agents_handler(),
create_claude_messages_handler(),
create_bedrock_agents_handler(),
create_bedrock_messages_handler(),
],
tools={
# LD documentation agent tools
Expand Down
2 changes: 2 additions & 0 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@
"langchain": "examples.langchain_example",
"langchain-agents": "examples.langchain_agents_example",
"langchain-messages": "examples.langchain_messages_example",
"bedrock-agents": "examples.bedrock_agents_example",
"bedrock-messages": "examples.bedrock_messages_example",
"native-graph": "examples.native_graph",
"native-graph-langchain": "examples.native_graph_langchain",
}
Expand Down
5 changes: 5 additions & 0 deletions packages/bedrock-agents/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Changelog

## 0.0.1

- Initial Amazon Bedrock Strands agent handler and graph convenience wrapper.
12 changes: 12 additions & 0 deletions packages/bedrock-agents/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# LaunchDarkly AI Bedrock Agents

Amazon Bedrock integration using Strands `Agent` and `BedrockModel`.

```python
from launchdarkly_ai_bedrock_agents import create_bedrock_agents_handler

handler = create_bedrock_agents_handler(region="us-east-1")
```

The factory also accepts a boto3 `client` or `boto_session`. Injected clients remain owned by the
caller. `bedrock_graph()` pre-wires the handler into LaunchDarkly's generic graph runner.
14 changes: 14 additions & 0 deletions packages/bedrock-agents/agents.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Agent Guide — `launchdarkly-ai-bedrock-agents`

This Tier 1 package routes `('Bedrock', 'agent')` configs through Strands `Agent` and
`BedrockModel`. It deliberately does not expose AgentCore or a Strands-native graph adapter.

Important invariants:

- `model.region` is an idempotent inference-profile prefix; factory `region` selects the endpoint.
- `model_options(config)` and documented model parameters configure `BedrockModel`;
`model.custom` is never consumed and generated `model_id` remains authoritative.
- A raw boto3 client is assigned to `model.client`; otherwise `boto_session` is forwarded.
- History uses Strands' structured message input rather than being flattened into the system prompt.
- `bedrock_graph()` pre-wires one Bedrock agent handler into the generic graph runner.
- Package telemetry uses the shared three-level span tree and folds Bedrock cache usage.
35 changes: 35 additions & 0 deletions packages/bedrock-agents/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
[project]
name = "launchdarkly-ai-bedrock-agents"
version = "0.0.1"
requires-python = ">=3.12"
dependencies = [
"boto3>=1.40",
"launchdarkly-ai-server",
"opentelemetry-api>=1.25",
"strands-agents>=1.0",
]
description = "Amazon Bedrock Strands agent handler for LaunchDarkly AI SDK"
readme = "README.md"
license = "Apache-2.0"
authors = [{name = "LaunchDarkly", email = "team@launchdarkly.com"}]
keywords = ["launchdarkly", "ai", "aws", "bedrock", "strands"]
classifiers = [
"Development Status :: 3 - Alpha",
"Intended Audience :: Developers",
"License :: OSI Approved :: Apache Software License",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.12",
"Topic :: Software Development :: Libraries",
]

[project.urls]
Homepage = "https://github.com/launchdarkly/python-ai-sdk"
Repository = "https://github.com/launchdarkly/python-ai-sdk"
"Bug Tracker" = "https://github.com/launchdarkly/python-ai-sdk/issues"

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

[tool.hatch.build.targets.wheel]
packages = ["src/launchdarkly_ai_bedrock_agents"]
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
"""LaunchDarkly AI SDK integration for Amazon Bedrock Strands agents."""

__version__ = "0.0.1" # x-release-please-version

from .graph import bedrock_graph
from .handler import bedrock_agents, create_bedrock_agents_handler

__all__ = ["bedrock_agents", "bedrock_graph", "create_bedrock_agents_handler"]
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
"""Graph convenience wrapper for Bedrock agents."""

from __future__ import annotations

from typing import Any

from launchdarkly_ai_server import graph

from .handler import create_bedrock_agents_handler


def bedrock_graph(key: str, **options: Any) -> Any:
"""Create a generic graph with exactly one Bedrock agent handler."""
options.pop("handlers", None)
return graph(key, handlers=[create_bedrock_agents_handler()], **options)
Loading
Loading