Skip to content

feat(agentcore): Bedrock Anthropic-Messages transport + buyer→seller runtime prox - #134

Open
rkmaws wants to merge 3 commits into
IABTechLab:mainfrom
rkmaws:buyer-mr1-transport
Open

rkmaws wants to merge 3 commits into
IABTechLab:mainfrom
rkmaws:buyer-mr1-transport

Conversation

@rkmaws

@rkmaws rkmaws commented Sep 22, 2026

Copy link
Copy Markdown
Contributor

Summary

Additive AgentCore transport foundation for the buyer: Claude on Bedrock via the
Anthropic Messages endpoint, the buyer→seller AgentCoreSellerProxy
(InvokeAgentRuntime + MCP over the OpenDirect surface), and deploy parity.

Changes

  • LLM transport: Messages endpoint + crewai_bedrock_anthropic_fix.py
    strict-strip; max_completion_tokens for GPT-5.x / o-series models.
  • Seller proxy: new interfaces/agentcore/agentcore_seller_proxy.py presenting
    the OpenDirect method surface over InvokeAgentRuntime; crew_tools wiring.
  • Deploy parity: auth-agentcore.yaml reference, deploy.sh, requirements.

Testing

Unit suites green (llm, agent-hierarchy, settings-lazy-init, seller-proxy);
integration test_runtime.py extended.

Base: IABTechLab/buyer-agent:main.

Ranjith Krishnamoorthy added 3 commits September 19, 2026 22:12
Wire the deployed buyer crew to a deployed seller by ARN, and close the
remaining gaps between the ECS and AgentCore runtimes for the buyer.

Buyer -> seller integration (AgentCoreSellerProxy):
- New OpenDirect-shaped proxy backed by bedrock-agentcore:InvokeAgentRuntime
  against the seller MCP runtime. Issues MCP tools/call over the
  Streamable-HTTP transport with the required Accept/contentType/protocol
  headers and the initialize -> notifications/initialized handshake, threads
  Mcp-Session-Id for microVM stickiness, and parses SSE-framed results.
  Maps structured seller products to OpenDirect via the shared wire mapper.
- crew_tools: use the proxy for the ARN seller case (was a localhost stub).
- New CFN stack infra/aws/agentcore/auth-agentcore.yaml: CFN-owned buyer
  runtime execution role with a scoped runtime/a4a_aamp_seller_* invoke
  wildcard, restricted to same-account / trusted cross-account (cross-org
  uses the gateway + CUSTOM_JWT path). deploy.sh deploys it and passes the
  role via `agentcore configure --execution-role`.

AgentCore deploy parity fixes (deploy.sh / requirements.txt):
- Add PYTHONPATH=/app/src so ad_buyer is importable in the runtime image.
- Default the LLM + memory models to Bedrock Claude Sonnet (was nova-pro /
  nova-lite), matching settings.py and the Bedrock migration.
- Pin crewai>=1.14.4,<2.0.0 (was ==1.10.1) to match pyproject.toml; the
  Bedrock fix patch and DealBookingFlow rely on CrewAI >=1.14.

Tests:
- Unit: tests/unit/agentcore/test_agentcore_seller_proxy.py (11) covering MCP
  result parsing/mapping, required MCP headers, the initialize handshake
  ordering + initialize-once, and SSE-framed response parsing.
- Integration: tests/integration/agentcore/test_runtime.py adds
  TestBuyerSellerIntegration (deployed buyer->seller loop asserts real
  seller inv-* inventory via CloudWatch); raise invoke timeouts for the real
  crew runtime on Claude.
- Fix test_agent_hierarchy temperature assertions to be model-aware:
  build_llm correctly omits temperature for Claude families that reject it
  (e.g. claude-sonnet-5), so assert the tuned value only when the configured
  model accepts temperature.

All three buyer runtime integration tests + the buyer->seller loop verified
live (real inv-* inventory reaches the buyer through the proxy).
…point

Route CrewAI's LLM calls through Amazon Bedrock's Anthropic-compatible
(Messages) endpoint instead of the Converse provider, and retire Amazon
Nova as the default model.

Motivation
----------
The Converse path required a monkey-patch (patches/crewai_bedrock_fix.py)
to strip orphaned toolUse/toolResult blocks. Bedrock's Anthropic Messages
endpoint (bedrock-runtime .../anthropic) assembles tool turns itself, so
that class of ValidationException does not arise. Nova Pro is being
deprecated; current-generation Claude tiers (Sonnet 5, Haiku 4.5) are
served on the Messages API.

Changes
-------
- llm.build_llm: add an Anthropic-Messages-compatible base_url branch,
  selected via ANTHROPIC_COMPATIBLE_LLM_API_BASE_URL. Takes precedence
  over the OpenAI-compatible branch so Claude is never misrouted to the
  OpenAI client (Claude is not served on Bedrock's Chat Completions).
- settings: add anthropic_compatible_llm_api_{base_url,key}; default
  model anthropic/claude-sonnet-4-5 -> anthropic/claude-sonnet-5.
- http_main: apply the Converse sanitizer only on the legacy Converse
  path (bedrock/ model + no Messages base URL); on the Messages path
  apply the new strict-strip patch instead.
- patches/crewai_bedrock_anthropic_fix.py (new): strip the tool "strict"
  field that CrewAI (>=1.15) emits, which Bedrock's Anthropic endpoint
  rejects (tools.0.custom.strict: Extra inputs are not permitted). Scoped
  to Bedrock base URLs only; real Anthropic is unchanged.
- agentcore memory patch + crew_tools fallback: Nova -> Claude Haiku 4.5.
- infra/aws/agentcore/deploy.sh: source .env; default to Sonnet 5 /
  Haiku 4.5 via the Messages endpoint; set PYTHONPATH=/app/src so the
  package resolves under the toolkit's module entrypoint.
- infra/aws/agentcore/requirements.txt: align crewai with pyproject
  (>=1.14.4) and add iab-agentic-primitives via a git-free archive URL
  (the build image has no git binary).
- .env.example: document the Messages-endpoint configuration.

Compatibility
-------------
Backward-compatible: the Converse provider and its patch remain available
for anyone using a bedrock/ Converse model. Removing the Converse patch
entirely is deferred to a follow-up change.

Testing
-------
- Unit + mocked integration: 3462 passed.
- Live AgentCore integration (deployed dev runtime): 4/4 passed
  (chat + three crew-plan invocations).
OpenAI's newer models (GPT-5.x, o1/o3/o4 reasoning models) reject the
legacy max_tokens parameter on Bedrock's OpenAI-compatible endpoint with
"400 invalid_request_error: Unsupported parameter: 'max_tokens' is not
supported with this model." They take max_completion_tokens instead.

build_llm now routes the token cap to max_completion_tokens for those
model families (matched as substrings so Bedrock inference-profile ids like
us.openai.gpt-5.6-sol and raw ids like gpt-5/o1 are covered) and keeps
max_tokens for everything else (gpt-4o, Claude, Nova, ...).

Surfaced while running the buyer crew against a Bedrock OpenAI (GPT-5.6)
model to validate the "any model on Bedrock" path; with the fix the GPT
crew invoke completes cleanly. Adds regression tests for the helper and the
build_llm parameter routing.

This branch has not been deployed

No deployments
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.

1 participant