It has become remarkably easy to give an AI agent capabilities. It's much harder to give one responsibility.
That's because responsibility requires control. LLMs are extraordinarily capable, but they're also inherently unpredictable. If you're going to put one in the path of a real business process — talking to customers, operating production systems, moving money — you need to surround that unpredictability with things that are predictable: policies you can enforce, execution you can rely on, and a history that tells you exactly what happened.
There are already great tools for building agents, but we think they tend toward two extremes. At one end are full-featured harnesses that do a lot for you, but make it difficult to own the controls that matter to your application. At the other are agent SDKs that give you that control, but stop well short of everything you need to run a production agent.
We've been working on a middle ground: something that allows you to keep working with the tools you've already invested in — your inner harness(es) of choice — and adds in a set of capabilities and hook points you can use to bring the controls that are so essential for your business. And underneath these features is something more fundamental: a durable history of what your agent has done. That foundation is what lets us bring reliability and control to an otherwise unpredictable system.
But aren't there already enough harnesses out there?#
I have a lot of sympathy for this position.
We have the likes of Claude (and I use it voraciously!). Claude Code and Cowork are full featured harnesses that manage the agent loop, context, tool calls, sessions, and more. You can extend them with tools, MCP servers, skills, and instructions that shape their behavior. Codex and other agent systems offer similar capabilities.
And for personal agents, this model can get you pretty far. The agent is working for you, in an environment you control. But what if the agent is itself performing some function of your business?
For example, you could specialize such an agent by giving it access to your CRM, inventory, and shipping systems. But now you have a bunch of concerns that go beyond what happens when the agent is acting on behalf of a customer, not you personally. What data can it access? Under what conditions should refunds be reviewed? What does your agent do when infrastructure fails in the middle of processing this customer request?
These aren't details around the edges of your agent. They're the business logic which makes it your agent.
Sure, the behavior of this agent is easy enough to describe through tools, skills, MCP servers and instructions — "Only access information for the customer you are communicating with" — but if you are anything like me, just seeing that instruction is making you a tad uncomfortable. The only way that I feel confident the agent won't break the rules is if the rules are applied in the harness. There are a whole host of concerns that my harness simply must control, including identity, authorization, business invariants, durable state, failure handling, and much more.
This type of agent harness is not designed to allow me to implement these controls.
So you drop down a level and reach for an agent SDK.
The market is filled with many inner harnesses: OpenAI Agents SDK, PydanticAI, LangGraph, AWS Strands, Google ADK, and many, many more. They implement much of the machinery every agent needs: agent loops, model interaction, tool calling, MCP, structured output, tracing, and increasingly some human-in-the-loop primitives. These things are commoditized at this point. You are likely already using one of these (or more than one!) and have developed a level of expertise and comfort with them.
And the good news is there is nothing to stand in the way of you implementing all of the controls we talked about above — it's just code.
But the bad news is that you'll have to build a lot.
That leaves two somewhat unsatisfying choices.
At one extreme, an agent SDK gives you control, but leaves you building a lot of undifferentiated infrastructure yourself.
On the other, a full-featured harness gives you much more out of the box, but you inherit its opinions about how agents execute, maintain state, and exercise authority.
One is too small. The other is too large.
We think that the sweet spot comes via an outer harness that both provides a set of features that can be used to build controls into your business agents, and a model for extending that set of features beyond the baseline. You bring the domain knowledge, processes, policies and controls — we bring the machinery that can help developers bring greater reliability and control to their agents.
That's the direction we're exploring with the Temporal Agent Harness.
The Temporal Agent Harness#
The Temporal Agent Harness sits around the agent SDK you already use and provides the machinery we think most production agents need while giving you full control to bring your own business context and processes.
The project is under active development and evolving quickly, and while we are making it available pretty early in its development lifecycle, we feel we've already nailed some sound principles: make execution durable, meet developers where they already are, provide strong control points and give agents first-class application semantics rather than treating them as fancy chat loops.
Let me tell you about some of the key pieces that are there today.
Durable execution#
We're Temporal, so you probably saw this one coming.
Every agent built with the harness is a Temporal Workflow, which means durability isn't something we've bolted onto individual features, it's foundational and shows up in many parts of the system. An agent can survive worker crashes and deployments, wait minutes or days for something to happen, retry failed model or tool calls according to policy, and resume exactly where it left off without rerunning completed work.
But that durability extends well beyond the capabilities of the inner loop. Outer loops are durable. Tool calls are durable. Waiting for human approval is durable. And, as we'll get to later, even model-generated code and the sandboxes it executes are durable.
For business agents that routinely cross process boundaries, depend on unreliable external systems, and wait on humans, this isn't an edge case. It's table stakes.
Bring your own inner harness#
As we've said, we don't think you need another implementation of the agent loop.
Whether you're already using the OpenAI Agents SDK, PydanticAI, Gemini, or something else, you've probably already made choices about models and agent SDKs. Sometimes those choices might even have been made for you, based on corporate policies or preferred suppliers.
So the Temporal Agent Harness doesn't try to replace this commodity. It extends it.
Today the harness integrates with Gemini, the OpenAI Agents SDK, and PydanticAI, with more to come. The Temporal Agent Harness capitalizes on the wide range of inner harness integrations that already exist, allowing you to program the inner loop while Temporal delivers durability over it.
Controls around tool calls#
Tool calling is where an agent stops reasoning about the world and starts changing it, so it's also one of the most important places to establish control.
The obvious example is approval. You may be happy to let an agent retrieve an order autonomously but require a human before it refunds one. The harness provides a policy layer around tool execution that can make that distinction, pause execution when approval is required, and resume durably when the decision arrives — even if that's hours or days later. Policies can be layered, changed at runtime, scoped to particular tools or sessions, and extended with your own predicates.
self._runner = AgentWorkflowRunner(
config,
stream=WorkflowStream(),
# No approval needed for tools deemed inherently safe.
approval_policy_default=ToolApprovalPolicy.allow_inherently_safe(),
)
Approval is the first implementation of a broader idea: there should be a seam between the model deciding to use a capability and that capability actually executing. That's where your application's controls belong.
Turns, not just agent loops#
The familiar ReAct-style agent loop is useful, but we've moved well beyond problems that can be solved with a singular agentic loop. Agents interact with people. They wait. They receive new information. They will invoke an inner harness several times over the course of a much longer-lived process.
The Temporal Agent Harness therefore introduces a higher-level concept: a turn. A turn invokes the inner harness exactly once, with its inner loop free to execute as many times as needed before reaching a terminal state. But that terminal state doesn't necessarily mean the agent's work is done, it may need more turns to complete its job. The harness stitches turns together, carrying context forward as the larger interaction progresses.
Responding to a customer message is one example of a turn. A customer might ask, "Where is my order?" with the agent looking up the customer and the order, checking its shipping status, and responding, "It shipped yesterday and should arrive Thursday." When the customer replies, "Can I change the delivery address?", that's a new turn, with the agent carrying the context from the previous turn into the next. The Temporal Agent Harness orchestrates those turns as parts of the same long-running agent interaction.
A turn doesn't have to start with a chat message. It might begin when an approval arrives, a timer fires, or an external system provides new information; the Temporal Agent Harness delivers the plumbing that carries context across any number of inner-harness invocations.
Strongly typed agents#
Most agent frameworks naturally gravitate toward an interface that looks like string → string. That's convenient for chat, but limiting when agents become components of applications.
Harness agents can instead expose named, strongly typed operations with typed inputs and outputs. The agent advertises those operations and their schemas, making its interface self-describing and callable programmatically — not just by a person typing into a chat box.
That matters for business agents because your domain already has structure. An incident isn't just some text. Neither is a customer, an order, a remediation request, or the result of a fraud review. Strong typing lets that structure cross the agent boundary without flattening everything into prompts and prose.
It also gives us something else: composition.
Agents compose like software#
Once agents expose typed interfaces, one agent can invoke another through the same kind of contract your application code uses. The harness can expose an agent's operations as a toolset to another agent, allowing you to build multi-agent systems without reducing communication between agents to strings pasted into prompts.
This is an important consequence of treating agents as application components rather than chatbots. You can build a specialized agent, define exactly what it accepts and returns, and then compose it into larger systems.
Durable, secure, and observable code mode#
Tool calling normally asks a model to choose a tool, receive its result, reason again, choose another tool, and repeat. That's a great fit for some problems and unnecessarily expensive and restrictive for others.
Code Mode gives the model another option: write a Python program over a provided set of tools. That program can use normal control flow — loops, conditions, filtering, and concurrency — to orchestrate many tool calls within a single turn.
But here's the important part: we want this Python program to be governed by the policies established through the harness. Rather than treating the sandbox as a black box with security applied at the perimeter, we still want that Python program to be durable, observable, and subject to the approval policies you've defined for your agent.
Tools can run where they need to#
Not every tool can or should run alongside or within the agent. A tool may need to access a file on a user's laptop, a camera on their phone, or a resource inside a private network.
Callback tools support these cases. The agent issues a typed request and durably waits while something performs the function of that tool and returns the result. Like other tools, callback tools participate in the harness's approval, lifecycle, and Durable Execution machinery.
This lets you put capabilities where they belong without changing how the agent invokes or controls them.
These capabilities share a common foundation: a structured event stream that captures the agent's execution as it happens. And that event stream turns out to enable much more than the features we've described so far.
Beyond just features, an agent-native foundation#
An agent isn't just its final answer. It has a trajectory.
It receives a request, the model reasons, it calls a tool, and the result changes its understanding of the problem. It may call another tool, wait three hours for a human, and resume with new information, before eventually producing a result.
The Temporal Agent Harness represents that trajectory as a stream of structured AgentEvents. Turns, model interactions, tool calls and results, approvals, handoffs, responses, and other significant parts of execution all appear in the same stream.
That stream isn't just a record of what happened. It's an interface to the running agent.
Other parts of your application can react to AgentEvents without being embedded in the agent loop. A frontend can render progress. An approval service can react when human input is needed. Another service can kick off downstream work when a tool completes. Analytics, evaluations, and audit systems can all consume the same stream independently.
This gives the harness an event-driven architecture around the agent. The agent can focus on reasoning and acting, while the systems around it evolve, operate, and scale independently. Adding another consumer doesn't require adding another responsibility to the agent itself.
It also gives you a stable boundary across inner harnesses. Whether a turn is driven by OpenAI Agents SDK, PydanticAI, Gemini, or something else, the rest of your application sees the same AgentEvent model.
One particularly snazzy demonstration is that when the trajectory is captured as events, you can play it back.
An execution from yesterday can be rendered as the sequence of turns, model interactions, tool calls, approvals, and responses that actually occurred. You're not asking the model to reconstruct what it thinks happened. You have the events.
That naturally makes the stream valuable for observability, debugging, audit, and evaluation too. When behavior is non-deterministic, the path the agent took is part of the product. You need to understand that path when something fails, when you're improving the agent, or when it makes a consequential decision.
A durable foundation underneath#
For AgentEvent to serve as an architectural pillar, not merely telemetry, it needs to be grounded in the execution itself.
Every agent built with the harness runs as a Temporal Workflow. Temporal uses an event-sourced execution model: the Workflow's Event History durably records the events that drive execution, allowing the Workflow to reconstruct its state and continue after crashes, deployments, outages, or long periods of inactivity.
AgentEvent is built on that durable foundation. The agent's long-running execution and the event stream representing its trajectory aren't separate systems bolted together after the fact.
That matters operationally. An agent can wait hours or days without keeping a process alive. Work can move between workers and resume after failure without starting over. Approvals, callbacks, timers, and other external events can participate naturally in long-running execution. And all of that can happen across a fleet of agents while the services consuming their event streams scale independently.
So AgentEvent isn't an observability feature layered onto the harness. It's part of its architecture: a durable, event-driven interface to agent execution that the rest of your application can build on.
What we're sharing today#
The Temporal Agent Harness is available today in our GitHub repo, along with documentation and a growing collection of examples. It currently integrates with three different inner harnesses — Google Gemini, OpenAI Agents SDK, and PydanticAI — with more to come.
We want to be clear about where this project is: it's early. Earlier than public preview. The APIs will change, there are rough edges, and we're still working through some of the abstractions you've read about in this post. The repository is a way for us to develop this work in the open and give you an early look at, and a voice into where we're headed.
Come build with us#
If the problems in this post sound familiar, we'd love for you to try the harness and tell us where we're getting it right — and where we're not.
Build an agent with it. Push on the abstractions. Tell us what your business agent needs that we haven't accounted for.
In particular, we'd love to hear which inner harnesses you'd like us to support next, what other systems the harness should integrate with — policy engines, identity systems, observability platforms, and more — and where you find yourself dropping beneath our abstractions because they don't give you enough control.
Open an issue in the repo, or come talk to us in the #ai channel in the Temporal Community Slack. And please tell us what you're building. The best way for us to make this useful is to see the real agents people try to build with it.
The trail ahead isn't fully mapped. Help us blaze the trail!