Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: johntango/openai-agents-python01
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: main
Choose a base ref
...
head repository: openai/openai-agents-python
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: main
Choose a head ref
Loading
Showing with 6,796 additions and 2,546 deletions.
  1. +1 −0 .github/workflows/issues.yml
  2. +71 −0 AGENTS.md
  3. +1 −0 CLAUDE.md
  4. +14 −4 README.md
  5. +2 −1 docs/context.md
  6. +1 −1 docs/guardrails.md
  7. +22 −22 docs/ja/guardrails.md
  8. +13 −5 docs/ja/mcp.md
  9. +0 −106 docs/ja/models.md
  10. +73 −34 docs/ja/models/index.md
  11. +22 −0 docs/ja/repl.md
  12. +4 −0 docs/ja/tools.md
  13. +2 −1 docs/ja/tracing.md
  14. +99 −4 docs/mcp.md
  15. +16 −0 docs/models/index.md
  16. +6 −0 docs/ref/repl.md
  17. +18 −0 docs/release.md
  18. +19 −0 docs/repl.md
  19. +41 −18 docs/scripts/translate_docs.py
  20. +32 −1 docs/tools.md
  21. +2 −0 docs/tracing.md
  22. +1 −1 examples/agent_patterns/input_guardrails.py
  23. +45 −0 examples/basic/hello_world_jupyter.ipynb
  24. +0 −11 examples/basic/hello_world_jupyter.py
  25. +79 −0 examples/basic/prompt_template.py
  26. 0 examples/hosted_mcp/__init__.py
  27. +61 −0 examples/hosted_mcp/approvals.py
  28. +47 −0 examples/hosted_mcp/simple.py
  29. +13 −0 examples/mcp/streamablehttp_example/README.md
  30. +83 −0 examples/mcp/streamablehttp_example/main.py
  31. +33 −0 examples/mcp/streamablehttp_example/server.py
  32. +3 −0 examples/reasoning_content/__init__.py
  33. +124 −0 examples/reasoning_content/main.py
  34. +88 −0 examples/reasoning_content/runner_example.py
  35. +1 −1 examples/research_bot/agents/search_agent.py
  36. +34 −0 examples/tools/code_interpreter.py
  37. +54 −0 examples/tools/image_generator.py
  38. +4 −0 mkdocs.yml
  39. +5 −5 pyproject.toml
  40. +28 −1 src/agents/__init__.py
  41. +237 −11 src/agents/_run_impl.py
  42. +40 −6 src/agents/agent.py
  43. +1 −1 src/agents/agent_output.py
  44. +38 −5 src/agents/exceptions.py
  45. +33 −5 src/agents/extensions/models/litellm_model.py
  46. +35 −18 src/agents/extensions/visualization.py
  47. +7 −5 src/agents/function_schema.py
  48. +17 −3 src/agents/handoffs.py
  49. +57 −3 src/agents/items.py
  50. +17 −1 src/agents/mcp/__init__.py
  51. +240 −23 src/agents/mcp/server.py
  52. +90 −6 src/agents/mcp/util.py
  53. +67 −6 src/agents/model_settings.py
  54. +13 −1 src/agents/models/chatcmpl_converter.py
  55. +152 −16 src/agents/models/chatcmpl_stream_handler.py
  56. +6 −0 src/agents/models/interface.py
  57. +45 −10 src/agents/models/openai_chatcompletions.py
  58. +68 −17 src/agents/models/openai_responses.py
  59. +76 −0 src/agents/prompts.py
  60. +62 −0 src/agents/repl.py
  61. +43 −13 src/agents/result.py
  62. +279 −107 src/agents/run.py
  63. +3 −0 src/agents/stream_events.py
  64. +139 −7 src/agents/tool.py
  65. +29 −0 src/agents/tool_context.py
  66. +10 −5 src/agents/tracing/__init__.py
  67. +16 −16 src/agents/tracing/create.py
  68. +1 −1 src/agents/tracing/processor_interface.py
  69. +29 −3 src/agents/tracing/processors.py
  70. +294 −0 src/agents/tracing/provider.py
  71. +13 −206 src/agents/tracing/setup.py
  72. +9 −10 src/agents/tracing/util.py
  73. +21 −1 src/agents/usage.py
  74. +12 −0 src/agents/util/_pretty_print.py
  75. +2 −0 src/agents/voice/model.py
  76. +8 −2 tests/conftest.py
  77. +3 −0 tests/fake_model.py
  78. +45 −4 tests/mcp/helpers.py
  79. +14 −8 tests/mcp/test_caching.py
  80. +39 −21 tests/mcp/test_mcp_tracing.py
  81. +14 −6 tests/mcp/test_mcp_util.py
  82. +6 −1 tests/mcp/test_server_errors.py
  83. +243 −0 tests/mcp/test_tool_filtering.py
  84. +106 −0 tests/model_settings/test_serialization.py
  85. +177 −0 tests/models/test_kwargs_functionality.py
  86. +17 −2 tests/models/test_litellm_chatcompletions_stream.py
  87. +44 −0 tests/models/test_litellm_extra_body.py
  88. +5 −4 tests/models/test_map.py
  89. +6 −5 tests/test_agent_config.py
  90. +97 −0 tests/test_agent_prompt.py
  91. +35 −0 tests/test_agent_runner.py
  92. +37 −0 tests/test_agent_runner_streamed.py
  93. +14 −6 tests/test_extra_headers.py
  94. +12 −0 tests/test_function_schema.py
  95. +59 −17 tests/test_function_tool.py
  96. +5 −4 tests/test_function_tool_decorator.py
  97. +102 −8 tests/test_handoff_tool.py
  98. +53 −2 tests/test_openai_chatcompletions.py
  99. +17 −2 tests/test_openai_chatcompletions_stream.py
  100. +8 −8 tests/test_output_tool.py
  101. +289 −0 tests/test_reasoning_content.py
  102. +28 −0 tests/test_repl.py
  103. +4 −2 tests/test_responses.py
  104. +29 −1 tests/test_responses_tracing.py
  105. +26 −0 tests/test_run.py
  106. +1 −1 tests/test_run_config.py
  107. +48 −0 tests/test_run_error_details.py
  108. +43 −4 tests/test_run_step_execution.py
  109. +24 −20 tests/test_run_step_processing.py
  110. +0 −4 tests/test_tracing_errors_streamed.py
  111. +52 −0 tests/test_usage.py
  112. +15 −0 tests/test_visualization.py
  113. +8 −2 tests/voice/test_workflow.py
  114. +1,700 −1,690 uv.lock
1 change: 1 addition & 0 deletions .github/workflows/issues.yml
Original file line number Diff line number Diff line change
@@ -21,6 +21,7 @@ jobs:
days-before-pr-stale: 10
days-before-pr-close: 7
stale-pr-label: "stale"
exempt-issue-labels: "skip-stale"
stale-pr-message: "This PR is stale because it has been open for 10 days with no activity."
close-pr-message: "This PR was closed because it has been inactive for 7 days since being marked as stale."
repo-token: ${{ secrets.GITHUB_TOKEN }}
71 changes: 71 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
Welcome to the OpenAI Agents SDK repository. This file contains the main points for new contributors.

## Repository overview

- **Source code**: `src/agents/` contains the implementation.
- **Tests**: `tests/` with a short guide in `tests/README.md`.
- **Examples**: under `examples/`.
- **Documentation**: markdown pages live in `docs/` with `mkdocs.yml` controlling the site.
- **Utilities**: developer commands are defined in the `Makefile`.
- **PR template**: `.github/PULL_REQUEST_TEMPLATE/pull_request_template.md` describes the information every PR must include.

## Local workflow

1. Format, lint and type‑check your changes:

```bash
make format
make lint
make mypy
```

2. Run the tests:

```bash
make tests
```

To run a single test, use `uv run pytest -s -k <test_name>`.

3. Build the documentation (optional but recommended for docs changes):

```bash
make build-docs
```

Coverage can be generated with `make coverage`.

All python commands should be run via `uv run python ...`

## Snapshot tests

Some tests rely on inline snapshots. See `tests/README.md` for details on updating them:

```bash
make snapshots-fix # update existing snapshots
make snapshots-create # create new snapshots
```

Run `make tests` again after updating snapshots to ensure they pass.

## Style notes

- Write comments as full sentences and end them with a period.

## Pull request expectations

PRs should use the template located at `.github/PULL_REQUEST_TEMPLATE/pull_request_template.md`. Provide a summary, test plan and issue number if applicable, then check that:

- New tests are added when needed.
- Documentation is updated.
- `make lint` and `make format` have been run.
- The full test suite passes.

Commit messages should be concise and written in the imperative mood. Small, focused commits are preferred.

## What reviewers look for

- Tests covering new behaviour.
- Consistent style: code formatted with `uv run ruff format`, imports sorted, and type hints passing `uv run mypy .`.
- Clear documentation for any public API changes.
- Clean history and a helpful PR description.
1 change: 1 addition & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Read the AGENTS.md file for instructions.
18 changes: 14 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -4,6 +4,9 @@ The OpenAI Agents SDK is a lightweight yet powerful framework for building multi

<img src="https://cdn.openai.com/API/docs/images/orchestration.png" alt="Image of the Agents Tracing UI" style="max-height: 803px;">

> [!NOTE]
> Looking for the JavaScript/TypeScript version? Check out [Agents SDK JS/TS](https://github.com/openai/openai-agents-js).
### Core concepts:

1. [**Agents**](https://openai.github.io/openai-agents-python/agents): LLMs configured with instructions, tools, guardrails, and handoffs
@@ -17,14 +20,21 @@ Explore the [examples](examples) directory to see the SDK in action, and read ou

1. Set up your Python environment

```
- Option A: Using venv (traditional method)
```bash
python -m venv env
source env/bin/activate
source env/bin/activate # On Windows: env\Scripts\activate
```

- Option B: Using uv (recommended)
```bash
uv venv
source .venv/bin/activate # On Windows: .venv\Scripts\activate
```

2. Install Agents SDK

```
```bash
pip install openai-agents
```

@@ -47,7 +57,7 @@ print(result.final_output)

(_If running this, ensure you set the `OPENAI_API_KEY` environment variable_)

(_For Jupyter notebook users, see [hello_world_jupyter.py](examples/basic/hello_world_jupyter.py)_)
(_For Jupyter notebook users, see [hello_world_jupyter.ipynb](examples/basic/hello_world_jupyter.ipynb)_)

## Handoffs example

3 changes: 2 additions & 1 deletion docs/context.md
Original file line number Diff line number Diff line change
@@ -38,7 +38,8 @@ class UserInfo: # (1)!

@function_tool
async def fetch_user_age(wrapper: RunContextWrapper[UserInfo]) -> str: # (2)!
return f"User {wrapper.context.name} is 47 years old"
"""Fetch the age of the user. Call this function to get user's age information."""
return f"The user {wrapper.context.name} is 47 years old"

async def main():
user_info = UserInfo(name="John", uid=123)
2 changes: 1 addition & 1 deletion docs/guardrails.md
Original file line number Diff line number Diff line change
@@ -23,7 +23,7 @@ Input guardrails run in 3 steps:

Output guardrails run in 3 steps:

1. First, the guardrail receives the same input passed to the agent.
1. First, the guardrail receives the output produced by the agent.
2. Next, the guardrail function runs to produce a [`GuardrailFunctionOutput`][agents.guardrail.GuardrailFunctionOutput], which is then wrapped in an [`OutputGuardrailResult`][agents.guardrail.OutputGuardrailResult]
3. Finally, we check if [`.tripwire_triggered`][agents.guardrail.GuardrailFunctionOutput.tripwire_triggered] is true. If true, an [`OutputGuardrailTripwireTriggered`][agents.exceptions.OutputGuardrailTripwireTriggered] exception is raised, so you can appropriately respond to the user or handle the exception.

44 changes: 22 additions & 22 deletions docs/ja/guardrails.md
Original file line number Diff line number Diff line change
@@ -4,44 +4,44 @@ search:
---
# ガードレール

ガードレールは エージェント と _並列_ に実行され、 ユーザー入力 のチェックとバリデーションを行います。たとえば、顧客からのリクエストを支援するために非常に賢い (そのため遅く / 高価な) モデルを使うエージェントがあるとします。悪意のある ユーザー がモデルに数学の宿題を手伝わせようとするのは避けたいですよね。その場合、 高速 / 低コスト のモデルでガードレールを実行できます。ガードレールが悪意のある利用を検知した場合、即座にエラーを送出して高価なモデルの実行を停止し、時間と費用を節約できます
ガードレールは エージェント と _並行して_ 実行され、ユーザー入力のチェックとバリデーションを行えます。例えば、とても賢い(つまり遅く/高価な)モデルを使用してカスタマーリクエストを処理するエージェントがあるとします。悪意のある ユーザー がモデルに数学の宿題を手伝わせようとするのは避けたいでしょう。そこで、速く/安価なモデルで動くガードレールを実行できます。ガードレールが悪意のある利用を検知すると、直ちにエラーを送出して高価なモデルの実行を停止し、時間とコストを節約できます

ガードレールには 2 種類あります
ガードレールには 2 種類あります:

1. Input ガードレールは最初の ユーザー入力 に対して実行されます
2. Output ガードレールは最終的なエージェント出力に対して実行されます
1. 入力ガードレール は初期 ユーザー 入力に対して実行されます
2. 出力ガードレール は最終的なエージェント出力に対して実行されます

## Input ガードレール
## 入力ガードレール

Input ガードレールは 3 つのステップで実行されます。
入力ガードレールは 3 ステップで実行されます:

1. まず、ガードレールはエージェントに渡されたものと同じ入力を受け取ります。
2. 次に、ガードレール関数が実行され [`GuardrailFunctionOutput`][agents.guardrail.GuardrailFunctionOutput] を生成し、それが [`InputGuardrailResult`][agents.guardrail.InputGuardrailResult] でラップされます
3. 最後に [`.tripwire_triggered`][agents.guardrail.GuardrailFunctionOutput.tripwire_triggered] が true かどうかを確認します。true の場合、[`InputGuardrailTripwireTriggered`][agents.exceptions.InputGuardrailTripwireTriggered] 例外が送出されるので、 ユーザー への適切な応答や例外処理を行えます
2. 次に、ガードレール関数が実行され [`GuardrailFunctionOutput`][agents.guardrail.GuardrailFunctionOutput] を生成し、それが [`InputGuardrailResult`][agents.guardrail.InputGuardrailResult] にラップされます
3. 最後に [.tripwire_triggered][agents.guardrail.GuardrailFunctionOutput.tripwire_triggered] が true かどうかを確認します。true の場合、[`InputGuardrailTripwireTriggered`][agents.exceptions.InputGuardrailTripwireTriggered] 例外が送出されるので、適切に ユーザー に応答したり例外を処理できます

!!! Note

Input ガードレールは ユーザー入力 に対して実行されることを想定しているため、エージェントのガードレールが実行されるのはそのエージェントが *最初* のエージェントである場合だけです。「なぜ `guardrails` プロパティがエージェントにあり、 `Runner.run` に渡さないのか?」と思うかもしれません。ガードレールは実際の エージェント に密接に関連する場合が多く、エージェントごとに異なるガードレールを実行するため、コードを同じ場所に置くことで可読性が向上するからです
入力ガードレールは ユーザー 入力に対して実行されることを意図しているため、ガードレールは *最初* のエージェントでのみ実行されます。「なぜ `guardrails` プロパティがエージェントにあり、`Runner.run` に渡さないのか」と疑問に思うかもしれません。これは、ガードレールが実際の エージェント と密接に関連していることが多いからです。異なるエージェントには異なるガードレールを実行するため、コードを同じ場所に置くことで可読性が向上します

## Output ガードレール
## 出力ガードレール

Output ガードレールは 3 つのステップで実行されます。
出力ガードレールは 3 ステップで実行されます:

1. まず、ガードレールはエージェントに渡されたものと同じ入力を受け取ります
2. 次に、ガードレール関数が実行され [`GuardrailFunctionOutput`][agents.guardrail.GuardrailFunctionOutput] を生成し、それが [`OutputGuardrailResult`][agents.guardrail.OutputGuardrailResult] でラップされます
3. 最後に [`.tripwire_triggered`][agents.guardrail.GuardrailFunctionOutput.tripwire_triggered] が true かどうかを確認します。true の場合、[`OutputGuardrailTripwireTriggered`][agents.exceptions.OutputGuardrailTripwireTriggered] 例外が送出されるので、 ユーザー への適切な応答や例外処理を行えます
1. まず、ガードレールはエージェントが生成した出力を受け取ります
2. 次に、ガードレール関数が実行され [`GuardrailFunctionOutput`][agents.guardrail.GuardrailFunctionOutput] を生成し、それが [`OutputGuardrailResult`][agents.guardrail.OutputGuardrailResult] にラップされます
3. 最後に [.tripwire_triggered][agents.guardrail.GuardrailFunctionOutput.tripwire_triggered] が true かどうかを確認します。true の場合、[`OutputGuardrailTripwireTriggered`][agents.exceptions.OutputGuardrailTripwireTriggered] 例外が送出されるので、適切に ユーザー に応答したり例外を処理できます

!!! Note

Output ガードレールは最終的なエージェント出力に対して実行されることを想定しているため、エージェントのガードレールが実行されるのはそのエージェントが *最後* のエージェントである場合だけです。Input ガードレール同様、ガードレールは実際の エージェント に密接に関連するため、コードを同じ場所に置くことで可読性が向上します。
出力ガードレールは最終的なエージェント出力に対して実行されることを意図しているため、ガードレールは *最後* のエージェントでのみ実行されます。入力ガードレールの場合と同様、ガードレールが実際の エージェント と密接に関連していることが多いため、コードを同じ場所に置くことで可読性が向上します。

## トリップワイヤ
## トリップワイヤー

入力または出力がガードレールに失敗した場合、ガードレールはトリップワイヤを用いてそれを通知できます。ガードレールがトリップワイヤを発火したことを検知すると、ただちに `{Input,Output}GuardrailTripwireTriggered` 例外を送出してエージェントの実行を停止します
入力または出力がガードレールを通過できなかった場合、ガードレールはトリップワイヤーでそれを示すことができます。トリップワイヤーがトリガーされたガードレールを検知した時点で、直ちに `{Input,Output}GuardrailTripwireTriggered` 例外を送出し、エージェントの実行を停止します

## ガードレールの実装

入力を受け取り、[`GuardrailFunctionOutput`][agents.guardrail.GuardrailFunctionOutput] を返す関数を用意する必要があります。次の例では、内部で エージェント を実行してこれを行います。
入力を受け取り、[`GuardrailFunctionOutput`][agents.guardrail.GuardrailFunctionOutput] を返す関数を提供する必要があります。この例では、内部で エージェント を実行してこれを行います。

```python
from pydantic import BaseModel
@@ -94,12 +94,12 @@ async def main():
print("Math homework guardrail tripped")
```

1. この エージェント をガードレール関数内で使用します
2. これはエージェントの入力 / コンテキストを受け取り、結果を返すガードレール関数です。
1. このエージェントをガードレール関数内で使用します
2. これはエージェントの入力/コンテキストを受け取り、結果を返すガードレール関数です。
3. ガードレール結果に追加情報を含めることができます。
4. これはワークフローを定義する実際のエージェントです。

Output ガードレールも同様です
出力ガードレールも同様です

```python
from pydantic import BaseModel
@@ -155,4 +155,4 @@ async def main():
1. これは実際のエージェントの出力型です。
2. これはガードレールの出力型です。
3. これはエージェントの出力を受け取り、結果を返すガードレール関数です。
4. これはワークフローを定義する実際のエージェントです。
4. これはワークフローを定義する実際のエージェントです。
18 changes: 13 additions & 5 deletions docs/ja/mcp.md
Original file line number Diff line number Diff line change
@@ -12,23 +12,31 @@ Agents SDK は MCP をサポートしており、これにより幅広い MCP

## MCP サーバー

現在、MCP 仕様では使用するトランスポート方式に基づき 2 種類のサーバーが定義されています。
現在、MCP 仕様では使用するトランスポート方式に基づき 3 種類のサーバーが定義されています。

1. **stdio** サーバー: アプリケーションのサブプロセスとして実行されます。ローカルで動かすイメージです。
1. **stdio** サーバー: アプリケーションのサブプロセスとして実行されます。ローカルで動かすイメージです。
2. **HTTP over SSE** サーバー: リモートで動作し、 URL 経由で接続します。
3. **Streamable HTTP** サーバー: MCP 仕様に定義された Streamable HTTP トランスポートを使用してリモートで動作します。

これらのサーバーへは [`MCPServerStdio`][agents.mcp.server.MCPServerStdio][`MCPServerSse`][agents.mcp.server.MCPServerSse] クラスを使用して接続できます。
これらのサーバーへは [`MCPServerStdio`][agents.mcp.server.MCPServerStdio][`MCPServerSse`][agents.mcp.server.MCPServerSse][`MCPServerStreamableHttp`][agents.mcp.server.MCPServerStreamableHttp] クラスを使用して接続できます。

たとえば、[公式 MCP filesystem サーバー](https://www.npmjs.com/package/@modelcontextprotocol/server-filesystem)を利用する場合は次のようになります。

```python
from agents.run_context import RunContextWrapper

async with MCPServerStdio(
params={
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", samples_dir],
}
) as server:
tools = await server.list_tools()
# 注意:実際には通常は MCP サーバーをエージェントに追加し、
# フレームワークがツール一覧の取得を自動的に処理するようにします。
# list_tools() への直接呼び出しには run_context と agent パラメータが必要です。
run_context = RunContextWrapper(context=None)
agent = Agent(name="test", instructions="test")
tools = await server.list_tools(run_context, agent)
```

## MCP サーバーの利用
@@ -46,7 +54,7 @@ agent=Agent(

## キャッシュ

エージェントが実行されるたびに、MCP サーバーへ `list_tools()` が呼び出されます。サーバーがリモートの場合は特にレイテンシが発生します。ツール一覧を自動でキャッシュしたい場合は、[`MCPServerStdio`][agents.mcp.server.MCPServerStdio][`MCPServerSse`][agents.mcp.server.MCPServerSse] の両方に `cache_tools_list=True` を渡してください。ツール一覧が変更されないと確信できる場合のみ使用してください。
エージェントが実行されるたびに、MCP サーバーへ `list_tools()` が呼び出されます。サーバーがリモートの場合は特にレイテンシが発生します。ツール一覧を自動でキャッシュしたい場合は、[`MCPServerStdio`][agents.mcp.server.MCPServerStdio][`MCPServerSse`][agents.mcp.server.MCPServerSse][`MCPServerStreamableHttp`][agents.mcp.server.MCPServerStreamableHttp] の各クラスに `cache_tools_list=True` を渡してください。ツール一覧が変更されないと確信できる場合のみ使用してください。

キャッシュを無効化したい場合は、サーバーで `invalidate_tools_cache()` を呼び出します。

Loading