Use Sync vs Async execution paths with LangGraph
mainThe 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.
| Invocation | Path used | Use Case |
|---|---|---|
agent.invoke(...) | Sync | Scripts, CLI tools, simple applications |
agent.ainvoke(...) / await agent.ainvoke(...) | Async | FastAPI, 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()viaasyncio.to_thread()to prevent the synchronous PaymentManager SDK from blocking the event loop. - Async error callbacks: Automatically awaits
on_payment_errorhandlers if they are defined asasync 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