diff --git a/pyproject.toml b/pyproject.toml index 6de0067cf..7bd92afd7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,7 +7,7 @@ requires-python = ">=3.9" license = "MIT" authors = [{ name = "OpenAI", email = "support@openai.com" }] dependencies = [ - "openai>=2.6.1,<3", + "openai>=2.7.1,<3", "pydantic>=2.12.3, <3", "griffe>=1.5.6, <2", "typing-extensions>=4.12.2, <5", diff --git a/src/agents/models/chatcmpl_converter.py b/src/agents/models/chatcmpl_converter.py index 6e01874a8..bc0304be0 100644 --- a/src/agents/models/chatcmpl_converter.py +++ b/src/agents/models/chatcmpl_converter.py @@ -51,6 +51,8 @@ from ..tool import FunctionTool, Tool from .fake_id import FAKE_RESPONSES_ID +ResponseInputContentWithAudioParam = Union[ResponseInputContentParam, ResponseInputAudioParam] + class Converter: @classmethod @@ -136,7 +138,9 @@ def message_to_output_items(cls, message: ChatCompletionMessage) -> list[TRespon ) if message.content: message_item.content.append( - ResponseOutputText(text=message.content, type="output_text", annotations=[]) + ResponseOutputText( + text=message.content, type="output_text", annotations=[], logprobs=[] + ) ) if message.refusal: message_item.content.append( @@ -246,7 +250,7 @@ def maybe_reasoning_message(cls, item: Any) -> ResponseReasoningItemParam | None @classmethod def extract_text_content( - cls, content: str | Iterable[ResponseInputContentParam] + cls, content: str | Iterable[ResponseInputContentWithAudioParam] ) -> str | list[ChatCompletionContentPartTextParam]: all_content = cls.extract_all_content(content) if isinstance(all_content, str): @@ -259,7 +263,7 @@ def extract_text_content( @classmethod def extract_all_content( - cls, content: str | Iterable[ResponseInputContentParam] + cls, content: str | Iterable[ResponseInputContentWithAudioParam] ) -> str | list[ChatCompletionContentPartParam]: if isinstance(content, str): return content @@ -535,7 +539,7 @@ def ensure_assistant_message() -> ChatCompletionAssistantMessageParam: elif func_output := cls.maybe_function_tool_call_output(item): flush_assistant_message() output_content = cast( - Union[str, Iterable[ResponseInputContentParam]], func_output["output"] + Union[str, Iterable[ResponseInputContentWithAudioParam]], func_output["output"] ) msg: ChatCompletionToolMessageParam = { "role": "tool", diff --git a/src/agents/models/chatcmpl_stream_handler.py b/src/agents/models/chatcmpl_stream_handler.py index 31d015a76..94dd10205 100644 --- a/src/agents/models/chatcmpl_stream_handler.py +++ b/src/agents/models/chatcmpl_stream_handler.py @@ -231,6 +231,7 @@ async def handle_stream( text="", type="output_text", annotations=[], + logprobs=[], ), ) # Start a new assistant message stream @@ -258,6 +259,7 @@ async def handle_stream( text="", type="output_text", annotations=[], + logprobs=[], ), type="response.content_part.added", sequence_number=sequence_number.get_and_increment(), diff --git a/tests/extensions/memory/test_sqlalchemy_session.py b/tests/extensions/memory/test_sqlalchemy_session.py index 0a498c189..b280a000f 100644 --- a/tests/extensions/memory/test_sqlalchemy_session.py +++ b/tests/extensions/memory/test_sqlalchemy_session.py @@ -36,6 +36,7 @@ def _make_message_item(item_id: str, text_value: str) -> TResponseInputItem: "type": "output_text", "text": text_value, "annotations": [], + "logprobs": [], } message: ResponseOutputMessageParam = { "id": item_id, diff --git a/tests/test_agent_as_tool.py b/tests/test_agent_as_tool.py index 1b8b99682..0f5736b03 100644 --- a/tests/test_agent_as_tool.py +++ b/tests/test_agent_as_tool.py @@ -240,7 +240,7 @@ async def test_agent_as_tool_returns_concatenated_text(monkeypatch: pytest.Monke annotations=[], text="Hello world", type="output_text", - logprobs=None, + logprobs=[], ) ], ) @@ -304,7 +304,7 @@ async def test_agent_as_tool_custom_output_extractor(monkeypatch: pytest.MonkeyP annotations=[], text="Original text", type="output_text", - logprobs=None, + logprobs=[], ) ], ) diff --git a/tests/test_agent_runner.py b/tests/test_agent_runner.py index 441054dd4..ceac6c50f 100644 --- a/tests/test_agent_runner.py +++ b/tests/test_agent_runner.py @@ -1226,6 +1226,7 @@ async def echo_tool(text: str) -> str: "content": [ { "annotations": [], + "logprobs": [], "text": "Summary: Echoed foo and bar", "type": "output_text", } diff --git a/tests/test_call_model_input_filter_unit.py b/tests/test_call_model_input_filter_unit.py index 7cf3a00a9..ff14fc282 100644 --- a/tests/test_call_model_input_filter_unit.py +++ b/tests/test_call_model_input_filter_unit.py @@ -28,7 +28,9 @@ async def test_call_model_input_filter_sync_non_streamed_unit() -> None: id="1", type="message", role="assistant", - content=[ResponseOutputText(text="ok", type="output_text", annotations=[])], + content=[ + ResponseOutputText(text="ok", type="output_text", annotations=[], logprobs=[]) + ], status="completed", ) ] @@ -64,7 +66,9 @@ async def test_call_model_input_filter_async_streamed_unit() -> None: id="1", type="message", role="assistant", - content=[ResponseOutputText(text="ok", type="output_text", annotations=[])], + content=[ + ResponseOutputText(text="ok", type="output_text", annotations=[], logprobs=[]) + ], status="completed", ) ] diff --git a/tests/test_extension_filters.py b/tests/test_extension_filters.py index 11fba51ba..0c7732995 100644 --- a/tests/test_extension_filters.py +++ b/tests/test_extension_filters.py @@ -42,7 +42,9 @@ def _get_message_output_run_item(content: str) -> MessageOutputItem: agent=fake_agent(), raw_item=ResponseOutputMessage( id="1", - content=[ResponseOutputText(text=content, annotations=[], type="output_text")], + content=[ + ResponseOutputText(text=content, annotations=[], type="output_text", logprobs=[]) + ], role="assistant", status="completed", type="message", diff --git a/tests/test_handoff_tool.py b/tests/test_handoff_tool.py index 70d9799fb..37c00efab 100644 --- a/tests/test_handoff_tool.py +++ b/tests/test_handoff_tool.py @@ -27,7 +27,9 @@ def message_item(content: str, agent: Agent[Any]) -> MessageOutputItem: status="completed", role="assistant", type="message", - content=[ResponseOutputText(text=content, type="output_text", annotations=[])], + content=[ + ResponseOutputText(text=content, type="output_text", annotations=[], logprobs=[]) + ], ), ) diff --git a/tests/test_items_helpers.py b/tests/test_items_helpers.py index a94d74547..0bead32db 100644 --- a/tests/test_items_helpers.py +++ b/tests/test_items_helpers.py @@ -57,8 +57,8 @@ def make_message( def test_extract_last_content_of_text_message() -> None: # Build a message containing two text segments. - content1 = ResponseOutputText(annotations=[], text="Hello ", type="output_text") - content2 = ResponseOutputText(annotations=[], text="world!", type="output_text") + content1 = ResponseOutputText(annotations=[], text="Hello ", type="output_text", logprobs=[]) + content2 = ResponseOutputText(annotations=[], text="world!", type="output_text", logprobs=[]) message = make_message([content1, content2]) # Helpers should yield the last segment's text. assert ItemHelpers.extract_last_content(message) == "world!" @@ -66,7 +66,9 @@ def test_extract_last_content_of_text_message() -> None: def test_extract_last_content_of_refusal_message() -> None: # Build a message whose last content entry is a refusal. - content1 = ResponseOutputText(annotations=[], text="Before refusal", type="output_text") + content1 = ResponseOutputText( + annotations=[], text="Before refusal", type="output_text", logprobs=[] + ) refusal = ResponseOutputRefusal(refusal="I cannot do that", type="refusal") message = make_message([content1, refusal]) # Helpers should extract the refusal string when last content is a refusal. @@ -87,8 +89,8 @@ def test_extract_last_content_non_message_returns_empty() -> None: def test_extract_last_text_returns_text_only() -> None: # A message whose last segment is text yields the text. - first_text = ResponseOutputText(annotations=[], text="part1", type="output_text") - second_text = ResponseOutputText(annotations=[], text="part2", type="output_text") + first_text = ResponseOutputText(annotations=[], text="part1", type="output_text", logprobs=[]) + second_text = ResponseOutputText(annotations=[], text="part2", type="output_text", logprobs=[]) message = make_message([first_text, second_text]) assert ItemHelpers.extract_last_text(message) == "part2" # Whereas when last content is a refusal, extract_last_text returns None. @@ -116,9 +118,9 @@ def test_input_to_new_input_list_deep_copies_lists() -> None: def test_text_message_output_concatenates_text_segments() -> None: # Build a message with both text and refusal segments, only text segments are concatenated. pieces: list[ResponseOutputText | ResponseOutputRefusal] = [] - pieces.append(ResponseOutputText(annotations=[], text="a", type="output_text")) + pieces.append(ResponseOutputText(annotations=[], text="a", type="output_text", logprobs=[])) pieces.append(ResponseOutputRefusal(refusal="denied", type="refusal")) - pieces.append(ResponseOutputText(annotations=[], text="b", type="output_text")) + pieces.append(ResponseOutputText(annotations=[], text="b", type="output_text", logprobs=[])) message = make_message(pieces) # Wrap into MessageOutputItem to feed into text_message_output. item = MessageOutputItem(agent=Agent(name="test"), raw_item=message) @@ -131,8 +133,12 @@ def test_text_message_outputs_across_list_of_runitems() -> None: that only MessageOutputItem instances contribute any text. The non-message (ReasoningItem) should be ignored by Helpers.text_message_outputs. """ - message1 = make_message([ResponseOutputText(annotations=[], text="foo", type="output_text")]) - message2 = make_message([ResponseOutputText(annotations=[], text="bar", type="output_text")]) + message1 = make_message( + [ResponseOutputText(annotations=[], text="foo", type="output_text", logprobs=[])] + ) + message2 = make_message( + [ResponseOutputText(annotations=[], text="bar", type="output_text", logprobs=[])] + ) 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. @@ -171,7 +177,9 @@ def test_tool_call_output_item_constructs_function_call_output_dict(): def test_to_input_items_for_message() -> None: """An output message should convert into an input dict matching the message's own structure.""" - content = ResponseOutputText(annotations=[], text="hello world", type="output_text") + content = ResponseOutputText( + annotations=[], text="hello world", type="output_text", logprobs=[] + ) message = ResponseOutputMessage( id="m1", content=[content], role="assistant", status="completed", type="message" ) @@ -184,6 +192,7 @@ def test_to_input_items_for_message() -> None: "content": [ { "annotations": [], + "logprobs": [], "text": "hello world", "type": "output_text", } @@ -305,6 +314,7 @@ def test_input_to_new_input_list_copies_the_ones_produced_by_pydantic() -> None: type="output_text", text="Hey, what's up?", annotations=[], + logprobs=[], ) ], role="assistant", diff --git a/tests/test_openai_chatcompletions_converter.py b/tests/test_openai_chatcompletions_converter.py index 18dfdf045..838c0eeed 100644 --- a/tests/test_openai_chatcompletions_converter.py +++ b/tests/test_openai_chatcompletions_converter.py @@ -152,6 +152,7 @@ def test_items_to_messages_with_output_message_and_function_call(): text="Part 1", type="output_text", annotations=[], + logprobs=[], ) refusal: ResponseOutputRefusal = ResponseOutputRefusal( refusal="won't do that", diff --git a/tests/test_responses.py b/tests/test_responses.py index 74212f61b..3bf242b00 100644 --- a/tests/test_responses.py +++ b/tests/test_responses.py @@ -31,7 +31,7 @@ def get_text_message(content: str) -> ResponseOutputItem: id="1", type="message", role="assistant", - content=[ResponseOutputText(text=content, type="output_text", annotations=[])], + content=[ResponseOutputText(text=content, type="output_text", annotations=[], logprobs=[])], status="completed", ) @@ -73,6 +73,6 @@ def get_final_output_message(args: str) -> ResponseOutputItem: id="1", type="message", role="assistant", - content=[ResponseOutputText(text=args, type="output_text", annotations=[])], + content=[ResponseOutputText(text=args, type="output_text", annotations=[], logprobs=[])], status="completed", ) diff --git a/tests/utils/test_json.py b/tests/utils/test_json.py index ff52364f0..fbd8a61c0 100644 --- a/tests/utils/test_json.py +++ b/tests/utils/test_json.py @@ -16,6 +16,7 @@ def test_to_dump_compatible(): type="output_text", text="Hey, what's up?", annotations=[], + logprobs=[], ) ].__iter__(), role="assistant", @@ -28,5 +29,5 @@ def test_to_dump_compatible(): result = json.dumps(_to_dump_compatible(input_iter)) assert ( result - == """[{"id": "a75654dc-7492-4d1c-bce0-89e8312fbdd7", "content": [{"type": "output_text", "text": "Hey, what's up?", "annotations": []}], "role": "assistant", "status": "completed", "type": "message"}]""" # noqa: E501 + == """[{"id": "a75654dc-7492-4d1c-bce0-89e8312fbdd7", "content": [{"type": "output_text", "text": "Hey, what's up?", "annotations": [], "logprobs": []}], "role": "assistant", "status": "completed", "type": "message"}]""" # noqa: E501 ) diff --git a/tests/voice/test_workflow.py b/tests/voice/test_workflow.py index 2b8548442..402c52128 100644 --- a/tests/voice/test_workflow.py +++ b/tests/voice/test_workflow.py @@ -139,7 +139,9 @@ async def test_single_agent_workflow(monkeypatch) -> None: }, { "id": "1", - "content": [{"annotations": [], "text": "a_message", "type": "output_text"}], + "content": [ + {"annotations": [], "logprobs": [], "text": "a_message", "type": "output_text"} + ], "role": "assistant", "status": "completed", "type": "message", @@ -151,7 +153,9 @@ async def test_single_agent_workflow(monkeypatch) -> None: }, { "id": "1", - "content": [{"annotations": [], "text": "done", "type": "output_text"}], + "content": [ + {"annotations": [], "logprobs": [], "text": "done", "type": "output_text"} + ], "role": "assistant", "status": "completed", "type": "message", @@ -179,7 +183,9 @@ async def test_single_agent_workflow(monkeypatch) -> None: }, { "id": "1", - "content": [{"annotations": [], "text": "a_message", "type": "output_text"}], + "content": [ + {"annotations": [], "logprobs": [], "text": "a_message", "type": "output_text"} + ], "role": "assistant", "status": "completed", "type": "message", @@ -191,7 +197,9 @@ async def test_single_agent_workflow(monkeypatch) -> None: }, { "id": "1", - "content": [{"annotations": [], "text": "done", "type": "output_text"}], + "content": [ + {"annotations": [], "logprobs": [], "text": "done", "type": "output_text"} + ], "role": "assistant", "status": "completed", "type": "message", @@ -199,7 +207,9 @@ async def test_single_agent_workflow(monkeypatch) -> None: {"role": "user", "content": "transcription_2"}, { "id": "1", - "content": [{"annotations": [], "text": "done_2", "type": "output_text"}], + "content": [ + {"annotations": [], "logprobs": [], "text": "done_2", "type": "output_text"} + ], "role": "assistant", "status": "completed", "type": "message", diff --git a/uv.lock b/uv.lock index 2d530db1f..0477c234f 100644 --- a/uv.lock +++ b/uv.lock @@ -850,6 +850,8 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/7f/91/ae2eb6b7979e2f9b035a9f612cf70f1bf54aad4e1d125129bef1eae96f19/greenlet-3.2.4-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c2ca18a03a8cfb5b25bc1cbe20f3d9a4c80d8c3b13ba3df49ac3961af0b1018d", size = 584358, upload-time = "2025-08-07T13:18:23.708Z" }, { url = "https://files.pythonhosted.org/packages/f7/85/433de0c9c0252b22b16d413c9407e6cb3b41df7389afc366ca204dbc1393/greenlet-3.2.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:9fe0a28a7b952a21e2c062cd5756d34354117796c6d9215a87f55e38d15402c5", size = 1113550, upload-time = "2025-08-07T13:42:37.467Z" }, { url = "https://files.pythonhosted.org/packages/a1/8d/88f3ebd2bc96bf7747093696f4335a0a8a4c5acfcf1b757717c0d2474ba3/greenlet-3.2.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8854167e06950ca75b898b104b63cc646573aa5fef1353d4508ecdd1ee76254f", size = 1137126, upload-time = "2025-08-07T13:18:20.239Z" }, + { url = "https://files.pythonhosted.org/packages/f1/29/74242b7d72385e29bcc5563fba67dad94943d7cd03552bac320d597f29b2/greenlet-3.2.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f47617f698838ba98f4ff4189aef02e7343952df3a615f847bb575c3feb177a7", size = 1544904, upload-time = "2025-11-04T12:42:04.763Z" }, + { url = "https://files.pythonhosted.org/packages/c8/e2/1572b8eeab0f77df5f6729d6ab6b141e4a84ee8eb9bc8c1e7918f94eda6d/greenlet-3.2.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:af41be48a4f60429d5cad9d22175217805098a9ef7c40bfef44f7669fb9d74d8", size = 1611228, upload-time = "2025-11-04T12:42:08.423Z" }, { url = "https://files.pythonhosted.org/packages/d6/6f/b60b0291d9623c496638c582297ead61f43c4b72eef5e9c926ef4565ec13/greenlet-3.2.4-cp310-cp310-win_amd64.whl", hash = "sha256:73f49b5368b5359d04e18d15828eecc1806033db5233397748f4ca813ff1056c", size = 298654, upload-time = "2025-08-07T13:50:00.469Z" }, { url = "https://files.pythonhosted.org/packages/a4/de/f28ced0a67749cac23fecb02b694f6473f47686dff6afaa211d186e2ef9c/greenlet-3.2.4-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:96378df1de302bc38e99c3a9aa311967b7dc80ced1dcc6f171e99842987882a2", size = 272305, upload-time = "2025-08-07T13:15:41.288Z" }, { url = "https://files.pythonhosted.org/packages/09/16/2c3792cba130000bf2a31c5272999113f4764fd9d874fb257ff588ac779a/greenlet-3.2.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:1ee8fae0519a337f2329cb78bd7a8e128ec0f881073d43f023c7b8d4831d5246", size = 632472, upload-time = "2025-08-07T13:42:55.044Z" }, @@ -859,6 +861,8 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/1f/8e/abdd3f14d735b2929290a018ecf133c901be4874b858dd1c604b9319f064/greenlet-3.2.4-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2523e5246274f54fdadbce8494458a2ebdcdbc7b802318466ac5606d3cded1f8", size = 587684, upload-time = "2025-08-07T13:18:25.164Z" }, { url = "https://files.pythonhosted.org/packages/5d/65/deb2a69c3e5996439b0176f6651e0052542bb6c8f8ec2e3fba97c9768805/greenlet-3.2.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:1987de92fec508535687fb807a5cea1560f6196285a4cde35c100b8cd632cc52", size = 1116647, upload-time = "2025-08-07T13:42:38.655Z" }, { url = "https://files.pythonhosted.org/packages/3f/cc/b07000438a29ac5cfb2194bfc128151d52f333cee74dd7dfe3fb733fc16c/greenlet-3.2.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:55e9c5affaa6775e2c6b67659f3a71684de4c549b3dd9afca3bc773533d284fa", size = 1142073, upload-time = "2025-08-07T13:18:21.737Z" }, + { url = "https://files.pythonhosted.org/packages/67/24/28a5b2fa42d12b3d7e5614145f0bd89714c34c08be6aabe39c14dd52db34/greenlet-3.2.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c9c6de1940a7d828635fbd254d69db79e54619f165ee7ce32fda763a9cb6a58c", size = 1548385, upload-time = "2025-11-04T12:42:11.067Z" }, + { url = "https://files.pythonhosted.org/packages/6a/05/03f2f0bdd0b0ff9a4f7b99333d57b53a7709c27723ec8123056b084e69cd/greenlet-3.2.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:03c5136e7be905045160b1b9fdca93dd6727b180feeafda6818e6496434ed8c5", size = 1613329, upload-time = "2025-11-04T12:42:12.928Z" }, { url = "https://files.pythonhosted.org/packages/d8/0f/30aef242fcab550b0b3520b8e3561156857c94288f0332a79928c31a52cf/greenlet-3.2.4-cp311-cp311-win_amd64.whl", hash = "sha256:9c40adce87eaa9ddb593ccb0fa6a07caf34015a29bf8d344811665b573138db9", size = 299100, upload-time = "2025-08-07T13:44:12.287Z" }, { url = "https://files.pythonhosted.org/packages/44/69/9b804adb5fd0671f367781560eb5eb586c4d495277c93bde4307b9e28068/greenlet-3.2.4-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:3b67ca49f54cede0186854a008109d6ee71f66bd57bb36abd6d0a0267b540cdd", size = 274079, upload-time = "2025-08-07T13:15:45.033Z" }, { url = "https://files.pythonhosted.org/packages/46/e9/d2a80c99f19a153eff70bc451ab78615583b8dac0754cfb942223d2c1a0d/greenlet-3.2.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ddf9164e7a5b08e9d22511526865780a576f19ddd00d62f8a665949327fde8bb", size = 640997, upload-time = "2025-08-07T13:42:56.234Z" }, @@ -868,6 +872,8 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/19/0d/6660d55f7373b2ff8152401a83e02084956da23ae58cddbfb0b330978fe9/greenlet-3.2.4-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3b3812d8d0c9579967815af437d96623f45c0f2ae5f04e366de62a12d83a8fb0", size = 607586, upload-time = "2025-08-07T13:18:28.544Z" }, { url = "https://files.pythonhosted.org/packages/8e/1a/c953fdedd22d81ee4629afbb38d2f9d71e37d23caace44775a3a969147d4/greenlet-3.2.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:abbf57b5a870d30c4675928c37278493044d7c14378350b3aa5d484fa65575f0", size = 1123281, upload-time = "2025-08-07T13:42:39.858Z" }, { url = "https://files.pythonhosted.org/packages/3f/c7/12381b18e21aef2c6bd3a636da1088b888b97b7a0362fac2e4de92405f97/greenlet-3.2.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:20fb936b4652b6e307b8f347665e2c615540d4b42b3b4c8a321d8286da7e520f", size = 1151142, upload-time = "2025-08-07T13:18:22.981Z" }, + { url = "https://files.pythonhosted.org/packages/27/45/80935968b53cfd3f33cf99ea5f08227f2646e044568c9b1555b58ffd61c2/greenlet-3.2.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:ee7a6ec486883397d70eec05059353b8e83eca9168b9f3f9a361971e77e0bcd0", size = 1564846, upload-time = "2025-11-04T12:42:15.191Z" }, + { url = "https://files.pythonhosted.org/packages/69/02/b7c30e5e04752cb4db6202a3858b149c0710e5453b71a3b2aec5d78a1aab/greenlet-3.2.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:326d234cbf337c9c3def0676412eb7040a35a768efc92504b947b3e9cfc7543d", size = 1633814, upload-time = "2025-11-04T12:42:17.175Z" }, { url = "https://files.pythonhosted.org/packages/e9/08/b0814846b79399e585f974bbeebf5580fbe59e258ea7be64d9dfb253c84f/greenlet-3.2.4-cp312-cp312-win_amd64.whl", hash = "sha256:a7d4e128405eea3814a12cc2605e0e6aedb4035bf32697f72deca74de4105e02", size = 299899, upload-time = "2025-08-07T13:38:53.448Z" }, { url = "https://files.pythonhosted.org/packages/49/e8/58c7f85958bda41dafea50497cbd59738c5c43dbbea5ee83d651234398f4/greenlet-3.2.4-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:1a921e542453fe531144e91e1feedf12e07351b1cf6c9e8a3325ea600a715a31", size = 272814, upload-time = "2025-08-07T13:15:50.011Z" }, { url = "https://files.pythonhosted.org/packages/62/dd/b9f59862e9e257a16e4e610480cfffd29e3fae018a68c2332090b53aac3d/greenlet-3.2.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:cd3c8e693bff0fff6ba55f140bf390fa92c994083f838fece0f63be121334945", size = 641073, upload-time = "2025-08-07T13:42:57.23Z" }, @@ -877,6 +883,8 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ee/43/3cecdc0349359e1a527cbf2e3e28e5f8f06d3343aaf82ca13437a9aa290f/greenlet-3.2.4-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:23768528f2911bcd7e475210822ffb5254ed10d71f4028387e5a99b4c6699671", size = 610497, upload-time = "2025-08-07T13:18:31.636Z" }, { url = "https://files.pythonhosted.org/packages/b8/19/06b6cf5d604e2c382a6f31cafafd6f33d5dea706f4db7bdab184bad2b21d/greenlet-3.2.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:00fadb3fedccc447f517ee0d3fd8fe49eae949e1cd0f6a611818f4f6fb7dc83b", size = 1121662, upload-time = "2025-08-07T13:42:41.117Z" }, { url = "https://files.pythonhosted.org/packages/a2/15/0d5e4e1a66fab130d98168fe984c509249c833c1a3c16806b90f253ce7b9/greenlet-3.2.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:d25c5091190f2dc0eaa3f950252122edbbadbb682aa7b1ef2f8af0f8c0afefae", size = 1149210, upload-time = "2025-08-07T13:18:24.072Z" }, + { url = "https://files.pythonhosted.org/packages/1c/53/f9c440463b3057485b8594d7a638bed53ba531165ef0ca0e6c364b5cc807/greenlet-3.2.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6e343822feb58ac4d0a1211bd9399de2b3a04963ddeec21530fc426cc121f19b", size = 1564759, upload-time = "2025-11-04T12:42:19.395Z" }, + { url = "https://files.pythonhosted.org/packages/47/e4/3bb4240abdd0a8d23f4f88adec746a3099f0d86bfedb623f063b2e3b4df0/greenlet-3.2.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ca7f6f1f2649b89ce02f6f229d7c19f680a6238af656f61e0115b24857917929", size = 1634288, upload-time = "2025-11-04T12:42:21.174Z" }, { url = "https://files.pythonhosted.org/packages/0b/55/2321e43595e6801e105fcfdee02b34c0f996eb71e6ddffca6b10b7e1d771/greenlet-3.2.4-cp313-cp313-win_amd64.whl", hash = "sha256:554b03b6e73aaabec3745364d6239e9e012d64c68ccd0b8430c64ccc14939a8b", size = 299685, upload-time = "2025-08-07T13:24:38.824Z" }, { url = "https://files.pythonhosted.org/packages/22/5c/85273fd7cc388285632b0498dbbab97596e04b154933dfe0f3e68156c68c/greenlet-3.2.4-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:49a30d5fda2507ae77be16479bdb62a660fa51b1eb4928b524975b3bde77b3c0", size = 273586, upload-time = "2025-08-07T13:16:08.004Z" }, { url = "https://files.pythonhosted.org/packages/d1/75/10aeeaa3da9332c2e761e4c50d4c3556c21113ee3f0afa2cf5769946f7a3/greenlet-3.2.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:299fd615cd8fc86267b47597123e3f43ad79c9d8a22bebdce535e53550763e2f", size = 686346, upload-time = "2025-08-07T13:42:59.944Z" }, @@ -884,6 +892,8 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/dc/8b/29aae55436521f1d6f8ff4e12fb676f3400de7fcf27fccd1d4d17fd8fecd/greenlet-3.2.4-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:b4a1870c51720687af7fa3e7cda6d08d801dae660f75a76f3845b642b4da6ee1", size = 694659, upload-time = "2025-08-07T13:53:17.759Z" }, { url = "https://files.pythonhosted.org/packages/92/2e/ea25914b1ebfde93b6fc4ff46d6864564fba59024e928bdc7de475affc25/greenlet-3.2.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:061dc4cf2c34852b052a8620d40f36324554bc192be474b9e9770e8c042fd735", size = 695355, upload-time = "2025-08-07T13:18:34.517Z" }, { url = "https://files.pythonhosted.org/packages/72/60/fc56c62046ec17f6b0d3060564562c64c862948c9d4bc8aa807cf5bd74f4/greenlet-3.2.4-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:44358b9bf66c8576a9f57a590d5f5d6e72fa4228b763d0e43fee6d3b06d3a337", size = 657512, upload-time = "2025-08-07T13:18:33.969Z" }, + { url = "https://files.pythonhosted.org/packages/23/6e/74407aed965a4ab6ddd93a7ded3180b730d281c77b765788419484cdfeef/greenlet-3.2.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:2917bdf657f5859fbf3386b12d68ede4cf1f04c90c3a6bc1f013dd68a22e2269", size = 1612508, upload-time = "2025-11-04T12:42:23.427Z" }, + { url = "https://files.pythonhosted.org/packages/0d/da/343cd760ab2f92bac1845ca07ee3faea9fe52bee65f7bcb19f16ad7de08b/greenlet-3.2.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:015d48959d4add5d6c9f6c5210ee3803a830dce46356e3bc326d6776bde54681", size = 1680760, upload-time = "2025-11-04T12:42:25.341Z" }, { url = "https://files.pythonhosted.org/packages/e3/a5/6ddab2b4c112be95601c13428db1d8b6608a8b6039816f2ba09c346c08fc/greenlet-3.2.4-cp314-cp314-win_amd64.whl", hash = "sha256:e37ab26028f12dbb0ff65f29a8d3d44a765c61e729647bf2ddfbbed621726f01", size = 303425, upload-time = "2025-08-07T13:32:27.59Z" }, { url = "https://files.pythonhosted.org/packages/f7/c0/93885c4106d2626bf51fdec377d6aef740dfa5c4877461889a7cf8e565cc/greenlet-3.2.4-cp39-cp39-macosx_11_0_universal2.whl", hash = "sha256:b6a7c19cf0d2742d0809a4c05975db036fdff50cd294a93632d6a310bf9ac02c", size = 269859, upload-time = "2025-08-07T13:16:16.003Z" }, { url = "https://files.pythonhosted.org/packages/4d/f5/33f05dc3ba10a02dedb1485870cf81c109227d3d3aa280f0e48486cac248/greenlet-3.2.4-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:27890167f55d2387576d1f41d9487ef171849ea0359ce1510ca6e06c8bece11d", size = 627610, upload-time = "2025-08-07T13:43:01.345Z" }, @@ -893,6 +903,8 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/6b/4c/f3de2a8de0e840ecb0253ad0dc7e2bb3747348e798ec7e397d783a3cb380/greenlet-3.2.4-cp39-cp39-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c9913f1a30e4526f432991f89ae263459b1c64d1608c0d22a5c79c287b3c70df", size = 582817, upload-time = "2025-08-07T13:18:35.48Z" }, { url = "https://files.pythonhosted.org/packages/89/80/7332915adc766035c8980b161c2e5d50b2f941f453af232c164cff5e0aeb/greenlet-3.2.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b90654e092f928f110e0007f572007c9727b5265f7632c2fa7415b4689351594", size = 1111985, upload-time = "2025-08-07T13:42:42.425Z" }, { url = "https://files.pythonhosted.org/packages/66/71/1928e2c80197353bcb9b50aa19c4d8e26ee6d7a900c564907665cf4b9a41/greenlet-3.2.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:81701fd84f26330f0d5f4944d4e92e61afe6319dcd9775e39396e39d7c3e5f98", size = 1136137, upload-time = "2025-08-07T13:18:26.168Z" }, + { url = "https://files.pythonhosted.org/packages/4b/bf/7bd33643e48ed45dcc0e22572f650767832bd4e1287f97434943cc402148/greenlet-3.2.4-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:28a3c6b7cd72a96f61b0e4b2a36f681025b60ae4779cc73c1535eb5f29560b10", size = 1542941, upload-time = "2025-11-04T12:42:27.427Z" }, + { url = "https://files.pythonhosted.org/packages/9b/74/4bc433f91d0d09a1c22954a371f9df928cb85e72640870158853a83415e5/greenlet-3.2.4-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:52206cd642670b0b320a1fd1cbfd95bca0e043179c1d8a045f2c6109dfe973be", size = 1609685, upload-time = "2025-11-04T12:42:29.242Z" }, { url = "https://files.pythonhosted.org/packages/89/48/a5dc74dde38aeb2b15d418cec76ed50e1dd3d620ccda84d8199703248968/greenlet-3.2.4-cp39-cp39-win32.whl", hash = "sha256:65458b409c1ed459ea899e939f0e1cdb14f58dbc803f2f93c5eab5694d32671b", size = 281400, upload-time = "2025-08-07T14:02:20.263Z" }, { url = "https://files.pythonhosted.org/packages/e5/44/342c4591db50db1076b8bda86ed0ad59240e3e1da17806a4cf10a6d0e447/greenlet-3.2.4-cp39-cp39-win_amd64.whl", hash = "sha256:d2e685ade4dafd447ede19c31277a224a239a0a1a4eca4e6390efedf20260cfb", size = 298533, upload-time = "2025-08-07T13:56:34.168Z" }, ] @@ -1858,7 +1870,7 @@ wheels = [ [[package]] name = "openai" -version = "2.6.1" +version = "2.7.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "anyio" }, @@ -1870,9 +1882,9 @@ dependencies = [ { name = "tqdm" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/c4/44/303deb97be7c1c9b53118b52825cbd1557aeeff510f3a52566b1fa66f6a2/openai-2.6.1.tar.gz", hash = "sha256:27ae704d190615fca0c0fc2b796a38f8b5879645a3a52c9c453b23f97141bb49", size = 593043, upload-time = "2025-10-24T13:29:52.79Z" } +sdist = { url = "https://files.pythonhosted.org/packages/51/a2/f4023c1e0c868a6a5854955b3374f17153388aed95e835af114a17eac95b/openai-2.7.1.tar.gz", hash = "sha256:df4d4a3622b2df3475ead8eb0fbb3c27fd1c070fa2e55d778ca4f40e0186c726", size = 595933, upload-time = "2025-11-04T06:07:23.069Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/15/0e/331df43df633e6105ff9cf45e0ce57762bd126a45ac16b25a43f6738d8a2/openai-2.6.1-py3-none-any.whl", hash = "sha256:904e4b5254a8416746a2f05649594fa41b19d799843cd134dac86167e094edef", size = 1005551, upload-time = "2025-10-24T13:29:50.973Z" }, + { url = "https://files.pythonhosted.org/packages/8c/74/6bfc3adc81f6c2cea4439f2a734c40e3a420703bbcdc539890096a732bbd/openai-2.7.1-py3-none-any.whl", hash = "sha256:2f2530354d94c59c614645a4662b9dab0a5b881c5cd767a8587398feac0c9021", size = 1008780, upload-time = "2025-11-04T06:07:20.818Z" }, ] [[package]] @@ -1952,7 +1964,7 @@ requires-dist = [ { name = "litellm", marker = "extra == 'litellm'", specifier = ">=1.67.4.post1,<2" }, { name = "mcp", marker = "python_full_version >= '3.10'", specifier = ">=1.11.0,<2" }, { name = "numpy", marker = "python_full_version >= '3.10' and extra == 'voice'", specifier = ">=2.2.0,<3" }, - { name = "openai", specifier = ">=2.6.1,<3" }, + { name = "openai", specifier = ">=2.7.1,<3" }, { name = "pydantic", specifier = ">=2.12.3,<3" }, { name = "redis", marker = "extra == 'redis'", specifier = ">=6.4.0" }, { name = "requests", specifier = ">=2.0,<3" },