Bedrock AgentCore SDK for Python

repository·main·Indexed 20 days ago

https://github.com/aws/bedrock-agentcore-sdk-python

An SDK for deploying and operating AI agents at scale using Bedrock AgentCore. It allows developers to wrap agent frameworks like LangGraph, CrewAI, Strands, or Autogen to offload infrastructure, security, memory, and observability to AWS. The SDK includes support for the AG-UI and A2A protocols, a tool search plugin for semantic discovery, and integration with the AgentCore Evaluation API for assessing agent performance using built-in or custom evaluators.

Tokens
72.5K
Snippets
177
Records
235
Agent score
72%

What's inside bedrock-agentcore

  1. Use Sync vs Async execution paths with LangGraph

    main

    The AgentCorePaymentsMiddleware automatically detects whether you are running a synchronous or asynchronous agent and uses the appropriate execution path (wrap_tool_call or awrap_tool_call). You do not need to manually select a path.

    InvocationPath usedUse Case
    agent.invoke(...)SyncScripts, CLI tools, simple applications
    agent.ainvoke(...) / await agent.ainvoke(...)AsyncFastAPI, Jupyter notebooks, web servers

    Async Path Advantages

    When using ainvoke, the middleware provides:

    • Non-blocking delay: Uses await asyncio.sleep() for blockchain timing delays to avoid blocking the event loop.
    • Threaded signing: Runs generate_payment_header() via asyncio.to_thread() to prevent the synchronous PaymentManager SDK from blocking the event loop.
    • Async error callbacks: Automatically awaits on_payment_error handlers if they are defined as async def.
    # Example: async in FastAPI
    from fastapi import FastAPI
    from langchain.agents import create_agent
    
    app = FastAPI()
    
    @app.post("/chat")
    async def chat(message: str):
        config = AgentCorePaymentsConfig(...)
        payments = AgentCorePaymentsMiddleware(config)
        agent = create_agent(model="claude-sonnet-4-20250514", tools=[], middleware=[payments])
    
        # Uses awrap_tool_call automatically — won't block other requests
        result = await agent.ainvoke({"messages": [{"role": "user", "content": message}]})
        return result
  2. Understand the Ping Status priority and contract

    main

    The agent's PingStatus determines if it is ready for new work. The status is determined by a specific priority order:

    1. Forced Status: Any status set via debug/force methods.
    2. Custom Handler: The logic defined in your @app.ping function.
    3. Automatic: The status derived from active functions decorated with @app.async_task.

    Available Statuses:

    • HEALTHY: Ready for new work.
    • HEALTHY_BUSY: Currently processing; avoid sending new work.
  3. Enable Auto-Session for lazy payment session creation

    main

    By setting auto_session=True in AgentCorePaymentsConfig, the middleware will automatically and lazily create a payment session upon encountering the first 402 response. This session is reused for all subsequent payments within that middleware instance.

    Key configuration options for auto-sessions:

    • auto_session: Set to True to enable.
    • auto_session_budget: A string representing the maximum budget (e.g., "5.00").
    • auto_session_expiry_minutes: Duration in minutes before the session expires.

    Important Lifecycle Note: Create one AgentCorePaymentsMiddleware instance per agent invocation or per user request. The middleware is not thread-safe; sharing an instance across concurrent invocations can cause race conditions during session creation and configuration mutations.

    config = AgentCorePaymentsConfig(
        payment_manager_arn="arn:...",
        user_id="user-1",
        payment_instrument_id="instr-1",
        region="us-east-1",
        auto_session=True,           # enable lazy creation
        auto_session_budget="5.00",  # $5 budget
        auto_session_expiry_minutes=120,  # 2 hours
    )
  4. How the AgentCoreToolSearchPlugin works

    main

    The plugin follows a specific lifecycle during each agent invocation to ensure only relevant tools are loaded:

    1. User query: The user sends a query to the Strands agent.
    2. Hook: The plugin intercepts the process before the model is invoked.
    3. Derive intent: The configured IntentProvider analyzes the conversation history (the last N messages) using an LLM to produce a concise intent string.
    4. Search gateway: The intent string is passed to the AgentCore Gateway's x_amz_bedrock_agentcore_search tool to find the most relevant tools.
    5. Invoke LLM: The agent invokes the LLM with the user query and the tools retrieved from the matched MCP targets (such as Lambda, API Gateway, or MCP Servers).

    Previously loaded tools are cleared before each search to ensure the agent always has the most up-to-date and relevant toolset available.

  5. Attach metadata to AgentCore Memory events

    main

    You can attach metadata to message events to facilitate filtering (e.g., via list_events). Metadata can be applied at three levels:

    1. Default Metadata: Applied to all messages via AgentCoreMemoryConfig(default_metadata=...). Plain strings are automatically wrapped as {"stringValue": "..."}.
    2. Dynamic Metadata: Provided via a metadata_provider callable in AgentCoreMemoryConfig. This is useful for values that change per invocation, like a traceId.
    3. Per-call Metadata: Passed directly to session_manager.create_message(...). Per-call values override both default and provider values.

    Constraints:

    • Maximum of 15 total metadata key-value pairs per event.
    • stateType and agentId are reserved for internal use.
    # Default Metadata
    config = AgentCoreMemoryConfig(
        memory_id=MEM_ID,
        session_id=SESSION_ID,
        actor_id=ACTOR_ID,
        default_metadata={"project": "atlas", "env": "production"},
    )
    
    # Dynamic Metadata
    def get_trace_metadata():
        return {"traceId": "some-dynamic-id"}
    
    config_dynamic = AgentCoreMemoryConfig(
        memory_id=MEM_ID,
        session_id=SESSION_ID,
        actor_id=ACTOR_ID,
        metadata_provider=get_trace_metadata,
    )
    
    # Per-call Metadata
    session_manager.create_message(
        session_id, agent_id, message,
        metadata={"priority": "high"},
    )
  6. How the x402 Payment Flow works

    main

    The plugin automates the handling of HTTP 402 (Payment Required) responses using the x402 Payment Required protocol.

    The workflow is as follows:

    1. An agent calls a tool (like http_request) that hits a paid API.
    2. The API returns an HTTP 402 response containing x402 payment requirements.
    3. The plugin's after_tool_call hook intercepts this response.
    4. The plugin extracts the requirements and calls PaymentManager.generate_payment_header() to process the payment.
    5. The plugin applies the resulting payment header to the tool input.
    6. The tool is automatically retried with the new payment credentials, allowing the API to return a successful response to the agent.
  7. Understand BedrockAgentCore async status and task values

    main

    When monitoring the async status of a BedrockAgentCore instance, the following values and fields are used to represent the system state:

    Status Values

    • Healthy: No active tasks are running; the system is ready for work.
    • HealthyBusy: Tasks are currently running, or the status has been manually forced to busy.

    Task and Status Metadata

    • active_count: The number of currently running asynchronous tasks.
    • running_jobs: A list containing details of each active task (e.g., name, duration).
    • time_of_last_update: A Unix timestamp indicating when the status last changed.

    Expected Lifecycle

    1. The server starts in a Healthy state.
    2. Initiating background tasks automatically transitions the status to HealthyBusy.
    3. Manual status forcing (via debug actions) overrides automatic detection.
    4. Multiple concurrent tasks are tracked and reflected in the active_count and running_jobs fields.
  8. Understand payment retry limits and failure detection

    main

    The AgentCorePaymentsPlugin implements specific safety limits to prevent infinite loops and excessive spending:

    • Retry Limits: The plugin enforces a maximum of 3 payment retry attempts per tool use and a configurable maximum of 5 interrupt retries. Note that interrupt retry limits do not gate 402 payment processing.
    • Post-Payment Failure Detection: If a 402 response is received after a payment retry has already been attempted (e.g., due to an invalid signature or insufficient balance), the plugin treats this as a non-retryable error and propagates it as an interrupt instead of retrying again.
    • Session Limits: Payment sessions have configurable spending limits and expiry times (15–480 minutes). You can monitor budgets using the get_payment_session tool to avoid InsufficientBudget errors.
  9. Concept: BedrockCallContextBuilder

    main

    The BedrockCallContextBuilder is the default context builder used by build_a2a_app and serve_a2a. It extracts Bedrock runtime headers from incoming requests and propagates them into BedrockAgentCoreContext contextvars.

    Extracted Headers:

    • X-Amzn-Bedrock-AgentCore-Runtime-Session-Id: session ID
    • X-Amzn-Bedrock-AgentCore-Runtime-Request-Id: request ID (auto-generated UUID if missing)
    • WorkloadAccessToken: workload access token
    • OAuth2CallbackUrl: OAuth2 callback URL
    • Authorization: authorization header
    • X-Amzn-Bedrock-AgentCore-Runtime-Custom-*: custom headers
  10. Understand Payment Control Plane vs. Data Plane test coverage

    main

    The integration tests are divided into two main functional areas:

    TestPaymentControlPlaneClient (Control Plane)

    Focuses on CRUD operations for managing the payment infrastructure:

    • Creating and retrieving payment managers
    • Listing and updating payment managers
    • Creating and retrieving payment connectors
    • Listing and updating payment connectors
    • Completing the full payment setup workflow

    TestPaymentClientDataPlane (Data Plane)

    Focuses on runtime payment operations for users:

    • Creating and retrieving payment instruments
    • Listing payment instruments for a user
    • Creating, retrieving, and deleting payment sessions
    • Processing payment transactions
    • End-to-end workflows (instrument $\rightarrow$ session $\rightarrow$ payment)
    • Verifying idempotency using client tokens
  11. How Bedrock AgentCore Memory components work together

    main

    The memory system follows a hierarchical structure to manage conversational data:

    • Memory: The top-level container for all data.
    • Actor: Represents an individual user or entity.
    • Session: A specific conversation context within an actor.
    • Events: Individual conversation turns or actions within a session.
    • Branches: Alternative conversation paths (e.g., for A/B testing or exploring different dialogue flows).

    To interact with this hierarchy, use the following recommended classes:

    • MemorySessionManager: The primary entry point for managing multiple sessions and actors.
    • MemorySession: A session-scoped interface that simplifies operations by automatically handling memory_id, actor_id, and session_id parameters.
  12. How the Bedrock AgentCore payments architecture works

    main

    The payments system uses a hierarchical structure to manage credentials, vendors, and user spending context:

    1. PaymentClient (Control Plane): Used to create and manage the underlying infrastructure like managers and connectors.
    2. Payment Manager: The top-level data plane resource that orchestrates operations like creating instruments and sessions.
    3. Payment Connector: Links a PaymentManager to a specific vendor's Payment Credential Provider (e.g., Coinbase or Stripe).
    4. Payment Credential Provider: Securely stores vendor-specific API keys and secrets.
    5. Payment Instrument: A user's registered payment method (like an embedded crypto wallet) created via a connector.
    6. Payment Session: A time-bounded context that defines spending limits for a user.