Skip to content
beam-agents
GitHub

Adapters

Which agent frameworks are supported today — LangGraph, Google ADK, and Pydantic AI, plus the reference protocol — and what adopting each costs.

PartialPartly implemented. The page states what is missing.

Agent authoring belongs to frameworks; execution guarantees belong here. That split only works if the adapters exist. Today three do, and each holds a seat on the same conformance matrix.

FrameworkStatus
LangGraphImplemented — src/beam_agents/adapters/langgraph/, langgraph extra
Google ADKImplemented — src/beam_agents/adapters/adk/, adk extra
Pydantic AIImplemented — src/beam_agents/adapters/pydantic_ai/, pydantic-ai extra
Reference protocol agent (a plain async function)Implemented — no adapter needed

Each adapter is an optional extra, imported lazily: without the extra installed, accessing its entry point raises an ImportError naming the extra to install.

Where an adapter sitsThree tiers. The authoring tier holds four ways to write an agent: LangGraph, a plain async function matching the reference protocol, Google ADK, and Pydantic AI. The adapter tier holds three boxes: LangGraphAgent, which supplies the per-activation checkpointer and the tool node; AdkAgent, which supplies the per-key session service and the tool shims; and PydanticAIAgent, which supplies the runtime toolset and message history. The plain async function passes straight down past this tier, needing no adapter. The runtime tier is a single bar, the RunAgent transform, which gives keyed state, the replay cache, intents and per-key ordering to everything above it.AUTHORINGLangGraphIMPLEMENTEDasync functionREFERENCE PROTOCOLGoogle ADKIMPLEMENTEDPydantic AIIMPLEMENTEDADAPTERLangGraphAgentCHECKPOINTER + TOOL NODENO ADAPTER NEEDEDAdkAgentSESSION + TOOL SHIMSPydanticAIAgentTOOLSET + HISTORYRUNTIMERunAgentKEYED STATE, REPLAY CACHE, INTENTS, PER-KEY ORDER
Only the adapter tier is framework-specific. Whatever reaches RunAgent gets the same keyed state, replay cache and intent path — and every registered adapter is held to the same seven lifecycle scenarios before it can claim that.

The LangGraph adapter

Adopting an existing graph takes three changes, none to its topology:

  1. Re-declare side-effectful tools with the runtime decorator: @tool(side_effect=True).
  2. Swap LangGraph's prebuilt ToolNode for BeamToolNode(tools).
  3. Wrap the graph: RunAgent(LangGraphAgent(graph, chat_models=[model])).
def build_agent() -> LangGraphAgent:
    """An ordinary model/tools graph, wrapped rather than rewritten."""
    model = _ChatModel(httpx.MockTransport(_tripwire))
    graph: StateGraph = StateGraph(GraphState)

    async def call_model(state: GraphState) -> GraphState:
        response = await model.root_async_client._client.post(
            "https://provider.example/v1/chat",
            json={"model": "demo", "messages": _to_wire(state["messages"]), "temperature": 0},
        )
        data = response.json()
        if "tool_call" in data:
            return {"messages": [AIMessage(content="", tool_calls=[data["tool_call"]])]}
        return {"messages": [AIMessage(content=data["content"])]}

    def route(state: GraphState) -> str:
        last = state["messages"][-1]
        return "tools" if isinstance(last, AIMessage) and last.tool_calls else END

    graph.add_node("model", call_model)
    # The only topology-adjacent change: BeamToolNode in place of ToolNode.
    graph.add_node("tools", BeamToolNode([page_oncall]))
    graph.add_edge(START, "model")
    graph.add_conditional_edges("model", route, {"tools": "tools", END: END})
    graph.add_edge("tools", "model")

    return LangGraphAgent(graph, chat_models=[model], encode_output=encode_output)
website/examples/langgraph_adapter.py (region: graph) — executed by the repository’s offline test tier.

A user-compiled graph is never mutated — the per-activation checkpointer is injected into a copy.

What the graph gains

Durable keyed checkpoints, side effects behind deduplicated intents, replay-cached model calls, and per-key serialization. interrupt(...) suspends the activation as an approval intent and resumes via Command(resume=...).

One suspension covers all pending graph work: each pending interrupt stages an intent, and re-injected results accumulate — the activation re-suspends, staging nothing new — until every pending intent is answered. The graph then resumes once, from the committed checkpoint.

What to know before relying on it

Two caveats, both documented by the adapter itself:

  • Checkpoints persist latest-only inside working memory, and the 1 MiB per-key cap applies. Long message histories must be trimmed or summarized on the LangGraph side.
  • An interrupted node re-runs from its start when the graph resumes — this is LangGraph's own resume semantics, not something the adapter adds. Code before an interrupt() executes again. Side effects can only live behind intents and model calls are replay-cached, so re-execution is deterministic and cheap, but pre-interrupt node code should be idempotent regardless.
  • Model transport. Recognized httpx-backed chat models are served through the runtime's replay-cached client. An unrecognized one falls back to direct calls with a one-time warning and a transport_fallback metric — so it still works, but without the replay guarantee.

The Google ADK adapter

AdkAgent runs an ADK agent's Runner inside the activation, against a per-key BeamSessionService — the session lives one-per-key under the reserved __adk__/ memory namespace, so it commits and replays with everything else. Side-effect tools become long-running function calls staged as intents, one suspension covers all pending work, the event stream is teed onto the runtime's trace vocabulary, and recognized google-genai clients are routed through the replay-cached model path with a warning fallback for the rest. Installed from the adk extra.

The Pydantic AI adapter

PydanticAIAgent runs one Agent.run segment per activation. Message history persists latest-only under the reserved __pydantic_ai__/ namespace, deferred tool calls map to intents with one suspension covering all of them, and runtime tools ride BeamToolset — read-only tools execute inline, side effects go external, approvals are gated. Recognized httpx-backed models are served through the replay-cached model path, with the same warning fallback as the other adapters. Installed from the pydantic-ai extra.

The conformance matrix

Adapters are not trusted on assertion. Seven lifecycle scenarios run against every registered adapter — the reference protocol agent, LangGraph, Google ADK, and Pydantic AI — across the DirectRunner and Flink legs, and a meta-test audits registry × scenario × leg against the collected cells so the matrix cannot silently shrink. An importable adapter subpackage without a registration fails collection outright.

That is why this page can say "implemented" three times with more confidence than a support table usually deserves.

Not yet implemented

  • Read-only MCP. Named in the module map under tools/; no code.

What backs this page

Symbol
beam_agents.LangGraphAgent
Symbol
beam_agents.AdkAgent
Symbol
beam_agents.PydanticAIAgent
Source
src/beam_agents/adapters/langgraph/agent.py
Source
src/beam_agents/adapters/langgraph/toolnode.py
Source
src/beam_agents/adapters/langgraph/checkpoint.py
Source
src/beam_agents/adapters/adk/agent.py
Source
src/beam_agents/adapters/adk/session.py
Source
src/beam_agents/adapters/adk/tools.py
Source
src/beam_agents/adapters/pydantic_ai/agent.py
Source
src/beam_agents/adapters/pydantic_ai/toolset.py
Source
src/beam_agents/adapters/pydantic_ai/history.py
Source
docs/adapters.md
Specification
openspec/specs/tool-registry/spec.md
Specification
openspec/specs/langgraph-adapter/spec.md
Specification
openspec/specs/pydantic-ai-adapter/spec.md
Specification
openspec/specs/adapter-conformance-matrix/spec.md
Test
tests/adapters/test_e2e_pipeline.py
Test
tests/adapters/adk/test_agent_fast_path.py
Test
tests/adapters/pydantic_ai/test_agent_fast_path.py
Test
tests/conformance/test_matrix.py
Test
tests/conformance/test_adk_registration.py
Example
langgraph_adapter.py

Cited sources

  1. LangGraph is an agent-authoring framework maintained by LangChain.

    https://github.com/langchain-ai/langgraph — retrieved

  2. The Agent Development Kit (ADK) is an agent-authoring framework maintained by Google.

    https://github.com/google/adk-python — retrieved

  3. Pydantic AI is an agent-authoring framework maintained by the Pydantic team.

    https://github.com/pydantic/pydantic-ai — retrieved