An OpenAI Agents SDK agent is a loop: the model picks a tool, the tool runs, the result goes back to the model, repeat until done. That loop is exactly where a crash hurts most — die on step seven of a ten-step run and, without durability, you restart at step one and re-pay for every token you already spent. Temporal's Python SDK now ships an official integration that makes the loop crash-proof without asking you to abandon the Agents SDK. Here's the whole setup.

The mental model: workflow vs activity#

Temporal's one rule governs everything: deterministic orchestration goes in a workflow, non-deterministic work goes in an activity. A workflow is replayed from saved history to recover, so it can't call time.now(), generate randomness, or hit the network directly — do that and replay diverges. An activity is the opposite: it's where model calls, tool calls, and I/O live, and its result is memoized so a completed activity is never re-run.

For an agent, that maps cleanly. The agent loop is orchestration — it lives in the workflow. Each tool and the model invocation touch the outside world — they're activities. The integration's job is to let the Agents SDK's Runner drive that loop while Temporal persists every step underneath it.

Step 1: define a tool as an activity#

Nothing exotic — a tool is just an @activity.defn:

from datetime import timedelta
from temporalio import activity, workflow
from temporalio.contrib import openai_agents
from agents import Agent, Runner

@activity.defn
async def get_weather(city: str) -> str:
    return f"{city}: 14-20C, sunny"

Step 2: run the agent inside a workflow#

The Runner.run() call you already have moves into a @workflow.defn class. Each tool is handed to the agent through activity_as_tool(), which wraps the activity as a normal SDK tool the model can call — with a Temporal timeout attached:

@workflow.defn
class WeatherAgent:
    @workflow.run
    async def run(self, question: str) -> str:
        agent = Agent(
            name="Weather Assistant",
            instructions="You are a helpful weather agent.",
            tools=[
                openai_agents.workflow.activity_as_tool(
                    get_weather, start_to_close_timeout=timedelta(seconds=10)
                )
            ],
        )
        result = await Runner.run(starting_agent=agent, input=question)
        return result.final_output

Read that carefully: the Agent and Runner.run are the Agents SDK's own API, unchanged. What's new is where they run — inside a workflow method — and that the tool is an activity. There is no TemporalRunner wrapper; secondary write-ups that mention one are describing an older shape. You use the SDK's runner directly.

Step 3: wire the plugin on client and worker#

The last piece is registering OpenAIAgentsPlugin so Temporal knows to route model and tool calls through activities. You add it once when you build the client and the worker; from then on the integration handles the plumbing.

The payoff is a single property: kill the worker mid-run and a fresh one replays the history to the last completed step. The model output you already got back is reused, not re-requested. Your token bill doesn't restart from zero.

That's the difference between a demo agent and one you can leave running against a real workload — the same durability argument we made when we put Temporal against Inngest and Restate, only now the agent framework snaps into it directly.

What to watch#

Two sub-features aren't GA. Streaming is flagged Experimental and OpenTelemetry export is Public Preview — fine to try, not something to hard-depend on in production yet. Gate them behind a flag and lean on the durable-run path, which is the mature part.

And keep the workflow-vs-activity discipline honest: any wall-clock read, random value, or direct network call in the workflow body will break replay. If a tool needs it, it belongs in an activity. That's the same replay trap that catches people resuming crashed agents, and it's the one rule worth tattooing on the back of your hand.

If you're weighing whether to run a whole orchestration server for this at all, we compared Temporal against DBOS — a Postgres library you pip install versus a cluster you run beside your app — and surveyed the durable-execution engines built for agents more broadly. But if you're already committed to the Agents SDK and you want the loop to survive a bad deploy, this integration is the shortest path: tools as activities, Runner.run in a workflow, plugin on the worker, done.