mirror of
https://github.com/microsoft/agent-framework.git
synced 2026-06-16 21:04:09 +08:00
.NET: Python: [BREAKING] Renamed Github to GitHub (#3486)
* Renamed Github to GitHub * Small fix * Updated package versions
This commit is contained in:
committed by
GitHub
Unverified
parent
fa74f27030
commit
45a020be43
+10
-1
@@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
## [1.0.0b260128] - 2026-01-28
|
||||
|
||||
### Changed
|
||||
|
||||
- **agent-framework-core**: [BREAKING] Renamed `@ai_function` decorator to `@tool` and `AIFunction` to `FunctionTool` ([#3413](https://github.com/microsoft/agent-framework/pull/3413))
|
||||
- **agent-framework-core**: [BREAKING] Add factory pattern to `GroupChatBuilder` and `MagenticBuilder` ([#3224](https://github.com/microsoft/agent-framework/pull/3224))
|
||||
- **agent-framework-github-copilot**: [BREAKING] Renamed `Github` to `GitHub` ([#3486](https://github.com/microsoft/agent-framework/pull/3486))
|
||||
|
||||
## [1.0.0b260127] - 2026-01-27
|
||||
|
||||
### Added
|
||||
@@ -548,7 +556,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
For more information, see the [announcement blog post](https://devblogs.microsoft.com/foundry/introducing-microsoft-agent-framework-the-open-source-engine-for-agentic-ai-apps/).
|
||||
|
||||
[Unreleased]: https://github.com/microsoft/agent-framework/compare/python-1.0.0b260127...HEAD
|
||||
[Unreleased]: https://github.com/microsoft/agent-framework/compare/python-1.0.0b260128...HEAD
|
||||
[1.0.0b260128]: https://github.com/microsoft/agent-framework/compare/python-1.0.0b260127...python-1.0.0b260128
|
||||
[1.0.0b260127]: https://github.com/microsoft/agent-framework/compare/python-1.0.0b260123...python-1.0.0b260127
|
||||
[1.0.0b260123]: https://github.com/microsoft/agent-framework/compare/python-1.0.0b260116...python-1.0.0b260123
|
||||
[1.0.0b260116]: https://github.com/microsoft/agent-framework/compare/python-1.0.0b260114...python-1.0.0b260116
|
||||
|
||||
@@ -4,7 +4,7 @@ description = "A2A integration for Microsoft Agent Framework."
|
||||
authors = [{ name = "Microsoft", email = "af-support@microsoft.com"}]
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.10"
|
||||
version = "1.0.0b260127"
|
||||
version = "1.0.0b260128"
|
||||
license-files = ["LICENSE"]
|
||||
urls.homepage = "https://aka.ms/agent-framework"
|
||||
urls.source = "https://github.com/microsoft/agent-framework/tree/main/python"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[project]
|
||||
name = "agent-framework-ag-ui"
|
||||
version = "1.0.0b260127"
|
||||
version = "1.0.0b260128"
|
||||
description = "AG-UI protocol integration for Agent Framework"
|
||||
readme = "README.md"
|
||||
license-files = ["LICENSE"]
|
||||
|
||||
@@ -4,7 +4,7 @@ description = "Anthropic integration for Microsoft Agent Framework."
|
||||
authors = [{ name = "Microsoft", email = "af-support@microsoft.com"}]
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.10"
|
||||
version = "1.0.0b260127"
|
||||
version = "1.0.0b260128"
|
||||
license-files = ["LICENSE"]
|
||||
urls.homepage = "https://aka.ms/agent-framework"
|
||||
urls.source = "https://github.com/microsoft/agent-framework/tree/main/python"
|
||||
|
||||
@@ -4,7 +4,7 @@ description = "Azure AI Search integration for Microsoft Agent Framework."
|
||||
authors = [{ name = "Microsoft", email = "af-support@microsoft.com"}]
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.10"
|
||||
version = "1.0.0b260127"
|
||||
version = "1.0.0b260128"
|
||||
license-files = ["LICENSE"]
|
||||
urls.homepage = "https://aka.ms/agent-framework"
|
||||
urls.source = "https://github.com/microsoft/agent-framework/tree/main/python"
|
||||
|
||||
@@ -4,7 +4,7 @@ description = "Azure AI Foundry integration for Microsoft Agent Framework."
|
||||
authors = [{ name = "Microsoft", email = "af-support@microsoft.com"}]
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.10"
|
||||
version = "1.0.0b260127"
|
||||
version = "1.0.0b260128"
|
||||
license-files = ["LICENSE"]
|
||||
urls.homepage = "https://aka.ms/agent-framework"
|
||||
urls.source = "https://github.com/microsoft/agent-framework/tree/main/python"
|
||||
|
||||
@@ -4,7 +4,7 @@ description = "Azure Functions integration for Microsoft Agent Framework."
|
||||
authors = [{ name = "Microsoft", email = "af-support@microsoft.com"}]
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.10"
|
||||
version = "1.0.0b260127"
|
||||
version = "1.0.0b260128"
|
||||
license-files = ["LICENSE"]
|
||||
urls.homepage = "https://aka.ms/agent-framework"
|
||||
urls.source = "https://github.com/microsoft/agent-framework/tree/main/python"
|
||||
|
||||
@@ -4,7 +4,7 @@ description = "Amazon Bedrock integration for Microsoft Agent Framework."
|
||||
authors = [{ name = "Microsoft", email = "af-support@microsoft.com"}]
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.10"
|
||||
version = "1.0.0b260127"
|
||||
version = "1.0.0b260128"
|
||||
license-files = ["LICENSE"]
|
||||
urls.homepage = "https://aka.ms/agent-framework"
|
||||
urls.source = "https://github.com/microsoft/agent-framework/tree/main/python"
|
||||
|
||||
@@ -4,7 +4,7 @@ description = "OpenAI ChatKit integration for Microsoft Agent Framework."
|
||||
authors = [{ name = "Microsoft", email = "af-support@microsoft.com"}]
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.10"
|
||||
version = "1.0.0b260127"
|
||||
version = "1.0.0b260128"
|
||||
license-files = ["LICENSE"]
|
||||
urls.homepage = "https://aka.ms/agent-framework"
|
||||
urls.source = "https://github.com/microsoft/agent-framework/tree/main/python"
|
||||
|
||||
@@ -4,7 +4,7 @@ description = "Copilot Studio integration for Microsoft Agent Framework."
|
||||
authors = [{ name = "Microsoft", email = "af-support@microsoft.com"}]
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.10"
|
||||
version = "1.0.0b260127"
|
||||
version = "1.0.0b260128"
|
||||
license-files = ["LICENSE"]
|
||||
urls.homepage = "https://aka.ms/agent-framework"
|
||||
urls.source = "https://github.com/microsoft/agent-framework/tree/main/python"
|
||||
|
||||
@@ -4,9 +4,9 @@ import importlib
|
||||
from typing import Any
|
||||
|
||||
_IMPORTS: dict[str, tuple[str, str]] = {
|
||||
"GithubCopilotAgent": ("agent_framework_github_copilot", "agent-framework-github-copilot"),
|
||||
"GithubCopilotOptions": ("agent_framework_github_copilot", "agent-framework-github-copilot"),
|
||||
"GithubCopilotSettings": ("agent_framework_github_copilot", "agent-framework-github-copilot"),
|
||||
"GitHubCopilotAgent": ("agent_framework_github_copilot", "agent-framework-github-copilot"),
|
||||
"GitHubCopilotOptions": ("agent_framework_github_copilot", "agent-framework-github-copilot"),
|
||||
"GitHubCopilotSettings": ("agent_framework_github_copilot", "agent-framework-github-copilot"),
|
||||
"__version__": ("agent_framework_github_copilot", "agent-framework-github-copilot"),
|
||||
}
|
||||
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
from agent_framework_github_copilot import (
|
||||
GithubCopilotAgent,
|
||||
GithubCopilotOptions,
|
||||
GithubCopilotSettings,
|
||||
GitHubCopilotAgent,
|
||||
GitHubCopilotOptions,
|
||||
GitHubCopilotSettings,
|
||||
__version__,
|
||||
)
|
||||
|
||||
__all__ = [
|
||||
"GithubCopilotAgent",
|
||||
"GithubCopilotOptions",
|
||||
"GithubCopilotSettings",
|
||||
"GitHubCopilotAgent",
|
||||
"GitHubCopilotOptions",
|
||||
"GitHubCopilotSettings",
|
||||
"__version__",
|
||||
]
|
||||
|
||||
@@ -4,7 +4,7 @@ description = "Microsoft Agent Framework for building AI Agents with Python. Thi
|
||||
authors = [{ name = "Microsoft", email = "af-support@microsoft.com"}]
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.10"
|
||||
version = "1.0.0b260127"
|
||||
version = "1.0.0b260128"
|
||||
license-files = ["LICENSE"]
|
||||
urls.homepage = "https://aka.ms/agent-framework"
|
||||
urls.source = "https://github.com/microsoft/agent-framework/tree/main/python"
|
||||
|
||||
@@ -4,7 +4,7 @@ description = "Declarative specification support for Microsoft Agent Framework."
|
||||
authors = [{ name = "Microsoft", email = "af-support@microsoft.com"}]
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.10"
|
||||
version = "1.0.0b260127"
|
||||
version = "1.0.0b260128"
|
||||
license-files = ["LICENSE"]
|
||||
urls.homepage = "https://aka.ms/agent-framework"
|
||||
urls.source = "https://github.com/microsoft/agent-framework/tree/main/python"
|
||||
|
||||
@@ -4,7 +4,7 @@ description = "Debug UI for Microsoft Agent Framework with OpenAI-compatible API
|
||||
authors = [{ name = "Microsoft", email = "af-support@microsoft.com"}]
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.10"
|
||||
version = "1.0.0b260127"
|
||||
version = "1.0.0b260128"
|
||||
license-files = ["LICENSE"]
|
||||
urls.homepage = "https://github.com/microsoft/agent-framework"
|
||||
urls.source = "https://github.com/microsoft/agent-framework/tree/main/python"
|
||||
|
||||
@@ -4,7 +4,7 @@ description = "Durable Task integration for Microsoft Agent Framework."
|
||||
authors = [{ name = "Microsoft", email = "af-support@microsoft.com"}]
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.10"
|
||||
version = "0.0.2b260126"
|
||||
version = "0.0.2b260128"
|
||||
license-files = ["LICENSE"]
|
||||
urls.homepage = "https://aka.ms/agent-framework"
|
||||
urls.source = "https://github.com/microsoft/agent-framework/tree/main/python"
|
||||
|
||||
@@ -4,7 +4,7 @@ description = "Foundry Local integration for Microsoft Agent Framework."
|
||||
authors = [{ name = "Microsoft", email = "af-support@microsoft.com"}]
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.10"
|
||||
version = "1.0.0b260127"
|
||||
version = "1.0.0b260128"
|
||||
license-files = ["LICENSE"]
|
||||
urls.homepage = "https://aka.ms/agent-framework"
|
||||
urls.source = "https://github.com/microsoft/agent-framework/tree/main/python"
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
import importlib.metadata
|
||||
|
||||
from ._agent import GithubCopilotAgent, GithubCopilotOptions
|
||||
from ._settings import GithubCopilotSettings
|
||||
from ._agent import GitHubCopilotAgent, GitHubCopilotOptions
|
||||
from ._settings import GitHubCopilotSettings
|
||||
|
||||
try:
|
||||
__version__ = importlib.metadata.version(__name__)
|
||||
@@ -11,8 +11,8 @@ except importlib.metadata.PackageNotFoundError:
|
||||
__version__ = "0.0.0"
|
||||
|
||||
__all__ = [
|
||||
"GithubCopilotAgent",
|
||||
"GithubCopilotOptions",
|
||||
"GithubCopilotSettings",
|
||||
"GitHubCopilotAgent",
|
||||
"GitHubCopilotOptions",
|
||||
"GitHubCopilotSettings",
|
||||
"__version__",
|
||||
]
|
||||
|
||||
@@ -37,7 +37,7 @@ from copilot.types import (
|
||||
from copilot.types import Tool as CopilotTool
|
||||
from pydantic import ValidationError
|
||||
|
||||
from ._settings import GithubCopilotSettings
|
||||
from ._settings import GitHubCopilotSettings
|
||||
|
||||
if sys.version_info >= (3, 13):
|
||||
from typing import TypeVar
|
||||
@@ -54,7 +54,7 @@ PermissionHandlerType = Callable[[PermissionRequest, dict[str, str]], Permission
|
||||
logger = logging.getLogger("agent_framework.github_copilot")
|
||||
|
||||
|
||||
class GithubCopilotOptions(TypedDict, total=False):
|
||||
class GitHubCopilotOptions(TypedDict, total=False):
|
||||
"""GitHub Copilot-specific options."""
|
||||
|
||||
instructions: str
|
||||
@@ -90,12 +90,12 @@ class GithubCopilotOptions(TypedDict, total=False):
|
||||
TOptions = TypeVar(
|
||||
"TOptions",
|
||||
bound=TypedDict, # type: ignore[valid-type]
|
||||
default="GithubCopilotOptions",
|
||||
default="GitHubCopilotOptions",
|
||||
covariant=True,
|
||||
)
|
||||
|
||||
|
||||
class GithubCopilotAgent(BaseAgent, Generic[TOptions]):
|
||||
class GitHubCopilotAgent(BaseAgent, Generic[TOptions]):
|
||||
"""A GitHub Copilot Agent.
|
||||
|
||||
This agent wraps the GitHub Copilot SDK to provide Copilot agentic capabilities
|
||||
@@ -109,7 +109,7 @@ class GithubCopilotAgent(BaseAgent, Generic[TOptions]):
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
async with GithubCopilotAgent() as agent:
|
||||
async with GitHubCopilotAgent() as agent:
|
||||
response = await agent.run("Hello, world!")
|
||||
print(response)
|
||||
|
||||
@@ -117,9 +117,9 @@ class GithubCopilotAgent(BaseAgent, Generic[TOptions]):
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from agent_framework_github_copilot import GithubCopilotAgent, GithubCopilotOptions
|
||||
from agent_framework_github_copilot import GitHubCopilotAgent, GitHubCopilotOptions
|
||||
|
||||
agent: GithubCopilotAgent[GithubCopilotOptions] = GithubCopilotAgent(
|
||||
agent: GitHubCopilotAgent[GitHubCopilotOptions] = GitHubCopilotAgent(
|
||||
default_options={"model": "claude-sonnet-4", "timeout": 120}
|
||||
)
|
||||
|
||||
@@ -131,7 +131,7 @@ class GithubCopilotAgent(BaseAgent, Generic[TOptions]):
|
||||
return f"Weather in {city} is sunny"
|
||||
|
||||
|
||||
async with GithubCopilotAgent(tools=[get_weather]) as agent:
|
||||
async with GitHubCopilotAgent(tools=[get_weather]) as agent:
|
||||
response = await agent.run("What's the weather in Seattle?")
|
||||
"""
|
||||
|
||||
@@ -160,9 +160,9 @@ class GithubCopilotAgent(BaseAgent, Generic[TOptions]):
|
||||
Keyword Args:
|
||||
client: Optional pre-configured CopilotClient instance. If not provided,
|
||||
a new client will be created using the other parameters.
|
||||
id: ID of the GithubCopilotAgent.
|
||||
name: Name of the GithubCopilotAgent.
|
||||
description: Description of the GithubCopilotAgent.
|
||||
id: ID of the GitHubCopilotAgent.
|
||||
name: Name of the GitHubCopilotAgent.
|
||||
description: Description of the GitHubCopilotAgent.
|
||||
context_provider: Context Provider, to be used by the agent.
|
||||
middleware: Agent middleware used by the agent.
|
||||
tools: Tools to use for the agent. Can be functions, ToolProtocol instances,
|
||||
@@ -197,7 +197,7 @@ class GithubCopilotAgent(BaseAgent, Generic[TOptions]):
|
||||
mcp_servers: dict[str, MCPServerConfig] | None = opts.pop("mcp_servers", None)
|
||||
|
||||
try:
|
||||
self._settings = GithubCopilotSettings(
|
||||
self._settings = GitHubCopilotSettings(
|
||||
cli_path=cli_path,
|
||||
model=model,
|
||||
timeout=timeout,
|
||||
@@ -215,7 +215,7 @@ class GithubCopilotAgent(BaseAgent, Generic[TOptions]):
|
||||
self._default_options = opts
|
||||
self._started = False
|
||||
|
||||
async def __aenter__(self) -> "GithubCopilotAgent[TOptions]":
|
||||
async def __aenter__(self) -> "GitHubCopilotAgent[TOptions]":
|
||||
"""Start the agent when entering async context."""
|
||||
await self.start()
|
||||
return self
|
||||
|
||||
@@ -5,7 +5,7 @@ from typing import ClassVar
|
||||
from agent_framework._pydantic import AFBaseSettings
|
||||
|
||||
|
||||
class GithubCopilotSettings(AFBaseSettings):
|
||||
class GitHubCopilotSettings(AFBaseSettings):
|
||||
"""GitHub Copilot model settings.
|
||||
|
||||
The settings are first loaded from environment variables with the prefix 'GITHUB_COPILOT_'.
|
||||
@@ -28,17 +28,17 @@ class GithubCopilotSettings(AFBaseSettings):
|
||||
Examples:
|
||||
.. code-block:: python
|
||||
|
||||
from agent_framework_github_copilot import GithubCopilotSettings
|
||||
from agent_framework_github_copilot import GitHubCopilotSettings
|
||||
|
||||
# Using environment variables
|
||||
# Set GITHUB_COPILOT_MODEL=gpt-5
|
||||
settings = GithubCopilotSettings()
|
||||
settings = GitHubCopilotSettings()
|
||||
|
||||
# Or passing parameters directly
|
||||
settings = GithubCopilotSettings(model="claude-sonnet-4", timeout=120)
|
||||
settings = GitHubCopilotSettings(model="claude-sonnet-4", timeout=120)
|
||||
|
||||
# Or loading from a .env file
|
||||
settings = GithubCopilotSettings(env_file_path="path/to/.env")
|
||||
settings = GitHubCopilotSettings(env_file_path="path/to/.env")
|
||||
"""
|
||||
|
||||
env_prefix: ClassVar[str] = "GITHUB_COPILOT_"
|
||||
|
||||
@@ -4,7 +4,7 @@ description = "GitHub Copilot integration for Microsoft Agent Framework."
|
||||
authors = [{ name = "Microsoft", email = "af-support@microsoft.com"}]
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.10"
|
||||
version = "1.0.0b260127"
|
||||
version = "1.0.0b260128"
|
||||
license-files = ["LICENSE"]
|
||||
urls.homepage = "https://aka.ms/agent-framework"
|
||||
urls.source = "https://github.com/microsoft/agent-framework/tree/main/python"
|
||||
|
||||
@@ -18,7 +18,7 @@ from agent_framework import (
|
||||
from agent_framework.exceptions import ServiceException
|
||||
from copilot.generated.session_events import Data, SessionEvent, SessionEventType
|
||||
|
||||
from agent_framework_github_copilot import GithubCopilotAgent, GithubCopilotOptions
|
||||
from agent_framework_github_copilot import GitHubCopilotAgent, GitHubCopilotOptions
|
||||
|
||||
|
||||
def create_session_event(
|
||||
@@ -101,26 +101,26 @@ def session_error_event() -> SessionEvent:
|
||||
)
|
||||
|
||||
|
||||
class TestGithubCopilotAgentInit:
|
||||
"""Test cases for GithubCopilotAgent initialization."""
|
||||
class TestGitHubCopilotAgentInit:
|
||||
"""Test cases for GitHubCopilotAgent initialization."""
|
||||
|
||||
def test_init_with_client(self, mock_client: MagicMock) -> None:
|
||||
"""Test initialization with pre-configured client."""
|
||||
agent = GithubCopilotAgent(client=mock_client)
|
||||
agent = GitHubCopilotAgent(client=mock_client)
|
||||
assert agent._client == mock_client # type: ignore
|
||||
assert agent._owns_client is False # type: ignore
|
||||
assert agent.id is not None
|
||||
|
||||
def test_init_without_client(self) -> None:
|
||||
"""Test initialization without client creates settings."""
|
||||
agent = GithubCopilotAgent()
|
||||
agent = GitHubCopilotAgent()
|
||||
assert agent._client is None # type: ignore
|
||||
assert agent._owns_client is True # type: ignore
|
||||
assert agent._settings is not None # type: ignore
|
||||
|
||||
def test_init_with_default_options(self) -> None:
|
||||
"""Test initialization with default_options parameter."""
|
||||
agent: GithubCopilotAgent[GithubCopilotOptions] = GithubCopilotAgent(
|
||||
agent: GitHubCopilotAgent[GitHubCopilotOptions] = GitHubCopilotAgent(
|
||||
default_options={"model": "claude-sonnet-4", "timeout": 120}
|
||||
)
|
||||
assert agent._settings.model == "claude-sonnet-4" # type: ignore
|
||||
@@ -132,18 +132,18 @@ class TestGithubCopilotAgentInit:
|
||||
def my_tool(arg: str) -> str:
|
||||
return f"Result: {arg}"
|
||||
|
||||
agent = GithubCopilotAgent(tools=[my_tool])
|
||||
agent = GitHubCopilotAgent(tools=[my_tool])
|
||||
assert len(agent._tools) == 1 # type: ignore
|
||||
|
||||
def test_init_with_instructions(self) -> None:
|
||||
"""Test initialization with custom instructions."""
|
||||
agent: GithubCopilotAgent[GithubCopilotOptions] = GithubCopilotAgent(
|
||||
agent: GitHubCopilotAgent[GitHubCopilotOptions] = GitHubCopilotAgent(
|
||||
default_options={"instructions": "You are a helpful assistant."}
|
||||
)
|
||||
assert agent._instructions == "You are a helpful assistant." # type: ignore
|
||||
|
||||
|
||||
class TestGithubCopilotAgentLifecycle:
|
||||
class TestGitHubCopilotAgentLifecycle:
|
||||
"""Test cases for agent lifecycle management."""
|
||||
|
||||
async def test_start_creates_client(self) -> None:
|
||||
@@ -153,7 +153,7 @@ class TestGithubCopilotAgentLifecycle:
|
||||
mock_client.start = AsyncMock()
|
||||
MockClient.return_value = mock_client
|
||||
|
||||
agent = GithubCopilotAgent()
|
||||
agent = GitHubCopilotAgent()
|
||||
await agent.start()
|
||||
|
||||
MockClient.assert_called_once()
|
||||
@@ -162,7 +162,7 @@ class TestGithubCopilotAgentLifecycle:
|
||||
|
||||
async def test_start_uses_existing_client(self, mock_client: MagicMock) -> None:
|
||||
"""Test that start uses provided client."""
|
||||
agent = GithubCopilotAgent(client=mock_client)
|
||||
agent = GitHubCopilotAgent(client=mock_client)
|
||||
await agent.start()
|
||||
|
||||
mock_client.start.assert_called_once()
|
||||
@@ -170,7 +170,7 @@ class TestGithubCopilotAgentLifecycle:
|
||||
|
||||
async def test_start_idempotent(self, mock_client: MagicMock) -> None:
|
||||
"""Test that calling start multiple times is safe."""
|
||||
agent = GithubCopilotAgent(client=mock_client)
|
||||
agent = GitHubCopilotAgent(client=mock_client)
|
||||
await agent.start()
|
||||
await agent.start()
|
||||
|
||||
@@ -178,7 +178,7 @@ class TestGithubCopilotAgentLifecycle:
|
||||
|
||||
async def test_stop_cleans_up(self, mock_client: MagicMock, mock_session: MagicMock) -> None:
|
||||
"""Test that stop resets started state."""
|
||||
agent = GithubCopilotAgent(client=mock_client)
|
||||
agent = GitHubCopilotAgent(client=mock_client)
|
||||
await agent.start()
|
||||
|
||||
await agent.stop()
|
||||
@@ -187,7 +187,7 @@ class TestGithubCopilotAgentLifecycle:
|
||||
|
||||
async def test_context_manager(self, mock_client: MagicMock) -> None:
|
||||
"""Test async context manager usage."""
|
||||
async with GithubCopilotAgent(client=mock_client) as agent:
|
||||
async with GitHubCopilotAgent(client=mock_client) as agent:
|
||||
assert agent._started is True # type: ignore
|
||||
|
||||
# When client is provided externally, agent doesn't own it and won't stop it
|
||||
@@ -202,7 +202,7 @@ class TestGithubCopilotAgentLifecycle:
|
||||
mock_client.stop = AsyncMock()
|
||||
MockClient.return_value = mock_client
|
||||
|
||||
agent = GithubCopilotAgent()
|
||||
agent = GitHubCopilotAgent()
|
||||
await agent.start()
|
||||
await agent.stop()
|
||||
|
||||
@@ -215,7 +215,7 @@ class TestGithubCopilotAgentLifecycle:
|
||||
mock_client.start = AsyncMock()
|
||||
MockClient.return_value = mock_client
|
||||
|
||||
agent: GithubCopilotAgent[GithubCopilotOptions] = GithubCopilotAgent(
|
||||
agent: GitHubCopilotAgent[GitHubCopilotOptions] = GitHubCopilotAgent(
|
||||
default_options={"cli_path": "/custom/path", "log_level": "debug"}
|
||||
)
|
||||
await agent.start()
|
||||
@@ -225,7 +225,7 @@ class TestGithubCopilotAgentLifecycle:
|
||||
assert call_args["log_level"] == "debug"
|
||||
|
||||
|
||||
class TestGithubCopilotAgentRun:
|
||||
class TestGitHubCopilotAgentRun:
|
||||
"""Test cases for run method."""
|
||||
|
||||
async def test_run_string_message(
|
||||
@@ -237,7 +237,7 @@ class TestGithubCopilotAgentRun:
|
||||
"""Test run method with string message."""
|
||||
mock_session.send_and_wait.return_value = assistant_message_event
|
||||
|
||||
agent = GithubCopilotAgent(client=mock_client)
|
||||
agent = GitHubCopilotAgent(client=mock_client)
|
||||
response = await agent.run("Hello")
|
||||
|
||||
assert isinstance(response, AgentResponse)
|
||||
@@ -254,7 +254,7 @@ class TestGithubCopilotAgentRun:
|
||||
"""Test run method with ChatMessage."""
|
||||
mock_session.send_and_wait.return_value = assistant_message_event
|
||||
|
||||
agent = GithubCopilotAgent(client=mock_client)
|
||||
agent = GitHubCopilotAgent(client=mock_client)
|
||||
chat_message = ChatMessage(role=Role.USER, contents=[Content.from_text("Hello")])
|
||||
response = await agent.run(chat_message)
|
||||
|
||||
@@ -270,7 +270,7 @@ class TestGithubCopilotAgentRun:
|
||||
"""Test run method with existing thread."""
|
||||
mock_session.send_and_wait.return_value = assistant_message_event
|
||||
|
||||
agent = GithubCopilotAgent(client=mock_client)
|
||||
agent = GitHubCopilotAgent(client=mock_client)
|
||||
thread = AgentThread()
|
||||
response = await agent.run("Hello", thread=thread)
|
||||
|
||||
@@ -286,7 +286,7 @@ class TestGithubCopilotAgentRun:
|
||||
"""Test run method with runtime options."""
|
||||
mock_session.send_and_wait.return_value = assistant_message_event
|
||||
|
||||
agent = GithubCopilotAgent(client=mock_client)
|
||||
agent = GitHubCopilotAgent(client=mock_client)
|
||||
response = await agent.run("Hello", options={"timeout": 30})
|
||||
|
||||
assert isinstance(response, AgentResponse)
|
||||
@@ -299,7 +299,7 @@ class TestGithubCopilotAgentRun:
|
||||
"""Test run method with no response event."""
|
||||
mock_session.send_and_wait.return_value = None
|
||||
|
||||
agent = GithubCopilotAgent(client=mock_client)
|
||||
agent = GitHubCopilotAgent(client=mock_client)
|
||||
response = await agent.run("Hello")
|
||||
|
||||
assert isinstance(response, AgentResponse)
|
||||
@@ -314,7 +314,7 @@ class TestGithubCopilotAgentRun:
|
||||
"""Test that run auto-starts the agent if not started."""
|
||||
mock_session.send_and_wait.return_value = assistant_message_event
|
||||
|
||||
agent = GithubCopilotAgent(client=mock_client)
|
||||
agent = GitHubCopilotAgent(client=mock_client)
|
||||
assert agent._started is False # type: ignore
|
||||
|
||||
await agent.run("Hello")
|
||||
@@ -323,7 +323,7 @@ class TestGithubCopilotAgentRun:
|
||||
mock_client.start.assert_called_once()
|
||||
|
||||
|
||||
class TestGithubCopilotAgentRunStream:
|
||||
class TestGitHubCopilotAgentRunStream:
|
||||
"""Test cases for run_stream method."""
|
||||
|
||||
async def test_run_stream_basic(
|
||||
@@ -343,7 +343,7 @@ class TestGithubCopilotAgentRunStream:
|
||||
|
||||
mock_session.on = mock_on
|
||||
|
||||
agent = GithubCopilotAgent(client=mock_client)
|
||||
agent = GitHubCopilotAgent(client=mock_client)
|
||||
responses: list[AgentResponseUpdate] = []
|
||||
async for update in agent.run_stream("Hello"):
|
||||
responses.append(update)
|
||||
@@ -367,7 +367,7 @@ class TestGithubCopilotAgentRunStream:
|
||||
|
||||
mock_session.on = mock_on
|
||||
|
||||
agent = GithubCopilotAgent(client=mock_client)
|
||||
agent = GitHubCopilotAgent(client=mock_client)
|
||||
thread = AgentThread()
|
||||
|
||||
async for _ in agent.run_stream("Hello", thread=thread):
|
||||
@@ -389,7 +389,7 @@ class TestGithubCopilotAgentRunStream:
|
||||
|
||||
mock_session.on = mock_on
|
||||
|
||||
agent = GithubCopilotAgent(client=mock_client)
|
||||
agent = GitHubCopilotAgent(client=mock_client)
|
||||
|
||||
with pytest.raises(ServiceException, match="session error"):
|
||||
async for _ in agent.run_stream("Hello"):
|
||||
@@ -409,7 +409,7 @@ class TestGithubCopilotAgentRunStream:
|
||||
|
||||
mock_session.on = mock_on
|
||||
|
||||
agent = GithubCopilotAgent(client=mock_client)
|
||||
agent = GitHubCopilotAgent(client=mock_client)
|
||||
assert agent._started is False # type: ignore
|
||||
|
||||
async for _ in agent.run_stream("Hello"):
|
||||
@@ -419,7 +419,7 @@ class TestGithubCopilotAgentRunStream:
|
||||
mock_client.start.assert_called_once()
|
||||
|
||||
|
||||
class TestGithubCopilotAgentSessionManagement:
|
||||
class TestGitHubCopilotAgentSessionManagement:
|
||||
"""Test cases for session management."""
|
||||
|
||||
async def test_session_resumed_for_same_thread(
|
||||
@@ -431,7 +431,7 @@ class TestGithubCopilotAgentSessionManagement:
|
||||
"""Test that subsequent calls on the same thread resume the session."""
|
||||
mock_session.send_and_wait.return_value = assistant_message_event
|
||||
|
||||
agent = GithubCopilotAgent(client=mock_client)
|
||||
agent = GitHubCopilotAgent(client=mock_client)
|
||||
thread = AgentThread()
|
||||
|
||||
await agent.run("Hello", thread=thread)
|
||||
@@ -446,7 +446,7 @@ class TestGithubCopilotAgentSessionManagement:
|
||||
mock_session: MagicMock,
|
||||
) -> None:
|
||||
"""Test that session config includes model setting."""
|
||||
agent: GithubCopilotAgent[GithubCopilotOptions] = GithubCopilotAgent(
|
||||
agent: GitHubCopilotAgent[GitHubCopilotOptions] = GitHubCopilotAgent(
|
||||
client=mock_client, default_options={"model": "claude-sonnet-4"}
|
||||
)
|
||||
await agent.start()
|
||||
@@ -463,7 +463,7 @@ class TestGithubCopilotAgentSessionManagement:
|
||||
mock_session: MagicMock,
|
||||
) -> None:
|
||||
"""Test that session config includes instructions."""
|
||||
agent: GithubCopilotAgent[GithubCopilotOptions] = GithubCopilotAgent(
|
||||
agent: GitHubCopilotAgent[GitHubCopilotOptions] = GitHubCopilotAgent(
|
||||
client=mock_client,
|
||||
default_options={"instructions": "You are a helpful assistant."},
|
||||
)
|
||||
@@ -482,7 +482,7 @@ class TestGithubCopilotAgentSessionManagement:
|
||||
mock_session: MagicMock,
|
||||
) -> None:
|
||||
"""Test that session config includes the streaming flag."""
|
||||
agent = GithubCopilotAgent(client=mock_client)
|
||||
agent = GitHubCopilotAgent(client=mock_client)
|
||||
await agent.start()
|
||||
|
||||
await agent._get_or_create_session(AgentThread(), streaming=True) # type: ignore
|
||||
@@ -497,7 +497,7 @@ class TestGithubCopilotAgentSessionManagement:
|
||||
mock_session: MagicMock,
|
||||
) -> None:
|
||||
"""Test that session is resumed when thread has a service_thread_id."""
|
||||
agent = GithubCopilotAgent(client=mock_client)
|
||||
agent = GitHubCopilotAgent(client=mock_client)
|
||||
await agent.start()
|
||||
|
||||
thread = AgentThread()
|
||||
@@ -525,7 +525,7 @@ class TestGithubCopilotAgentSessionManagement:
|
||||
"""A test tool."""
|
||||
return arg
|
||||
|
||||
agent: GithubCopilotAgent[GithubCopilotOptions] = GithubCopilotAgent(
|
||||
agent: GitHubCopilotAgent[GitHubCopilotOptions] = GitHubCopilotAgent(
|
||||
client=mock_client,
|
||||
tools=[my_tool],
|
||||
default_options={"on_permission_request": my_handler},
|
||||
@@ -544,7 +544,7 @@ class TestGithubCopilotAgentSessionManagement:
|
||||
assert "on_permission_request" in config
|
||||
|
||||
|
||||
class TestGithubCopilotAgentMCPServers:
|
||||
class TestGitHubCopilotAgentMCPServers:
|
||||
"""Test cases for MCP server configuration."""
|
||||
|
||||
async def test_mcp_servers_passed_to_create_session(
|
||||
@@ -569,7 +569,7 @@ class TestGithubCopilotAgentMCPServers:
|
||||
},
|
||||
}
|
||||
|
||||
agent: GithubCopilotAgent[GithubCopilotOptions] = GithubCopilotAgent(
|
||||
agent: GitHubCopilotAgent[GitHubCopilotOptions] = GitHubCopilotAgent(
|
||||
client=mock_client,
|
||||
default_options={"mcp_servers": mcp_servers},
|
||||
)
|
||||
@@ -602,7 +602,7 @@ class TestGithubCopilotAgentMCPServers:
|
||||
},
|
||||
}
|
||||
|
||||
agent: GithubCopilotAgent[GithubCopilotOptions] = GithubCopilotAgent(
|
||||
agent: GitHubCopilotAgent[GitHubCopilotOptions] = GitHubCopilotAgent(
|
||||
client=mock_client,
|
||||
default_options={"mcp_servers": mcp_servers},
|
||||
)
|
||||
@@ -625,7 +625,7 @@ class TestGithubCopilotAgentMCPServers:
|
||||
mock_session: MagicMock,
|
||||
) -> None:
|
||||
"""Test that session config does not include mcp_servers when not set."""
|
||||
agent = GithubCopilotAgent(client=mock_client)
|
||||
agent = GitHubCopilotAgent(client=mock_client)
|
||||
await agent.start()
|
||||
|
||||
await agent._get_or_create_session(AgentThread()) # type: ignore
|
||||
@@ -635,7 +635,7 @@ class TestGithubCopilotAgentMCPServers:
|
||||
assert "mcp_servers" not in config
|
||||
|
||||
|
||||
class TestGithubCopilotAgentToolConversion:
|
||||
class TestGitHubCopilotAgentToolConversion:
|
||||
"""Test cases for tool conversion."""
|
||||
|
||||
async def test_function_tool_conversion(
|
||||
@@ -649,7 +649,7 @@ class TestGithubCopilotAgentToolConversion:
|
||||
"""A test tool."""
|
||||
return f"Result: {arg}"
|
||||
|
||||
agent = GithubCopilotAgent(client=mock_client, tools=[my_tool])
|
||||
agent = GitHubCopilotAgent(client=mock_client, tools=[my_tool])
|
||||
await agent.start()
|
||||
|
||||
await agent._get_or_create_session(AgentThread()) # type: ignore
|
||||
@@ -672,7 +672,7 @@ class TestGithubCopilotAgentToolConversion:
|
||||
"""A test tool."""
|
||||
return f"Result: {arg}"
|
||||
|
||||
agent = GithubCopilotAgent(client=mock_client, tools=[my_tool])
|
||||
agent = GitHubCopilotAgent(client=mock_client, tools=[my_tool])
|
||||
await agent.start()
|
||||
|
||||
await agent._get_or_create_session(AgentThread()) # type: ignore
|
||||
@@ -697,7 +697,7 @@ class TestGithubCopilotAgentToolConversion:
|
||||
"""A tool that fails."""
|
||||
raise ValueError("Something went wrong")
|
||||
|
||||
agent = GithubCopilotAgent(client=mock_client, tools=[failing_tool])
|
||||
agent = GitHubCopilotAgent(client=mock_client, tools=[failing_tool])
|
||||
await agent.start()
|
||||
|
||||
await agent._get_or_create_session(AgentThread()) # type: ignore
|
||||
@@ -729,7 +729,7 @@ class TestGithubCopilotAgentToolConversion:
|
||||
parameters={"type": "object", "properties": {}},
|
||||
)
|
||||
|
||||
agent = GithubCopilotAgent(client=mock_client)
|
||||
agent = GitHubCopilotAgent(client=mock_client)
|
||||
result = agent._prepare_tools([copilot_tool]) # type: ignore
|
||||
|
||||
assert len(result) == 1
|
||||
@@ -757,7 +757,7 @@ class TestGithubCopilotAgentToolConversion:
|
||||
handler=tool_handler,
|
||||
)
|
||||
|
||||
agent = GithubCopilotAgent(client=mock_client)
|
||||
agent = GitHubCopilotAgent(client=mock_client)
|
||||
result = agent._prepare_tools([my_function, copilot_tool]) # type: ignore
|
||||
|
||||
assert len(result) == 2
|
||||
@@ -767,14 +767,14 @@ class TestGithubCopilotAgentToolConversion:
|
||||
assert result[1] == copilot_tool
|
||||
|
||||
|
||||
class TestGithubCopilotAgentErrorHandling:
|
||||
class TestGitHubCopilotAgentErrorHandling:
|
||||
"""Test cases for error handling."""
|
||||
|
||||
async def test_start_raises_on_client_error(self, mock_client: MagicMock) -> None:
|
||||
"""Test that start raises ServiceException when client fails to start."""
|
||||
mock_client.start.side_effect = Exception("Connection failed")
|
||||
|
||||
agent = GithubCopilotAgent(client=mock_client)
|
||||
agent = GitHubCopilotAgent(client=mock_client)
|
||||
|
||||
with pytest.raises(ServiceException, match="Failed to start GitHub Copilot client"):
|
||||
await agent.start()
|
||||
@@ -787,7 +787,7 @@ class TestGithubCopilotAgentErrorHandling:
|
||||
"""Test that run raises ServiceException when send_and_wait fails."""
|
||||
mock_session.send_and_wait.side_effect = Exception("Request timeout")
|
||||
|
||||
agent = GithubCopilotAgent(client=mock_client)
|
||||
agent = GitHubCopilotAgent(client=mock_client)
|
||||
|
||||
with pytest.raises(ServiceException, match="GitHub Copilot request failed"):
|
||||
await agent.run("Hello")
|
||||
@@ -799,7 +799,7 @@ class TestGithubCopilotAgentErrorHandling:
|
||||
"""Test that _get_or_create_session raises ServiceException when create_session fails."""
|
||||
mock_client.create_session.side_effect = Exception("Session creation failed")
|
||||
|
||||
agent = GithubCopilotAgent(client=mock_client)
|
||||
agent = GitHubCopilotAgent(client=mock_client)
|
||||
await agent.start()
|
||||
|
||||
with pytest.raises(ServiceException, match="Failed to create GitHub Copilot session"):
|
||||
@@ -807,19 +807,19 @@ class TestGithubCopilotAgentErrorHandling:
|
||||
|
||||
async def test_get_or_create_session_raises_when_client_not_initialized(self) -> None:
|
||||
"""Test that _get_or_create_session raises ServiceException when client is not initialized."""
|
||||
agent = GithubCopilotAgent()
|
||||
agent = GitHubCopilotAgent()
|
||||
# Don't call start() - client remains None
|
||||
|
||||
with pytest.raises(ServiceException, match="GitHub Copilot client not initialized"):
|
||||
await agent._get_or_create_session(AgentThread()) # type: ignore
|
||||
|
||||
|
||||
class TestGithubCopilotAgentPermissions:
|
||||
class TestGitHubCopilotAgentPermissions:
|
||||
"""Test cases for permission handling."""
|
||||
|
||||
def test_no_permission_handler_when_not_provided(self) -> None:
|
||||
"""Test that no handler is set when on_permission_request is not provided."""
|
||||
agent = GithubCopilotAgent()
|
||||
agent = GitHubCopilotAgent()
|
||||
assert agent._permission_handler is None # type: ignore
|
||||
|
||||
def test_permission_handler_set_when_provided(self) -> None:
|
||||
@@ -831,7 +831,7 @@ class TestGithubCopilotAgentPermissions:
|
||||
return PermissionRequestResult(kind="approved")
|
||||
return PermissionRequestResult(kind="denied-interactively-by-user")
|
||||
|
||||
agent: GithubCopilotAgent[GithubCopilotOptions] = GithubCopilotAgent(
|
||||
agent: GitHubCopilotAgent[GitHubCopilotOptions] = GitHubCopilotAgent(
|
||||
default_options={"on_permission_request": approve_shell}
|
||||
)
|
||||
assert agent._permission_handler is not None # type: ignore
|
||||
@@ -849,7 +849,7 @@ class TestGithubCopilotAgentPermissions:
|
||||
return PermissionRequestResult(kind="approved")
|
||||
return PermissionRequestResult(kind="denied-interactively-by-user")
|
||||
|
||||
agent: GithubCopilotAgent[GithubCopilotOptions] = GithubCopilotAgent(
|
||||
agent: GitHubCopilotAgent[GitHubCopilotOptions] = GitHubCopilotAgent(
|
||||
client=mock_client,
|
||||
default_options={"on_permission_request": approve_shell_read},
|
||||
)
|
||||
@@ -868,7 +868,7 @@ class TestGithubCopilotAgentPermissions:
|
||||
mock_session: MagicMock,
|
||||
) -> None:
|
||||
"""Test that session config does not include permission handler when not set."""
|
||||
agent = GithubCopilotAgent(client=mock_client)
|
||||
agent = GitHubCopilotAgent(client=mock_client)
|
||||
await agent.start()
|
||||
|
||||
await agent._get_or_create_session(AgentThread()) # type: ignore
|
||||
|
||||
@@ -4,7 +4,7 @@ description = "Experimental modules for Microsoft Agent Framework"
|
||||
authors = [{ name = "Microsoft", email = "af-support@microsoft.com"}]
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.10"
|
||||
version = "1.0.0b260127"
|
||||
version = "1.0.0b260128"
|
||||
license-files = ["LICENSE"]
|
||||
urls.homepage = "https://aka.ms/agent-framework"
|
||||
urls.source = "https://github.com/microsoft/agent-framework/tree/main/python"
|
||||
|
||||
@@ -4,7 +4,7 @@ description = "Mem0 integration for Microsoft Agent Framework."
|
||||
authors = [{ name = "Microsoft", email = "af-support@microsoft.com"}]
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.10"
|
||||
version = "1.0.0b260127"
|
||||
version = "1.0.0b260128"
|
||||
license-files = ["LICENSE"]
|
||||
urls.homepage = "https://aka.ms/agent-framework"
|
||||
urls.source = "https://github.com/microsoft/agent-framework/tree/main/python"
|
||||
|
||||
@@ -4,7 +4,7 @@ description = "Ollama integration for Microsoft Agent Framework."
|
||||
authors = [{ name = "Microsoft", email = "af-support@microsoft.com"}]
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.10"
|
||||
version = "1.0.0b260127"
|
||||
version = "1.0.0b260128"
|
||||
license-files = ["LICENSE"]
|
||||
urls.homepage = "https://learn.microsoft.com/en-us/agent-framework/"
|
||||
urls.source = "https://github.com/microsoft/agent-framework/tree/main/python"
|
||||
|
||||
@@ -4,7 +4,7 @@ description = "Microsoft Purview (Graph dataSecurityAndGovernance) integration f
|
||||
authors = [{ name = "Microsoft", email = "af-support@microsoft.com"}]
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.10"
|
||||
version = "1.0.0b260127"
|
||||
version = "1.0.0b260128"
|
||||
license-files = ["LICENSE"]
|
||||
urls.homepage = "https://github.com/microsoft/agent-framework"
|
||||
urls.source = "https://github.com/microsoft/agent-framework/tree/main/python"
|
||||
|
||||
@@ -4,7 +4,7 @@ description = "Redis integration for Microsoft Agent Framework."
|
||||
authors = [{ name = "Microsoft", email = "af-support@microsoft.com"}]
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.10"
|
||||
version = "1.0.0b260127"
|
||||
version = "1.0.0b260128"
|
||||
license-files = ["LICENSE"]
|
||||
urls.homepage = "https://aka.ms/agent-framework"
|
||||
urls.source = "https://github.com/microsoft/agent-framework/tree/main/python"
|
||||
|
||||
@@ -4,7 +4,7 @@ description = "Microsoft Agent Framework for building AI Agents with Python. Thi
|
||||
authors = [{ name = "Microsoft", email = "af-support@microsoft.com"}]
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.10"
|
||||
version = "1.0.0b260127"
|
||||
version = "1.0.0b260128"
|
||||
license-files = ["LICENSE"]
|
||||
urls.homepage = "https://aka.ms/agent-framework"
|
||||
urls.source = "https://github.com/microsoft/agent-framework/tree/main/python"
|
||||
@@ -23,7 +23,7 @@ classifiers = [
|
||||
"Typing :: Typed",
|
||||
]
|
||||
dependencies = [
|
||||
"agent-framework-core[all]==1.0.0b260127",
|
||||
"agent-framework-core[all]==1.0.0b260128",
|
||||
]
|
||||
|
||||
[dependency-groups]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# GitHub Copilot Agent Examples
|
||||
|
||||
This directory contains examples demonstrating how to use the `GithubCopilotAgent` from the Microsoft Agent Framework.
|
||||
This directory contains examples demonstrating how to use the `GitHubCopilotAgent` from the Microsoft Agent Framework.
|
||||
|
||||
> **Security Note**: These examples demonstrate various permission types (shell, read, write, url). Only enable permissions that are necessary for your use case. Each permission grants the agent additional capabilities that could affect your system.
|
||||
|
||||
@@ -28,7 +28,7 @@ The following environment variables can be configured:
|
||||
|
||||
| File | Description |
|
||||
|------|-------------|
|
||||
| [`github_copilot_basic.py`](github_copilot_basic.py) | The simplest way to create an agent using `GithubCopilotAgent`. Demonstrates both streaming and non-streaming responses with function tools. |
|
||||
| [`github_copilot_basic.py`](github_copilot_basic.py) | The simplest way to create an agent using `GitHubCopilotAgent`. Demonstrates both streaming and non-streaming responses with function tools. |
|
||||
| [`github_copilot_with_session.py`](github_copilot_with_session.py) | Shows session management with automatic creation, persistence via thread objects, and resuming sessions by ID. |
|
||||
| [`github_copilot_with_shell.py`](github_copilot_with_shell.py) | Shows how to enable shell command execution permissions. Demonstrates running system commands like listing files and getting system information. |
|
||||
| [`github_copilot_with_file_operations.py`](github_copilot_with_file_operations.py) | Shows how to enable file read and write permissions. Demonstrates reading file contents and creating new files. |
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"""
|
||||
GitHub Copilot Agent Basic Example
|
||||
|
||||
This sample demonstrates basic usage of GithubCopilotAgent.
|
||||
This sample demonstrates basic usage of GitHubCopilotAgent.
|
||||
Shows both streaming and non-streaming responses with function tools.
|
||||
|
||||
Environment variables (optional):
|
||||
@@ -17,9 +17,10 @@ import asyncio
|
||||
from random import randint
|
||||
from typing import Annotated
|
||||
|
||||
from agent_framework.github import GithubCopilotAgent, GithubCopilotOptions
|
||||
from pydantic import Field
|
||||
from agent_framework import tool
|
||||
from agent_framework.github import GitHubCopilotAgent, GitHubCopilotOptions
|
||||
from pydantic import Field
|
||||
|
||||
|
||||
# NOTE: approval_mode="never_require" is for sample brevity. Use "always_require" in production; see samples/getting_started/tools/function_tool_with_approval.py and samples/getting_started/tools/function_tool_with_approval_and_threads.py.
|
||||
@tool(approval_mode="never_require")
|
||||
@@ -35,7 +36,7 @@ async def non_streaming_example() -> None:
|
||||
"""Example of non-streaming response (get the complete result at once)."""
|
||||
print("=== Non-streaming Response Example ===")
|
||||
|
||||
agent: GithubCopilotAgent[GithubCopilotOptions] = GithubCopilotAgent(
|
||||
agent: GitHubCopilotAgent[GitHubCopilotOptions] = GitHubCopilotAgent(
|
||||
default_options={"instructions": "You are a helpful weather agent."},
|
||||
tools=[get_weather],
|
||||
)
|
||||
@@ -51,7 +52,7 @@ async def streaming_example() -> None:
|
||||
"""Example of streaming response (get results as they are generated)."""
|
||||
print("=== Streaming Response Example ===")
|
||||
|
||||
agent: GithubCopilotAgent[GithubCopilotOptions] = GithubCopilotAgent(
|
||||
agent: GitHubCopilotAgent[GitHubCopilotOptions] = GitHubCopilotAgent(
|
||||
default_options={"instructions": "You are a helpful weather agent."},
|
||||
tools=[get_weather],
|
||||
)
|
||||
|
||||
+3
-3
@@ -3,7 +3,7 @@
|
||||
"""
|
||||
GitHub Copilot Agent with File Operation Permissions
|
||||
|
||||
This sample demonstrates how to enable file read and write operations with GithubCopilotAgent.
|
||||
This sample demonstrates how to enable file read and write operations with GitHubCopilotAgent.
|
||||
By providing a permission handler that approves "read" and/or "write" requests, the agent can
|
||||
read from and write to files on the filesystem.
|
||||
|
||||
@@ -14,7 +14,7 @@ SECURITY NOTE: Only enable file permissions when you trust the agent's actions.
|
||||
|
||||
import asyncio
|
||||
|
||||
from agent_framework.github import GithubCopilotAgent, GithubCopilotOptions
|
||||
from agent_framework.github import GitHubCopilotAgent, GitHubCopilotOptions
|
||||
from copilot.types import PermissionRequest, PermissionRequestResult
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ def prompt_permission(request: PermissionRequest, context: dict[str, str]) -> Pe
|
||||
async def main() -> None:
|
||||
print("=== GitHub Copilot Agent with File Operation Permissions ===\n")
|
||||
|
||||
agent: GithubCopilotAgent[GithubCopilotOptions] = GithubCopilotAgent(
|
||||
agent: GitHubCopilotAgent[GitHubCopilotOptions] = GitHubCopilotAgent(
|
||||
default_options={
|
||||
"instructions": "You are a helpful assistant that can read and write files.",
|
||||
"on_permission_request": prompt_permission,
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
GitHub Copilot Agent with MCP Servers
|
||||
|
||||
This sample demonstrates how to configure MCP (Model Context Protocol) servers
|
||||
with GithubCopilotAgent. It shows both local (stdio) and remote (HTTP) server
|
||||
with GitHubCopilotAgent. It shows both local (stdio) and remote (HTTP) server
|
||||
configurations, giving the agent access to external tools and data sources.
|
||||
|
||||
SECURITY NOTE: MCP servers can expose powerful capabilities. Only configure
|
||||
@@ -14,7 +14,7 @@ of MCP-related actions.
|
||||
|
||||
import asyncio
|
||||
|
||||
from agent_framework.github import GithubCopilotAgent, GithubCopilotOptions
|
||||
from agent_framework.github import GitHubCopilotAgent, GitHubCopilotOptions
|
||||
from copilot.types import MCPServerConfig, PermissionRequest, PermissionRequestResult
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ async def main() -> None:
|
||||
},
|
||||
}
|
||||
|
||||
agent: GithubCopilotAgent[GithubCopilotOptions] = GithubCopilotAgent(
|
||||
agent: GitHubCopilotAgent[GitHubCopilotOptions] = GitHubCopilotAgent(
|
||||
default_options={
|
||||
"instructions": "You are a helpful assistant with access to the local filesystem and Microsoft Learn.",
|
||||
"on_permission_request": prompt_permission,
|
||||
|
||||
+3
-3
@@ -3,7 +3,7 @@
|
||||
"""
|
||||
GitHub Copilot Agent with Multiple Permissions
|
||||
|
||||
This sample demonstrates how to enable multiple permission types with GithubCopilotAgent.
|
||||
This sample demonstrates how to enable multiple permission types with GitHubCopilotAgent.
|
||||
By combining different permission kinds in the handler, the agent can perform complex tasks
|
||||
that require multiple capabilities.
|
||||
|
||||
@@ -20,7 +20,7 @@ More permissions mean more potential for unintended actions.
|
||||
|
||||
import asyncio
|
||||
|
||||
from agent_framework.github import GithubCopilotAgent, GithubCopilotOptions
|
||||
from agent_framework.github import GitHubCopilotAgent, GitHubCopilotOptions
|
||||
from copilot.types import PermissionRequest, PermissionRequestResult
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ def prompt_permission(request: PermissionRequest, context: dict[str, str]) -> Pe
|
||||
async def main() -> None:
|
||||
print("=== GitHub Copilot Agent with Multiple Permissions ===\n")
|
||||
|
||||
agent: GithubCopilotAgent[GithubCopilotOptions] = GithubCopilotAgent(
|
||||
agent: GitHubCopilotAgent[GitHubCopilotOptions] = GitHubCopilotAgent(
|
||||
default_options={
|
||||
"instructions": "You are a helpful development assistant that can read, write files and run commands.",
|
||||
"on_permission_request": prompt_permission,
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"""
|
||||
GitHub Copilot Agent with Session Management
|
||||
|
||||
This sample demonstrates session management with GithubCopilotAgent, showing
|
||||
This sample demonstrates session management with GitHubCopilotAgent, showing
|
||||
persistent conversation capabilities. Sessions are automatically persisted
|
||||
server-side by the Copilot CLI.
|
||||
"""
|
||||
@@ -12,9 +12,10 @@ import asyncio
|
||||
from random import randint
|
||||
from typing import Annotated
|
||||
|
||||
from agent_framework.github import GithubCopilotAgent, GithubCopilotOptions
|
||||
from pydantic import Field
|
||||
from agent_framework import tool
|
||||
from agent_framework.github import GitHubCopilotAgent, GitHubCopilotOptions
|
||||
from pydantic import Field
|
||||
|
||||
|
||||
# NOTE: approval_mode="never_require" is for sample brevity. Use "always_require" in production; see samples/getting_started/tools/function_tool_with_approval.py and samples/getting_started/tools/function_tool_with_approval_and_threads.py.
|
||||
@tool(approval_mode="never_require")
|
||||
@@ -30,7 +31,7 @@ async def example_with_automatic_session_creation() -> None:
|
||||
"""Each run() without thread creates a new session."""
|
||||
print("=== Automatic Session Creation Example ===")
|
||||
|
||||
agent: GithubCopilotAgent[GithubCopilotOptions] = GithubCopilotAgent(
|
||||
agent: GitHubCopilotAgent[GitHubCopilotOptions] = GitHubCopilotAgent(
|
||||
default_options={"instructions": "You are a helpful weather agent."},
|
||||
tools=[get_weather],
|
||||
)
|
||||
@@ -54,7 +55,7 @@ async def example_with_session_persistence() -> None:
|
||||
"""Reuse session via thread object for multi-turn conversations."""
|
||||
print("=== Session Persistence Example ===")
|
||||
|
||||
agent: GithubCopilotAgent[GithubCopilotOptions] = GithubCopilotAgent(
|
||||
agent: GitHubCopilotAgent[GitHubCopilotOptions] = GitHubCopilotAgent(
|
||||
default_options={"instructions": "You are a helpful weather agent."},
|
||||
tools=[get_weather],
|
||||
)
|
||||
@@ -90,7 +91,7 @@ async def example_with_existing_session_id() -> None:
|
||||
existing_session_id = None
|
||||
|
||||
# First agent instance - start a conversation
|
||||
agent1: GithubCopilotAgent[GithubCopilotOptions] = GithubCopilotAgent(
|
||||
agent1: GitHubCopilotAgent[GitHubCopilotOptions] = GitHubCopilotAgent(
|
||||
default_options={"instructions": "You are a helpful weather agent."},
|
||||
tools=[get_weather],
|
||||
)
|
||||
@@ -111,7 +112,7 @@ async def example_with_existing_session_id() -> None:
|
||||
print("\n--- Continuing with the same session ID in a new agent instance ---")
|
||||
|
||||
# Second agent instance - resume the conversation
|
||||
agent2: GithubCopilotAgent[GithubCopilotOptions] = GithubCopilotAgent(
|
||||
agent2: GitHubCopilotAgent[GitHubCopilotOptions] = GitHubCopilotAgent(
|
||||
default_options={"instructions": "You are a helpful weather agent."},
|
||||
tools=[get_weather],
|
||||
)
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"""
|
||||
GitHub Copilot Agent with Shell Permissions
|
||||
|
||||
This sample demonstrates how to enable shell command execution with GithubCopilotAgent.
|
||||
This sample demonstrates how to enable shell command execution with GitHubCopilotAgent.
|
||||
By providing a permission handler that approves "shell" requests, the agent can execute
|
||||
shell commands to perform tasks like listing files, running scripts, or executing system commands.
|
||||
|
||||
@@ -13,7 +13,7 @@ Shell commands have full access to your system within the permissions of the run
|
||||
|
||||
import asyncio
|
||||
|
||||
from agent_framework.github import GithubCopilotAgent, GithubCopilotOptions
|
||||
from agent_framework.github import GitHubCopilotAgent, GitHubCopilotOptions
|
||||
from copilot.types import PermissionRequest, PermissionRequestResult
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ def prompt_permission(request: PermissionRequest, context: dict[str, str]) -> Pe
|
||||
async def main() -> None:
|
||||
print("=== GitHub Copilot Agent with Shell Permissions ===\n")
|
||||
|
||||
agent: GithubCopilotAgent[GithubCopilotOptions] = GithubCopilotAgent(
|
||||
agent: GitHubCopilotAgent[GitHubCopilotOptions] = GitHubCopilotAgent(
|
||||
default_options={
|
||||
"instructions": "You are a helpful assistant that can execute shell commands.",
|
||||
"on_permission_request": prompt_permission,
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"""
|
||||
GitHub Copilot Agent with URL Fetching
|
||||
|
||||
This sample demonstrates how to enable URL fetching with GithubCopilotAgent.
|
||||
This sample demonstrates how to enable URL fetching with GitHubCopilotAgent.
|
||||
By providing a permission handler that approves "url" requests, the agent can
|
||||
fetch and process content from web URLs.
|
||||
|
||||
@@ -13,7 +13,7 @@ URL fetching allows the agent to access any URL accessible from your network.
|
||||
|
||||
import asyncio
|
||||
|
||||
from agent_framework.github import GithubCopilotAgent, GithubCopilotOptions
|
||||
from agent_framework.github import GitHubCopilotAgent, GitHubCopilotOptions
|
||||
from copilot.types import PermissionRequest, PermissionRequestResult
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ def prompt_permission(request: PermissionRequest, context: dict[str, str]) -> Pe
|
||||
async def main() -> None:
|
||||
print("=== GitHub Copilot Agent with URL Fetching ===\n")
|
||||
|
||||
agent: GithubCopilotAgent[GithubCopilotOptions] = GithubCopilotAgent(
|
||||
agent: GitHubCopilotAgent[GitHubCopilotOptions] = GitHubCopilotAgent(
|
||||
default_options={
|
||||
"instructions": "You are a helpful assistant that can fetch and summarize web content.",
|
||||
"on_permission_request": prompt_permission,
|
||||
|
||||
@@ -9,7 +9,7 @@ from agent_framework import tool
|
||||
"""
|
||||
This sample demonstrates how to expose an Agent as an MCP server.
|
||||
|
||||
To run this sample, set up your MCP host (like Claude Desktop or VSCode Github Copilot Agents)
|
||||
To run this sample, set up your MCP host (like Claude Desktop or VSCode GitHub Copilot Agents)
|
||||
with the following configuration:
|
||||
```json
|
||||
{
|
||||
|
||||
Generated
+32
-26
@@ -94,7 +94,7 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "agent-framework"
|
||||
version = "1.0.0b260127"
|
||||
version = "1.0.0b260128"
|
||||
source = { virtual = "." }
|
||||
dependencies = [
|
||||
{ name = "agent-framework-core", extra = ["all"], marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" },
|
||||
@@ -161,7 +161,7 @@ docs = [
|
||||
|
||||
[[package]]
|
||||
name = "agent-framework-a2a"
|
||||
version = "1.0.0b260127"
|
||||
version = "1.0.0b260128"
|
||||
source = { editable = "packages/a2a" }
|
||||
dependencies = [
|
||||
{ name = "a2a-sdk", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" },
|
||||
@@ -176,7 +176,7 @@ requires-dist = [
|
||||
|
||||
[[package]]
|
||||
name = "agent-framework-ag-ui"
|
||||
version = "1.0.0b260127"
|
||||
version = "1.0.0b260128"
|
||||
source = { editable = "packages/ag-ui" }
|
||||
dependencies = [
|
||||
{ name = "ag-ui-protocol", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" },
|
||||
@@ -206,7 +206,7 @@ provides-extras = ["dev"]
|
||||
|
||||
[[package]]
|
||||
name = "agent-framework-anthropic"
|
||||
version = "1.0.0b260127"
|
||||
version = "1.0.0b260128"
|
||||
source = { editable = "packages/anthropic" }
|
||||
dependencies = [
|
||||
{ name = "agent-framework-core", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" },
|
||||
@@ -221,7 +221,7 @@ requires-dist = [
|
||||
|
||||
[[package]]
|
||||
name = "agent-framework-azure-ai"
|
||||
version = "1.0.0b260127"
|
||||
version = "1.0.0b260128"
|
||||
source = { editable = "packages/azure-ai" }
|
||||
dependencies = [
|
||||
{ name = "agent-framework-core", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" },
|
||||
@@ -240,7 +240,7 @@ requires-dist = [
|
||||
|
||||
[[package]]
|
||||
name = "agent-framework-azure-ai-search"
|
||||
version = "1.0.0b260127"
|
||||
version = "1.0.0b260128"
|
||||
source = { editable = "packages/azure-ai-search" }
|
||||
dependencies = [
|
||||
{ name = "agent-framework-core", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" },
|
||||
@@ -255,7 +255,7 @@ requires-dist = [
|
||||
|
||||
[[package]]
|
||||
name = "agent-framework-azurefunctions"
|
||||
version = "1.0.0b260127"
|
||||
version = "1.0.0b260128"
|
||||
source = { editable = "packages/azurefunctions" }
|
||||
dependencies = [
|
||||
{ name = "agent-framework-core", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" },
|
||||
@@ -282,7 +282,7 @@ dev = [{ name = "types-python-dateutil", specifier = ">=2.9.0" }]
|
||||
|
||||
[[package]]
|
||||
name = "agent-framework-bedrock"
|
||||
version = "1.0.0b260127"
|
||||
version = "1.0.0b260128"
|
||||
source = { editable = "packages/bedrock" }
|
||||
dependencies = [
|
||||
{ name = "agent-framework-core", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" },
|
||||
@@ -299,7 +299,7 @@ requires-dist = [
|
||||
|
||||
[[package]]
|
||||
name = "agent-framework-chatkit"
|
||||
version = "1.0.0b260127"
|
||||
version = "1.0.0b260128"
|
||||
source = { editable = "packages/chatkit" }
|
||||
dependencies = [
|
||||
{ name = "agent-framework-core", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" },
|
||||
@@ -314,7 +314,7 @@ requires-dist = [
|
||||
|
||||
[[package]]
|
||||
name = "agent-framework-copilotstudio"
|
||||
version = "1.0.0b260127"
|
||||
version = "1.0.0b260128"
|
||||
source = { editable = "packages/copilotstudio" }
|
||||
dependencies = [
|
||||
{ name = "agent-framework-core", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" },
|
||||
@@ -329,7 +329,7 @@ requires-dist = [
|
||||
|
||||
[[package]]
|
||||
name = "agent-framework-core"
|
||||
version = "1.0.0b260127"
|
||||
version = "1.0.0b260128"
|
||||
source = { editable = "packages/core" }
|
||||
dependencies = [
|
||||
{ name = "azure-identity", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" },
|
||||
@@ -399,7 +399,7 @@ provides-extras = ["all"]
|
||||
|
||||
[[package]]
|
||||
name = "agent-framework-declarative"
|
||||
version = "1.0.0b260127"
|
||||
version = "1.0.0b260128"
|
||||
source = { editable = "packages/declarative" }
|
||||
dependencies = [
|
||||
{ name = "agent-framework-core", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" },
|
||||
@@ -424,7 +424,7 @@ dev = [{ name = "types-pyyaml" }]
|
||||
|
||||
[[package]]
|
||||
name = "agent-framework-devui"
|
||||
version = "1.0.0b260127"
|
||||
version = "1.0.0b260128"
|
||||
source = { editable = "packages/devui" }
|
||||
dependencies = [
|
||||
{ name = "agent-framework-core", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" },
|
||||
@@ -458,7 +458,7 @@ provides-extras = ["dev", "all"]
|
||||
|
||||
[[package]]
|
||||
name = "agent-framework-durabletask"
|
||||
version = "0.0.2b260126"
|
||||
version = "0.0.2b260128"
|
||||
source = { editable = "packages/durabletask" }
|
||||
dependencies = [
|
||||
{ name = "agent-framework-core", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" },
|
||||
@@ -483,7 +483,7 @@ dev = [{ name = "types-python-dateutil", specifier = ">=2.9.0" }]
|
||||
|
||||
[[package]]
|
||||
name = "agent-framework-foundry-local"
|
||||
version = "1.0.0b260127"
|
||||
version = "1.0.0b260128"
|
||||
source = { editable = "packages/foundry_local" }
|
||||
dependencies = [
|
||||
{ name = "agent-framework-core", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" },
|
||||
@@ -498,7 +498,7 @@ requires-dist = [
|
||||
|
||||
[[package]]
|
||||
name = "agent-framework-github-copilot"
|
||||
version = "1.0.0b260127"
|
||||
version = "1.0.0b260128"
|
||||
source = { editable = "packages/github_copilot" }
|
||||
dependencies = [
|
||||
{ name = "agent-framework-core", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" },
|
||||
@@ -513,7 +513,7 @@ requires-dist = [
|
||||
|
||||
[[package]]
|
||||
name = "agent-framework-lab"
|
||||
version = "1.0.0b260127"
|
||||
version = "1.0.0b260128"
|
||||
source = { editable = "packages/lab" }
|
||||
dependencies = [
|
||||
{ name = "agent-framework-core", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" },
|
||||
@@ -604,7 +604,7 @@ dev = [
|
||||
|
||||
[[package]]
|
||||
name = "agent-framework-mem0"
|
||||
version = "1.0.0b260127"
|
||||
version = "1.0.0b260128"
|
||||
source = { editable = "packages/mem0" }
|
||||
dependencies = [
|
||||
{ name = "agent-framework-core", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" },
|
||||
@@ -619,7 +619,7 @@ requires-dist = [
|
||||
|
||||
[[package]]
|
||||
name = "agent-framework-ollama"
|
||||
version = "1.0.0b260127"
|
||||
version = "1.0.0b260128"
|
||||
source = { editable = "packages/ollama" }
|
||||
dependencies = [
|
||||
{ name = "agent-framework-core", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" },
|
||||
@@ -634,7 +634,7 @@ requires-dist = [
|
||||
|
||||
[[package]]
|
||||
name = "agent-framework-purview"
|
||||
version = "1.0.0b260127"
|
||||
version = "1.0.0b260128"
|
||||
source = { editable = "packages/purview" }
|
||||
dependencies = [
|
||||
{ name = "agent-framework-core", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" },
|
||||
@@ -651,7 +651,7 @@ requires-dist = [
|
||||
|
||||
[[package]]
|
||||
name = "agent-framework-redis"
|
||||
version = "1.0.0b260127"
|
||||
version = "1.0.0b260128"
|
||||
source = { editable = "packages/redis" }
|
||||
dependencies = [
|
||||
{ name = "agent-framework-core", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" },
|
||||
@@ -1426,7 +1426,7 @@ name = "clr-loader"
|
||||
version = "0.2.10"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "cffi", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" },
|
||||
{ name = "cffi", marker = "(python_full_version < '3.14' and sys_platform == 'darwin') or (python_full_version < '3.14' and sys_platform == 'linux') or (python_full_version < '3.14' and sys_platform == 'win32')" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/18/24/c12faf3f61614b3131b5c98d3bf0d376b49c7feaa73edca559aeb2aee080/clr_loader-0.2.10.tar.gz", hash = "sha256:81f114afbc5005bafc5efe5af1341d400e22137e275b042a8979f3feb9fc9446", size = 83605, upload-time = "2026-01-03T23:13:06.984Z" }
|
||||
wheels = [
|
||||
@@ -1934,7 +1934,7 @@ name = "exceptiongroup"
|
||||
version = "1.3.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "typing-extensions", marker = "(python_full_version < '3.13' and sys_platform == 'darwin') or (python_full_version < '3.13' and sys_platform == 'linux') or (python_full_version < '3.13' and sys_platform == 'win32')" },
|
||||
{ name = "typing-extensions", marker = "(python_full_version < '3.11' and sys_platform == 'darwin') or (python_full_version < '3.11' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform == 'win32')" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/50/79/66800aadf48771f6b62f7eb014e352e5d06856655206165d775e675a02c9/exceptiongroup-1.3.1.tar.gz", hash = "sha256:8b412432c6055b0b7d14c310000ae93352ed6754f70fa8f7c34141f91c4e3219", size = 30371, upload-time = "2025-11-21T23:01:54.787Z" }
|
||||
wheels = [
|
||||
@@ -2395,6 +2395,7 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/fe/65/5b235b40581ad75ab97dcd8b4218022ae8e3ab77c13c919f1a1dfe9171fd/greenlet-3.3.1-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:04bee4775f40ecefcdaa9d115ab44736cd4b9c5fba733575bfe9379419582e13", size = 273723, upload-time = "2026-01-23T15:30:37.521Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ce/ad/eb4729b85cba2d29499e0a04ca6fbdd8f540afd7be142fd571eea43d712f/greenlet-3.3.1-cp310-cp310-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:50e1457f4fed12a50e427988a07f0f9df53cf0ee8da23fab16e6732c2ec909d4", size = 574874, upload-time = "2026-01-23T16:00:54.551Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/87/32/57cad7fe4c8b82fdaa098c89498ef85ad92dfbb09d5eb713adedfc2ae1f5/greenlet-3.3.1-cp310-cp310-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:070472cd156f0656f86f92e954591644e158fd65aa415ffbe2d44ca77656a8f5", size = 586309, upload-time = "2026-01-23T16:05:25.18Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/66/66/f041005cb87055e62b0d68680e88ec1a57f4688523d5e2fb305841bc8307/greenlet-3.3.1-cp310-cp310-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:1108b61b06b5224656121c3c8ee8876161c491cbe74e5c519e0634c837cf93d5", size = 597461, upload-time = "2026-01-23T16:15:51.943Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/87/eb/8a1ec2da4d55824f160594a75a9d8354a5fe0a300fb1c48e7944265217e1/greenlet-3.3.1-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3a300354f27dd86bae5fbf7002e6dd2b3255cd372e9242c933faf5e859b703fe", size = 586985, upload-time = "2026-01-23T15:32:47.968Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/15/1c/0621dd4321dd8c351372ee8f9308136acb628600658a49be1b7504208738/greenlet-3.3.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:e84b51cbebf9ae573b5fbd15df88887815e3253fc000a7d0ff95170e8f7e9729", size = 1547271, upload-time = "2026-01-23T16:04:18.977Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/9d/53/24047f8924c83bea7a59c8678d9571209c6bfe5f4c17c94a78c06024e9f2/greenlet-3.3.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e0093bd1a06d899892427217f0ff2a3c8f306182b8c754336d32e2d587c131b4", size = 1613427, upload-time = "2026-01-23T15:33:44.428Z" },
|
||||
@@ -2402,6 +2403,7 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/ec/e8/2e1462c8fdbe0f210feb5ac7ad2d9029af8be3bf45bd9fa39765f821642f/greenlet-3.3.1-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:5fd23b9bc6d37b563211c6abbb1b3cab27db385a4449af5c32e932f93017080c", size = 274974, upload-time = "2026-01-23T15:31:02.891Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/7e/a8/530a401419a6b302af59f67aaf0b9ba1015855ea7e56c036b5928793c5bd/greenlet-3.3.1-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:09f51496a0bfbaa9d74d36a52d2580d1ef5ed4fdfcff0a73730abfbbbe1403dd", size = 577175, upload-time = "2026-01-23T16:00:56.213Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8e/89/7e812bb9c05e1aaef9b597ac1d0962b9021d2c6269354966451e885c4e6b/greenlet-3.3.1-cp311-cp311-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:cb0feb07fe6e6a74615ee62a880007d976cf739b6669cce95daa7373d4fc69c5", size = 590401, upload-time = "2026-01-23T16:05:26.365Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/70/ae/e2d5f0e59b94a2269b68a629173263fa40b63da32f5c231307c349315871/greenlet-3.3.1-cp311-cp311-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:67ea3fc73c8cd92f42467a72b75e8f05ed51a0e9b1d15398c913416f2dafd49f", size = 601161, upload-time = "2026-01-23T16:15:53.456Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/5c/ae/8d472e1f5ac5efe55c563f3eabb38c98a44b832602e12910750a7c025802/greenlet-3.3.1-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:39eda9ba259cc9801da05351eaa8576e9aa83eb9411e8f0c299e05d712a210f2", size = 590272, upload-time = "2026-01-23T15:32:49.411Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a8/51/0fde34bebfcadc833550717eade64e35ec8738e6b097d5d248274a01258b/greenlet-3.3.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:e2e7e882f83149f0a71ac822ebf156d902e7a5d22c9045e3e0d1daf59cee2cc9", size = 1550729, upload-time = "2026-01-23T16:04:20.867Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/16/c9/2fb47bee83b25b119d5a35d580807bb8b92480a54b68fef009a02945629f/greenlet-3.3.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:80aa4d79eb5564f2e0a6144fcc744b5a37c56c4a92d60920720e99210d88db0f", size = 1615552, upload-time = "2026-01-23T15:33:45.743Z" },
|
||||
@@ -2410,6 +2412,7 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/f9/c8/9d76a66421d1ae24340dfae7e79c313957f6e3195c144d2c73333b5bfe34/greenlet-3.3.1-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:7e806ca53acf6d15a888405880766ec84721aa4181261cd11a457dfe9a7a4975", size = 276443, upload-time = "2026-01-23T15:30:10.066Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/81/99/401ff34bb3c032d1f10477d199724f5e5f6fbfb59816ad1455c79c1eb8e7/greenlet-3.3.1-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d842c94b9155f1c9b3058036c24ffb8ff78b428414a19792b2380be9cecf4f36", size = 597359, upload-time = "2026-01-23T16:00:57.394Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2b/bc/4dcc0871ed557792d304f50be0f7487a14e017952ec689effe2180a6ff35/greenlet-3.3.1-cp312-cp312-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:20fedaadd422fa02695f82093f9a98bad3dab5fcda793c658b945fcde2ab27ba", size = 607805, upload-time = "2026-01-23T16:05:28.068Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/3b/cd/7a7ca57588dac3389e97f7c9521cb6641fd8b6602faf1eaa4188384757df/greenlet-3.3.1-cp312-cp312-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:c620051669fd04ac6b60ebc70478210119c56e2d5d5df848baec4312e260e4ca", size = 622363, upload-time = "2026-01-23T16:15:54.754Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/cf/05/821587cf19e2ce1f2b24945d890b164401e5085f9d09cbd969b0c193cd20/greenlet-3.3.1-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:14194f5f4305800ff329cbf02c5fcc88f01886cadd29941b807668a45f0d2336", size = 609947, upload-time = "2026-01-23T15:32:51.004Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a4/52/ee8c46ed9f8babaa93a19e577f26e3d28a519feac6350ed6f25f1afee7e9/greenlet-3.3.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7b2fe4150a0cf59f847a67db8c155ac36aed89080a6a639e9f16df5d6c6096f1", size = 1567487, upload-time = "2026-01-23T16:04:22.125Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8f/7c/456a74f07029597626f3a6db71b273a3632aecb9afafeeca452cfa633197/greenlet-3.3.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:49f4ad195d45f4a66a0eb9c1ba4832bb380570d361912fa3554746830d332149", size = 1636087, upload-time = "2026-01-23T15:33:47.486Z" },
|
||||
@@ -2418,6 +2421,7 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/ec/ab/d26750f2b7242c2b90ea2ad71de70cfcd73a948a49513188a0fc0d6fc15a/greenlet-3.3.1-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:7ab327905cabb0622adca5971e488064e35115430cec2c35a50fd36e72a315b3", size = 275205, upload-time = "2026-01-23T15:30:24.556Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/10/d3/be7d19e8fad7c5a78eeefb2d896a08cd4643e1e90c605c4be3b46264998f/greenlet-3.3.1-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:65be2f026ca6a176f88fb935ee23c18333ccea97048076aef4db1ef5bc0713ac", size = 599284, upload-time = "2026-01-23T16:00:58.584Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ae/21/fe703aaa056fdb0f17e5afd4b5c80195bbdab701208918938bd15b00d39b/greenlet-3.3.1-cp313-cp313-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:7a3ae05b3d225b4155bda56b072ceb09d05e974bc74be6c3fc15463cf69f33fd", size = 610274, upload-time = "2026-01-23T16:05:29.312Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/06/00/95df0b6a935103c0452dad2203f5be8377e551b8466a29650c4c5a5af6cc/greenlet-3.3.1-cp313-cp313-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:12184c61e5d64268a160226fb4818af4df02cfead8379d7f8b99a56c3a54ff3e", size = 624375, upload-time = "2026-01-23T16:15:55.915Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/cb/86/5c6ab23bb3c28c21ed6bebad006515cfe08b04613eb105ca0041fecca852/greenlet-3.3.1-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6423481193bbbe871313de5fd06a082f2649e7ce6e08015d2a76c1e9186ca5b3", size = 612904, upload-time = "2026-01-23T15:32:52.317Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c2/f3/7949994264e22639e40718c2daf6f6df5169bf48fb038c008a489ec53a50/greenlet-3.3.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:33a956fe78bbbda82bfc95e128d61129b32d66bcf0a20a1f0c08aa4839ffa951", size = 1567316, upload-time = "2026-01-23T16:04:23.316Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8d/6e/d73c94d13b6465e9f7cd6231c68abde838bb22408596c05d9059830b7872/greenlet-3.3.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4b065d3284be43728dd280f6f9a13990b56470b81be20375a207cdc814a983f2", size = 1636549, upload-time = "2026-01-23T15:33:48.643Z" },
|
||||
@@ -2426,6 +2430,7 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/ae/fb/011c7c717213182caf78084a9bea51c8590b0afda98001f69d9f853a495b/greenlet-3.3.1-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:bd59acd8529b372775cd0fcbc5f420ae20681c5b045ce25bd453ed8455ab99b5", size = 275737, upload-time = "2026-01-23T15:32:16.889Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/41/2e/a3a417d620363fdbb08a48b1dd582956a46a61bf8fd27ee8164f9dfe87c2/greenlet-3.3.1-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b31c05dd84ef6871dd47120386aed35323c944d86c3d91a17c4b8d23df62f15b", size = 646422, upload-time = "2026-01-23T16:01:00.354Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b4/09/c6c4a0db47defafd2d6bab8ddfe47ad19963b4e30f5bed84d75328059f8c/greenlet-3.3.1-cp314-cp314-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:02925a0bfffc41e542c70aa14c7eda3593e4d7e274bfcccca1827e6c0875902e", size = 658219, upload-time = "2026-01-23T16:05:30.956Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e2/89/b95f2ddcc5f3c2bc09c8ee8d77be312df7f9e7175703ab780f2014a0e781/greenlet-3.3.1-cp314-cp314-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:3e0f3878ca3a3ff63ab4ea478585942b53df66ddde327b59ecb191b19dbbd62d", size = 671455, upload-time = "2026-01-23T16:15:57.232Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/80/38/9d42d60dffb04b45f03dbab9430898352dba277758640751dc5cc316c521/greenlet-3.3.1-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:34a729e2e4e4ffe9ae2408d5ecaf12f944853f40ad724929b7585bca808a9d6f", size = 660237, upload-time = "2026-01-23T15:32:53.967Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/96/61/373c30b7197f9e756e4c81ae90a8d55dc3598c17673f91f4d31c3c689c3f/greenlet-3.3.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:aec9ab04e82918e623415947921dea15851b152b822661cce3f8e4393c3df683", size = 1615261, upload-time = "2026-01-23T16:04:25.066Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/fd/d3/ca534310343f5945316f9451e953dcd89b36fe7a19de652a1dc5a0eeef3f/greenlet-3.3.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:71c767cf281a80d02b6c1bdc41c9468e1f5a494fb11bc8688c360524e273d7b1", size = 1683719, upload-time = "2026-01-23T15:33:50.61Z" },
|
||||
@@ -2434,6 +2439,7 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/28/24/cbbec49bacdcc9ec652a81d3efef7b59f326697e7edf6ed775a5e08e54c2/greenlet-3.3.1-cp314-cp314t-macosx_11_0_universal2.whl", hash = "sha256:3e63252943c921b90abb035ebe9de832c436401d9c45f262d80e2d06cc659242", size = 282706, upload-time = "2026-01-23T15:33:05.525Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/86/2e/4f2b9323c144c4fe8842a4e0d92121465485c3c2c5b9e9b30a52e80f523f/greenlet-3.3.1-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:76e39058e68eb125de10c92524573924e827927df5d3891fbc97bd55764a8774", size = 651209, upload-time = "2026-01-23T16:01:01.517Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d9/87/50ca60e515f5bb55a2fbc5f0c9b5b156de7d2fc51a0a69abc9d23914a237/greenlet-3.3.1-cp314-cp314t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c9f9d5e7a9310b7a2f416dd13d2e3fd8b42d803968ea580b7c0f322ccb389b97", size = 654300, upload-time = "2026-01-23T16:05:32.199Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/7c/25/c51a63f3f463171e09cb586eb64db0861eb06667ab01a7968371a24c4f3b/greenlet-3.3.1-cp314-cp314t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:4b9721549a95db96689458a1e0ae32412ca18776ed004463df3a9299c1b257ab", size = 662574, upload-time = "2026-01-23T16:15:58.364Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1d/94/74310866dfa2b73dd08659a3d18762f83985ad3281901ba0ee9a815194fb/greenlet-3.3.1-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:92497c78adf3ac703b57f1e3813c2d874f27f71a178f9ea5887855da413cd6d2", size = 653842, upload-time = "2026-01-23T15:32:55.671Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/97/43/8bf0ffa3d498eeee4c58c212a3905dd6146c01c8dc0b0a046481ca29b18c/greenlet-3.3.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:ed6b402bc74d6557a705e197d47f9063733091ed6357b3de33619d8a8d93ac53", size = 1614917, upload-time = "2026-01-23T16:04:26.276Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/89/90/a3be7a5f378fc6e84abe4dcfb2ba32b07786861172e502388b4c90000d1b/greenlet-3.3.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:59913f1e5ada20fde795ba906916aea25d442abcc0593fba7e26c92b7ad76249", size = 1676092, upload-time = "2026-01-23T15:33:52.176Z" },
|
||||
@@ -4689,8 +4695,8 @@ name = "powerfx"
|
||||
version = "0.0.34"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "cffi", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" },
|
||||
{ name = "pythonnet", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" },
|
||||
{ name = "cffi", marker = "(python_full_version < '3.14' and sys_platform == 'darwin') or (python_full_version < '3.14' and sys_platform == 'linux') or (python_full_version < '3.14' and sys_platform == 'win32')" },
|
||||
{ name = "pythonnet", marker = "(python_full_version < '3.14' and sys_platform == 'darwin') or (python_full_version < '3.14' and sys_platform == 'linux') or (python_full_version < '3.14' and sys_platform == 'win32')" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/9f/fb/6c4bf87e0c74ca1c563921ce89ca1c5785b7576bca932f7255cdf81082a7/powerfx-0.0.34.tar.gz", hash = "sha256:956992e7afd272657ed16d80f4cad24ec95d9e4a79fb9dfa4a068a09e136af32", size = 3237555, upload-time = "2025-12-22T15:50:59.682Z" }
|
||||
wheels = [
|
||||
@@ -5357,7 +5363,7 @@ name = "pythonnet"
|
||||
version = "3.0.5"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "clr-loader", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" },
|
||||
{ name = "clr-loader", marker = "(python_full_version < '3.14' and sys_platform == 'darwin') or (python_full_version < '3.14' and sys_platform == 'linux') or (python_full_version < '3.14' and sys_platform == 'win32')" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/9a/d6/1afd75edd932306ae9bd2c2d961d603dc2b52fcec51b04afea464f1f6646/pythonnet-3.0.5.tar.gz", hash = "sha256:48e43ca463941b3608b32b4e236db92d8d40db4c58a75ace902985f76dac21cf", size = 239212, upload-time = "2024-12-13T08:30:44.393Z" }
|
||||
wheels = [
|
||||
|
||||
Reference in New Issue
Block a user