Skip to content

Commit 3aff9ff

Browse files
committed
Adding cahnges to openai agents temporal sdk tutorials
1 parent e677b31 commit 3aff9ff

File tree

3 files changed

+308
-38
lines changed
  • examples/tutorials/10_agentic/10_temporal

3 files changed

+308
-38
lines changed

examples/tutorials/10_agentic/10_temporal/060_open_ai_agents_sdk_hello_world/README.md

Lines changed: 53 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,53 @@
11
# [Temporal] OpenAI Agents SDK - Hello World
22

3+
**Part of the [OpenAI SDK + Temporal integration series](../README.md)**
4+
35
## What You'll Learn
46

57
The OpenAI Agents SDK plugin automatically converts LLM calls into durable Temporal activities. When `Runner.run()` executes, the LLM invocation becomes an `invoke_model_activity` visible in Temporal UI with full observability, automatic retries, and durability.
68

79
**Key insight:** You don't need to wrap agent calls in activities manually - the plugin handles this automatically, making non-deterministic LLM calls work seamlessly in Temporal workflows.
810

11+
## Prerequisites
12+
13+
1. Agentex backend running with Temporal (`make dev` in agentex repo)
14+
2. OpenAI API key configured (see setup below)
15+
16+
## Setup
17+
18+
This tutorial uses the OpenAI Agents SDK plugin, which needs to be added in two places:
19+
20+
### 1. Add Plugin to ACP (`project/acp.py`)
21+
```python
22+
from agentex.lib.plugins.openai_agents import OpenAIAgentsPlugin
23+
24+
acp = FastACP.create(
25+
config=TemporalACPConfig(
26+
plugins=[OpenAIAgentsPlugin()] # Add this
27+
)
28+
)
29+
```
30+
31+
### 2. Add Plugin to Worker (`project/run_worker.py`)
32+
```python
33+
from agentex.lib.plugins.openai_agents import OpenAIAgentsPlugin
34+
35+
worker = AgentexWorker(
36+
task_queue=task_queue_name,
37+
plugins=[OpenAIAgentsPlugin()], # Add this
38+
)
39+
```
40+
41+
### 3. Configure OpenAI API Key
42+
Add to `manifest.yaml`:
43+
```yaml
44+
secrets:
45+
- name: OPENAI_API_KEY
46+
value: "your-openai-api-key-here"
47+
```
48+
49+
Or set in `.env` file: `OPENAI_API_KEY=your-key-here`
50+
951
## Quick Start
1052

1153
```bash
@@ -18,10 +60,17 @@ uv run agentex agents run --manifest manifest.yaml
1860
## Try It
1961

2062
1. Send a message to the agent (it responds in haikus)
21-
2. Open Temporal UI at http://localhost:8080
22-
3. Find your workflow execution
23-
4. Look for the `invoke_model_activity` - this was created automatically
24-
5. Inspect the activity to see:
63+
2. Check the agent response:
64+
65+
![Agent Response](../_images/hello_world_response.png)
66+
67+
3. Open Temporal UI at http://localhost:8080
68+
4. Find your workflow execution
69+
5. Look for the `invoke_model_activity` - this was created automatically:
70+
71+
![Temporal UI](../_images/hello_world_temporal.png)
72+
73+
6. Inspect the activity to see:
2574
- Input parameters (your message)
2675
- Output (agent's haiku response)
2776
- Execution time
Lines changed: 116 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# [Temporal] OpenAI Agents SDK - Tools
22

3+
**Part of the [OpenAI SDK + Temporal integration series](../README.md)** → Previous: [060 Hello World](../060_open_ai_agents_sdk_hello_world/)
4+
35
## What You'll Learn
46

57
Two patterns for making agent tools durable with Temporal:
@@ -15,6 +17,10 @@ Two patterns for making agent tools durable with Temporal:
1517
- 1:many mapping - your code controls execution order, not the LLM
1618
- Ensures atomic operations (withdraw always happens before deposit)
1719

20+
## Prerequisites
21+
22+
See [Hello World tutorial](../060_open_ai_agents_sdk_hello_world/) for basic setup of the OpenAI Agents SDK plugin.
23+
1824
## Quick Start
1925

2026
```bash
@@ -26,35 +32,131 @@ uv run agentex agents run --manifest manifest.yaml
2632

2733
## Try It
2834

29-
**Pattern 1 (implemented):** Ask "What's the weather in San Francisco?"
30-
- Open Temporal UI (localhost:8080)
31-
- See a single `get_weather` activity created
32-
- The activity shows the external call with retry capability
35+
### Pattern 1: Single Activity Tool
36+
37+
Ask "What's the weather in San Francisco?"
38+
39+
1. Check the agent response:
40+
41+
![Weather Response](../_images/weather_response.png)
42+
43+
2. Open Temporal UI (localhost:8080)
44+
3. See a single `get_weather` activity created:
45+
46+
![Weather Activity](../_images/weather_activity_tool.png)
47+
48+
The activity shows the external call with retry capability. Each step (model invocation → tool call → model invocation) is durable.
49+
50+
### Pattern 2: Multi-Activity Tool (Optional)
51+
52+
To try the advanced banking example, uncomment the `move_money` sections in the code, then ask to move money.
53+
54+
1. Check the agent response:
3355

34-
**Pattern 2 (commented out in code):** Uncomment the `move_money` section, then ask to move money
35-
- See TWO sequential activities: `withdraw_money``deposit_money`
36-
- If the system crashes after withdraw but before deposit, Temporal resumes exactly where it left off
37-
- The deposit will still happen - guaranteed transactional integrity
56+
![Money Transfer Response](../_images/move_money_response.png)
57+
58+
2. Open Temporal UI and see TWO sequential activities:
59+
60+
![Money Transfer Workflow](../_images/move_money_temporal.png)
61+
62+
- First: `withdraw_money` activity executes
63+
- Then: `deposit_money` activity executes
64+
- Each activity shows its parameters and execution time
65+
66+
**Critical insight:** If the system crashes after withdraw but before deposit, Temporal resumes exactly where it left off. The deposit will still happen - guaranteed transactional integrity.
3867

3968
## Key Code
4069

70+
### Pattern 1: Single Activity Tool
4171
```python
42-
# Pattern 1: Direct activity conversion
72+
# Define the activity
73+
@activity.defn
74+
async def get_weather(city: str) -> str:
75+
"""Get the weather for a given city"""
76+
# This could be an API call - Temporal handles retries
77+
return f"The weather in {city} is sunny"
78+
79+
# Use activity_as_tool to convert it
4380
weather_agent = Agent(
81+
name="Weather Assistant",
82+
instructions="Use the get_weather tool to answer weather questions.",
4483
tools=[
4584
activity_as_tool(get_weather, start_to_close_timeout=timedelta(seconds=10))
4685
]
4786
)
87+
```
4888

49-
# Pattern 2: Function tool coordinating multiple activities (see code for full example)
50-
# The tool internally calls workflow.start_activity_method() multiple times
51-
# guaranteeing the sequence and making each step durable
89+
### Pattern 2: Multi-Activity Tool
90+
```python
91+
# Define individual activities
92+
@activity.defn
93+
async def withdraw_money(from_account: str, amount: float) -> str:
94+
# Simulate API call
95+
await asyncio.sleep(5)
96+
return f"Withdrew ${amount} from {from_account}"
97+
98+
@activity.defn
99+
async def deposit_money(to_account: str, amount: float) -> str:
100+
# Simulate API call
101+
await asyncio.sleep(10)
102+
return f"Deposited ${amount} into {to_account}"
103+
104+
# Create a function tool that orchestrates both activities
105+
@function_tool
106+
async def move_money(from_account: str, to_account: str, amount: float) -> str:
107+
"""Move money from one account to another"""
108+
109+
# Step 1: Withdraw (becomes an activity)
110+
await workflow.start_activity(
111+
"withdraw_money",
112+
args=[from_account, amount],
113+
start_to_close_timeout=timedelta(days=1)
114+
)
115+
116+
# Step 2: Deposit (becomes an activity)
117+
await workflow.start_activity(
118+
"deposit_money",
119+
args=[to_account, amount],
120+
start_to_close_timeout=timedelta(days=1)
121+
)
122+
123+
return "Money transferred successfully"
124+
125+
# Use the tool in your agent
126+
money_agent = Agent(
127+
name="Money Mover",
128+
instructions="Use move_money to transfer funds between accounts.",
129+
tools=[move_money]
130+
)
52131
```
53132

133+
## When to Use Each Pattern
134+
135+
### Use Pattern 1 when:
136+
- Tool performs a single external operation (API call, DB query)
137+
- Operation is already idempotent
138+
- No sequencing guarantees needed
139+
140+
### Use Pattern 2 when:
141+
- Tool requires multiple sequential operations
142+
- Order must be guaranteed (withdraw THEN deposit)
143+
- Operations need to be atomic from the agent's perspective
144+
- You want transactional integrity across steps
145+
54146
## Why This Matters
55147

56148
**Without Temporal:** If you withdraw money but crash before depositing, you're stuck in a broken state. The money is gone from the source account with no way to recover.
57149

58-
**With Temporal:** Guaranteed execution with exact resumption after failures. Either both operations complete, or the workflow can handle partial completion. This is what makes agents production-ready for real-world operations like financial transactions, order fulfillment, or any multi-step process.
150+
**With Temporal (Pattern 2):**
151+
- Guaranteed execution with exact resumption after failures
152+
- If the system crashes after withdraw, Temporal resumes and completes deposit
153+
- Each step is tracked and retried independently
154+
- Full observability of the entire operation
155+
156+
**Key insight:** Pattern 2 moves sequencing control from the LLM (which might call tools in wrong order) to your deterministic code (which guarantees correct order). The LLM still decides *when* to call the tool, but your code controls *how* the operations execute.
59157

60-
**Key insight:** Pattern 2 moves sequencing control from the LLM (which might call tools in wrong order) to your deterministic code (which guarantees correct order).
158+
This makes agents production-ready for:
159+
- Financial transactions
160+
- Order fulfillment workflows
161+
- Multi-step API integrations
162+
- Any operation where partial completion is dangerous

0 commit comments

Comments
 (0)