diff --git a/examples/langchain_thinking.py b/examples/langchain_thinking.py index 05673df..7718368 100644 --- a/examples/langchain_thinking.py +++ b/examples/langchain_thinking.py @@ -1,10 +1,11 @@ """ Example: langchain_messages() against a Claude model with extended thinking turned on. -With thinking on, Anthropic returns ``content`` as a list of blocks — a ``thinking`` block followed -by a ``text`` block — instead of a plain string. A handler that only reads string content reports -an empty response for these runs while the tokens are still spent, so this example fails loudly -when no text comes back. +Point this at a flag whose ``model.parameters`` enable thinking (and whose ``max_tokens`` +exceeds the thinking budget). Anthropic then returns ``content`` as a list of blocks — a +``thinking`` block followed by a ``text`` block — instead of a plain string. A handler that +only reads string content reports an empty response for these runs while the tokens are still +spent, so this example fails loudly when no text comes back. Anthropic omits thinking from the turn that follows a tool result, so give this a prompt the model can answer on its own — a run that goes through the tool loop ends on a plain string and never @@ -28,10 +29,6 @@ from launchdarkly_ai_langchain_messages import create_langchain_messages_handler from launchdarkly_ai_server import config -# Anthropic requires max_tokens to exceed the thinking budget. -_THINKING_BUDGET_TOKENS = 1024 -_MAX_TOKENS = 4096 - async def run(key: str, user_input: str) -> None: from langchain_anthropic import ChatAnthropic @@ -39,15 +36,9 @@ async def run(key: str, user_input: str) -> None: def build_model(ai_config: Any) -> Any: model = ai_config.get("model") or {} raw = model.get("parameters") - parameters: dict[str, Any] = dict(raw) if isinstance(raw, dict) else {} - return ChatAnthropic( - timeout=None, - stop=None, - **parameters, - model_name=str(model.get("name") or "claude-sonnet-4-5"), - thinking={"type": "enabled", "budget_tokens": _THINKING_BUDGET_TOKENS}, - max_tokens_to_sample=_MAX_TOKENS, - ) + kwargs: dict[str, Any] = dict(raw) if isinstance(raw, dict) else {} + kwargs["model"] = str(model.get("name") or "claude-sonnet-4-5") + return ChatAnthropic(**kwargs) response = await config( key=key, diff --git a/packages/langchain-agents/README.md b/packages/langchain-agents/README.md index 803c037..71599fe 100644 --- a/packages/langchain-agents/README.md +++ b/packages/langchain-agents/README.md @@ -52,8 +52,10 @@ be built after evaluation: ```python handler = create_langchain_agents_handler( lambda config: ChatAnthropic( - model=config["model"]["name"], - **(config["model"].get("parameters") or {}), + **{ + **(config["model"].get("parameters") or {}), + "model": config["model"]["name"], + } ) ) ``` diff --git a/packages/langchain-messages/README.md b/packages/langchain-messages/README.md index 36a9ac9..abe5e2b 100644 --- a/packages/langchain-messages/README.md +++ b/packages/langchain-messages/README.md @@ -48,8 +48,10 @@ be built after evaluation: ```python handler = create_langchain_messages_handler( lambda config: ChatAnthropic( - model=config["model"]["name"], - **(config["model"].get("parameters") or {}), + **{ + **(config["model"].get("parameters") or {}), + "model": config["model"]["name"], + } ) ) ``` diff --git a/uv.lock b/uv.lock index c3e6d32..c1c9677 100644 --- a/uv.lock +++ b/uv.lock @@ -790,7 +790,7 @@ wheels = [ [[package]] name = "launchdarkly-ai-claude-agents" -version = "0.2.1" +version = "0.2.2" source = { editable = "packages/claude-agents" } dependencies = [ { name = "anthropic" }, @@ -809,7 +809,7 @@ requires-dist = [ [[package]] name = "launchdarkly-ai-claude-messages" -version = "0.2.1" +version = "0.2.2" source = { editable = "packages/claude-messages" } dependencies = [ { name = "anthropic" }, @@ -826,7 +826,7 @@ requires-dist = [ [[package]] name = "launchdarkly-ai-langchain-agents" -version = "0.2.1" +version = "0.2.2" source = { editable = "packages/langchain-agents" } dependencies = [ { name = "langchain-core" }, @@ -845,7 +845,7 @@ requires-dist = [ [[package]] name = "launchdarkly-ai-langchain-messages" -version = "0.2.1" +version = "0.2.2" source = { editable = "packages/langchain-messages" } dependencies = [ { name = "langchain-core" }, @@ -862,7 +862,7 @@ requires-dist = [ [[package]] name = "launchdarkly-ai-openai-agents" -version = "0.2.1" +version = "0.2.2" source = { editable = "packages/openai-agents" } dependencies = [ { name = "launchdarkly-ai-server" }, @@ -881,7 +881,7 @@ requires-dist = [ [[package]] name = "launchdarkly-ai-openai-messages" -version = "0.2.1" +version = "0.2.2" source = { editable = "packages/openai-messages" } dependencies = [ { name = "launchdarkly-ai-server" }, @@ -898,7 +898,7 @@ requires-dist = [ [[package]] name = "launchdarkly-ai-python" -version = "0.1.5" +version = "0.1.6" source = { editable = "packages/ai" } dependencies = [ { name = "launchdarkly-ai-server" }, @@ -918,7 +918,7 @@ provides-extras = ["otel"] [[package]] name = "launchdarkly-ai-server" -version = "0.2.1" +version = "0.2.2" source = { editable = "packages/client" } dependencies = [ { name = "opentelemetry-api" },