Upgrade openAI sdk version (#730)
--- [//]: # (BEGIN SAPLING FOOTER) * #732 * #731 * __->__ #730
This commit is contained in:
parent
466b44df18
commit
ce2e2a4571
7 changed files with 43 additions and 18 deletions
|
|
@ -7,7 +7,7 @@ requires-python = ">=3.9"
|
|||
license = "MIT"
|
||||
authors = [{ name = "OpenAI", email = "support@openai.com" }]
|
||||
dependencies = [
|
||||
"openai>=1.76.0",
|
||||
"openai>=1.81.0",
|
||||
"pydantic>=2.10, <3",
|
||||
"griffe>=1.5.6, <2",
|
||||
"typing-extensions>=4.12.2, <5",
|
||||
|
|
|
|||
|
|
@ -38,6 +38,16 @@ class StreamingState:
|
|||
function_calls: dict[int, ResponseFunctionToolCall] = field(default_factory=dict)
|
||||
|
||||
|
||||
class SequenceNumber:
|
||||
def __init__(self):
|
||||
self._sequence_number = 0
|
||||
|
||||
def get_and_increment(self) -> int:
|
||||
num = self._sequence_number
|
||||
self._sequence_number += 1
|
||||
return num
|
||||
|
||||
|
||||
class ChatCmplStreamHandler:
|
||||
@classmethod
|
||||
async def handle_stream(
|
||||
|
|
@ -47,13 +57,14 @@ class ChatCmplStreamHandler:
|
|||
) -> AsyncIterator[TResponseStreamEvent]:
|
||||
usage: CompletionUsage | None = None
|
||||
state = StreamingState()
|
||||
|
||||
sequence_number = SequenceNumber()
|
||||
async for chunk in stream:
|
||||
if not state.started:
|
||||
state.started = True
|
||||
yield ResponseCreatedEvent(
|
||||
response=response,
|
||||
type="response.created",
|
||||
sequence_number=sequence_number.get_and_increment(),
|
||||
)
|
||||
|
||||
# This is always set by the OpenAI API, but not by others e.g. LiteLLM
|
||||
|
|
@ -89,6 +100,7 @@ class ChatCmplStreamHandler:
|
|||
item=assistant_item,
|
||||
output_index=0,
|
||||
type="response.output_item.added",
|
||||
sequence_number=sequence_number.get_and_increment(),
|
||||
)
|
||||
yield ResponseContentPartAddedEvent(
|
||||
content_index=state.text_content_index_and_output[0],
|
||||
|
|
@ -100,6 +112,7 @@ class ChatCmplStreamHandler:
|
|||
annotations=[],
|
||||
),
|
||||
type="response.content_part.added",
|
||||
sequence_number=sequence_number.get_and_increment(),
|
||||
)
|
||||
# Emit the delta for this segment of content
|
||||
yield ResponseTextDeltaEvent(
|
||||
|
|
@ -108,6 +121,7 @@ class ChatCmplStreamHandler:
|
|||
item_id=FAKE_RESPONSES_ID,
|
||||
output_index=0,
|
||||
type="response.output_text.delta",
|
||||
sequence_number=sequence_number.get_and_increment(),
|
||||
)
|
||||
# Accumulate the text into the response part
|
||||
state.text_content_index_and_output[1].text += delta.content
|
||||
|
|
@ -134,6 +148,7 @@ class ChatCmplStreamHandler:
|
|||
item=assistant_item,
|
||||
output_index=0,
|
||||
type="response.output_item.added",
|
||||
sequence_number=sequence_number.get_and_increment(),
|
||||
)
|
||||
yield ResponseContentPartAddedEvent(
|
||||
content_index=state.refusal_content_index_and_output[0],
|
||||
|
|
@ -145,6 +160,7 @@ class ChatCmplStreamHandler:
|
|||
annotations=[],
|
||||
),
|
||||
type="response.content_part.added",
|
||||
sequence_number=sequence_number.get_and_increment(),
|
||||
)
|
||||
# Emit the delta for this segment of refusal
|
||||
yield ResponseRefusalDeltaEvent(
|
||||
|
|
@ -153,6 +169,7 @@ class ChatCmplStreamHandler:
|
|||
item_id=FAKE_RESPONSES_ID,
|
||||
output_index=0,
|
||||
type="response.refusal.delta",
|
||||
sequence_number=sequence_number.get_and_increment(),
|
||||
)
|
||||
# Accumulate the refusal string in the output part
|
||||
state.refusal_content_index_and_output[1].refusal += delta.refusal
|
||||
|
|
@ -190,6 +207,7 @@ class ChatCmplStreamHandler:
|
|||
output_index=0,
|
||||
part=state.text_content_index_and_output[1],
|
||||
type="response.content_part.done",
|
||||
sequence_number=sequence_number.get_and_increment(),
|
||||
)
|
||||
|
||||
if state.refusal_content_index_and_output:
|
||||
|
|
@ -201,6 +219,7 @@ class ChatCmplStreamHandler:
|
|||
output_index=0,
|
||||
part=state.refusal_content_index_and_output[1],
|
||||
type="response.content_part.done",
|
||||
sequence_number=sequence_number.get_and_increment(),
|
||||
)
|
||||
|
||||
# Actually send events for the function calls
|
||||
|
|
@ -216,6 +235,7 @@ class ChatCmplStreamHandler:
|
|||
),
|
||||
output_index=function_call_starting_index,
|
||||
type="response.output_item.added",
|
||||
sequence_number=sequence_number.get_and_increment(),
|
||||
)
|
||||
# Then, yield the args
|
||||
yield ResponseFunctionCallArgumentsDeltaEvent(
|
||||
|
|
@ -223,6 +243,7 @@ class ChatCmplStreamHandler:
|
|||
item_id=FAKE_RESPONSES_ID,
|
||||
output_index=function_call_starting_index,
|
||||
type="response.function_call_arguments.delta",
|
||||
sequence_number=sequence_number.get_and_increment(),
|
||||
)
|
||||
# Finally, the ResponseOutputItemDone
|
||||
yield ResponseOutputItemDoneEvent(
|
||||
|
|
@ -235,6 +256,7 @@ class ChatCmplStreamHandler:
|
|||
),
|
||||
output_index=function_call_starting_index,
|
||||
type="response.output_item.done",
|
||||
sequence_number=sequence_number.get_and_increment(),
|
||||
)
|
||||
|
||||
# Finally, send the Response completed event
|
||||
|
|
@ -258,6 +280,7 @@ class ChatCmplStreamHandler:
|
|||
item=assistant_msg,
|
||||
output_index=0,
|
||||
type="response.output_item.done",
|
||||
sequence_number=sequence_number.get_and_increment(),
|
||||
)
|
||||
|
||||
for function_call in state.function_calls.values():
|
||||
|
|
@ -289,4 +312,5 @@ class ChatCmplStreamHandler:
|
|||
yield ResponseCompletedEvent(
|
||||
response=final_response,
|
||||
type="response.completed",
|
||||
sequence_number=sequence_number.get_and_increment(),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ from openai.types import ChatModel
|
|||
from openai.types.responses import (
|
||||
Response,
|
||||
ResponseCompletedEvent,
|
||||
ResponseIncludable,
|
||||
ResponseStreamEvent,
|
||||
ResponseTextConfigParam,
|
||||
ToolParam,
|
||||
|
|
@ -36,13 +37,6 @@ if TYPE_CHECKING:
|
|||
_USER_AGENT = f"Agents/Python {__version__}"
|
||||
_HEADERS = {"User-Agent": _USER_AGENT}
|
||||
|
||||
# From the Responses API
|
||||
IncludeLiteral = Literal[
|
||||
"file_search_call.results",
|
||||
"message.input_image.image_url",
|
||||
"computer_call_output.output.image_url",
|
||||
]
|
||||
|
||||
|
||||
class OpenAIResponsesModel(Model):
|
||||
"""
|
||||
|
|
@ -273,7 +267,7 @@ class OpenAIResponsesModel(Model):
|
|||
@dataclass
|
||||
class ConvertedTools:
|
||||
tools: list[ToolParam]
|
||||
includes: list[IncludeLiteral]
|
||||
includes: list[ResponseIncludable]
|
||||
|
||||
|
||||
class Converter:
|
||||
|
|
@ -330,7 +324,7 @@ class Converter:
|
|||
handoffs: list[Handoff[Any]],
|
||||
) -> ConvertedTools:
|
||||
converted_tools: list[ToolParam] = []
|
||||
includes: list[IncludeLiteral] = []
|
||||
includes: list[ResponseIncludable] = []
|
||||
|
||||
computer_tools = [tool for tool in tools if isinstance(tool, ComputerTool)]
|
||||
if len(computer_tools) > 1:
|
||||
|
|
@ -348,7 +342,7 @@ class Converter:
|
|||
return ConvertedTools(tools=converted_tools, includes=includes)
|
||||
|
||||
@classmethod
|
||||
def _convert_tool(cls, tool: Tool) -> tuple[ToolParam, IncludeLiteral | None]:
|
||||
def _convert_tool(cls, tool: Tool) -> tuple[ToolParam, ResponseIncludable | None]:
|
||||
"""Returns converted tool and includes"""
|
||||
|
||||
if isinstance(tool, FunctionTool):
|
||||
|
|
@ -359,7 +353,7 @@ class Converter:
|
|||
"type": "function",
|
||||
"description": tool.description,
|
||||
}
|
||||
includes: IncludeLiteral | None = None
|
||||
includes: ResponseIncludable | None = None
|
||||
elif isinstance(tool, WebSearchTool):
|
||||
ws: WebSearchToolParam = {
|
||||
"type": "web_search_preview",
|
||||
|
|
|
|||
|
|
@ -129,6 +129,7 @@ class FakeModel(Model):
|
|||
yield ResponseCompletedEvent(
|
||||
type="response.completed",
|
||||
response=get_response_obj(output, usage=self.hardcoded_usage),
|
||||
sequence_number=0,
|
||||
)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ class DummyResponse:
|
|||
yield ResponseCompletedEvent(
|
||||
type="response.completed",
|
||||
response=fake_model.get_response_obj(self.output),
|
||||
sequence_number=0,
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -201,6 +202,7 @@ async def test_stream_response_creates_trace(monkeypatch):
|
|||
yield ResponseCompletedEvent(
|
||||
type="response.completed",
|
||||
response=fake_model.get_response_obj([], "dummy-id-123"),
|
||||
sequence_number=0,
|
||||
)
|
||||
|
||||
return DummyStream()
|
||||
|
|
@ -253,6 +255,7 @@ async def test_stream_non_data_tracing_doesnt_set_response_id(monkeypatch):
|
|||
yield ResponseCompletedEvent(
|
||||
type="response.completed",
|
||||
response=fake_model.get_response_obj([], "dummy-id-123"),
|
||||
sequence_number=0,
|
||||
)
|
||||
|
||||
return DummyStream()
|
||||
|
|
@ -304,6 +307,7 @@ async def test_stream_disabled_tracing_doesnt_create_span(monkeypatch):
|
|||
yield ResponseCompletedEvent(
|
||||
type="response.completed",
|
||||
response=fake_model.get_response_obj([], "dummy-id-123"),
|
||||
sequence_number=0,
|
||||
)
|
||||
|
||||
return DummyStream()
|
||||
|
|
|
|||
|
|
@ -81,11 +81,13 @@ class FakeStreamingModel(Model):
|
|||
type="response.output_text.delta",
|
||||
output_index=0,
|
||||
item_id=item.id,
|
||||
sequence_number=0,
|
||||
)
|
||||
|
||||
yield ResponseCompletedEvent(
|
||||
type="response.completed",
|
||||
response=get_response_obj(output),
|
||||
sequence_number=1,
|
||||
)
|
||||
|
||||
|
||||
|
|
|
|||
10
uv.lock
10
uv.lock
|
|
@ -1461,7 +1461,7 @@ wheels = [
|
|||
|
||||
[[package]]
|
||||
name = "openai"
|
||||
version = "1.76.0"
|
||||
version = "1.81.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "anyio" },
|
||||
|
|
@ -1473,14 +1473,14 @@ dependencies = [
|
|||
{ name = "tqdm" },
|
||||
{ name = "typing-extensions" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/84/51/817969ec969b73d8ddad085670ecd8a45ef1af1811d8c3b8a177ca4d1309/openai-1.76.0.tar.gz", hash = "sha256:fd2bfaf4608f48102d6b74f9e11c5ecaa058b60dad9c36e409c12477dfd91fb2", size = 434660 }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/1c/89/a1e4f3fa7ca4f7fec90dbf47d93b7cd5ff65924926733af15044e302a192/openai-1.81.0.tar.gz", hash = "sha256:349567a8607e0bcffd28e02f96b5c2397d0d25d06732d90ab3ecbf97abf030f9", size = 456861 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/59/aa/84e02ab500ca871eb8f62784426963a1c7c17a72fea3c7f268af4bbaafa5/openai-1.76.0-py3-none-any.whl", hash = "sha256:a712b50e78cf78e6d7b2a8f69c4978243517c2c36999756673e07a14ce37dc0a", size = 661201 },
|
||||
{ url = "https://files.pythonhosted.org/packages/02/66/bcc7f9bf48e8610a33e3b5c96a5a644dad032d92404ea2a5e8b43ba067e8/openai-1.81.0-py3-none-any.whl", hash = "sha256:1c71572e22b43876c5d7d65ade0b7b516bb527c3d44ae94111267a09125f7bae", size = 717529 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "openai-agents"
|
||||
version = "0.0.14"
|
||||
version = "0.0.15"
|
||||
source = { editable = "." }
|
||||
dependencies = [
|
||||
{ name = "griffe" },
|
||||
|
|
@ -1536,7 +1536,7 @@ requires-dist = [
|
|||
{ name = "litellm", marker = "extra == 'litellm'", specifier = ">=1.67.4.post1,<2" },
|
||||
{ name = "mcp", marker = "python_full_version >= '3.10'", specifier = ">=1.8.0,<2" },
|
||||
{ name = "numpy", marker = "python_full_version >= '3.10' and extra == 'voice'", specifier = ">=2.2.0,<3" },
|
||||
{ name = "openai", specifier = ">=1.76.0" },
|
||||
{ name = "openai", specifier = ">=1.81.0" },
|
||||
{ name = "pydantic", specifier = ">=2.10,<3" },
|
||||
{ name = "requests", specifier = ">=2.0,<3" },
|
||||
{ name = "types-requests", specifier = ">=2.0,<3" },
|
||||
|
|
|
|||
Loading…
Reference in a new issue