Skip to content

fix(AIC-3382): support Bedrock configs in LangChain handlers - #101

Merged
andrewklatzke merged 4 commits into
mainfrom
aklatzke/AIC-3382/langchain-bedrock-fixes
Sep 18, 2026
Merged

andrewklatzke merged 4 commits into
mainfrom
aklatzke/AIC-3382/langchain-bedrock-fixes

Conversation

@andrewklatzke

@andrewklatzke andrewklatzke commented Sep 18, 2026

Copy link
Copy Markdown
Contributor

Summary

Three fixes for LangChain handlers (langchain-agents and langchain-messages):

  • Bedrock configs with no explicit llm now instantiate langchain_aws.ChatBedrockConverse instead of falling through to ChatOpenAI. Model parameters and the region-prefixed model ID are forwarded. If langchain-aws is unavailable, the handler raises a clear error with the required install command.
  • For Bedrock, model.region is prepended to the model ID as an inference-profile prefix. Prefixing is idempotent and applies to default constructors and user-supplied factories without mutating the caller's config.
  • gen_ai.provider.name now reports the configured provider lower-cased rather than collapsing non-Anthropic providers to OpenAI. gen_ai.system remains langchain.

Test plan

  • Unit tests for both LangChain handlers, including Bedrock default construction, region prefixing, missing-package errors, and factory config handling
  • Cross-handler parity suite
  • Integration scenarios for success and failure paths
  • Ruff and type checks

Jira: AIC-3382


Note

Overview
LangChain handlers (langchain-agents, langchain-messages) now treat Bedrock as a first-class default provider: missing llm builds ChatBedrockConverse (requires langchain-aws), resolves model.region into an idempotent inference-profile prefix on the model id, and passes that via a non-mutating shallow config copy to default constructors and user factories. Bedrock constructor kwargs drop tools from model.parameters so tool wiring stays on the handler path.

Telemetry changes: gen_ai.provider.name is the configured provider name lower-cased (empty → openai), not the previous anthropic-vs-openai collapse; gen_ai.system stays langchain.

The streaming example prints the final response when no chunk events arrived, and adds trailing newline formatting after usage/judge output.

Reviewed by Cursor Bugbot for commit 221c23f. Bugbot is set up for automated code reviews on this repo. Configure here.

Apply inference-profile prefixes before model construction and report the configured provider so Bedrock calls and telemetry stay aligned.

Co-authored-by: Cursor <cursoragent@cursor.com>
Route Bedrock configs through ChatBedrockConverse so callers no longer need to provide a custom model factory.

Co-authored-by: Cursor <cursoragent@cursor.com>
See TELEMETRY-CONTRACT.md section 9.
"""
provider = str((config.get("provider") or {}).get("name") or "").lower()
return "anthropic" if provider == "anthropic" else "openai"

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Not sure where this came from but obviously no bueno - uses the provider name from the config now

Prevent payload-owned tool definitions from leaking into ChatBedrockConverse constructor arguments while preserving the evaluated config.

Co-authored-by: Cursor <cursoragent@cursor.com>
Comment thread examples/streaming.py
print("Usage:", json_pretty(event.get("usage")))
if event.get("judgeResults"):
print("Judge results:", json_pretty(event["judgeResults"]))
sys.stdout.write("\n")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The TS version writes the response as a fallback if no chunk was output, did we want to do the same in this example?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Should be aligned now

@andrewklatzke

Copy link
Copy Markdown
Contributor Author
Screenshot 2026-09-18 at 1 06 30 PM

Confirmed langchain on bedrock in the sample app

Keep the streaming example aligned with TypeScript when a provider emits only a final event.

Co-authored-by: Cursor <cursoragent@cursor.com>
andrewklatzke added a commit to launchdarkly/js-ai-sdk that referenced this pull request Sep 18, 2026
## Summary

TypeScript counterpart to launchdarkly/python-ai-sdk#101. Three fixes
for LangChain handlers (`langchain-agents` and `langchain-messages`):

- Bedrock configs with no explicit `llm` now instantiate
`@langchain/aws`'s `ChatBedrockConverse` instead of falling through to
`ChatOpenAI`. Model parameters and the region-prefixed model ID are
forwarded. `@langchain/aws` is an optional peer dependency, with a clear
install error when absent.
- For Bedrock, `model.region` is prepended to the model ID as an
inference-profile prefix. Prefixing is idempotent and applies to default
constructors and user-supplied factories without mutating the caller's
config.
- `gen_ai.provider.name` now reports the configured provider lower-cased
rather than collapsing non-Anthropic providers to OpenAI.
`gen_ai.system` remains `langchain`.

The streaming example also falls back to the final response when no
chunk events are emitted.

## Test plan

- [x] Unit tests for both LangChain handlers, including Bedrock default
construction, region prefixing, and factory config handling
- [x] Integration scenarios for success and failure paths
- [x] Biome and TypeScript checks

Jira: AIC-3382

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Overview**
> Adds **AWS Bedrock** as a first-class default model path for the
`langchain-agents` and `langchain-messages` handlers: Bedrock configs
without a custom `llm` now build `ChatBedrockConverse` via dynamic
`@langchain/aws` import (optional peer; clear error if missing).
> 
> **Bedrock model IDs** get `model.region` prepended once as an
inference-profile prefix (`us.model…`), without double-prefixing or
mutating the caller’s config; factories receive a shallow copy with the
resolved name. Bedrock constructor args **drop `tools` from
`model.parameters`** so tool wiring stays on the agent/handler side.
> 
> **OpenTelemetry** `gen_ai.provider.name` is now the configured
provider name lower-cased (empty → `openai`), not only `anthropic` vs
`openai`; `gen_ai.system` stays `langchain`.
> 
> The **streaming example** prints the final `response` when no chunk
events arrive, and logs usage/judge results on stdout instead of stderr
debug noise.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
fc1079d. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
@andrewklatzke
andrewklatzke merged commit 04a67c7 into main Sep 18, 2026
7 checks passed
@andrewklatzke
andrewklatzke deleted the aklatzke/AIC-3382/langchain-bedrock-fixes branch September 18, 2026 21:24
@github-actions github-actions Bot mentioned this pull request Sep 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants