Skip to content

Commit 643db6d

Browse files
committed
AI-266: Add @temporalio/openai-agents sample suite
Fourteen self-contained samples demonstrating how to run OpenAI Agents SDK agents as Temporal Workflows with the @temporalio/openai-agents integration: the basic building blocks, handoffs, agent patterns, sessions, human approval, hosted/Nexus/MCP tools, tracing, model providers, reasoning content, a research bot, and a customer-service chat. Each sample is a standalone package with a fake-model Worker test that runs without an API key, and the suite is wired into the pnpm workspace, CI, and the samples list.
1 parent f0e415e commit 643db6d

247 files changed

Lines changed: 9381 additions & 66 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/ci.yml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,20 @@ jobs:
6868
timer-examples
6969
message-passing/introduction
7070
message-passing/safe-message-handlers
71+
openai-agents/agent-patterns
72+
openai-agents/basic
73+
openai-agents/customer-service
74+
openai-agents/handoffs
75+
openai-agents/hosted-mcp
76+
openai-agents/human-approval
77+
openai-agents/mcp
78+
openai-agents/model-providers
79+
openai-agents/nexus-tools
80+
openai-agents/reasoning-content
81+
openai-agents/research-bot
82+
openai-agents/sessions
83+
openai-agents/tools
84+
openai-agents/tracing
7185
polling/infrequent
7286
)
7387
for project in "${projects[@]}"; do

.scripts/copy-shared-files.mjs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ const ADDITIONAL_SAMPLES = [];
1313
// as samples.
1414
const HAS_CHILD_SAMPLES = [
1515
'message-passing',
16+
'openai-agents',
1617
'polling',
1718
];
1819

.scripts/list-of-samples.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,20 @@
5454
"message-passing/execute-update",
5555
"message-passing/introduction",
5656
"message-passing/safe-message-handlers",
57+
"openai-agents/agent-patterns",
58+
"openai-agents/basic",
59+
"openai-agents/customer-service",
60+
"openai-agents/handoffs",
61+
"openai-agents/hosted-mcp",
62+
"openai-agents/human-approval",
63+
"openai-agents/mcp",
64+
"openai-agents/model-providers",
65+
"openai-agents/nexus-tools",
66+
"openai-agents/reasoning-content",
67+
"openai-agents/research-bot",
68+
"openai-agents/sessions",
69+
"openai-agents/tools",
70+
"openai-agents/tracing",
5771
"polling/infrequent"
5872
]
5973
}

README.md

Lines changed: 37 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,25 @@
33
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
44
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
55

6-
- [samples-typescript](#samples-typescript)
7-
- [Running](#running)
8-
- [Locally](#locally)
9-
- [Scaffold](#scaffold)
10-
- [Samples](#samples)
11-
- [Basic](#basic)
12-
- [API demos](#api-demos)
13-
- [Activity APIs and design patterns](#activity-apis-and-design-patterns)
14-
- [Nexus APIs](#nexus-apis)
15-
- [Workflow APIs](#workflow-apis)
16-
- [Production APIs](#production-apis)
17-
- [Advanced APIs](#advanced-apis)
18-
- [Test APIs](#test-apis)
19-
- [Full-stack apps](#full-stack-apps)
20-
- [External apps \& libraries](#external-apps--libraries)
21-
- [Contributing](#contributing)
22-
- [Dependencies](#dependencies)
23-
- [Upgrading the SDK version in `package.json`s](#upgrading-the-sdk-version-in-packagejsons)
24-
- [Config files](#config-files)
6+
- [Running](#running)
7+
- [Locally](#locally)
8+
- [Scaffold](#scaffold)
9+
- [Samples](#samples)
10+
- [Basic](#basic)
11+
- [API demos](#api-demos)
12+
- [Activity APIs and design patterns](#activity-apis-and-design-patterns)
13+
- [Nexus APIs](#nexus-apis)
14+
- [Workflow APIs](#workflow-apis)
15+
- [Production APIs](#production-apis)
16+
- [Advanced APIs](#advanced-apis)
17+
- [Test APIs](#test-apis)
18+
- [AI / LLM](#ai--llm)
19+
- [Full-stack apps](#full-stack-apps)
20+
- [External apps & libraries](#external-apps--libraries)
21+
- [Contributing](#contributing)
22+
- [Dependencies](#dependencies)
23+
- [Upgrading the SDK version in `package.json`s](#upgrading-the-sdk-version-in-packagejsons)
24+
- [Config files](#config-files)
2525

2626
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
2727

@@ -161,6 +161,24 @@ and you'll be given the list of sample options.
161161
- [**Mocha with code coverage or Jest**](https://github.com/temporalio/samples-typescript/tree/main/activities-examples#testing)
162162
- [**Time skipping**](https://github.com/temporalio/samples-typescript/tree/main/timer-examples#testing)
163163

164+
#### AI / LLM
165+
166+
- [**OpenAI Agents**](./openai-agents): Run [OpenAI Agents SDK](https://github.com/openai/openai-agents-js) agents as Temporal Workflows with the `@temporalio/openai-agents` integration. The [`openai-agents/`](./openai-agents) directory contains fourteen samples:
167+
- [**Basic**](./openai-agents/basic): A single agent plus the building blocks — Activity-backed and inline tools, local-Activity tools, agent context, structured output, per-run model override, and dynamic instructions.
168+
- [**Handoffs**](./openai-agents/handoffs): A triage agent routes each request to a specialist agent, using both the `Agent[]` and `handoff()` forms and a per-handoff input filter.
169+
- [**Agent Patterns**](./openai-agents/agent-patterns): Multi-agent orchestration patterns — deterministic chaining, parallelization, LLM-as-judge, agents-as-tools, and input/output guardrails.
170+
- [**Sessions**](./openai-agents/sessions): Conversation history with `WorkflowSafeMemorySession`, including carrying history across a `continueAsNew` boundary.
171+
- [**Human Approval**](./openai-agents/human-approval): A human-in-the-loop tool that pauses the run for an `approve` Signal, then resumes by serializing and rehydrating the run state across `continueAsNew`.
172+
- [**Tools**](./openai-agents/tools): Server-side hosted tools — web search, image generation, and code interpreter — executed by the model provider in the model Activity.
173+
- [**Tracing**](./openai-agents/tracing): The three supported tracing paths — a custom `TracingProcessor`, the OpenAI hosted exporter, and OpenTelemetry — plus `temporal:*` orchestration spans.
174+
- [**Model Providers**](./openai-agents/model-providers): Pass a custom `ModelProvider` to point an agent at any OpenAI-compatible endpoint.
175+
- [**Reasoning Content**](./openai-agents/reasoning-content): Read a reasoning model's `reasoning_content` field by calling the `openai` SDK directly from an Activity.
176+
- [**MCP**](./openai-agents/mcp): Stateless and stateful Model Context Protocol servers (stdio, Streamable HTTP, SSE, and prompt servers) running locally.
177+
- [**Hosted MCP**](./openai-agents/hosted-mcp): A `HostedMCPTool` the model calls server-side, with and without a Signal-driven approval round trip.
178+
- [**Research Bot**](./openai-agents/research-bot): A planner agent fans out concurrent web searches and a writer agent synthesizes a final report.
179+
- [**Customer Service**](./openai-agents/customer-service): A long-running, multi-turn Workflow driven by Updates and Queries, with triage handoffs and `continueAsNew` to bound history.
180+
- [**Nexus Tools**](./openai-agents/nexus-tools): Expose a Nexus Operation as an agent tool with `nexusOperationAsTool`.
181+
164182
### Full-stack apps
165183

166184
- **Next.js**:

openai-agents/README.md

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# OpenAI Agents
2+
3+
These samples use the `@temporalio/openai-agents` integration to run [OpenAI Agents SDK](https://github.com/openai/openai-agents-js) agents as Temporal Workflows. Agent orchestration — the agent loop, handoffs, tool calls, and guardrails — runs inside the Workflow, while model calls run as durable Activities, so they retry on failure and are not repeated during Workflow replay.
4+
5+
Each subdirectory is a standalone sample with its own `package.json` and README. The integration package itself is documented in the [`@temporalio/openai-agents` README](https://github.com/temporalio/sdk-typescript/tree/main/packages/openai-agents).
6+
7+
## Prerequisites
8+
9+
These apply to every sample in this directory:
10+
11+
- A running Temporal dev server: `temporal server start-dev`.
12+
- Node 22 or later.
13+
- An OpenAI API key: `export OPENAI_API_KEY=...`.
14+
- Dependencies installed in the sample directory: `npm install`.
15+
16+
Each sample's README describes how to start its Worker and run its scenarios.
17+
18+
## Samples
19+
20+
| Sample | Demonstrates |
21+
| :------------------------------------------ | :-------------------------------------------------------------------------------------------------------------------------------------- |
22+
| [`basic`](./basic) | A single agent plus the core building blocks: Activity-backed and inline tools, local-Activity tools, agent context, structured output, per-run model override, and dynamic instructions. |
23+
| [`handoffs`](./handoffs) | A triage agent routes each request to a specialist agent, using both the `Agent[]` and `handoff()` forms and a per-handoff input filter. |
24+
| [`agent-patterns`](./agent-patterns) | Multi-agent orchestration patterns: deterministic chaining, parallelization, LLM-as-judge, agents-as-tools, and input/output guardrails. |
25+
| [`sessions`](./sessions) | Conversation history with `WorkflowSafeMemorySession`, including carrying history across a `continueAsNew` boundary. |
26+
| [`human-approval`](./human-approval) | A human-in-the-loop tool that pauses the run for an `approve` Signal, then resumes by serializing and rehydrating the run state across `continueAsNew`. |
27+
| [`tools`](./tools) | Server-side hosted tools — web search, image generation, and code interpreter — executed by the model provider during the model Activity. |
28+
| [`tracing`](./tracing) | The three supported tracing paths: a custom `TracingProcessor`, the OpenAI hosted exporter, and OpenTelemetry, plus `temporal:*` orchestration spans. |
29+
| [`model-providers`](./model-providers) | Pass a custom `ModelProvider` to point an agent at any OpenAI-compatible endpoint. |
30+
| [`reasoning-content`](./reasoning-content) | Read a reasoning model's `reasoning_content` field by calling the `openai` SDK directly from an Activity. |
31+
| [`mcp`](./mcp) | Stateless and stateful Model Context Protocol servers (stdio, Streamable HTTP, SSE, and prompt servers) running locally. |
32+
| [`hosted-mcp`](./hosted-mcp) | A `HostedMCPTool` the model calls server-side, with and without a Signal-driven approval round trip. |
33+
| [`research-bot`](./research-bot) | A planner agent fans out concurrent web searches and a writer agent synthesizes a final report. |
34+
| [`customer-service`](./customer-service) | A long-running, multi-turn Workflow driven by Updates and Queries, with triage handoffs and `continueAsNew` to bound history. |
35+
| [`nexus-tools`](./nexus-tools) | Expose a [Nexus](https://docs.temporal.io/nexus) Operation as an agent tool with `nexusOperationAsTool`. |
36+
37+
## Feature support
38+
39+
Any OpenAI Agents SDK `ModelProvider` can drive the model Activity. The provider runs in the Activity, never inside the Workflow sandbox.
40+
41+
| Feature | Status | Notes |
42+
| :---------------------- | :------------ | :-------------------------------------------------------------------------------------- |
43+
| Multi-turn agents | Supported | Agent loop runs durably in the Workflow |
44+
| Handoffs | Supported | `Agent` and `handoff()` forms |
45+
| Inline function tools | Supported | Must be deterministic |
46+
| Activity-backed tools | Supported | Via `activityAsTool()` |
47+
| Nexus operation tools | Supported | Via `nexusOperationAsTool()` |
48+
| Nested agent tools | Supported | Via `agentAsTool()` |
49+
| Hosted tools | Supported | Executed server-side by the model provider |
50+
| Stateless MCP servers | Supported | Via `StatelessMCPServerProvider` and `statelessMcpServer()` |
51+
| Stateful MCP servers | Supported | Via `StatefulMCPServerProvider` and `statefulMcpServer()` |
52+
| Sessions | Supported | Via `WorkflowSafeMemorySession`; upstream `MemorySession` is rejected |
53+
| Run state and approvals | Supported | Serialize with `result.state.toString()` and rehydrate with `RunState.fromString` |
54+
| Guardrails | Supported | Guardrail callbacks must be deterministic |
55+
| Tracing | Supported | OpenAI hosted traces, custom `TracingProcessor`s, OTel, and optional `temporal:*` spans |
56+
| Agent context | Supported | Activity tools receive a copy |
57+
| `continueAsNew` | Supported | Plugin config propagates to the continuation |
58+
| Child Workflows | Supported | Plugin config propagates to children |
59+
| Local Activities | Supported | Set `useLocalActivity: true` in `modelParams` |
60+
| Model override per run | Supported | `runConfig.model` accepts a string model name |
61+
| Streaming | Not supported | Use `runner.run()` |
62+
| Voice agents | Not supported | |
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
node_modules
2+
lib
3+
.eslintrc.js
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
const { builtinModules } = require('module');
2+
const ALLOWED_NODE_BUILTINS = new Set(['assert']);
3+
module.exports = {
4+
root: true,
5+
parser: '@typescript-eslint/parser',
6+
parserOptions: { project: './tsconfig.json', tsconfigRootDir: __dirname },
7+
plugins: ['@typescript-eslint', 'deprecation'],
8+
extends: [
9+
'eslint:recommended',
10+
'plugin:@typescript-eslint/eslint-recommended',
11+
'plugin:@typescript-eslint/recommended',
12+
'prettier',
13+
],
14+
rules: {
15+
'@typescript-eslint/no-floating-promises': 'error',
16+
'deprecation/deprecation': 'warn',
17+
'object-shorthand': ['error', 'always'],
18+
'@typescript-eslint/no-unused-vars': ['warn', { argsIgnorePattern: '^_', varsIgnorePattern: '^_' }],
19+
'@typescript-eslint/no-explicit-any': 'off',
20+
},
21+
overrides: [
22+
{
23+
files: ['src/workflows.ts', 'src/workflows-*.ts', 'src/workflows/*.ts'],
24+
rules: {
25+
'no-restricted-imports': [
26+
'error',
27+
...builtinModules.filter((m) => !ALLOWED_NODE_BUILTINS.has(m)).flatMap((m) => [m, `node:${m}`]),
28+
],
29+
},
30+
},
31+
],
32+
};
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
lib
2+
node_modules
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
package-lock=false
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
22

0 commit comments

Comments
 (0)