diff --git a/examples/tools/computer_use.py b/examples/tools/computer_use.py index ae339552..832255e8 100644 --- a/examples/tools/computer_use.py +++ b/examples/tools/computer_use.py @@ -1,6 +1,5 @@ import asyncio import base64 -import logging from typing import Literal, Union from playwright.async_api import Browser, Page, Playwright, async_playwright @@ -16,8 +15,10 @@ trace, ) -logging.getLogger("openai.agents").setLevel(logging.DEBUG) -logging.getLogger("openai.agents").addHandler(logging.StreamHandler()) +# Uncomment to see very verbose logs +# import logging +# logging.getLogger("openai.agents").setLevel(logging.DEBUG) +# logging.getLogger("openai.agents").addHandler(logging.StreamHandler()) async def main(): diff --git a/pyproject.toml b/pyproject.toml index 9c18d5f6..262ce17c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "openai-agents" -version = "0.0.2" +version = "0.0.3" description = "OpenAI Agents SDK" readme = "README.md" requires-python = ">=3.9" @@ -9,7 +9,7 @@ authors = [ { name = "OpenAI", email = "support@openai.com" }, ] dependencies = [ - "openai>=1.66.0", + "openai>=1.66.2", "pydantic>=2.10, <3", "griffe>=1.5.6, <2", "typing-extensions>=4.12.2, <5", diff --git a/src/agents/_run_impl.py b/src/agents/_run_impl.py index 112819c8..47ee8cdd 100644 --- a/src/agents/_run_impl.py +++ b/src/agents/_run_impl.py @@ -23,7 +23,7 @@ ActionWait, ) from openai.types.responses.response_input_param import ComputerCallOutput -from openai.types.responses.response_output_item import Reasoning +from openai.types.responses.response_reasoning_item import ResponseReasoningItem from . import _utils from .agent import Agent @@ -288,7 +288,7 @@ def process_model_response( items.append(ToolCallItem(raw_item=output, agent=agent)) elif isinstance(output, ResponseFunctionWebSearch): items.append(ToolCallItem(raw_item=output, agent=agent)) - elif isinstance(output, Reasoning): + elif isinstance(output, ResponseReasoningItem): items.append(ReasoningItem(raw_item=output, agent=agent)) elif isinstance(output, ResponseComputerToolCall): items.append(ToolCallItem(raw_item=output, agent=agent)) diff --git a/src/agents/items.py b/src/agents/items.py index bbaf49d8..ffbeba02 100644 --- a/src/agents/items.py +++ b/src/agents/items.py @@ -19,7 +19,7 @@ ResponseStreamEvent, ) from openai.types.responses.response_input_item_param import ComputerCallOutput, FunctionCallOutput -from openai.types.responses.response_output_item import Reasoning +from openai.types.responses.response_reasoning_item import ResponseReasoningItem from pydantic import BaseModel from typing_extensions import TypeAlias @@ -136,10 +136,10 @@ class ToolCallOutputItem(RunItemBase[Union[FunctionCallOutput, ComputerCallOutpu @dataclass -class ReasoningItem(RunItemBase[Reasoning]): +class ReasoningItem(RunItemBase[ResponseReasoningItem]): """Represents a reasoning item.""" - raw_item: Reasoning + raw_item: ResponseReasoningItem """The raw reasoning item.""" type: Literal["reasoning_item"] = "reasoning_item" diff --git a/src/agents/models/openai_responses.py b/src/agents/models/openai_responses.py index a10d7b98..e060fb8e 100644 --- a/src/agents/models/openai_responses.py +++ b/src/agents/models/openai_responses.py @@ -361,7 +361,7 @@ def _convert_tool(cls, tool: Tool) -> tuple[ToolParam, IncludeLiteral | None]: includes = "file_search_call.results" if tool.include_search_results else None elif isinstance(tool, ComputerTool): converted_tool = { - "type": "computer-preview", + "type": "computer_use_preview", "environment": tool.computer.environment, "display_width": tool.computer.dimensions[0], "display_height": tool.computer.dimensions[1], diff --git a/src/agents/tool.py b/src/agents/tool.py index 75872680..8a3bc9eb 100644 --- a/src/agents/tool.py +++ b/src/agents/tool.py @@ -284,3 +284,5 @@ def decorator(real_func: ToolFunction[...]) -> FunctionTool: return _create_function_tool(real_func) return decorator + return decorator + return decorator diff --git a/tests/test_items_helpers.py b/tests/test_items_helpers.py index 64e2dcda..90fe6475 100644 --- a/tests/test_items_helpers.py +++ b/tests/test_items_helpers.py @@ -13,12 +13,12 @@ from openai.types.responses.response_function_tool_call_param import ResponseFunctionToolCallParam from openai.types.responses.response_function_web_search import ResponseFunctionWebSearch from openai.types.responses.response_function_web_search_param import ResponseFunctionWebSearchParam -from openai.types.responses.response_input_item_param import Reasoning as ReasoningInputParam -from openai.types.responses.response_output_item import Reasoning, ReasoningContent from openai.types.responses.response_output_message import ResponseOutputMessage from openai.types.responses.response_output_message_param import ResponseOutputMessageParam from openai.types.responses.response_output_refusal import ResponseOutputRefusal from openai.types.responses.response_output_text import ResponseOutputText +from openai.types.responses.response_reasoning_item import ResponseReasoningItem, Summary +from openai.types.responses.response_reasoning_item_param import ResponseReasoningItemParam from agents import ( Agent, @@ -129,7 +129,7 @@ def test_text_message_outputs_across_list_of_runitems() -> None: item1: RunItem = MessageOutputItem(agent=Agent(name="test"), raw_item=message1) item2: RunItem = MessageOutputItem(agent=Agent(name="test"), raw_item=message2) # Create a non-message run item of a different type, e.g., a reasoning trace. - reasoning = Reasoning(id="rid", content=[], type="reasoning") + reasoning = ResponseReasoningItem(id="rid", summary=[], type="reasoning") non_message_item: RunItem = ReasoningItem(agent=Agent(name="test"), raw_item=reasoning) # Confirm only the message outputs are concatenated. assert ItemHelpers.text_message_outputs([item1, non_message_item, item2]) == "foobar" @@ -266,16 +266,18 @@ def test_to_input_items_for_computer_call_click() -> None: def test_to_input_items_for_reasoning() -> None: """A reasoning output should produce the same dict as a reasoning input item.""" - rc = ReasoningContent(text="why", type="reasoning_summary") - reasoning = Reasoning(id="rid1", content=[rc], type="reasoning") + rc = Summary(text="why", type="summary_text") + reasoning = ResponseReasoningItem(id="rid1", summary=[rc], type="reasoning") resp = ModelResponse(output=[reasoning], usage=Usage(), referenceable_id=None) input_items = resp.to_input_items() assert isinstance(input_items, list) and len(input_items) == 1 converted_dict = input_items[0] - expected: ReasoningInputParam = { + expected: ResponseReasoningItemParam = { "id": "rid1", - "content": [{"text": "why", "type": "reasoning_summary"}], + "summary": [{"text": "why", "type": "summary_text"}], "type": "reasoning", } + print(converted_dict) + print(expected) assert converted_dict == expected diff --git a/tests/test_openai_responses_converter.py b/tests/test_openai_responses_converter.py index 58204265..34cbac5c 100644 --- a/tests/test_openai_responses_converter.py +++ b/tests/test_openai_responses_converter.py @@ -163,7 +163,7 @@ def drag(self, path: list[tuple[int, int]]) -> None: assert "function" in types assert "file_search" in types assert "web_search_preview" in types - assert "computer-preview" in types + assert "computer_use_preview" in types # Verify file search tool contains max_num_results and vector_store_ids file_params = next(ct for ct in converted.tools if ct["type"] == "file_search") assert file_params.get("max_num_results") == file_tool.max_num_results @@ -173,7 +173,7 @@ def drag(self, path: list[tuple[int, int]]) -> None: assert web_params.get("user_location") == web_tool.user_location assert web_params.get("search_context_size") == web_tool.search_context_size # Verify computer tool contains environment and computed dimensions - comp_params = next(ct for ct in converted.tools if ct["type"] == "computer-preview") + comp_params = next(ct for ct in converted.tools if ct["type"] == "computer_use_preview") assert comp_params.get("environment") == "mac" assert comp_params.get("display_width") == 800 assert comp_params.get("display_height") == 600 diff --git a/tests/test_run_step_processing.py b/tests/test_run_step_processing.py index 41f65c4c..24f9e8e3 100644 --- a/tests/test_run_step_processing.py +++ b/tests/test_run_step_processing.py @@ -7,7 +7,7 @@ ResponseFunctionWebSearch, ) from openai.types.responses.response_computer_tool_call import ActionClick -from openai.types.responses.response_output_item import Reasoning, ReasoningContent +from openai.types.responses.response_reasoning_item import ResponseReasoningItem, Summary from pydantic import BaseModel from agents import ( @@ -287,8 +287,8 @@ def test_function_web_search_tool_call_parsed_correctly(): def test_reasoning_item_parsed_correctly(): # Verify that a Reasoning output item is converted into a ReasoningItem. - reasoning = Reasoning( - id="r1", type="reasoning", content=[ReasoningContent(text="why", type="reasoning_summary")] + reasoning = ResponseReasoningItem( + id="r1", type="reasoning", summary=[Summary(text="why", type="summary_text")] ) response = ModelResponse( output=[reasoning], diff --git a/uv.lock b/uv.lock index 2bceea75..9179bd4f 100644 --- a/uv.lock +++ b/uv.lock @@ -764,7 +764,7 @@ wheels = [ [[package]] name = "openai" -version = "1.66.0" +version = "1.66.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "anyio" }, @@ -776,14 +776,14 @@ dependencies = [ { name = "tqdm" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/84/c5/3c422ca3ccc81c063955e7c20739d7f8f37fea0af865c4a60c81e6225e14/openai-1.66.0.tar.gz", hash = "sha256:8a9e672bc6eadec60a962f0b40d7d1c09050010179c919ed65322e433e2d1025", size = 396819 } +sdist = { url = "https://files.pythonhosted.org/packages/d8/e1/b3e1fda1aa32d4f40d4de744e91de4de65c854c3e53c63342e4b5f9c5995/openai-1.66.2.tar.gz", hash = "sha256:9b3a843c25f81ee09b6469d483d9fba779d5c6ea41861180772f043481b0598d", size = 397041 } wheels = [ - { url = "https://files.pythonhosted.org/packages/d7/f1/d52960dac9519c9de64593460826a0fe2e19159389ec97ecf3e931d2e6a3/openai-1.66.0-py3-none-any.whl", hash = "sha256:43e4a3c0c066cc5809be4e6aac456a3ebc4ec1848226ef9d1340859ac130d45a", size = 566389 }, + { url = "https://files.pythonhosted.org/packages/2c/6f/3315b3583ffe3e31c55b446cb22d2a7c235e65ca191674fffae62deb3c11/openai-1.66.2-py3-none-any.whl", hash = "sha256:75194057ee6bb8b732526387b6041327a05656d976fc21c064e21c8ac6b07999", size = 567268 }, ] [[package]] name = "openai-agents" -version = "0.0.2" +version = "0.0.3" source = { editable = "." } dependencies = [ { name = "griffe" }, @@ -812,7 +812,7 @@ dev = [ [package.metadata] requires-dist = [ { name = "griffe", specifier = ">=1.5.6,<2" }, - { name = "openai", specifier = ">=1.66.0" }, + { name = "openai", specifier = ">=1.66.2" }, { name = "pydantic", specifier = ">=2.10,<3" }, { name = "requests", specifier = ">=2.0,<3" }, { name = "types-requests", specifier = ">=2.0,<3" },