From cd48c1424cb5ec4df774743256494a084d10bfff Mon Sep 17 00:00:00 2001 From: Tao Chen Date: Mon, 20 Apr 2026 17:46:06 -0700 Subject: [PATCH] Python: Add more types (#5378) * Add more type supports * Upgrade packages * Remove TODOs in README --- python/packages/foundry_hosting/README.md | 8 - .../_responses.py | 218 +++++++++- .../packages/foundry_hosting/pyproject.toml | 8 +- .../foundry_hosting/tests/test_responses.py | 393 ++++++++++++++++++ python/uv.lock | 30 +- 5 files changed, 626 insertions(+), 31 deletions(-) diff --git a/python/packages/foundry_hosting/README.md b/python/packages/foundry_hosting/README.md index 9222c01aa8..c0794fd4b0 100644 --- a/python/packages/foundry_hosting/README.md +++ b/python/packages/foundry_hosting/README.md @@ -1,11 +1,3 @@ # Foundry Hosting This package provides the integration of Agent Framework agents and workflows with the Foundry Agent Server, which can be hosted on Foundry infrastructure. - -## Responses - -TODO - -## Invocations - -TODO diff --git a/python/packages/foundry_hosting/agent_framework_foundry_hosting/_responses.py b/python/packages/foundry_hosting/agent_framework_foundry_hosting/_responses.py index d41e70d94e..8e1fdc7dae 100644 --- a/python/packages/foundry_hosting/agent_framework_foundry_hosting/_responses.py +++ b/python/packages/foundry_hosting/agent_framework_foundry_hosting/_responses.py @@ -42,15 +42,34 @@ from azure.ai.agentserver.responses.models import ( MessageContentOutputTextContent, MessageContentReasoningTextContent, MessageContentRefusalContent, + OAuthConsentRequestOutputItem, OutputItem, + OutputItemApplyPatchToolCall, + OutputItemApplyPatchToolCallOutput, + OutputItemCodeInterpreterToolCall, + OutputItemComputerToolCall, + OutputItemComputerToolCallOutputResource, + OutputItemCustomToolCall, + OutputItemCustomToolCallOutput, + OutputItemFileSearchToolCall, + OutputItemFunctionShellCall, + OutputItemFunctionShellCallOutput, OutputItemFunctionToolCall, + OutputItemImageGenToolCall, + OutputItemLocalShellToolCall, + OutputItemLocalShellToolCallOutput, + OutputItemMcpApprovalRequest, + OutputItemMcpApprovalResponseResource, + OutputItemMcpToolCall, OutputItemMessage, OutputItemOutputMessage, OutputItemReasoningItem, + OutputItemWebSearchToolCall, OutputMessageContent, OutputMessageContentOutputTextContent, OutputMessageContentRefusalContent, ResponseStreamEvent, + StructuredOutputsOutputItem, SummaryTextContent, TextContent, ) @@ -572,6 +591,203 @@ def _to_message(item: OutputItem) -> Message: contents.append(Content.from_text(summary.text)) return Message(role="assistant", contents=contents) + if item.type == "mcp_call": + mcp = cast(OutputItemMcpToolCall, item) + return Message( + role="assistant", + contents=[ + Content.from_mcp_server_tool_call( + mcp.id, + mcp.name, + server_name=mcp.server_label, + arguments=mcp.arguments, + ) + ], + ) + + if item.type == "mcp_approval_request": + mcp_req = cast(OutputItemMcpApprovalRequest, item) + fc = Content.from_mcp_server_tool_call( + mcp_req.id, + mcp_req.name, + server_name=mcp_req.server_label, + arguments=mcp_req.arguments, + ) + return Message( + role="assistant", + contents=[Content.from_function_approval_request(mcp_req.id, fc)], + ) + + if item.type == "mcp_approval_response": + mcp_resp = cast(OutputItemMcpApprovalResponseResource, item) + # Build a placeholder function_call Content since the original call details are not available + fc = Content.from_function_call(mcp_resp.approval_request_id, "mcp_approval") + return Message( + role="user", + contents=[Content.from_function_approval_response(mcp_resp.approve, mcp_resp.id, fc)], + ) + + if item.type == "code_interpreter_call": + ci = cast(OutputItemCodeInterpreterToolCall, item) + return Message( + role="assistant", + contents=[Content.from_code_interpreter_tool_call(call_id=ci.id)], + ) + + if item.type == "image_generation_call": + ig = cast(OutputItemImageGenToolCall, item) + return Message( + role="assistant", + contents=[Content.from_image_generation_tool_call(image_id=ig.id)], + ) + + if item.type == "shell_call": + sc = cast(OutputItemFunctionShellCall, item) + return Message( + role="assistant", + contents=[ + Content.from_shell_tool_call( + call_id=sc.call_id, + commands=sc.action.commands, + status=str(sc.status), + ) + ], + ) + + if item.type == "shell_call_output": + sco = cast(OutputItemFunctionShellCallOutput, item) + outputs = [ + Content.from_shell_command_output( + stdout=out.stdout or "", + stderr=out.stderr or "", + exit_code=getattr(out.outcome, "exit_code", None) if hasattr(out, "outcome") else None, + ) + for out in (sco.output or []) + ] + return Message( + role="tool", + contents=[ + Content.from_shell_tool_result( + call_id=sco.call_id, + outputs=outputs, + max_output_length=sco.max_output_length, + ) + ], + ) + + if item.type == "local_shell_call": + lsc = cast(OutputItemLocalShellToolCall, item) + commands = lsc.action.command if hasattr(lsc.action, "command") and lsc.action.command else [] + return Message( + role="assistant", + contents=[ + Content.from_shell_tool_call( + call_id=lsc.call_id, + commands=commands, + status=str(lsc.status), + ) + ], + ) + + if item.type == "local_shell_call_output": + lsco = cast(OutputItemLocalShellToolCallOutput, item) + return Message( + role="tool", + contents=[ + Content.from_shell_tool_result( + call_id=lsco.id, + outputs=[Content.from_shell_command_output(stdout=lsco.output)], + ) + ], + ) + + if item.type == "file_search_call": + fs = cast(OutputItemFileSearchToolCall, item) + return Message( + role="assistant", + contents=[ + Content.from_function_call( + fs.id, + "file_search", + arguments=json.dumps({"queries": fs.queries}), + ) + ], + ) + + if item.type == "web_search_call": + ws = cast(OutputItemWebSearchToolCall, item) + return Message( + role="assistant", + contents=[Content.from_function_call(ws.id, "web_search")], + ) + + if item.type == "computer_call": + cc = cast(OutputItemComputerToolCall, item) + return Message( + role="assistant", + contents=[ + Content.from_function_call( + cc.call_id, + "computer_use", + arguments=str(cc.action), + ) + ], + ) + + if item.type == "computer_call_output": + cco = cast(OutputItemComputerToolCallOutputResource, item) + return Message( + role="tool", + contents=[Content.from_function_result(cco.call_id, result=str(cco.output))], + ) + + if item.type == "custom_tool_call": + ct = cast(OutputItemCustomToolCall, item) + return Message( + role="assistant", + contents=[Content.from_function_call(ct.call_id, ct.name, arguments=ct.input)], + ) + + if item.type == "custom_tool_call_output": + cto = cast(OutputItemCustomToolCallOutput, item) + output = cto.output if isinstance(cto.output, str) else str(cto.output) + return Message( + role="tool", + contents=[Content.from_function_result(cto.call_id, result=output)], + ) + + if item.type == "apply_patch_call": + ap = cast(OutputItemApplyPatchToolCall, item) + return Message( + role="assistant", + contents=[ + Content.from_function_call( + ap.call_id, + "apply_patch", + arguments=str(ap.operation), + ) + ], + ) + + if item.type == "apply_patch_call_output": + apo = cast(OutputItemApplyPatchToolCallOutput, item) + return Message( + role="tool", + contents=[Content.from_function_result(apo.call_id, result=apo.output or "")], + ) + + if item.type == "oauth_consent_request": + oauth = cast(OAuthConsentRequestOutputItem, item) + return Message( + role="assistant", + contents=[Content.from_oauth_consent_request(oauth.consent_link)], + ) + + if item.type == "structured_outputs": + so = cast(StructuredOutputsOutputItem, item) + text = json.dumps(so.output) if not isinstance(so.output, str) else so.output + return Message(role="assistant", contents=[Content.from_text(text)]) + raise ValueError(f"Unsupported OutputItem type: {item.type}") @@ -752,7 +968,7 @@ async def _to_outputs(stream: ResponseEventStream, content: Content) -> AsyncIte yield event else: # Log a warning for unsupported content types instead of raising an error to avoid breaking the response stream. - logger.warning(f"Content type '{content.type}' is not supported yet.") + logger.warning(f"Content type '{content.type}' is not supported yet. This is usually safe to ignore.") # endregion diff --git a/python/packages/foundry_hosting/pyproject.toml b/python/packages/foundry_hosting/pyproject.toml index b85c8ed798..3078e018d2 100644 --- a/python/packages/foundry_hosting/pyproject.toml +++ b/python/packages/foundry_hosting/pyproject.toml @@ -4,7 +4,7 @@ description = "Foundry Hosting integration for Microsoft Agent Framework." authors = [{ name = "Microsoft", email = "af-support@microsoft.com"}] readme = "README.md" requires-python = ">=3.10" -version = "1.0.0a260402" +version = "1.0.0a260420" license-files = ["LICENSE"] urls.homepage = "https://aka.ms/agent-framework" urls.source = "https://github.com/microsoft/agent-framework/tree/main/python" @@ -24,9 +24,9 @@ classifiers = [ ] dependencies = [ "agent-framework-core>=1.0.0,<2", - "azure-ai-agentserver-core==2.0.0b1", - "azure-ai-agentserver-responses==1.0.0b1", - "azure-ai-agentserver-invocations==1.0.0b1", + "azure-ai-agentserver-core==2.0.0b2", + "azure-ai-agentserver-responses==1.0.0b4", + "azure-ai-agentserver-invocations==1.0.0b2", ] [tool.uv] diff --git a/python/packages/foundry_hosting/tests/test_responses.py b/python/packages/foundry_hosting/tests/test_responses.py index 6a9eac9bc4..f30d033009 100644 --- a/python/packages/foundry_hosting/tests/test_responses.py +++ b/python/packages/foundry_hosting/tests/test_responses.py @@ -29,6 +29,7 @@ from azure.ai.agentserver.responses import InMemoryResponseProvider from typing_extensions import Any from agent_framework_foundry_hosting import ResponsesHostServer +from agent_framework_foundry_hosting._responses import _to_message # pyright: ignore[reportPrivateUsage] # region Helpers @@ -522,3 +523,395 @@ class TestStreaming: # endregion + + +# region _to_message conversion + + +class TestToMessage: + """Tests for _to_message covering all supported OutputItem types.""" + + def test_output_message(self) -> None: + from azure.ai.agentserver.responses.models import OutputItemOutputMessage, OutputMessageContentOutputTextContent + + item = OutputItemOutputMessage({ + "type": "output_message", + "role": "assistant", + "content": [OutputMessageContentOutputTextContent({"type": "output_text", "text": "hello"})], + "status": "completed", + "id": "msg-1", + }) + msg = _to_message(item) + assert msg.role == "assistant" + assert len(msg.contents) == 1 + assert msg.contents[0].type == "text" + assert msg.contents[0].text == "hello" + + def test_message(self) -> None: + from azure.ai.agentserver.responses.models import MessageContentInputTextContent, OutputItemMessage + + item = OutputItemMessage({ + "type": "message", + "role": "user", + "content": [MessageContentInputTextContent({"type": "input_text", "text": "hi"})], + }) + msg = _to_message(item) + assert msg.role == "user" + assert len(msg.contents) == 1 + assert msg.contents[0].text == "hi" + + def test_function_call(self) -> None: + from azure.ai.agentserver.responses.models import OutputItemFunctionToolCall + + item = OutputItemFunctionToolCall({ + "type": "function_call", + "call_id": "call_1", + "name": "get_weather", + "arguments": '{"city": "NYC"}', + "status": "completed", + "id": "fc-1", + }) + msg = _to_message(item) + assert msg.role == "assistant" + assert msg.contents[0].type == "function_call" + assert msg.contents[0].call_id == "call_1" + assert msg.contents[0].name == "get_weather" + + def test_function_call_output(self) -> None: + from azure.ai.agentserver.responses.models import FunctionCallOutputItemParam + + item = FunctionCallOutputItemParam({"type": "function_call_output", "call_id": "call_1", "output": "sunny"}) + msg = _to_message(item) # type: ignore[arg-type] + assert msg.role == "tool" + assert msg.contents[0].type == "function_result" + assert msg.contents[0].call_id == "call_1" + assert msg.contents[0].result == "sunny" + + def test_reasoning(self) -> None: + from azure.ai.agentserver.responses.models import OutputItemReasoningItem, SummaryTextContent + + item = OutputItemReasoningItem({ + "type": "reasoning", + "id": "r-1", + "summary": [SummaryTextContent({"type": "summary_text", "text": "thinking hard"})], + }) + msg = _to_message(item) + assert msg.role == "assistant" + assert len(msg.contents) == 1 + assert msg.contents[0].text == "thinking hard" + + def test_reasoning_no_summary(self) -> None: + from azure.ai.agentserver.responses.models import OutputItemReasoningItem + + item = OutputItemReasoningItem({"type": "reasoning", "id": "r-2"}) + msg = _to_message(item) + assert msg.role == "assistant" + assert msg.contents == [] + + def test_mcp_call(self) -> None: + from azure.ai.agentserver.responses.models import OutputItemMcpToolCall + + item = OutputItemMcpToolCall({ + "type": "mcp_call", + "id": "mcp-1", + "server_label": "my_server", + "name": "search", + "arguments": '{"q": "test"}', + }) + msg = _to_message(item) + assert msg.role == "assistant" + assert msg.contents[0].type == "mcp_server_tool_call" + assert msg.contents[0].server_name == "my_server" + assert msg.contents[0].tool_name == "search" + + def test_mcp_approval_request(self) -> None: + from azure.ai.agentserver.responses.models import OutputItemMcpApprovalRequest + + item = OutputItemMcpApprovalRequest({ + "type": "mcp_approval_request", + "id": "apr-1", + "server_label": "srv", + "name": "dangerous_tool", + "arguments": "{}", + }) + msg = _to_message(item) + assert msg.role == "assistant" + assert msg.contents[0].type == "function_approval_request" + + def test_mcp_approval_response(self) -> None: + from azure.ai.agentserver.responses.models import OutputItemMcpApprovalResponseResource + + item = OutputItemMcpApprovalResponseResource({ + "type": "mcp_approval_response", + "id": "resp-1", + "approval_request_id": "apr-1", + "approve": True, + }) + msg = _to_message(item) + assert msg.role == "user" + assert msg.contents[0].type == "function_approval_response" + assert msg.contents[0].approved is True + + def test_code_interpreter_call(self) -> None: + from azure.ai.agentserver.responses.models import OutputItemCodeInterpreterToolCall + + item = OutputItemCodeInterpreterToolCall({ + "type": "code_interpreter_call", + "id": "ci-1", + "status": "completed", + "container_id": "c-1", + "code": "print('hi')", + "outputs": [], + }) + msg = _to_message(item) + assert msg.role == "assistant" + assert msg.contents[0].type == "code_interpreter_tool_call" + + def test_image_generation_call(self) -> None: + from azure.ai.agentserver.responses.models import OutputItemImageGenToolCall + + item = OutputItemImageGenToolCall({"type": "image_generation_call", "id": "ig-1", "status": "completed"}) + msg = _to_message(item) + assert msg.role == "assistant" + assert msg.contents[0].type == "image_generation_tool_call" + + def test_shell_call(self) -> None: + from azure.ai.agentserver.responses.models import ( + FunctionShellAction, + FunctionShellCallEnvironment, + OutputItemFunctionShellCall, + ) + + item = OutputItemFunctionShellCall({ + "type": "shell_call", + "id": "sc-1", + "call_id": "call_sc", + "action": FunctionShellAction({"commands": ["ls", "-la"], "timeout_ms": 5000, "max_output_length": 1024}), + "status": "completed", + "environment": FunctionShellCallEnvironment({"type": "local"}), + }) + msg = _to_message(item) + assert msg.role == "assistant" + assert msg.contents[0].type == "shell_tool_call" + assert msg.contents[0].commands == ["ls", "-la"] + assert msg.contents[0].call_id == "call_sc" + + def test_shell_call_output(self) -> None: + from azure.ai.agentserver.responses.models import ( + FunctionShellCallOutputContent, + FunctionShellCallOutputExitOutcome, + OutputItemFunctionShellCallOutput, + ) + + item = OutputItemFunctionShellCallOutput({ + "type": "shell_call_output", + "id": "sco-1", + "call_id": "call_sc", + "status": "completed", + "output": [ + FunctionShellCallOutputContent({ + "stdout": "file.txt", + "stderr": "", + "outcome": FunctionShellCallOutputExitOutcome({"exit_code": 0}), + }) + ], + "max_output_length": 1024, + }) + msg = _to_message(item) + assert msg.role == "tool" + assert msg.contents[0].type == "shell_tool_result" + assert msg.contents[0].call_id == "call_sc" + + def test_local_shell_call(self) -> None: + from azure.ai.agentserver.responses.models import LocalShellExecAction, OutputItemLocalShellToolCall + + item = OutputItemLocalShellToolCall({ + "type": "local_shell_call", + "id": "lsc-1", + "call_id": "call_lsc", + "action": LocalShellExecAction({"type": "exec", "command": ["echo", "hello"], "env": {}}), + "status": "completed", + }) + msg = _to_message(item) + assert msg.role == "assistant" + assert msg.contents[0].type == "shell_tool_call" + assert msg.contents[0].commands == ["echo", "hello"] + + def test_local_shell_call_output(self) -> None: + from azure.ai.agentserver.responses.models import OutputItemLocalShellToolCallOutput + + item = OutputItemLocalShellToolCallOutput({ + "type": "local_shell_call_output", + "id": "lsco-1", + "output": "hello\n", + }) + msg = _to_message(item) + assert msg.role == "tool" + assert msg.contents[0].type == "shell_tool_result" + + def test_file_search_call(self) -> None: + from azure.ai.agentserver.responses.models import OutputItemFileSearchToolCall + + item = OutputItemFileSearchToolCall({ + "type": "file_search_call", + "id": "fs-1", + "status": "completed", + "queries": ["what is AI"], + }) + msg = _to_message(item) + assert msg.role == "assistant" + assert msg.contents[0].type == "function_call" + assert msg.contents[0].name == "file_search" + assert '"what is AI"' in (msg.contents[0].arguments or "") + + def test_web_search_call(self) -> None: + from azure.ai.agentserver.responses.models import OutputItemWebSearchToolCall, WebSearchActionSearch + + item = OutputItemWebSearchToolCall({ + "type": "web_search_call", + "id": "ws-1", + "status": "completed", + "action": WebSearchActionSearch({"type": "search", "query": "test"}), + }) + msg = _to_message(item) + assert msg.role == "assistant" + assert msg.contents[0].type == "function_call" + assert msg.contents[0].name == "web_search" + + def test_computer_call(self) -> None: + from azure.ai.agentserver.responses.models import ComputerAction, OutputItemComputerToolCall + + item = OutputItemComputerToolCall({ + "type": "computer_call", + "id": "cc-1", + "call_id": "call_cc", + "action": ComputerAction({"type": "click"}), + "pending_safety_checks": [], + "status": "completed", + }) + msg = _to_message(item) + assert msg.role == "assistant" + assert msg.contents[0].type == "function_call" + assert msg.contents[0].name == "computer_use" + + def test_computer_call_output(self) -> None: + from azure.ai.agentserver.responses.models import ( + ComputerScreenshotImage, + OutputItemComputerToolCallOutputResource, + ) + + item = OutputItemComputerToolCallOutputResource({ + "type": "computer_call_output", + "call_id": "call_cc", + "output": ComputerScreenshotImage({ + "type": "computer_screenshot", + "image_url": "data:image/png;base64,abc", + }), + }) + msg = _to_message(item) + assert msg.role == "tool" + assert msg.contents[0].type == "function_result" + assert msg.contents[0].call_id == "call_cc" + + def test_custom_tool_call(self) -> None: + from azure.ai.agentserver.responses.models import OutputItemCustomToolCall + + item = OutputItemCustomToolCall({ + "type": "custom_tool_call", + "call_id": "call_ct", + "name": "my_tool", + "input": '{"key": "value"}', + }) + msg = _to_message(item) + assert msg.role == "assistant" + assert msg.contents[0].type == "function_call" + assert msg.contents[0].name == "my_tool" + assert msg.contents[0].arguments == '{"key": "value"}' + + def test_custom_tool_call_output(self) -> None: + from azure.ai.agentserver.responses.models import OutputItemCustomToolCallOutput + + item = OutputItemCustomToolCallOutput({ + "type": "custom_tool_call_output", + "call_id": "call_ct", + "output": "result text", + }) + msg = _to_message(item) + assert msg.role == "tool" + assert msg.contents[0].type == "function_result" + assert msg.contents[0].result == "result text" + + def test_apply_patch_call(self) -> None: + from azure.ai.agentserver.responses.models import ApplyPatchUpdateFileOperation, OutputItemApplyPatchToolCall + + item = OutputItemApplyPatchToolCall({ + "type": "apply_patch_call", + "id": "ap-1", + "call_id": "call_ap", + "status": "completed", + "operation": ApplyPatchUpdateFileOperation({ + "type": "update_file", + "path": "file.py", + "diff": "+ new line", + }), + }) + msg = _to_message(item) + assert msg.role == "assistant" + assert msg.contents[0].type == "function_call" + assert msg.contents[0].name == "apply_patch" + + def test_apply_patch_call_output(self) -> None: + from azure.ai.agentserver.responses.models import OutputItemApplyPatchToolCallOutput + + item = OutputItemApplyPatchToolCallOutput({ + "type": "apply_patch_call_output", + "id": "apo-1", + "call_id": "call_ap", + "status": "completed", + "output": "patch applied", + }) + msg = _to_message(item) + assert msg.role == "tool" + assert msg.contents[0].type == "function_result" + assert msg.contents[0].result == "patch applied" + + def test_oauth_consent_request(self) -> None: + from azure.ai.agentserver.responses.models import OAuthConsentRequestOutputItem + + item = OAuthConsentRequestOutputItem({ + "type": "oauth_consent_request", + "id": "oauth-1", + "consent_link": "https://example.com/consent", + "server_label": "my_server", + }) + msg = _to_message(item) + assert msg.role == "assistant" + assert msg.contents[0].type == "oauth_consent_request" + assert msg.contents[0].consent_link == "https://example.com/consent" + + def test_structured_outputs_dict(self) -> None: + from azure.ai.agentserver.responses.models import StructuredOutputsOutputItem + + item = StructuredOutputsOutputItem({"type": "structured_outputs", "id": "so-1", "output": {"answer": 42}}) + msg = _to_message(item) + assert msg.role == "assistant" + assert msg.contents[0].type == "text" + assert json.loads(msg.contents[0].text or "") == {"answer": 42} + + def test_structured_outputs_string(self) -> None: + from azure.ai.agentserver.responses.models import StructuredOutputsOutputItem + + item = StructuredOutputsOutputItem({"type": "structured_outputs", "id": "so-2", "output": "plain text"}) + msg = _to_message(item) + assert msg.role == "assistant" + assert msg.contents[0].text == "plain text" + + def test_unsupported_type_raises(self) -> None: + from azure.ai.agentserver.responses.models import OutputItem + + item = OutputItem({"type": "some_unknown_type"}) + with pytest.raises(ValueError, match="Unsupported OutputItem type: some_unknown_type"): + _to_message(item) + + +# endregion diff --git a/python/uv.lock b/python/uv.lock index ea5b8dd8b0..f156438515 100644 --- a/python/uv.lock +++ b/python/uv.lock @@ -513,9 +513,9 @@ dependencies = [ [package.metadata] requires-dist = [ { name = "agent-framework-core", editable = "packages/core" }, - { name = "azure-ai-agentserver-core", specifier = "==2.0.0b1" }, - { name = "azure-ai-agentserver-invocations", specifier = "==1.0.0b1" }, - { name = "azure-ai-agentserver-responses", specifier = "==1.0.0b1" }, + { name = "azure-ai-agentserver-core", specifier = "==2.0.0b2" }, + { name = "azure-ai-agentserver-invocations", specifier = "==1.0.0b2" }, + { name = "azure-ai-agentserver-responses", specifier = "==1.0.0b4" }, ] [[package]] @@ -1034,7 +1034,7 @@ wheels = [ [[package]] name = "azure-ai-agentserver-core" -version = "2.0.0b1" +version = "2.0.0b2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "azure-monitor-opentelemetry-exporter", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, @@ -1044,26 +1044,26 @@ dependencies = [ { name = "opentelemetry-sdk", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, { name = "starlette", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/50/a5/8007cc0cbb004290998182f123d6151676fd3cdefaf0bddb2394a6a98278/azure_ai_agentserver_core-2.0.0b1.tar.gz", hash = "sha256:a762186a027586f5c365c096c3fc6ae7dac3b53a3b00b523f0fd9c1d9b8e7bc7", size = 37035, upload-time = "2026-04-15T19:09:40.022Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a0/25/25865cfa76cbc20c18c4e9ed337456fd7374c01e930dd151463b4c183ac0/azure_ai_agentserver_core-2.0.0b2.tar.gz", hash = "sha256:cc6c90fdc4c2b2ce594f0e85288fda84910c04939d1427a64a485b2d48d6d684", size = 41605, upload-time = "2026-04-19T08:58:09.27Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a1/1c/e917df68bb92239816f5bf177d6885a04c27a51d77f23608b49c60654325/azure_ai_agentserver_core-2.0.0b1-py3-none-any.whl", hash = "sha256:85c3e4470c30451bc122aa7fe009778514b6f0d52897562f4104ce5f9e382ba5", size = 24317, upload-time = "2026-04-15T19:09:41.197Z" }, + { url = "https://files.pythonhosted.org/packages/69/35/cf8a034f86d653fa902edb5ffa0a86005ea941f2840d2fa27302484856c1/azure_ai_agentserver_core-2.0.0b2-py3-none-any.whl", hash = "sha256:931e7a2d82275a01d7eb5ef08a70dba230938e3646be64c03d82749dd7be8afc", size = 27494, upload-time = "2026-04-19T08:58:10.588Z" }, ] [[package]] name = "azure-ai-agentserver-invocations" -version = "1.0.0b1" +version = "1.0.0b2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "azure-ai-agentserver-core", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/b4/33/207f901d484646764b5d9eec3f3a02a90658c32aa78821d0221323b01081/azure_ai_agentserver_invocations-1.0.0b1.tar.gz", hash = "sha256:800dd39e32f6e58c0bc56fe74bb77bf4ccda77e133c4eaaa69d7cd8b0bf77a03", size = 29957, upload-time = "2026-04-15T19:35:31.015Z" } +sdist = { url = "https://files.pythonhosted.org/packages/9d/ef/11a161fa400f28390e9885854c434417fbd204ae006ca02b3a45ab285069/azure_ai_agentserver_invocations-1.0.0b2.tar.gz", hash = "sha256:cf352fd11b0057a2af28b1a921c84fb11f2fcbb9b4185cae9d93f2a45980227b", size = 30242, upload-time = "2026-04-19T09:43:31.439Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/52/02/e1dfa6747de27163c16bc4bfbb7aeac2d2bb6565e85ed92a6675ccee1ff8/azure_ai_agentserver_invocations-1.0.0b1-py3-none-any.whl", hash = "sha256:3efa15cc6011ba203760048b0153bd711a75adb56fe9b2a34565145a0fa82b09", size = 11376, upload-time = "2026-04-15T19:35:32.067Z" }, + { url = "https://files.pythonhosted.org/packages/0c/f4/057206e0fca266b30ea68a531fa425078fd883500e779d5552858fe33d5b/azure_ai_agentserver_invocations-1.0.0b2-py3-none-any.whl", hash = "sha256:e799a9e6e54a10499296ee4f61720377fb31f540204832b654bac6f20e801597", size = 11432, upload-time = "2026-04-19T09:43:32.744Z" }, ] [[package]] name = "azure-ai-agentserver-responses" -version = "1.0.0b1" +version = "1.0.0b4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "aiohttp", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, @@ -1071,9 +1071,9 @@ dependencies = [ { name = "azure-core", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, { name = "isodate", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/cf/68/9a500cf1869d416810c3d856e483d707890686124adf0d35ff5179f59a4a/azure_ai_agentserver_responses-1.0.0b1.tar.gz", hash = "sha256:8af679bc0369f3e2637348b571942b5b41a1bccc5f261d965211e590a191049b", size = 361804, upload-time = "2026-04-15T19:34:19.404Z" } +sdist = { url = "https://files.pythonhosted.org/packages/cc/01/614dafa9366a5bdfe50ec112b15faa57e32a96866796bc2812ba329f4fec/azure_ai_agentserver_responses-1.0.0b4.tar.gz", hash = "sha256:2fa69db26ff52d8d2cd667a1461675e5124aabf8f268b842402e36f50d6c7176", size = 397007, upload-time = "2026-04-20T07:33:18.612Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/41/e8/cf0ac9673b9d8952fd03ee3de9d6d3d51320942ae31b72cdc503f9892d2f/azure_ai_agentserver_responses-1.0.0b1-py3-none-any.whl", hash = "sha256:4d42534b5b6e523219e92d837efde48f76e03882f7013d1fbb4af21e47c6469b", size = 253262, upload-time = "2026-04-15T19:34:21.069Z" }, + { url = "https://files.pythonhosted.org/packages/24/bd/c56df7c9257f10014ae1cd161ac08784bd9fe682233ab1a987c98b5b78c0/azure_ai_agentserver_responses-1.0.0b4-py3-none-any.whl", hash = "sha256:7684c6bef57bdcd1941cce2d6b5e2ea07edd7ce9f90e84f171804cc728b60fcc", size = 263375, upload-time = "2026-04-20T07:33:19.956Z" }, ] [[package]] @@ -2487,7 +2487,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/38/3f/9859f655d11901e7b2996c6e3d33e0caa9a1d4572c3bc61ed0faa64b2f4c/greenlet-3.3.2-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:9bc885b89709d901859cf95179ec9f6bb67a3d2bb1f0e88456461bd4b7f8fd0d", size = 277747, upload-time = "2026-02-20T20:16:21.325Z" }, { url = "https://files.pythonhosted.org/packages/fb/07/cb284a8b5c6498dbd7cba35d31380bb123d7dceaa7907f606c8ff5993cbf/greenlet-3.3.2-cp310-cp310-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b568183cf65b94919be4438dc28416b234b678c608cafac8874dfeeb2a9bbe13", size = 579202, upload-time = "2026-02-20T20:47:28.955Z" }, { url = "https://files.pythonhosted.org/packages/ed/45/67922992b3a152f726163b19f890a85129a992f39607a2a53155de3448b8/greenlet-3.3.2-cp310-cp310-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:527fec58dc9f90efd594b9b700662ed3fb2493c2122067ac9c740d98080a620e", size = 590620, upload-time = "2026-02-20T20:55:55.581Z" }, - { url = "https://files.pythonhosted.org/packages/03/5f/6e2a7d80c353587751ef3d44bb947f0565ec008a2e0927821c007e96d3a7/greenlet-3.3.2-cp310-cp310-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:508c7f01f1791fbc8e011bd508f6794cb95397fdb198a46cb6635eb5b78d85a7", size = 602132, upload-time = "2026-02-20T21:02:43.261Z" }, { url = "https://files.pythonhosted.org/packages/ad/55/9f1ebb5a825215fadcc0f7d5073f6e79e3007e3282b14b22d6aba7ca6cb8/greenlet-3.3.2-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ad0c8917dd42a819fe77e6bdfcb84e3379c0de956469301d9fd36427a1ca501f", size = 591729, upload-time = "2026-02-20T20:20:58.395Z" }, { url = "https://files.pythonhosted.org/packages/24/b4/21f5455773d37f94b866eb3cf5caed88d6cea6dd2c6e1f9c34f463cba3ec/greenlet-3.3.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:97245cc10e5515dbc8c3104b2928f7f02b6813002770cfaffaf9a6e0fc2b94ef", size = 1551946, upload-time = "2026-02-20T20:49:31.102Z" }, { url = "https://files.pythonhosted.org/packages/00/68/91f061a926abead128fe1a87f0b453ccf07368666bd59ffa46016627a930/greenlet-3.3.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8c1fdd7d1b309ff0da81d60a9688a8bd044ac4e18b250320a96fc68d31c209ca", size = 1618494, upload-time = "2026-02-20T20:21:06.541Z" }, @@ -2495,7 +2494,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/f3/47/16400cb42d18d7a6bb46f0626852c1718612e35dcb0dffa16bbaffdf5dd2/greenlet-3.3.2-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:c56692189a7d1c7606cb794be0a8381470d95c57ce5be03fb3d0ef57c7853b86", size = 278890, upload-time = "2026-02-20T20:19:39.263Z" }, { url = "https://files.pythonhosted.org/packages/a3/90/42762b77a5b6aa96cd8c0e80612663d39211e8ae8a6cd47c7f1249a66262/greenlet-3.3.2-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1ebd458fa8285960f382841da585e02201b53a5ec2bac6b156fc623b5ce4499f", size = 581120, upload-time = "2026-02-20T20:47:30.161Z" }, { url = "https://files.pythonhosted.org/packages/bf/6f/f3d64f4fa0a9c7b5c5b3c810ff1df614540d5aa7d519261b53fba55d4df9/greenlet-3.3.2-cp311-cp311-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a443358b33c4ec7b05b79a7c8b466f5d275025e750298be7340f8fc63dff2a55", size = 594363, upload-time = "2026-02-20T20:55:56.965Z" }, - { url = "https://files.pythonhosted.org/packages/9c/8b/1430a04657735a3f23116c2e0d5eb10220928846e4537a938a41b350bed6/greenlet-3.3.2-cp311-cp311-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:4375a58e49522698d3e70cc0b801c19433021b5c37686f7ce9c65b0d5c8677d2", size = 605046, upload-time = "2026-02-20T21:02:45.234Z" }, { url = "https://files.pythonhosted.org/packages/72/83/3e06a52aca8128bdd4dcd67e932b809e76a96ab8c232a8b025b2850264c5/greenlet-3.3.2-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8e2cd90d413acbf5e77ae41e5d3c9b3ac1d011a756d7284d7f3f2b806bbd6358", size = 594156, upload-time = "2026-02-20T20:20:59.955Z" }, { url = "https://files.pythonhosted.org/packages/70/79/0de5e62b873e08fe3cef7dbe84e5c4bc0e8ed0c7ff131bccb8405cd107c8/greenlet-3.3.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:442b6057453c8cb29b4fb36a2ac689382fc71112273726e2423f7f17dc73bf99", size = 1554649, upload-time = "2026-02-20T20:49:32.293Z" }, { url = "https://files.pythonhosted.org/packages/5a/00/32d30dee8389dc36d42170a9c66217757289e2afb0de59a3565260f38373/greenlet-3.3.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:45abe8eb6339518180d5a7fa47fa01945414d7cca5ecb745346fc6a87d2750be", size = 1619472, upload-time = "2026-02-20T20:21:07.966Z" }, @@ -2504,7 +2502,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ea/ab/1608e5a7578e62113506740b88066bf09888322a311cff602105e619bd87/greenlet-3.3.2-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:ac8d61d4343b799d1e526db579833d72f23759c71e07181c2d2944e429eb09cd", size = 280358, upload-time = "2026-02-20T20:17:43.971Z" }, { url = "https://files.pythonhosted.org/packages/a5/23/0eae412a4ade4e6623ff7626e38998cb9b11e9ff1ebacaa021e4e108ec15/greenlet-3.3.2-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3ceec72030dae6ac0c8ed7591b96b70410a8be370b6a477b1dbc072856ad02bd", size = 601217, upload-time = "2026-02-20T20:47:31.462Z" }, { url = "https://files.pythonhosted.org/packages/f8/16/5b1678a9c07098ecb9ab2dd159fafaf12e963293e61ee8d10ecb55273e5e/greenlet-3.3.2-cp312-cp312-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a2a5be83a45ce6188c045bcc44b0ee037d6a518978de9a5d97438548b953a1ac", size = 611792, upload-time = "2026-02-20T20:55:58.423Z" }, - { url = "https://files.pythonhosted.org/packages/5c/c5/cc09412a29e43406eba18d61c70baa936e299bc27e074e2be3806ed29098/greenlet-3.3.2-cp312-cp312-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:ae9e21c84035c490506c17002f5c8ab25f980205c3e61ddb3a2a2a2e6c411fcb", size = 626250, upload-time = "2026-02-20T21:02:46.596Z" }, { url = "https://files.pythonhosted.org/packages/50/1f/5155f55bd71cabd03765a4aac9ac446be129895271f73872c36ebd4b04b6/greenlet-3.3.2-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:43e99d1749147ac21dde49b99c9abffcbc1e2d55c67501465ef0930d6e78e070", size = 613875, upload-time = "2026-02-20T20:21:01.102Z" }, { url = "https://files.pythonhosted.org/packages/fc/dd/845f249c3fcd69e32df80cdab059b4be8b766ef5830a3d0aa9d6cad55beb/greenlet-3.3.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:4c956a19350e2c37f2c48b336a3afb4bff120b36076d9d7fb68cb44e05d95b79", size = 1571467, upload-time = "2026-02-20T20:49:33.495Z" }, { url = "https://files.pythonhosted.org/packages/2a/50/2649fe21fcc2b56659a452868e695634722a6655ba245d9f77f5656010bf/greenlet-3.3.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:6c6f8ba97d17a1e7d664151284cb3315fc5f8353e75221ed4324f84eb162b395", size = 1640001, upload-time = "2026-02-20T20:21:09.154Z" }, @@ -2513,7 +2510,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ac/48/f8b875fa7dea7dd9b33245e37f065af59df6a25af2f9561efa8d822fde51/greenlet-3.3.2-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:aa6ac98bdfd716a749b84d4034486863fd81c3abde9aa3cf8eff9127981a4ae4", size = 279120, upload-time = "2026-02-20T20:19:01.9Z" }, { url = "https://files.pythonhosted.org/packages/49/8d/9771d03e7a8b1ee456511961e1b97a6d77ae1dea4a34a5b98eee706689d3/greenlet-3.3.2-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ab0c7e7901a00bc0a7284907273dc165b32e0d109a6713babd04471327ff7986", size = 603238, upload-time = "2026-02-20T20:47:32.873Z" }, { url = "https://files.pythonhosted.org/packages/59/0e/4223c2bbb63cd5c97f28ffb2a8aee71bdfb30b323c35d409450f51b91e3e/greenlet-3.3.2-cp313-cp313-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:d248d8c23c67d2291ffd47af766e2a3aa9fa1c6703155c099feb11f526c63a92", size = 614219, upload-time = "2026-02-20T20:55:59.817Z" }, - { url = "https://files.pythonhosted.org/packages/94/2b/4d012a69759ac9d77210b8bfb128bc621125f5b20fc398bce3940d036b1c/greenlet-3.3.2-cp313-cp313-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:ccd21bb86944ca9be6d967cf7691e658e43417782bce90b5d2faeda0ff78a7dd", size = 628268, upload-time = "2026-02-20T21:02:48.024Z" }, { url = "https://files.pythonhosted.org/packages/7a/34/259b28ea7a2a0c904b11cd36c79b8cef8019b26ee5dbe24e73b469dea347/greenlet-3.3.2-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b6997d360a4e6a4e936c0f9625b1c20416b8a0ea18a8e19cabbefc712e7397ab", size = 616774, upload-time = "2026-02-20T20:21:02.454Z" }, { url = "https://files.pythonhosted.org/packages/0a/03/996c2d1689d486a6e199cb0f1cf9e4aa940c500e01bdf201299d7d61fa69/greenlet-3.3.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:64970c33a50551c7c50491671265d8954046cb6e8e2999aacdd60e439b70418a", size = 1571277, upload-time = "2026-02-20T20:49:34.795Z" }, { url = "https://files.pythonhosted.org/packages/d9/c4/2570fc07f34a39f2caf0bf9f24b0a1a0a47bc2e8e465b2c2424821389dfc/greenlet-3.3.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:1a9172f5bf6bd88e6ba5a84e0a68afeac9dc7b6b412b245dd64f52d83c81e55b", size = 1640455, upload-time = "2026-02-20T20:21:10.261Z" }, @@ -2522,7 +2518,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/3f/ae/8bffcbd373b57a5992cd077cbe8858fff39110480a9d50697091faea6f39/greenlet-3.3.2-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:8d1658d7291f9859beed69a776c10822a0a799bc4bfe1bd4272bb60e62507dab", size = 279650, upload-time = "2026-02-20T20:18:00.783Z" }, { url = "https://files.pythonhosted.org/packages/d1/c0/45f93f348fa49abf32ac8439938726c480bd96b2a3c6f4d949ec0124b69f/greenlet-3.3.2-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:18cb1b7337bca281915b3c5d5ae19f4e76d35e1df80f4ad3c1a7be91fadf1082", size = 650295, upload-time = "2026-02-20T20:47:34.036Z" }, { url = "https://files.pythonhosted.org/packages/b3/de/dd7589b3f2b8372069ab3e4763ea5329940fc7ad9dcd3e272a37516d7c9b/greenlet-3.3.2-cp314-cp314-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c2e47408e8ce1c6f1ceea0dffcdf6ebb85cc09e55c7af407c99f1112016e45e9", size = 662163, upload-time = "2026-02-20T20:56:01.295Z" }, - { url = "https://files.pythonhosted.org/packages/cd/ac/85804f74f1ccea31ba518dcc8ee6f14c79f73fe36fa1beba38930806df09/greenlet-3.3.2-cp314-cp314-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:e3cb43ce200f59483eb82949bf1835a99cf43d7571e900d7c8d5c62cdf25d2f9", size = 675371, upload-time = "2026-02-20T21:02:49.664Z" }, { url = "https://files.pythonhosted.org/packages/d2/d8/09bfa816572a4d83bccd6750df1926f79158b1c36c5f73786e26dbe4ee38/greenlet-3.3.2-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:63d10328839d1973e5ba35e98cccbca71b232b14051fd957b6f8b6e8e80d0506", size = 664160, upload-time = "2026-02-20T20:21:04.015Z" }, { url = "https://files.pythonhosted.org/packages/48/cf/56832f0c8255d27f6c35d41b5ec91168d74ec721d85f01a12131eec6b93c/greenlet-3.3.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:8e4ab3cfb02993c8cc248ea73d7dae6cec0253e9afa311c9b37e603ca9fad2ce", size = 1619181, upload-time = "2026-02-20T20:49:36.052Z" }, { url = "https://files.pythonhosted.org/packages/0a/23/b90b60a4aabb4cec0796e55f25ffbfb579a907c3898cd2905c8918acaa16/greenlet-3.3.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:94ad81f0fd3c0c0681a018a976e5c2bd2ca2d9d94895f23e7bb1af4e8af4e2d5", size = 1687713, upload-time = "2026-02-20T20:21:11.684Z" }, @@ -2531,7 +2526,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/98/6d/8f2ef704e614bcf58ed43cfb8d87afa1c285e98194ab2cfad351bf04f81e/greenlet-3.3.2-cp314-cp314t-macosx_11_0_universal2.whl", hash = "sha256:e26e72bec7ab387ac80caa7496e0f908ff954f31065b0ffc1f8ecb1338b11b54", size = 286617, upload-time = "2026-02-20T20:19:29.856Z" }, { url = "https://files.pythonhosted.org/packages/5e/0d/93894161d307c6ea237a43988f27eba0947b360b99ac5239ad3fe09f0b47/greenlet-3.3.2-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8b466dff7a4ffda6ca975979bab80bdadde979e29fc947ac3be4451428d8b0e4", size = 655189, upload-time = "2026-02-20T20:47:35.742Z" }, { url = "https://files.pythonhosted.org/packages/f5/2c/d2d506ebd8abcb57386ec4f7ba20f4030cbe56eae541bc6fd6ef399c0b41/greenlet-3.3.2-cp314-cp314t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:b8bddc5b73c9720bea487b3bffdb1840fe4e3656fba3bd40aa1489e9f37877ff", size = 658225, upload-time = "2026-02-20T20:56:02.527Z" }, - { url = "https://files.pythonhosted.org/packages/d1/67/8197b7e7e602150938049d8e7f30de1660cfb87e4c8ee349b42b67bdb2e1/greenlet-3.3.2-cp314-cp314t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:59b3e2c40f6706b05a9cd299c836c6aa2378cabe25d021acd80f13abf81181cf", size = 666581, upload-time = "2026-02-20T21:02:51.526Z" }, { url = "https://files.pythonhosted.org/packages/8e/30/3a09155fbf728673a1dea713572d2d31159f824a37c22da82127056c44e4/greenlet-3.3.2-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b26b0f4428b871a751968285a1ac9648944cea09807177ac639b030bddebcea4", size = 657907, upload-time = "2026-02-20T20:21:05.259Z" }, { url = "https://files.pythonhosted.org/packages/f3/fd/d05a4b7acd0154ed758797f0a43b4c0962a843bedfe980115e842c5b2d08/greenlet-3.3.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:1fb39a11ee2e4d94be9a76671482be9398560955c9e568550de0224e41104727", size = 1618857, upload-time = "2026-02-20T20:49:37.309Z" }, { url = "https://files.pythonhosted.org/packages/6f/e1/50ee92a5db521de8f35075b5eff060dd43d39ebd46c2181a2042f7070385/greenlet-3.3.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:20154044d9085151bc309e7689d6f7ba10027f8f5a8c0676ad398b951913d89e", size = 1680010, upload-time = "2026-02-20T20:21:13.427Z" },