.NET: Python: [BREAKING] Renamed Github to GitHub (#3486)

* Renamed Github to GitHub

* Small fix

* Updated package versions
This commit is contained in:
Dmytro Struk
2026-01-28 11:58:31 -08:00
committed by GitHub
Unverified
parent fa74f27030
commit 45a020be43
55 changed files with 251 additions and 234 deletions
+10 -1
View File
@@ -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
+1 -1
View File
@@ -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 -1
View File
@@ -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"]
+1 -1
View File
@@ -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"
+1 -1
View File
@@ -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"
+1 -1
View File
@@ -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"
+1 -1
View File
@@ -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"
+1 -1
View File
@@ -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__",
]
+1 -1
View File
@@ -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"
+1 -1
View File
@@ -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"
+1 -1
View File
@@ -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"
+1 -1
View File
@@ -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"
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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"
+1 -1
View File
@@ -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"
+1 -1
View File
@@ -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"
+1 -1
View File
@@ -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"
+1 -1
View File
@@ -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"
+2 -2
View File
@@ -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,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,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
{
+32 -26
View File
@@ -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 = [