launchdarkly-ai-langchain-agents
LangChain handler for launchdarkly-ai-server using LangGraph's StateGraph (langgraph). Delegates the full agentic loop to the LangGraph ReAct agent. Works with any BaseChatModel — defaults to ChatOpenAI.
provides_for: ['*', 'agent'] — matches any flag variation where meta.mode is "agent" and no more-specific handler is registered. LangChain is a framework adapter, not a provider: it routes through langchain-anthropic, langchain-openai, and others at runtime based on config.provider.name. Use '*' so that flags configured with provider.name = "Anthropic" or "OpenAI" are automatically handled without requiring a separate native handler.
Installation
pip install launchdarkly-ai-server launchdarkly-ai-langchain-agents
The default model is ChatOpenAI, so set OPENAI_API_KEY unless you pass a custom BaseChatModel.
Usage
With the default model (ChatOpenAI)
import asyncio
from launchdarkly_ai_server import config, shutdown
from launchdarkly_ai_langchain_agents import create_langchain_agents_handler
async def main():
result = await config(
key="my-ai-config-flag",
handler=create_langchain_agents_handler(),
tool_handlers={"search": lambda q: "..."},
).invoke(
"Research and summarize feature flagging best practices",
{"kind": "user", "key": "user-123"},
)
print(result.response)
await shutdown()
asyncio.run(main())
With a custom BaseChatModel
from langchain_anthropic import ChatAnthropic
from launchdarkly_ai_langchain_agents import create_langchain_agents_handler
handler = create_langchain_agents_handler(ChatAnthropic(model="claude-opus-4-5"))
Convenience wrapper
import asyncio
from launchdarkly_ai_langchain_agents import langchain_agents
async def main():
user_input = "Research feature flagging best practices"
result = await langchain_agents(
user_input,
{"kind": "user", "key": "user-123"},
{"key": "my-ai-config-flag"},
variables={"user_input": user_input},
)
print(result.response)
asyncio.run(main())
Agent graphs — langchain_graph()
Runs a LaunchDarkly agent graph with the LangChain agent handler pre-bound. Equivalent to calling the base graph() with handlers=[create_langchain_agents_handler()]. See the core client docs for the full graph() API.
import asyncio
from launchdarkly_ai_langchain_agents import langchain_graph
async def main():
result = await langchain_graph("support-graph").invoke(
"I was double charged",
{"kind": "user", "key": "user-123"},
)
print(result["response"])
asyncio.run(main())
Native graph adapter — to_lang_graph()
Converts a resolve_graph() result into a framework-native LangGraph StateGraph. Pre-order traversal (root → leaves) builds a compiled StateGraph. Single-child edges become direct edges after a tool loop; multi-child edges use Command-returning handoff tools (bound with parallel_tool_calls=False) so the model picks exactly one target.
import asyncio
from launchdarkly_ai_server import resolve_graph
from launchdarkly_ai_langchain_agents import to_lang_graph
async def main():
ctx = {"kind": "user", "key": "user-123"}
result = await to_lang_graph(
resolve_graph("support-graph", context=ctx),
{
"tool_handlers": registry.tools,
"context": ctx,
# optional: supply your own model per node
"model_factory": lambda node: ChatOpenAI(model=node["config"]["model"]["name"]),
},
).invoke("I was double charged")
print(result["response"])
asyncio.run(main())
How It Works
- Uses the system prompt and conversation history defined in your LaunchDarkly flag config.
- Template placeholders (
{{variable}}) in the prompt are substituted usingvariablesbefore the call. - The LangGraph ReAct agent manages the full reasoning and tool-call loop autonomously — reasoning through steps, calling tools, and deciding when to stop.
- Emits an OTel span and LaunchDarkly telemetry for every call.
Choosing Between langchain-agents and langchain-messages
langchain-agents |
langchain-messages |
|
|---|---|---|
| Orchestration | LangGraph StateGraph |
Manual tool loop |
| Reasoning style | ReAct (reason + act cycles) | Single invoke per tool round-trip |
| Best for | Complex multi-step reasoning | Straightforward tool calls |
Environment Variables
| Variable | Description |
|---|---|
OPENAI_API_KEY |
Required when using the default ChatOpenAI model |
LD_SDK_KEY |
LaunchDarkly server-side SDK key |
LD_SERVICE_NAME |
OTel service.name resource attribute (default: python-sdk) |
LD_ENVIRONMENT |
deployment.environment attribute attached to telemetry |
OTEL_EXPORTER_OTLP_ENDPOINT |
OTLP endpoint override (default: LaunchDarkly Observability backend) |
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file launchdarkly_ai_langchain_agents-0.1.4.tar.gz.
File metadata
- Download URL: launchdarkly_ai_langchain_agents-0.1.4.tar.gz
- Upload date:
- Size: 24.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b047d454f01a8fcceb23876a6afa0ee92d68e6e1250f67246964068bd3fbb0b7
|
|
| MD5 |
4e11311e145ae962fbf41ee678805947
|
|
| BLAKE2b-256 |
08c1bf79d0ae3fb9ac74bfab49e641e89c3df89a273ef79b0089de5ef6c3660e
|
File details
Details for the file launchdarkly_ai_langchain_agents-0.1.4-py3-none-any.whl.
File metadata
- Download URL: launchdarkly_ai_langchain_agents-0.1.4-py3-none-any.whl
- Upload date:
- Size: 11.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
210719d320e83cffbc512a990aa218ab017fddeddec4e6743c94abda2f3edb19
|
|
| MD5 |
837c1ccc45591192bbe695f2cabf9bf7
|
|
| BLAKE2b-256 |
d3ac5d94bd3b27aa61277c001825e068944f0dc2eeecf9e9aae0cc5668bf4d1d
|