agent-framework-github-copilot 1.0.0rc2__tar.gz → 1.0.0rc3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {agent_framework_github_copilot-1.0.0rc2 → agent_framework_github_copilot-1.0.0rc3}/PKG-INFO +2 -2
- {agent_framework_github_copilot-1.0.0rc2 → agent_framework_github_copilot-1.0.0rc3}/agent_framework_github_copilot/_agent.py +115 -15
- {agent_framework_github_copilot-1.0.0rc2 → agent_framework_github_copilot-1.0.0rc3}/pyproject.toml +2 -3
- {agent_framework_github_copilot-1.0.0rc2 → agent_framework_github_copilot-1.0.0rc3}/LICENSE +0 -0
- {agent_framework_github_copilot-1.0.0rc2 → agent_framework_github_copilot-1.0.0rc3}/README.md +0 -0
- {agent_framework_github_copilot-1.0.0rc2 → agent_framework_github_copilot-1.0.0rc3}/agent_framework_github_copilot/__init__.py +0 -0
{agent_framework_github_copilot-1.0.0rc2 → agent_framework_github_copilot-1.0.0rc3}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: agent-framework-github-copilot
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.0rc3
|
|
4
4
|
Summary: GitHub Copilot integration for Microsoft Agent Framework.
|
|
5
5
|
Author-email: Microsoft <af-support@microsoft.com>
|
|
6
6
|
Requires-Python: >=3.10
|
|
@@ -16,7 +16,7 @@ Classifier: Programming Language :: Python :: 3.13
|
|
|
16
16
|
Classifier: Programming Language :: Python :: 3.14
|
|
17
17
|
Classifier: Typing :: Typed
|
|
18
18
|
License-File: LICENSE
|
|
19
|
-
Requires-Dist: agent-framework-core>=1.
|
|
19
|
+
Requires-Dist: agent-framework-core>=1.11.0,<2
|
|
20
20
|
Requires-Dist: github-copilot-sdk==1.0.2; python_version >= '3.11'
|
|
21
21
|
Project-URL: homepage, https://aka.ms/agent-framework
|
|
22
22
|
Project-URL: issues, https://github.com/microsoft/agent-framework/issues
|
|
@@ -9,12 +9,7 @@ import logging
|
|
|
9
9
|
import sys
|
|
10
10
|
import warnings
|
|
11
11
|
from collections.abc import AsyncIterable, Awaitable, Callable, Mapping, MutableMapping, Sequence
|
|
12
|
-
from typing import Any, ClassVar, Generic, Literal, TypedDict, overload
|
|
13
|
-
|
|
14
|
-
if sys.version_info >= (3, 11):
|
|
15
|
-
from typing import Self # pragma: no cover
|
|
16
|
-
else:
|
|
17
|
-
from typing_extensions import Self # pragma: no cover
|
|
12
|
+
from typing import Any, ClassVar, Generic, Literal, TypedDict, cast, overload
|
|
18
13
|
|
|
19
14
|
from agent_framework import (
|
|
20
15
|
AgentMiddlewareLayer,
|
|
@@ -29,6 +24,8 @@ from agent_framework import (
|
|
|
29
24
|
Message,
|
|
30
25
|
ResponseStream,
|
|
31
26
|
SessionContext,
|
|
27
|
+
UsageDetails,
|
|
28
|
+
add_usage_details,
|
|
32
29
|
normalize_messages,
|
|
33
30
|
)
|
|
34
31
|
from agent_framework._settings import load_settings
|
|
@@ -37,6 +34,15 @@ from agent_framework._types import AgentRunInputs, normalize_tools
|
|
|
37
34
|
from agent_framework.exceptions import AgentException
|
|
38
35
|
from agent_framework.observability import AgentTelemetryLayer
|
|
39
36
|
|
|
37
|
+
if sys.version_info >= (3, 11):
|
|
38
|
+
from typing import Self # pragma: no cover
|
|
39
|
+
else:
|
|
40
|
+
from typing_extensions import Self # pragma: no cover
|
|
41
|
+
if sys.version_info >= (3, 13):
|
|
42
|
+
from typing import TypeVar # pragma: no cover
|
|
43
|
+
else:
|
|
44
|
+
from typing_extensions import TypeVar # pragma: no cover
|
|
45
|
+
|
|
40
46
|
try:
|
|
41
47
|
from copilot import CopilotClient, CopilotSession, RuntimeConnection
|
|
42
48
|
from copilot.generated.rpc import PermissionDecisionUserNotAvailable
|
|
@@ -49,7 +55,7 @@ try:
|
|
|
49
55
|
SessionHooks,
|
|
50
56
|
SystemMessageConfig,
|
|
51
57
|
)
|
|
52
|
-
from copilot.session_events import PermissionRequest, SessionEvent, SessionEventType
|
|
58
|
+
from copilot.session_events import AssistantUsageData, PermissionRequest, SessionEvent, SessionEventType
|
|
53
59
|
from copilot.tools import Tool as CopilotTool
|
|
54
60
|
from copilot.tools import ToolInvocation, ToolResult
|
|
55
61
|
except ImportError as _copilot_import_error:
|
|
@@ -58,12 +64,6 @@ except ImportError as _copilot_import_error:
|
|
|
58
64
|
"Please use Python 3.11 or later."
|
|
59
65
|
) from _copilot_import_error
|
|
60
66
|
|
|
61
|
-
if sys.version_info >= (3, 13):
|
|
62
|
-
from typing import TypeVar # pragma: no cover
|
|
63
|
-
else:
|
|
64
|
-
from typing_extensions import TypeVar # pragma: no cover
|
|
65
|
-
|
|
66
|
-
|
|
67
67
|
DEFAULT_TIMEOUT_SECONDS: float = 60.0
|
|
68
68
|
"""Default timeout in seconds for Copilot requests."""
|
|
69
69
|
|
|
@@ -206,6 +206,18 @@ class GitHubCopilotOptions(TypedDict, total=False):
|
|
|
206
206
|
files beyond the default locations.
|
|
207
207
|
"""
|
|
208
208
|
|
|
209
|
+
skill_directories: list[str]
|
|
210
|
+
"""Directories containing SKILL.md files to load into the Copilot CLI session.
|
|
211
|
+
These are loaded natively by the Copilot CLI process, letting applications point
|
|
212
|
+
the CLI at project-specific or team-shared skills beyond the default locations.
|
|
213
|
+
"""
|
|
214
|
+
|
|
215
|
+
disabled_skills: list[str]
|
|
216
|
+
"""Names of skills to disable for the session.
|
|
217
|
+
Lets applications opt out of specific skills that would otherwise be discovered
|
|
218
|
+
from ``skill_directories`` or the default locations.
|
|
219
|
+
"""
|
|
220
|
+
|
|
209
221
|
base_directory: str
|
|
210
222
|
"""Directory where the CLI stores session state, configuration, and other persistent data."""
|
|
211
223
|
|
|
@@ -346,6 +358,8 @@ class RawGitHubCopilotAgent(BaseAgent, Generic[OptionsT]):
|
|
|
346
358
|
mcp_servers: dict[str, MCPServerConfig] | None = opts.pop("mcp_servers", None)
|
|
347
359
|
provider: ProviderConfig | None = opts.pop("provider", None)
|
|
348
360
|
instruction_directories: list[str] | None = opts.pop("instruction_directories", None)
|
|
361
|
+
skill_directories: list[str] | None = opts.pop("skill_directories", None)
|
|
362
|
+
disabled_skills: list[str] | None = opts.pop("disabled_skills", None)
|
|
349
363
|
on_pre_tool_use: PreToolUseHandler | None = opts.pop("on_pre_tool_use", None)
|
|
350
364
|
on_function_approval: FunctionApprovalCallback | None = opts.pop("on_function_approval", None)
|
|
351
365
|
base_directory = opts.pop("base_directory", None)
|
|
@@ -386,6 +400,8 @@ class RawGitHubCopilotAgent(BaseAgent, Generic[OptionsT]):
|
|
|
386
400
|
self._mcp_servers = mcp_servers
|
|
387
401
|
self._provider = provider
|
|
388
402
|
self._instruction_directories = instruction_directories
|
|
403
|
+
self._skill_directories = skill_directories
|
|
404
|
+
self._disabled_skills = disabled_skills
|
|
389
405
|
self._default_options = opts
|
|
390
406
|
self._started = False
|
|
391
407
|
|
|
@@ -547,6 +563,27 @@ class RawGitHubCopilotAgent(BaseAgent, Generic[OptionsT]):
|
|
|
547
563
|
)
|
|
548
564
|
return self._run_impl(messages=messages, session=session, options=options)
|
|
549
565
|
|
|
566
|
+
@staticmethod
|
|
567
|
+
def _parse_usage_details_from_copilot(data: AssistantUsageData) -> UsageDetails | None:
|
|
568
|
+
total_token_count = (
|
|
569
|
+
data.input_tokens + data.output_tokens
|
|
570
|
+
if data.input_tokens is not None and data.output_tokens is not None
|
|
571
|
+
else None
|
|
572
|
+
)
|
|
573
|
+
usage_details = UsageDetails(**{
|
|
574
|
+
key: value
|
|
575
|
+
for key, value in {
|
|
576
|
+
"input_token_count": data.input_tokens,
|
|
577
|
+
"output_token_count": data.output_tokens,
|
|
578
|
+
"total_token_count": total_token_count,
|
|
579
|
+
"cache_read_input_token_count": data.cache_read_tokens,
|
|
580
|
+
"cache_creation_input_token_count": data.cache_write_tokens,
|
|
581
|
+
"reasoning_output_token_count": data.reasoning_tokens,
|
|
582
|
+
}.items()
|
|
583
|
+
if value is not None
|
|
584
|
+
})
|
|
585
|
+
return usage_details or None
|
|
586
|
+
|
|
550
587
|
async def _run_impl(
|
|
551
588
|
self,
|
|
552
589
|
messages: AgentRunInputs | None = None,
|
|
@@ -586,6 +623,27 @@ class RawGitHubCopilotAgent(BaseAgent, Generic[OptionsT]):
|
|
|
586
623
|
opts["tools"] = existing + list(session_context.tools)
|
|
587
624
|
|
|
588
625
|
copilot_session = await self._get_or_create_session(session, streaming=False, runtime_options=opts)
|
|
626
|
+
usage_details: UsageDetails | None = None
|
|
627
|
+
finish_reason: str | None = None
|
|
628
|
+
model: str | None = None
|
|
629
|
+
|
|
630
|
+
def usage_event_handler(event: SessionEvent) -> None:
|
|
631
|
+
nonlocal usage_details, finish_reason, model
|
|
632
|
+
if event.type != SessionEventType.ASSISTANT_USAGE:
|
|
633
|
+
return
|
|
634
|
+
if isinstance(event.data, AssistantUsageData):
|
|
635
|
+
parsed_usage_details = self._parse_usage_details_from_copilot(event.data)
|
|
636
|
+
if parsed_usage_details:
|
|
637
|
+
usage_details = add_usage_details(usage_details, parsed_usage_details)
|
|
638
|
+
if event.data.finish_reason:
|
|
639
|
+
finish_reason = event.data.finish_reason
|
|
640
|
+
if event.data.model:
|
|
641
|
+
model = event.data.model
|
|
642
|
+
else:
|
|
643
|
+
logger.warning(
|
|
644
|
+
"Ignoring GitHub Copilot assistant usage event with unexpected payload type: %s",
|
|
645
|
+
type(event.data).__name__,
|
|
646
|
+
)
|
|
589
647
|
|
|
590
648
|
# Build the prompt from the full set of messages in the session context,
|
|
591
649
|
# so that any context/history provider-injected messages are included.
|
|
@@ -594,10 +652,13 @@ class RawGitHubCopilotAgent(BaseAgent, Generic[OptionsT]):
|
|
|
594
652
|
if session_context.instructions:
|
|
595
653
|
prompt = "\n".join(session_context.instructions) + "\n" + prompt
|
|
596
654
|
|
|
655
|
+
unsubscribe = copilot_session.on(usage_event_handler)
|
|
597
656
|
try:
|
|
598
657
|
response_event = await copilot_session.send_and_wait(prompt, timeout=timeout)
|
|
599
658
|
except Exception as ex:
|
|
600
659
|
raise AgentException(f"GitHub Copilot request failed: {ex}") from ex
|
|
660
|
+
finally:
|
|
661
|
+
unsubscribe()
|
|
601
662
|
|
|
602
663
|
response_messages: list[Message] = []
|
|
603
664
|
response_id: str | None = None
|
|
@@ -619,7 +680,13 @@ class RawGitHubCopilotAgent(BaseAgent, Generic[OptionsT]):
|
|
|
619
680
|
)
|
|
620
681
|
response_id = message_id
|
|
621
682
|
|
|
622
|
-
response = AgentResponse(
|
|
683
|
+
response = AgentResponse(
|
|
684
|
+
messages=response_messages,
|
|
685
|
+
response_id=response_id,
|
|
686
|
+
finish_reason=cast(Any, finish_reason),
|
|
687
|
+
usage_details=usage_details,
|
|
688
|
+
additional_properties={"model": model} if model else None,
|
|
689
|
+
)
|
|
623
690
|
session_context._response = response # type: ignore[assignment]
|
|
624
691
|
await self._run_after_providers(session=session, context=session_context)
|
|
625
692
|
return response
|
|
@@ -705,6 +772,26 @@ class RawGitHubCopilotAgent(BaseAgent, Generic[OptionsT]):
|
|
|
705
772
|
raw_representation=event,
|
|
706
773
|
)
|
|
707
774
|
queue.put_nowait(update)
|
|
775
|
+
elif event.type == SessionEventType.ASSISTANT_USAGE:
|
|
776
|
+
if not isinstance(event.data, AssistantUsageData):
|
|
777
|
+
logger.warning(
|
|
778
|
+
"Ignoring GitHub Copilot assistant usage event with unexpected payload type: %s",
|
|
779
|
+
type(event.data).__name__,
|
|
780
|
+
)
|
|
781
|
+
return
|
|
782
|
+
usage_details = self._parse_usage_details_from_copilot(event.data)
|
|
783
|
+
finish_reason = event.data.finish_reason or None
|
|
784
|
+
model = event.data.model or None
|
|
785
|
+
if usage_details or finish_reason or model:
|
|
786
|
+
update = AgentResponseUpdate(
|
|
787
|
+
contents=[Content.from_usage(usage_details, raw_representation=event.data)]
|
|
788
|
+
if usage_details
|
|
789
|
+
else None,
|
|
790
|
+
finish_reason=cast(Any, finish_reason),
|
|
791
|
+
additional_properties={"model": model} if model else None,
|
|
792
|
+
raw_representation=event,
|
|
793
|
+
)
|
|
794
|
+
queue.put_nowait(update)
|
|
708
795
|
elif event.type == SessionEventType.TOOL_EXECUTION_START:
|
|
709
796
|
tool_call_id = getattr(event.data, "tool_call_id", None) or ""
|
|
710
797
|
tool_name = getattr(event.data, "tool_name", None) or ""
|
|
@@ -1007,7 +1094,12 @@ class RawGitHubCopilotAgent(BaseAgent, Generic[OptionsT]):
|
|
|
1007
1094
|
|
|
1008
1095
|
try:
|
|
1009
1096
|
if agent_session.service_session_id:
|
|
1010
|
-
|
|
1097
|
+
service_session_id = agent_session.service_session_id
|
|
1098
|
+
if not isinstance(service_session_id, str):
|
|
1099
|
+
raise AgentException(
|
|
1100
|
+
"GitHubCopilotAgent expects a string service_session_id for session resumption."
|
|
1101
|
+
)
|
|
1102
|
+
return await self._resume_session(service_session_id, streaming, runtime_options)
|
|
1011
1103
|
|
|
1012
1104
|
session = await self._create_session(streaming, runtime_options)
|
|
1013
1105
|
agent_session.service_session_id = session.session_id
|
|
@@ -1038,6 +1130,8 @@ class RawGitHubCopilotAgent(BaseAgent, Generic[OptionsT]):
|
|
|
1038
1130
|
mcp_servers = opts.get("mcp_servers") or self._mcp_servers or None
|
|
1039
1131
|
provider = opts.get("provider") or self._provider or None
|
|
1040
1132
|
instruction_directories = opts.get("instruction_directories", self._instruction_directories)
|
|
1133
|
+
skill_directories = opts.get("skill_directories", self._skill_directories)
|
|
1134
|
+
disabled_skills = opts.get("disabled_skills", self._disabled_skills)
|
|
1041
1135
|
all_tools = list(self._tools or []) + list(opts.get("tools") or [])
|
|
1042
1136
|
tools = self._prepare_tools(all_tools) if all_tools else None
|
|
1043
1137
|
hooks = self._build_session_hooks(all_tools, opts)
|
|
@@ -1051,6 +1145,8 @@ class RawGitHubCopilotAgent(BaseAgent, Generic[OptionsT]):
|
|
|
1051
1145
|
mcp_servers=mcp_servers or None,
|
|
1052
1146
|
provider=provider or None,
|
|
1053
1147
|
instruction_directories=instruction_directories,
|
|
1148
|
+
skill_directories=skill_directories,
|
|
1149
|
+
disabled_skills=disabled_skills,
|
|
1054
1150
|
hooks=hooks,
|
|
1055
1151
|
)
|
|
1056
1152
|
|
|
@@ -1079,6 +1175,8 @@ class RawGitHubCopilotAgent(BaseAgent, Generic[OptionsT]):
|
|
|
1079
1175
|
mcp_servers = opts.get("mcp_servers") or self._mcp_servers or None
|
|
1080
1176
|
provider = opts.get("provider") or self._provider or None
|
|
1081
1177
|
instruction_directories = opts.get("instruction_directories", self._instruction_directories)
|
|
1178
|
+
skill_directories = opts.get("skill_directories", self._skill_directories)
|
|
1179
|
+
disabled_skills = opts.get("disabled_skills", self._disabled_skills)
|
|
1082
1180
|
all_tools = list(self._tools or []) + list(opts.get("tools") or [])
|
|
1083
1181
|
tools = self._prepare_tools(all_tools) if all_tools else None
|
|
1084
1182
|
hooks = self._build_session_hooks(all_tools, opts)
|
|
@@ -1093,6 +1191,8 @@ class RawGitHubCopilotAgent(BaseAgent, Generic[OptionsT]):
|
|
|
1093
1191
|
mcp_servers=mcp_servers or None,
|
|
1094
1192
|
provider=provider or None,
|
|
1095
1193
|
instruction_directories=instruction_directories,
|
|
1194
|
+
skill_directories=skill_directories,
|
|
1195
|
+
disabled_skills=disabled_skills,
|
|
1096
1196
|
hooks=hooks,
|
|
1097
1197
|
)
|
|
1098
1198
|
|
{agent_framework_github_copilot-1.0.0rc2 → agent_framework_github_copilot-1.0.0rc3}/pyproject.toml
RENAMED
|
@@ -4,7 +4,7 @@ description = "GitHub Copilot integration for Microsoft Agent Framework."
|
|
|
4
4
|
authors = [{ name = "Microsoft", email = "af-support@microsoft.com"}]
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.10"
|
|
7
|
-
version = "1.0.
|
|
7
|
+
version = "1.0.0rc3"
|
|
8
8
|
license-files = ["LICENSE"]
|
|
9
9
|
urls.homepage = "https://aka.ms/agent-framework"
|
|
10
10
|
urls.source = "https://github.com/microsoft/agent-framework/tree/main/python"
|
|
@@ -23,7 +23,7 @@ classifiers = [
|
|
|
23
23
|
"Typing :: Typed",
|
|
24
24
|
]
|
|
25
25
|
dependencies = [
|
|
26
|
-
"agent-framework-core>=1.
|
|
26
|
+
"agent-framework-core>=1.11.0,<2",
|
|
27
27
|
"github-copilot-sdk==1.0.2; python_version >= '3.11'",
|
|
28
28
|
]
|
|
29
29
|
|
|
@@ -102,4 +102,3 @@ interpreter = "posix"
|
|
|
102
102
|
[build-system]
|
|
103
103
|
requires = ["flit-core >= 3.11,<4.0"]
|
|
104
104
|
build-backend = "flit_core.buildapi"
|
|
105
|
-
|
|
File without changes
|
{agent_framework_github_copilot-1.0.0rc2 → agent_framework_github_copilot-1.0.0rc3}/README.md
RENAMED
|
File without changes
|