Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 51 additions & 60 deletions temporalio/contrib/openai_agents/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
⚠️ **Public Preview** - The interface to this module is subject to change prior to General Availability.
We welcome questions and feedback in the [#python-sdk](https://temporalio.slack.com/archives/CTT84RS0P) Slack channel at [temporalio.slack.com](https://temporalio.slack.com/).


## Introduction

This integration combines [OpenAI Agents SDK](https://github.com/openai/openai-agents-python) with [Temporal's durable execution](https://docs.temporal.io/evaluate/understanding-temporal#durable-execution).
Expand All @@ -14,14 +13,14 @@ Temporal provides a crash-proof system foundation, taking care of the distribute
OpenAI Agents SDK offers a lightweight yet powerful framework for defining those agents.

This document is organized as follows:
- **[Hello World Durable Agent](#hello-world-durable-agent).** Your first durable agent example.
- **[Background Concepts](#core-concepts).** Background on durable execution and AI agents.
- **[Full Example](#full-example)** Running the Hello World Durable Agent example.
- **[Tool Calling](#tool-calling).** Calling agent Tools in Temporal.
- **[Feature Support](#feature-support).** Compatibility matrix.

The [samples repository](https://github.com/temporalio/samples-python/tree/main/openai_agents) contains examples including basic usage, common agent patterns, and more complete samples.
- **[Hello World Durable Agent](#hello-world-durable-agent).** Your first durable agent example.
- **[Background Concepts](#core-concepts).** Background on durable execution and AI agents.
- **[Full Example](#full-example)** Running the Hello World Durable Agent example.
- **[Tool Calling](#tool-calling).** Calling agent Tools in Temporal.
- **[Feature Support](#feature-support).** Compatibility matrix.

The [samples repository](https://github.com/temporalio/samples-python/tree/main/openai_agents) contains examples including basic usage, common agent patterns, and more complete samples.

## Hello World Durable Agent

Expand Down Expand Up @@ -54,7 +53,6 @@ The `@workflow.defn` annotation on the `HelloWorldAgent` indicates that this cla
We use the `Agent` class from OpenAI Agents SDK to define a simple agent, instructing it to always respond with haikus.
We then run that agent, using the `Runner` class from OpenAI Agents SDK, passing through `prompt` as an argument.


We will [complete this example below](#full-example).
Before digging further into the code, we will review some background that will make it easier to understand.

Expand All @@ -70,13 +68,13 @@ In the OpenAI Agents SDK, an agent is an AI model configured with instructions,

We describe each of these briefly:

- *AI model*. An LLM such as OpenAI's GPT, Google's Gemini, or one of many others.
- *Instructions*. Also known as a system prompt, the instructions contain the initial input to the model, which configures it for the job it will do.
- *Tools*. Typically, Python functions that the model may choose to invoke. Tools are functions with text-descriptions that explain their functionality to the model.
- *MCP servers*. Best known for providing tools, MCP offers a pluggable standard for interoperability, including file-like resources, prompt templates, and human approvals. MCP servers may be accessed over the network or run in a local process.
- *Guardrails*. Checks on the input or the output of an agent to ensure compliance or safety. Guardrails may be implemented as regular code or as AI agents.
- *Handoffs*. A handoff occurs when an agent delegates a task to another agent. During a handoff the conversation history remains the same, and passes to a new agent with its own model, instructions, tools.
- *Context*. This is an overloaded term. Here, context refers to a framework object that is shared across tools and other code, but is not passed to the model.
- _AI model_. An LLM such as OpenAI's GPT, Google's Gemini, or one of many others.
- _Instructions_. Also known as a system prompt, the instructions contain the initial input to the model, which configures it for the job it will do.
- _Tools_. Typically, Python functions that the model may choose to invoke. Tools are functions with text-descriptions that explain their functionality to the model.
- _MCP servers_. Best known for providing tools, MCP offers a pluggable standard for interoperability, including file-like resources, prompt templates, and human approvals. MCP servers may be accessed over the network or run in a local process.
- _Guardrails_. Checks on the input or the output of an agent to ensure compliance or safety. Guardrails may be implemented as regular code or as AI agents.
- _Handoffs_. A handoff occurs when an agent delegates a task to another agent. During a handoff the conversation history remains the same, and passes to a new agent with its own model, instructions, tools.
- _Context_. This is an overloaded term. Here, context refers to a framework object that is shared across tools and other code, but is not passed to the model.

Now, let's see how these components work together.
In a common pattern, the model first receives user input and then reasons about which tool to invoke.
Expand Down Expand Up @@ -126,23 +124,22 @@ As the program makes progress, Temporal saves key inputs and decisions, allowing

The key to making this work is to separate the applications repeatable (deterministic) and non-repeatable (non-deterministic) parts:

1. Deterministic pieces, termed *workflows*, execute the same way when re-run with the same inputs.
2. Non-deterministic pieces, termed *activities*, can run arbitrary code, performing I/O and any other operations.
1. Deterministic pieces, termed _workflows_, execute the same way when re-run with the same inputs.
2. Non-deterministic pieces, termed _activities_, can run arbitrary code, performing I/O and any other operations.

Workflow code can run for extended periods and, if interrupted, resume exactly where it left off.
Activity code faces no restrictions on I/O or external interactions, but if it fails part-way through it restarts from the beginning.

In the AI-agent example above, model invocations and tool calls run inside activities, while the logic that coordinates them lives in the workflow.
This pattern generalizes to more sophisticated agents.
We refer to that coordinating logic as *agent orchestration*.
We refer to that coordinating logic as _agent orchestration_.

As a general rule, agent orchestration code executes within the Temporal workflow, whereas model calls and any I/O-bound tool invocations execute as Temporal activities.

The diagram below shows the overall architecture of an agentic application in Temporal.
The Temporal Server is responsible to tracking program execution and making sure associated state is preserved reliably (i.e., stored to a database, possibly replicated across cloud regions).
Temporal Server manages data in encrypted form, so all data processing occurs on the Worker, which runs the workflow and activities.


```text
+---------------------+
| Temporal Server | (Stores workflow state,
Expand Down Expand Up @@ -172,17 +169,14 @@ Temporal Server manages data in encrypted form, so all data processing occurs on
[External APIs, services, databases, etc.]
```


See the [Temporal documentation](https://docs.temporal.io/evaluate/understanding-temporal#temporal-application-the-building-blocks) for more information.


## Complete Example

To make the [Hello World durable agent](#hello-world-durable-agent) shown earlier available in Temporal, we need to create a worker program.
To see it run, we also need a client to launch it.
We show these files below.


### File 2: Launch Worker (`run_worker.py`)

```python
Expand Down Expand Up @@ -225,12 +219,12 @@ if __name__ == "__main__":

We use the `OpenAIAgentsPlugin` to configure Temporal for use with OpenAI Agents SDK.
The plugin automatically handles several important setup tasks:

- Ensures proper serialization of Pydantic types
- Propagates context for [OpenAI Agents tracing](https://openai.github.io/openai-agents-python/tracing/).
- Registers an activity for invoking model calls with the Temporal worker.
- Configures OpenAI Agents SDK to run model calls as Temporal activities.


### File 3: Client Execution (`run_hello_world_workflow.py`)

```python
Expand All @@ -257,7 +251,8 @@ async def main():
"Tell me about recursion in programming.",
id="my-workflow-id",
task_queue="my-task-queue",
id_reuse_policy=WorkflowIDReusePolicy.TERMINATE_IF_RUNNING,
id_reuse_policy=WorkflowIDReusePolicy.ALLOW_DUPLICATE,
id_conflict_policy=WorkflowIDConflictPolicy.TERMINATE_EXISTING,
)
print(f"Result: {result}")

Expand All @@ -268,7 +263,6 @@ if __name__ == "__main__":
This file is a standard Temporal launch script.
We also configure the client with the `OpenAIAgentsPlugin` to ensure serialization is compatible with the worker.


To run this example, see the detailed instructions in the [Temporal Python Samples Repository](https://github.com/temporalio/samples-python/tree/main/openai_agents).

## Tool Calling
Expand Down Expand Up @@ -308,7 +302,7 @@ class WeatherAgent:
instructions="You are a helpful weather agent.",
tools=[
openai_agents.workflow.activity_as_tool(
get_weather,
get_weather,
start_to_close_timeout=timedelta(seconds=10)
)
],
Expand Down Expand Up @@ -350,7 +344,6 @@ Of course, code running in the workflow can invoke a Temporal activity at any ti

Tools that run in the workflow can also update OpenAI Agents context, which is read-only for tools run as Temporal activities.


## MCP Support

This integration provides support for Model Context Protocol (MCP) servers through two wrapper approaches designed to handle different implications of failures.
Expand Down Expand Up @@ -434,13 +427,13 @@ class FileSystemWorkflow:
async def run(self, query: str) -> str:
# Reference the MCP server by name (matches name in worker configuration)
server = openai_agents.workflow.stateless_mcp_server("FileSystemServer")

agent = Agent(
name="File Assistant",
instructions="Use the filesystem tools to read files and answer questions.",
mcp_servers=[server],
)

result = await Runner.run(agent, input=query)
return result.final_output
```
Expand All @@ -467,18 +460,18 @@ Certain tools are not suitable for a distributed computing environment, so these
### Model Providers

| Model Provider | Supported |
|:--------------|:---------:|
| OpenAI | Yes |
| LiteLLM | Yes |
| :------------- | :-------: |
| OpenAI | Yes |
| LiteLLM | Yes |

### Model Response format

This integration does not presently support streaming.

| Model Response | Supported |
|:--------------|:---------:|
| Get Response | Yes |
| Streaming | No |
| :------------- | :-------: |
| Get Response | Yes |
| Streaming | No |

### Tools

Expand All @@ -487,7 +480,7 @@ This integration does not presently support streaming.
`LocalShellTool` and `ComputerTool` are not suited to a distributed computing setting.

| Tool Type | Supported |
|:-------------------|:---------:|
| :------------------ | :-------: |
| FunctionTool | Yes |
| LocalShellTool | No |
| WebSearchTool | Yes |
Expand All @@ -501,12 +494,12 @@ This integration does not presently support streaming.

As described in [Tool Calling](#tool-calling), context propagation is read-only when Temporal activities are used as tools.

| Context Propagation | Supported |
|:----------------------------------------|:---------:|
| Activity Tool receives copy of context | Yes |
| Activity Tool can update context | No |
| Function Tool received context | Yes |
| Function Tool can update context | Yes |
| Context Propagation | Supported |
| :------------------------------------- | :-------: |
| Activity Tool receives copy of context | Yes |
| Activity Tool can update context | No |
| Function Tool received context | Yes |
| Function Tool can update context | Yes |

### MCP

Expand All @@ -516,50 +509,48 @@ These wrappers work with all transport varieties.

Note that when using network-accessible MCP servers, you also can also use the tool `HostedMCPTool`, which is part of the OpenAI Responses API and uses an MCP client hosted by OpenAI.

| MCP Class | Supported |
|:-----------------------|:---------:|
| MCPServerStdio | Yes |
| MCPServerSse | Yes |
| MCPServerStreamableHttp| Yes |
| MCP Class | Supported |
| :---------------------- | :-------: |
| MCPServerStdio | Yes |
| MCPServerSse | Yes |
| MCPServerStreamableHttp | Yes |

### Guardrails

| Guardrail Type | Supported |
|:---------------|:---------:|
| :------------- | :-------: |
| Code | Yes |
| Agent | Yes |

### Sessions

SQLite storage is not suited to a distributed environment.

| Feature | Supported |
|:---------------|:---------:|
| SQLiteSession | No |
| Feature | Supported |
| :------------ | :-------: |
| SQLiteSession | No |

### Tracing

| Tracing Provider | Supported |
|:-----------------|:---------:|
| :--------------- | :-------: |
| OpenAI platform | Yes |

### Voice
### Voice

| Mode | Supported |
|:------------------------|:---------:|
| Voice agents (pipelines)| No |
| Realtime agents | No |
| Mode | Supported |
| :----------------------- | :-------: |
| Voice agents (pipelines) | No |
| Realtime agents | No |

### Utilities

The REPL utility is not suitable for a distributed setting.

| Utility | Supported |
|:--------|:---------:|
| :------ | :-------: |
| REPL | No |


## Additional Examples

You can find additional examples in the [Temporal Python Samples Repository](https://github.com/temporalio/samples-python/tree/main/openai_agents).

Loading