Framework Support
View as MarkdownEvery agent framework runs on the same session Flow through its own adapter. Pick your framework to see how its turn maps onto Steps, which session features it has, and its limits.
How your framework runs a turn
Most adapters stop the framework before a tool runs, so each tool call runs in its own Step, in parallel: CallTool for a read or an idempotent write, CallSingleAttemptTool for any other write. A call that needs approval waits in AwaitToolApproval first. The next RunModel gives the framework the recorded results, so no tool runs again. A turn that looks up an order runs RunModel, CallTool, ResumeTurn, and RunModel. The Claude Agent SDK is the exception: it runs reads inside RunModel.
The tabs show how each framework is stopped and resumed, and where a framework differs.
- Claude Agent SDK
- Google ADK
- LangChain and LangGraph
- Mastra
- OpenAI Agents SDK
- Pydantic AI
- Vercel AI SDK
The Claude Agent SDK runs Claude Code as an agent. Its agent loop runs in the Claude Code CLI, a subprocess of the Worker. The Dex adapter runs that loop inside a durable session. It is available for Python and TypeScript.
When to use it
Use it when you want the Claude Code agent loop, its context management, and its tools. Use it when your agent already uses the Claude Agent SDK.
Use the built-in agent loop when you want one model call per Step, parallel tool Steps, or Dex compaction.
How a session runs
Claude Code runs a whole turn, so the adapter splits a turn into segments. One RunModel Step runs the CLI for one segment. Model calls run inside the segment. So do read tools: a deferred read would restart the CLI. A Connector tool call is the exception: it always leaves the segment, even a read. See Connect Connectors.
A write tool call ends the segment. It waits in AwaitToolApproval when it needs approval. Then it runs in its own Step: CallTool for an idempotent write, CallSingleAttemptTool for any other write. ResumeTurn then returns to RunModel, which resumes the same Claude session. The CLI gets the recorded result and does not run the tool again.
A failed segment retries, up to three attempts, and reruns whole. Model calls and reads inside it run again. A write that ran in its own Step does not run again when the segment retries.
A turn that looks up an order runs one RunModel Step. A turn that cancels an order runs RunModel, AwaitToolApproval, CallSingleAttemptTool, ResumeTurn, and RunModel.
Google ADK, the Agent Development Kit, builds agents and multi-agent trees for Gemini and other models. The Dex adapter runs an ADK agent inside a durable session. It is available for Python.
When to use it
Use it when your agent already uses Google ADK, including sequential, loop, and parallel agents. Keep the agent tree and its tools, and let Dex own the session.
How a session runs
The adapter adds a plugin to the ADK App. For each tool call, the plugin asks ADK for a confirmation, so ADK pauses before the tool runs. Each RunModel Step makes one model call and stores the turn's ADK events.
The tool Step runs the tool once. The next RunModel confirms the paused calls, and the plugin returns the recorded results instead of running the tools again.
LangChain create_agent builds a tool-calling agent on LangGraph. The Dex adapter runs a create_agent agent or a custom LangGraph graph inside a durable session. It is available for Python.
When to use it
Use it when your agent already uses LangChain create_agent or a LangGraph graph. Keep the graph, its middleware, and its tools, and let Dex own the session.
How a session runs
DurableToolCallMiddleware stops each tool call with a LangGraph interrupt, so no tool runs inside RunModel. The RunModel Step runs the graph to its next tool calls, usually with one model call, and stores the graph checkpoint.
The tool Step validates the arguments and calls the tool once. The next RunModel restores the checkpoint and resumes the graph with the recorded results.
A custom graph builds its tool node with durable_tool_node instead of ToolNode. Its state must hold the conversation as LangChain messages.
Mastra is a TypeScript framework for agents, tools, and workflows. The Dex adapter runs a Mastra agent inside a durable session. It is available for TypeScript.
When to use it
Use it when your agent already uses Mastra. Keep the agent, its tools, and its model router, and let Dex own the session.
How a session runs
Every agent tool, read tools included, goes to Mastra as a client tool. So Mastra stops after the model call with the tool calls. Each RunModel Step makes one model call.
Each tool call runs the agent's original tool once, in its own Step. The next RunModel adds the recorded results and calls the model again.
The OpenAI Agents SDK defines an agent with instructions, function tools, and handoffs. The Dex adapter runs the SDK's runner inside a durable session. It is available for Python and TypeScript.
When to use it
Use it when your agent already uses the OpenAI Agents SDK, with or without handoffs. Keep the SDK's agent definition, tools, and guardrails, and let Dex own the session.
How a session runs
The adapter copies the agent graph once and intercepts every function tool. So the SDK stops right after each model call and returns the tool calls the model asks for. Each RunModel Step makes one model call.
Each function tool call runs in its own Step. The next RunModel restores the SDK's run state and gives it the recorded results. The tool does not run again.
A handoff runs inside RunModel, unlike a function tool, so a Step that hands off also makes the next agent's model call.
Pydantic AI defines a typed agent with tools, dependencies, and output types. The Dex adapter runs a Pydantic AI agent inside a durable session. It is available for Python.
When to use it
Use it when your agent already uses Pydantic AI. Keep the agent, its tools, and its capabilities, and let Dex own the session. The adapter replaces Pydantic AI's own durable execution integrations.
How a session runs
Each RunModel Step runs the agent with a capability that marks every function tool as an external tool. Pydantic AI never runs an external tool, so the run ends right after the model asks for tools.
The tool Step runs the tool once, through the agent, so the agent's tool hooks run there. The next RunModel resumes the run with the recorded results.
The Vercel AI SDK gives TypeScript one API for many model providers, with typed tools. The Dex adapter runs an AI SDK agent definition inside a durable session. It is available for TypeScript.
When to use it
Use it when your TypeScript application already uses AI SDK models and tools. Keep the model, the tools, and stopWhen, and let Dex own the session.
How a session runs
Every tool reaches the model without its execute, so the AI SDK returns the tool calls instead of running them. Each RunModel Step makes one model call with streamText.
Each tool call runs the tool's original execute in its own Step. The next RunModel adds the recorded results, checks stopWhen, and calls the model again.
Features by harness
Some session features depend on the harness:
| Feature | Framework adapters | Built-in agent loop |
|---|---|---|
Queued messages, Steer, and cancel_turn | Yes | Yes |
| Dex compaction of old messages | Yes, except the Claude Agent SDK | Yes |
Questions to the user (ask_user) | No | Yes |
Plans (plan mode and execute_plan) | No | Yes |
Limits
Each tab lists the limits of one adapter that change how you write an agent, with what to do instead.
- Claude Agent SDK
- Google ADK
- LangChain and LangGraph
- Mastra
- OpenAI Agents SDK
- Pydantic AI
- Vercel AI SDK
- One write call per segment leaves the turn. A reply with two writes costs one more segment and model call. The writes of one reply never run as parallel Steps.
- Tools that run inside the CLI, such as Bash or Edit, are at least once. They run again when a segment reruns. Files the CLI changes are not recorded.
- A segment must finish within the
RunModelmethod timeout, 15 minutes by default. Raise it withrun_model_limitin Python orrunModelLimitin TypeScript. - Claude Code compacts its own transcript, and Dex compaction stays off. A long session ends at the state limit, not the context window: the active state of one session, 64 MiB by default (Session limits).
- A recorded tool result keeps text only.
- A write call inside a subagent is denied. The model is asked to call it from the main conversation.
- The App root must be a
BaseAgent. ADK Workflow roots are not supported. - A tool runs outside the ADK run, with a fresh
ToolContext. Its state and artifact changes are discarded. Pass what it needs as arguments. - A tool that asks for a confirmation or a credential inside its Step fails.
- Agents that continue without tools make their model calls in the same
RunModel. - A
before_tool_callbackruns in theRunModelthat requests the call, and again if that Step retries. - Code executors other than
BuiltInCodeExecutorare refused. Run such code from a tool instead. - app: and user: state keys live in the Dex session, not across sessions.
- A graph whose nodes make several model calls before a tool node makes them all in one
RunModel. Summarization middleware and a planner node are examples. A retry repeats them all. - Provider-run tools repeat when
RunModelreruns. - History is append-only. A graph that edits or removes earlier messages does not change the stored history.
- Only the message list survives between turns. Other state keys start from their defaults on every turn; within one turn they survive. Keep a value that must last across turns in a store you own, read through a tool.
- Tools run outside the graph. They cannot use
ToolRuntime,InjectedState, orInjectedStore, and cannot return a graph Command.InjectedToolCallIdworks. - The graph may raise no interrupts of its own.
- Tools Mastra runs itself, such as sub-agents, workflows, and Memory tools, cannot run in a Step. The adapter offers one only when
toolPoliciesnames it as a read without approval. It then runs insideRunModeland repeats when that Step reruns. - The session stores every message and gives the agent the history, in place of Mastra Memory. Leave the Memory thread unset in the agent's defaults and scopes. For memory across sessions, give the agent a tool over a store you own, as What a session remembers describes.
beforeToolCallandafterToolCallhooks run only for tools Mastra runs itself.- A tool result reaches the model as text.
toModelOutputis not applied. - A tool that calls
suspend()fails. Use the session's approval instead. - Tool names must be at most 63 characters of letters, digits, _, and -, and must not start with a digit or -.
- Only function tools get their own Steps. Hosted tools, such as web search, run at the provider during the model call. They repeat when
RunModelreruns. - Tools the SDK runs itself, such as tools of
Agent.mcp_serversand local shell tools, cannot wait for approval. The adapter refuses them by default.-
For an MCP server, pass it through
McpToolSourceintool_sourcesinstead ofmcp_servers. Each of its tools then runs in its own Step with a policy, and a tool markedreadOnlyHintis a read. This function from the quick start example adds an MCP server to the Python quick start agent; openai_agents_mcp.py has the imports:def build_durable_agent_with_mcp(
order_desk: OrderDesk, model: str | Model, mcp_servers: Sequence[McpServerConfig]
) -> AgentSessionFlow:
"""Returns the quick start agent with MCP tools, each call in its own Step.
The servers go through tool_sources, not Agent.mcp_servers, which the
adapter refuses. A tool marked readOnlyHint is a read.
"""
return openai_agents_session_flow(
build_plain_agent(order_desk, model),
flow_type="OpenAIAgentsMcpQuickStart",
tool_policies={
"look_up_order": ToolPolicy(ToolEffect.READ),
"cancel_order": ToolPolicy(ToolEffect.NON_IDEMPOTENT_WRITE),
},
tool_sources=[McpToolSource(mcp_servers)],
) -
Or set
allow_at_least_once_tools=True. Those tools then run insideRunModeland repeat when it retries, so use this only for reads. -
Wrap a write in a function tool to give it its own Step.
-
- Function tool names must be unique across the agent graph. The graph is copied when the Flow is built, so later changes to it do not reach the Flow.
- The session is the history. Do not use server-managed conversation state or SDK sessions. Send each new message with
send_user_message, and the session gives the agent the earlier turns. - An agent used as a tool runs its nested run inside one tool Step in Python. TypeScript rejects it; hand off instead.
- Retries that Pydantic AI sends to the model itself make another model call in the same
RunModelStep. Examples are invalid tool arguments and output that fails validation. - Output functions run inside
RunModeland are at least once. Put a write in a tool instead. - Provider-run tools, such as
WebSearchTool, repeat whenRunModelreruns. - A deferred tool returns text to the model. Images and files are lost.
- A tool that asks for approval only while it runs needs a
ToolPolicywithrequires_approval=True. UsageLimitsand tool retry budgets apply per Step, not per turn.
- A crash in
RunModelreruns that model call and any provider-executed tools in it. - A tool's execute gets
toolCallIdandabortSignal. Its messages are empty and its context is undefined. - Approval belongs to Dex. AI SDK
toolApprovalis not exposed, and aneedsApprovalfunction is rejected. Provider-executed tools never wait for approval. - Every tool runs in Dex, so a tool without execute, such as a browser-side tool, is rejected.
- Tool inputs and outputs must survive JSON.
prepareStep,activeTools, output, and stream transforms are not exposed.
Limits for long sessions has the server limits.
Next
- Built-in Agent Loop: the harness with every session feature.
- Run Agents in Production: the checklist before you run sessions for real users.