agent-framework-github-copilot 2.0.0__py3-none-any.whl → 2.0.2__py3-none-any.whl

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.
@@ -9,7 +9,17 @@ import json
9
9
  import logging
10
10
  import sys
11
11
  import warnings
12
- from collections.abc import AsyncIterable, Awaitable, Callable, Mapping, MutableMapping, Sequence
12
+ import weakref
13
+ from collections.abc import (
14
+ AsyncGenerator,
15
+ AsyncIterable,
16
+ Awaitable,
17
+ Callable,
18
+ Collection,
19
+ Mapping,
20
+ MutableMapping,
21
+ Sequence,
22
+ )
13
23
  from pathlib import Path
14
24
  from typing import Any, ClassVar, Generic, Literal, TypedDict, cast, overload
15
25
  from urllib.parse import urlparse
@@ -23,6 +33,7 @@ from agent_framework import (
23
33
  BaseAgent,
24
34
  Content,
25
35
  ContextProvider,
36
+ FunctionInvocationContext,
26
37
  HistoryProvider,
27
38
  Message,
28
39
  ResponseStream,
@@ -181,6 +192,21 @@ async def _resolve_function_approval(
181
192
 
182
193
  logger = logging.getLogger("agent_framework.github_copilot")
183
194
 
195
+
196
+ def _provider_service_session_state_keys(agent: object, client: object | None) -> frozenset[str]:
197
+ """Return provider-owned session-state keys declared by the Copilot agent or client."""
198
+ keys: set[str] = set()
199
+ for owner in (agent, client):
200
+ declared = getattr(owner, "service_session_state_keys", ())
201
+ if isinstance(declared, (list, tuple, set, frozenset)):
202
+ keys.update(key for key in cast(Collection[Any], declared) if isinstance(key, str))
203
+ return frozenset(keys)
204
+
205
+
206
+ # One lock per (CopilotClient, service session ID), shared across agents that share a client.
207
+ # Entries disappear once no run holds or awaits the lock.
208
+ _SESSION_RUN_LOCKS: weakref.WeakValueDictionary[tuple[int, str], asyncio.Lock] = weakref.WeakValueDictionary()
209
+
184
210
  _MCP_TOOL_MESSAGE = (
185
211
  "MCP server '{name}' cannot be passed to GitHubCopilotAgent as a tool: the Copilot SDK "
186
212
  "connects to MCP servers itself, so a framework-managed MCPTool would keep none of its "
@@ -813,6 +839,7 @@ class RawGitHubCopilotAgent(BaseAgent, Generic[OptionsT]):
813
839
  session: AgentSession | None = None,
814
840
  middleware: Sequence[AgentMiddlewareTypes] | None = None,
815
841
  options: OptionsT | None = None,
842
+ function_invocation_kwargs: Mapping[str, Any] | None = None,
816
843
  **kwargs: Any,
817
844
  ) -> Awaitable[AgentResponse]: ...
818
845
 
@@ -825,6 +852,7 @@ class RawGitHubCopilotAgent(BaseAgent, Generic[OptionsT]):
825
852
  session: AgentSession | None = None,
826
853
  middleware: Sequence[AgentMiddlewareTypes] | None = None,
827
854
  options: OptionsT | None = None,
855
+ function_invocation_kwargs: Mapping[str, Any] | None = None,
828
856
  **kwargs: Any,
829
857
  ) -> ResponseStream[AgentResponseUpdate, AgentResponse]: ...
830
858
 
@@ -836,6 +864,7 @@ class RawGitHubCopilotAgent(BaseAgent, Generic[OptionsT]):
836
864
  session: AgentSession | None = None,
837
865
  middleware: Sequence[AgentMiddlewareTypes] | None = None,
838
866
  options: OptionsT | None = None,
867
+ function_invocation_kwargs: Mapping[str, Any] | None = None,
839
868
  **kwargs: Any,
840
869
  ) -> Awaitable[AgentResponse] | ResponseStream[AgentResponseUpdate, AgentResponse]:
841
870
  """Get a response from the agent.
@@ -854,6 +883,9 @@ class RawGitHubCopilotAgent(BaseAgent, Generic[OptionsT]):
854
883
  compatibility; pass middleware via :class:`GitHubCopilotAgent` which
855
884
  forwards it through :class:`AgentTelemetryLayer`.
856
885
  options: Runtime options (model, timeout, etc.).
886
+ function_invocation_kwargs: Keyword arguments forwarded to tool invocations.
887
+ Tools receive them through ``FunctionInvocationContext.kwargs`` when they
888
+ declare a ``FunctionInvocationContext`` parameter.
857
889
  kwargs: Additional keyword arguments for compatibility with the shared agent
858
890
  interface (e.g. compaction_strategy, tokenizer). Not used by this agent.
859
891
 
@@ -887,11 +919,22 @@ class RawGitHubCopilotAgent(BaseAgent, Generic[OptionsT]):
887
919
  return AgentResponse.from_updates(updates)
888
920
 
889
921
  return ResponseStream(
890
- self._stream_updates(messages=messages, session=session, options=options, _ctx_holder=ctx_holder),
922
+ self._stream_updates(
923
+ messages=messages,
924
+ session=session,
925
+ options=options,
926
+ function_invocation_kwargs=function_invocation_kwargs,
927
+ _ctx_holder=ctx_holder,
928
+ ),
891
929
  finalizer=_finalize,
892
930
  result_hooks=[_after_run_hook],
893
931
  )
894
- return self._run_impl(messages=messages, session=session, options=options)
932
+ return self._run_impl(
933
+ messages=messages,
934
+ session=session,
935
+ options=options,
936
+ function_invocation_kwargs=function_invocation_kwargs,
937
+ )
895
938
 
896
939
  @staticmethod
897
940
  def _parse_usage_details_from_copilot(data: AssistantUsageData) -> UsageDetails | None:
@@ -920,6 +963,7 @@ class RawGitHubCopilotAgent(BaseAgent, Generic[OptionsT]):
920
963
  *,
921
964
  session: AgentSession | None = None,
922
965
  options: OptionsT | None = None,
966
+ function_invocation_kwargs: Mapping[str, Any] | None = None,
923
967
  ) -> AgentResponse:
924
968
  """Non-streaming implementation of run."""
925
969
  if not self._started:
@@ -952,7 +996,6 @@ class RawGitHubCopilotAgent(BaseAgent, Generic[OptionsT]):
952
996
  existing = list(opts.get("tools") or [])
953
997
  opts["tools"] = existing + list(session_context.tools)
954
998
 
955
- copilot_session = await self._get_or_create_session(session, streaming=False, runtime_options=opts)
956
999
  usage_details: UsageDetails | None = None
957
1000
  finish_reason: str | None = None
958
1001
  model: str | None = None
@@ -986,14 +1029,20 @@ class RawGitHubCopilotAgent(BaseAgent, Generic[OptionsT]):
986
1029
  prompt = "\n".join(session_context.instructions) + "\n" + prompt
987
1030
  attachments = self._prepare_attachments_for_copilot(context_messages)
988
1031
 
989
- unsubscribe = copilot_session.on(usage_event_handler)
990
- try:
991
- mark_feature_used(FeatureIndex.GITHUB_COPILOT)
992
- response_event = await copilot_session.send_and_wait(prompt, attachments=attachments, timeout=timeout)
993
- except Exception as ex:
994
- raise AgentException(f"GitHub Copilot request failed: {ex}") from ex
995
- finally:
996
- unsubscribe()
1032
+ async with self._session_run_scope(
1033
+ session,
1034
+ streaming=False,
1035
+ runtime_options=opts,
1036
+ function_invocation_kwargs=function_invocation_kwargs,
1037
+ ) as copilot_session:
1038
+ unsubscribe = copilot_session.on(usage_event_handler)
1039
+ try:
1040
+ mark_feature_used(FeatureIndex.GITHUB_COPILOT)
1041
+ response_event = await copilot_session.send_and_wait(prompt, attachments=attachments, timeout=timeout)
1042
+ except Exception as ex:
1043
+ raise AgentException(f"GitHub Copilot request failed: {ex}") from ex
1044
+ finally:
1045
+ unsubscribe()
997
1046
 
998
1047
  response_messages: list[Message] = []
999
1048
  response_id: str | None = None
@@ -1032,6 +1081,7 @@ class RawGitHubCopilotAgent(BaseAgent, Generic[OptionsT]):
1032
1081
  *,
1033
1082
  session: AgentSession | None = None,
1034
1083
  options: OptionsT | None = None,
1084
+ function_invocation_kwargs: Mapping[str, Any] | None = None,
1035
1085
  _ctx_holder: dict[str, Any] | None = None,
1036
1086
  ) -> AsyncIterable[AgentResponseUpdate]:
1037
1087
  """Internal method to stream updates from GitHub Copilot.
@@ -1042,6 +1092,7 @@ class RawGitHubCopilotAgent(BaseAgent, Generic[OptionsT]):
1042
1092
  Keyword Args:
1043
1093
  session: The conversation session associated with the message(s).
1044
1094
  options: Runtime options (model, timeout, etc.).
1095
+ function_invocation_kwargs: Keyword arguments forwarded to tool invocations.
1045
1096
  _ctx_holder: Internal dict populated with session_context and session
1046
1097
  so that the caller (via a ResponseStream result_hook) can run
1047
1098
  after_run providers without duplicating the updates buffer.
@@ -1081,12 +1132,6 @@ class RawGitHubCopilotAgent(BaseAgent, Generic[OptionsT]):
1081
1132
  existing = list(opts.get("tools") or [])
1082
1133
  opts["tools"] = existing + list(session_context.tools)
1083
1134
 
1084
- copilot_session = await self._get_or_create_session(session, streaming=True, runtime_options=opts)
1085
-
1086
- if _ctx_holder is not None:
1087
- _ctx_holder["session_context"] = session_context
1088
- _ctx_holder["session"] = session
1089
-
1090
1135
  # Build the prompt from the full session context so provider-injected messages are included.
1091
1136
  context_messages = session_context.get_messages(include_input=True)
1092
1137
  prompt = "\n".join([message.text for message in context_messages])
@@ -1172,18 +1217,28 @@ class RawGitHubCopilotAgent(BaseAgent, Generic[OptionsT]):
1172
1217
  error_msg = error_data.message or "Unknown error"
1173
1218
  queue.put_nowait(AgentException(f"GitHub Copilot session error: {error_msg}"))
1174
1219
 
1175
- unsubscribe = copilot_session.on(event_handler)
1220
+ async with self._session_run_scope(
1221
+ session,
1222
+ streaming=True,
1223
+ runtime_options=opts,
1224
+ function_invocation_kwargs=function_invocation_kwargs,
1225
+ ) as copilot_session:
1226
+ if _ctx_holder is not None:
1227
+ _ctx_holder["session_context"] = session_context
1228
+ _ctx_holder["session"] = session
1176
1229
 
1177
- try:
1178
- mark_feature_used(FeatureIndex.GITHUB_COPILOT)
1179
- await copilot_session.send(prompt, attachments=attachments)
1230
+ unsubscribe = copilot_session.on(event_handler)
1180
1231
 
1181
- while (item := await queue.get()) is not None:
1182
- if isinstance(item, Exception):
1183
- raise item
1184
- yield item
1185
- finally:
1186
- unsubscribe()
1232
+ try:
1233
+ mark_feature_used(FeatureIndex.GITHUB_COPILOT)
1234
+ await copilot_session.send(prompt, attachments=attachments)
1235
+
1236
+ while (item := await queue.get()) is not None:
1237
+ if isinstance(item, Exception):
1238
+ raise item
1239
+ yield item
1240
+ finally:
1241
+ unsubscribe()
1187
1242
 
1188
1243
  async def _run_before_providers(
1189
1244
  self,
@@ -1301,40 +1356,77 @@ class RawGitHubCopilotAgent(BaseAgent, Generic[OptionsT]):
1301
1356
  def _prepare_tools(
1302
1357
  self,
1303
1358
  tools: Sequence[ToolTypes | CopilotTool],
1359
+ *,
1360
+ agent_session: AgentSession | None = None,
1361
+ function_invocation_kwargs: Mapping[str, Any] | None = None,
1304
1362
  ) -> list[CopilotTool]:
1305
1363
  """Convert Agent Framework tools to Copilot SDK tools.
1306
1364
 
1307
1365
  Args:
1308
1366
  tools: List of Agent Framework tools.
1309
1367
 
1368
+ Keyword Args:
1369
+ agent_session: The conversation session, exposed to tools through their
1370
+ ``FunctionInvocationContext``.
1371
+ function_invocation_kwargs: Keyword arguments forwarded to tool invocations.
1372
+
1310
1373
  Returns:
1311
1374
  List of Copilot SDK tools.
1312
1375
  """
1313
1376
  copilot_tools: list[CopilotTool] = []
1377
+ parent_service_session_state_keys = _provider_service_session_state_keys(self, self._client)
1314
1378
 
1315
1379
  for tool in tools:
1316
1380
  if isinstance(tool, CopilotTool):
1317
1381
  copilot_tools.append(tool)
1318
1382
  elif isinstance(tool, FunctionTool):
1319
- copilot_tools.append(self._tool_to_copilot_tool(tool))
1383
+ copilot_tools.append(
1384
+ self._tool_to_copilot_tool(
1385
+ tool,
1386
+ agent_session=agent_session,
1387
+ function_invocation_kwargs=function_invocation_kwargs,
1388
+ parent_service_session_state_keys=parent_service_session_state_keys,
1389
+ )
1390
+ )
1320
1391
  elif isinstance(tool, MutableMapping):
1321
1392
  copilot_tools.append(tool) # type: ignore[arg-type]
1322
1393
  # Note: Other tool types (e.g., dict-based hosted tools) are skipped
1323
1394
 
1324
1395
  return copilot_tools
1325
1396
 
1326
- def _tool_to_copilot_tool(self, ai_func: FunctionTool) -> CopilotTool:
1397
+ def _tool_to_copilot_tool(
1398
+ self,
1399
+ ai_func: FunctionTool,
1400
+ *,
1401
+ agent_session: AgentSession | None = None,
1402
+ function_invocation_kwargs: Mapping[str, Any] | None = None,
1403
+ parent_service_session_state_keys: frozenset[str] = frozenset(),
1404
+ ) -> CopilotTool:
1327
1405
  """Convert an FunctionTool to a Copilot SDK tool.
1328
1406
 
1407
+ Each invocation receives a ``FunctionInvocationContext`` carrying the run's
1408
+ ``function_invocation_kwargs`` and ``agent_session``, so tools that declare a
1409
+ ``FunctionInvocationContext`` parameter can read them the same way they do
1410
+ with a chat-client-backed agent.
1411
+
1329
1412
  Approval for tools declared with ``approval_mode="always_require"`` is normally
1330
1413
  enforced by the Copilot SDK's native ``on_pre_tool_use`` hook (see
1331
1414
  :meth:`_build_session_hooks`). When the deprecated ``on_function_approval``
1332
1415
  callback is configured instead, approval is enforced inside this handler for
1333
1416
  backward compatibility. (``on_function_approval`` and ``on_pre_tool_use`` are
1334
1417
  mutually exclusive, so only one mechanism is ever active.)
1418
+
1419
+ Args:
1420
+ ai_func: Agent Framework function tool to convert.
1421
+
1422
+ Keyword Args:
1423
+ agent_session: Parent agent session passed to the tool.
1424
+ function_invocation_kwargs: Runtime keyword arguments forwarded to the tool.
1425
+ parent_service_session_state_keys: Provider-owned state declared by the parent agent and client.
1335
1426
  """
1336
1427
  approval_handler = self._function_approval_handler
1337
1428
  enforce = approval_handler is not None and ai_func.approval_mode == "always_require"
1429
+ runtime_kwargs = dict(function_invocation_kwargs) if function_invocation_kwargs is not None else {}
1338
1430
 
1339
1431
  async def handler(invocation: ToolInvocation) -> ToolResult:
1340
1432
  args: dict[str, Any] = invocation.arguments or {}
@@ -1353,11 +1445,22 @@ class RawGitHubCopilotAgent(BaseAgent, Generic[OptionsT]):
1353
1445
  result_type="failure",
1354
1446
  error="approval_denied",
1355
1447
  )
1448
+ context = FunctionInvocationContext(
1449
+ function=ai_func,
1450
+ arguments=args,
1451
+ session=agent_session,
1452
+ kwargs=runtime_kwargs,
1453
+ parent_service_session_state_keys=parent_service_session_state_keys,
1454
+ )
1356
1455
  if ai_func.input_model:
1357
1456
  args_instance = ai_func.input_model(**args)
1358
- result = await ai_func.invoke(arguments=args_instance)
1457
+ result = await ai_func.invoke(
1458
+ arguments=args_instance, context=context, tool_call_id=invocation.tool_call_id or None
1459
+ )
1359
1460
  else:
1360
- result = await ai_func.invoke(arguments=args)
1461
+ result = await ai_func.invoke(
1462
+ arguments=args, context=context, tool_call_id=invocation.tool_call_id or None
1463
+ )
1361
1464
  rich = [c for c in result if c.type in ("data", "uri")]
1362
1465
  if rich:
1363
1466
  logger.warning(
@@ -1471,11 +1574,73 @@ class RawGitHubCopilotAgent(BaseAgent, Generic[OptionsT]):
1471
1574
 
1472
1575
  return {"on_pre_tool_use": default_pre_tool_use}
1473
1576
 
1577
+ def _session_run_lock(self, service_session_id: str) -> asyncio.Lock:
1578
+ """Return the lock that serializes runs on one Copilot service session."""
1579
+ key = (id(self._client), service_session_id)
1580
+ lock = _SESSION_RUN_LOCKS.get(key)
1581
+ if lock is None:
1582
+ lock = asyncio.Lock()
1583
+ _SESSION_RUN_LOCKS[key] = lock
1584
+ return lock
1585
+
1586
+ @contextlib.asynccontextmanager
1587
+ async def _session_run_scope(
1588
+ self,
1589
+ agent_session: AgentSession,
1590
+ *,
1591
+ streaming: bool,
1592
+ runtime_options: dict[str, Any],
1593
+ function_invocation_kwargs: Mapping[str, Any] | None,
1594
+ ) -> AsyncGenerator[CopilotSession]:
1595
+ """Open the Copilot session for one run and hold it exclusively until the run ends.
1596
+
1597
+ The Copilot SDK keeps a single session object per service session ID and
1598
+ re-registers tools on it on every resume, dispatching tool calls by session ID.
1599
+ Tool handlers capture the run's ``function_invocation_kwargs`` and session, so
1600
+ an overlapping resume would let one run's tool calls execute with another run's
1601
+ context. Runs on the same service session are therefore serialized.
1602
+
1603
+ Args:
1604
+ agent_session: The conversation session.
1605
+
1606
+ Keyword Args:
1607
+ streaming: Whether to enable streaming for the session.
1608
+ runtime_options: Runtime options from run that take precedence.
1609
+ function_invocation_kwargs: Keyword arguments forwarded to tool invocations.
1610
+
1611
+ Yields:
1612
+ The created or resumed CopilotSession.
1613
+ """
1614
+ lock: asyncio.Lock | None = None
1615
+ service_session_id = agent_session.service_session_id
1616
+ if isinstance(service_session_id, str):
1617
+ resume_lock = self._session_run_lock(service_session_id)
1618
+ await resume_lock.acquire()
1619
+ lock = resume_lock
1620
+ try:
1621
+ copilot_session = await self._get_or_create_session(
1622
+ agent_session,
1623
+ streaming=streaming,
1624
+ runtime_options=runtime_options,
1625
+ function_invocation_kwargs=function_invocation_kwargs,
1626
+ )
1627
+ if lock is None:
1628
+ # A newly created service session ID is not known to any other run yet,
1629
+ # so this acquire never waits.
1630
+ create_lock = self._session_run_lock(copilot_session.session_id)
1631
+ await create_lock.acquire()
1632
+ lock = create_lock
1633
+ yield copilot_session
1634
+ finally:
1635
+ if lock is not None:
1636
+ lock.release()
1637
+
1474
1638
  async def _get_or_create_session(
1475
1639
  self,
1476
1640
  agent_session: AgentSession,
1477
1641
  streaming: bool = False,
1478
1642
  runtime_options: dict[str, Any] | None = None,
1643
+ function_invocation_kwargs: Mapping[str, Any] | None = None,
1479
1644
  ) -> CopilotSession:
1480
1645
  """Get an existing session or create a new one for the session.
1481
1646
 
@@ -1483,6 +1648,7 @@ class RawGitHubCopilotAgent(BaseAgent, Generic[OptionsT]):
1483
1648
  agent_session: The conversation session.
1484
1649
  streaming: Whether to enable streaming for the session.
1485
1650
  runtime_options: Runtime options from run that take precedence.
1651
+ function_invocation_kwargs: Keyword arguments forwarded to tool invocations.
1486
1652
 
1487
1653
  Returns:
1488
1654
  A CopilotSession instance.
@@ -1500,9 +1666,20 @@ class RawGitHubCopilotAgent(BaseAgent, Generic[OptionsT]):
1500
1666
  raise AgentException(
1501
1667
  "GitHubCopilotAgent expects a string service_session_id for session resumption."
1502
1668
  )
1503
- return await self._resume_session(service_session_id, streaming, runtime_options)
1669
+ return await self._resume_session(
1670
+ service_session_id,
1671
+ streaming,
1672
+ runtime_options,
1673
+ agent_session=agent_session,
1674
+ function_invocation_kwargs=function_invocation_kwargs,
1675
+ )
1504
1676
 
1505
- session = await self._create_session(streaming, runtime_options)
1677
+ session = await self._create_session(
1678
+ streaming,
1679
+ runtime_options,
1680
+ agent_session=agent_session,
1681
+ function_invocation_kwargs=function_invocation_kwargs,
1682
+ )
1506
1683
  agent_session.service_session_id = session.session_id
1507
1684
  return session
1508
1685
  except Exception as ex:
@@ -1533,6 +1710,9 @@ class RawGitHubCopilotAgent(BaseAgent, Generic[OptionsT]):
1533
1710
  self,
1534
1711
  streaming: bool,
1535
1712
  runtime_options: dict[str, Any] | None,
1713
+ *,
1714
+ agent_session: AgentSession | None = None,
1715
+ function_invocation_kwargs: Mapping[str, Any] | None = None,
1536
1716
  ) -> dict[str, Any]:
1537
1717
  """Assemble keyword arguments for ``create_session`` / ``resume_session``.
1538
1718
 
@@ -1551,6 +1731,11 @@ class RawGitHubCopilotAgent(BaseAgent, Generic[OptionsT]):
1551
1731
  streaming: Whether to enable streaming for the session.
1552
1732
  runtime_options: Runtime options that take precedence over default_options.
1553
1733
 
1734
+ Keyword Args:
1735
+ agent_session: The conversation session, exposed to tools through their
1736
+ ``FunctionInvocationContext``.
1737
+ function_invocation_kwargs: Keyword arguments forwarded to tool invocations.
1738
+
1554
1739
  Returns:
1555
1740
  The keyword arguments to splat into the SDK session factory.
1556
1741
  """
@@ -1565,7 +1750,15 @@ class RawGitHubCopilotAgent(BaseAgent, Generic[OptionsT]):
1565
1750
  # and flattens tool-collection wrappers, which can otherwise hide an MCPTool.
1566
1751
  all_tools = normalize_tools(list(self._tools or []) + list(kwargs.get("tools") or []))
1567
1752
  _reject_mcp_tools(all_tools)
1568
- kwargs["tools"] = self._prepare_tools(all_tools) if all_tools else None
1753
+ kwargs["tools"] = (
1754
+ self._prepare_tools(
1755
+ all_tools,
1756
+ agent_session=agent_session,
1757
+ function_invocation_kwargs=function_invocation_kwargs,
1758
+ )
1759
+ if all_tools
1760
+ else None
1761
+ )
1569
1762
 
1570
1763
  kwargs["streaming"] = streaming
1571
1764
  # model may already be present from per-run options (merged above); otherwise fall
@@ -1606,23 +1799,40 @@ class RawGitHubCopilotAgent(BaseAgent, Generic[OptionsT]):
1606
1799
  self,
1607
1800
  streaming: bool,
1608
1801
  runtime_options: dict[str, Any] | None = None,
1802
+ *,
1803
+ agent_session: AgentSession | None = None,
1804
+ function_invocation_kwargs: Mapping[str, Any] | None = None,
1609
1805
  ) -> CopilotSession:
1610
1806
  """Create a new Copilot session.
1611
1807
 
1612
1808
  Args:
1613
1809
  streaming: Whether to enable streaming for the session.
1614
1810
  runtime_options: Runtime options that take precedence over default_options.
1811
+
1812
+ Keyword Args:
1813
+ agent_session: The conversation session, exposed to tools.
1814
+ function_invocation_kwargs: Keyword arguments forwarded to tool invocations.
1615
1815
  """
1616
1816
  if not self._client:
1617
1817
  raise RuntimeError("GitHub Copilot client not initialized. Call start() first.")
1618
1818
 
1619
- return await self._client.create_session(**self._build_session_kwargs(streaming, runtime_options))
1819
+ return await self._client.create_session(
1820
+ **self._build_session_kwargs(
1821
+ streaming,
1822
+ runtime_options,
1823
+ agent_session=agent_session,
1824
+ function_invocation_kwargs=function_invocation_kwargs,
1825
+ )
1826
+ )
1620
1827
 
1621
1828
  async def _resume_session(
1622
1829
  self,
1623
1830
  session_id: str,
1624
1831
  streaming: bool,
1625
1832
  runtime_options: dict[str, Any] | None = None,
1833
+ *,
1834
+ agent_session: AgentSession | None = None,
1835
+ function_invocation_kwargs: Mapping[str, Any] | None = None,
1626
1836
  ) -> CopilotSession:
1627
1837
  """Resume an existing Copilot session by ID.
1628
1838
 
@@ -1630,11 +1840,23 @@ class RawGitHubCopilotAgent(BaseAgent, Generic[OptionsT]):
1630
1840
  session_id: The session ID to resume.
1631
1841
  streaming: Whether to enable streaming for the session.
1632
1842
  runtime_options: Runtime options that take precedence over default_options.
1843
+
1844
+ Keyword Args:
1845
+ agent_session: The conversation session, exposed to tools.
1846
+ function_invocation_kwargs: Keyword arguments forwarded to tool invocations.
1633
1847
  """
1634
1848
  if not self._client:
1635
1849
  raise RuntimeError("GitHub Copilot client not initialized. Call start() first.")
1636
1850
 
1637
- return await self._client.resume_session(session_id, **self._build_session_kwargs(streaming, runtime_options))
1851
+ return await self._client.resume_session(
1852
+ session_id,
1853
+ **self._build_session_kwargs(
1854
+ streaming,
1855
+ runtime_options,
1856
+ agent_session=agent_session,
1857
+ function_invocation_kwargs=function_invocation_kwargs,
1858
+ ),
1859
+ )
1638
1860
 
1639
1861
 
1640
1862
  class GitHubCopilotAgent( # type: ignore[misc]
File without changes
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agent-framework-github-copilot
3
- Version: 2.0.0
3
+ Version: 2.0.2
4
4
  Summary: GitHub Copilot integration for Microsoft Agent Framework.
5
5
  Author-email: Microsoft <af-support@microsoft.com>
6
6
  Requires-Python: >=3.11
@@ -15,8 +15,8 @@ Classifier: Programming Language :: Python :: 3.13
15
15
  Classifier: Programming Language :: Python :: 3.14
16
16
  Classifier: Typing :: Typed
17
17
  License-File: LICENSE
18
- Requires-Dist: agent-framework-core>=1.15.0,<2
19
- Requires-Dist: github-copilot-sdk==1.0.11; python_version >= '3.11'
18
+ Requires-Dist: agent-framework-core>=1.21.0,<2
19
+ Requires-Dist: github-copilot-sdk>=1.0.16,<2.0; python_version >= '3.11'
20
20
  Project-URL: homepage, https://aka.ms/agent-framework
21
21
  Project-URL: issues, https://github.com/microsoft/agent-framework/issues
22
22
  Project-URL: release_notes, https://github.com/microsoft/agent-framework/releases?q=tag%3Apython-1&expanded=true
@@ -0,0 +1,8 @@
1
+ agent_framework_github_copilot/__init__.py,sha256=A8xc4tEW9aFASMSwBmiWIn6MWnOU1rXGyN3HMzEOZxw,464
2
+ agent_framework_github_copilot/_agent.py,sha256=dEtgB9gWYSWEcfD_1bhv66dBsjLB2LldV9kab9jW6zk,84543
3
+ agent_framework_github_copilot/_feature_usage.py,sha256=UfIdQLxq6ppR2zrjHZTo5kptX7PPR4Be_N2Wd7DSV4U,184
4
+ agent_framework_github_copilot/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
+ agent_framework_github_copilot-2.0.2.dist-info/licenses/LICENSE,sha256=ws_MuBL-SCEBqPBFl9_FqZkaaydIJmxHrJG2parhU4M,1141
6
+ agent_framework_github_copilot-2.0.2.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
7
+ agent_framework_github_copilot-2.0.2.dist-info/METADATA,sha256=WoxwFE83ClsFtPyO5P7V1hh5-AB_B0_UunDW5yohdRw,6452
8
+ agent_framework_github_copilot-2.0.2.dist-info/RECORD,,
@@ -1,7 +0,0 @@
1
- agent_framework_github_copilot/__init__.py,sha256=A8xc4tEW9aFASMSwBmiWIn6MWnOU1rXGyN3HMzEOZxw,464
2
- agent_framework_github_copilot/_agent.py,sha256=aR9nKRDa_1L9QAyfgh74qyvRVm6f-0NgVNYW7MVEOus,75345
3
- agent_framework_github_copilot/_feature_usage.py,sha256=UfIdQLxq6ppR2zrjHZTo5kptX7PPR4Be_N2Wd7DSV4U,184
4
- agent_framework_github_copilot-2.0.0.dist-info/licenses/LICENSE,sha256=ws_MuBL-SCEBqPBFl9_FqZkaaydIJmxHrJG2parhU4M,1141
5
- agent_framework_github_copilot-2.0.0.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
6
- agent_framework_github_copilot-2.0.0.dist-info/METADATA,sha256=JrePbSIdKKpIMChvVH0n7KKh-k7Qp8voz30Mb8IjVWw,6447
7
- agent_framework_github_copilot-2.0.0.dist-info/RECORD,,