Skip to content

Integrations

@once.tool works with any framework, since it returns a normal function. The integration helpers add one thing: they take the scope from the framework's own run, thread or session id, so you don't have to wrap each run in once.scope().

framework module extra scope comes from
MCP once.integrations.mcp mcp the MCP session id
LangChain and LangGraph once.integrations.langchain langchain configurable.thread_id
OpenAI Agents SDK once.integrations.openai_agents openai-agents RunConfig.group_id
Pydantic AI once.integrations.pydantic_ai pydantic-ai ctx.conversation_id
CrewAI once.integrations.crewai crewai once.scope() around kickoff()

Every helper is called as once_tool(once, fn, ...) or used as a decorator, @once_tool(once, ...), and takes name, timeout, ttl and verify like @once.tool. Most also take scope_arg, the name of a tool argument to use as the scope instead, such as an order id. Framework objects like the context or config argument are left out of the key.

The openai-agents extra needs openai-agents>=0.8.4 and pydantic-ai needs pydantic-ai-slim>=1.89. Older releases don't expose RunConfig to tools or RunContext.conversation_id, and the helpers would silently fall back to one shared key.

None of these modules import the framework itself, so they import fine without it.

Note

The crewai and openai-agents extras can't be installed in one environment: CrewAI pins openai<3 and the OpenAI Agents SDK needs openai>=3. Use separate environments if you need both.