Skip to content

Python: Fix GitHubCopilotAgent to include tools added by ContextProvider.before_run in session creation#5780

Merged
giles17 merged 5 commits into
microsoft:mainfrom
giles17:agent/fix-5736-1
May 15, 2026
Merged

Python: Fix GitHubCopilotAgent to include tools added by ContextProvider.before_run in session creation#5780
giles17 merged 5 commits into
microsoft:mainfrom
giles17:agent/fix-5736-1

Conversation

@giles17
Copy link
Copy Markdown
Contributor

@giles17 giles17 commented May 12, 2026

Motivation and Context

SkillsProvider.before_run registers tools like load_skill via context.extend_tools(), but GitHubCopilotAgent only forwarded constructor-supplied tools (self._tools) when creating or resuming Copilot sessions. This caused provider-contributed tools to be silently dropped, so the model would see skill instructions in the system prompt but fail to invoke them.

Fixes #5736

Description

The root cause was that _create_session and _resume_session only passed self._tools to CopilotClient, ignoring any tools that context providers added to SessionContext during before_run. The fix merges session_context.tools into the runtime options dict before session creation in both the synchronous and streaming run paths, and updates _create_session/_resume_session to combine constructor tools with the runtime-option tools. Tests verify that provider-contributed tools appear in session creation for both non-streaming and streaming runs, and that they merge correctly with constructor-supplied tools.

Contribution Checklist

  • The code builds clean without any errors or warnings
  • The PR follows the Contribution Guidelines
  • All unit tests pass, and I have added new tests where possible
  • Is this a breaking change? If yes, add "[BREAKING]" prefix to the title of the PR.

Note: PR autogenerated by giles17's agent

Copilot and others added 2 commits May 12, 2026 01:21
…ft#5736)

_create_session and _resume_session only forwarded self._tools (constructor
tools) to CopilotClient.create_session, dropping any tools contributed by
context providers via session_context.extend_tools() during before_run.

Merge provider-contributed tools into runtime_options in both _run_impl and
_stream_updates before session creation, mirroring how RawAgent handles the
merge at lines 1435-1440 in _agents.py. Update _create_session and
_resume_session to combine self._tools with the merged runtime tools.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings May 12, 2026 14:09
@giles17 giles17 self-assigned this May 12, 2026
Copy link
Copy Markdown
Contributor Author

@giles17 giles17 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Automated Code Review

Reviewers: 4 | Confidence: 74% | Result: All clear

Reviewed: Correctness, Security Reliability, Test Coverage, Design Approach


Automated review by giles17's agents

@moonbox3
Copy link
Copy Markdown
Contributor

moonbox3 commented May 12, 2026

Python Test Coverage

Python Test Coverage Report •
FileStmtsMissCoverMissing
packages/a2a/agent_framework_a2a
   _agent.py2581793%162, 349, 354, 356, 522, 538, 541, 546, 566, 587, 615, 631, 641, 652, 659–660, 701
packages/github_copilot/agent_framework_github_copilot
   _agent.py3381396%45–46, 52, 124, 468, 483–484, 780–781, 819, 822, 889, 928
TOTAL33850390688% 

Python Unit Test Overview

Tests Skipped Failures Errors Time
6667 30 💤 0 ❌ 0 🔥 1m 52s ⏱️

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes GitHubCopilotAgent session creation/resume so that tools added by ContextProvider.before_run (e.g., SkillsProvider’s load_skill / read_skill_resource) are included in the Copilot SDK session tool registry, preventing provider-contributed tools from being silently dropped.

Changes:

  • Merge SessionContext.tools into per-run runtime options before creating/resuming Copilot sessions (both non-streaming and streaming paths).
  • Update _create_session / _resume_session to combine constructor tools with runtime-option tools when building the Copilot SDK session config.
  • Add unit tests validating provider tool forwarding/merging in both non-streaming and streaming runs.

Reviewed changes

Copilot reviewed 3 out of 4 changed files in this pull request and generated 2 comments.

File Description
python/packages/github_copilot/agent_framework_github_copilot/_agent.py Merges provider-contributed tools into runtime options and ensures session creation/resume receives the combined tool set.
python/packages/github_copilot/tests/test_github_copilot_agent.py Adds coverage to ensure provider-added tools are forwarded and merged correctly (streaming + non-streaming).
python/samples/02-agents/skills/mixed_skills/mixed_skills.py Minor formatting adjustments (blank lines) in the skills sample.
python/uv.lock Lockfile metadata ordering change for github-copilot-sdk specifier.

Comment thread python/packages/github_copilot/agent_framework_github_copilot/_agent.py Outdated
Comment thread python/packages/github_copilot/agent_framework_github_copilot/_agent.py Outdated
Copy link
Copy Markdown

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Automated Code Review

Reviewers: 4 | Confidence: 92%

✓ Correctness

The PR correctly addresses the stated goal of forwarding provider-contributed tools to Copilot session creation. The _create_session and _resume_session merging logic (all_tools = list(self._tools or []) + list(opts.get("tools") or [])) is sound and avoids double-counting. However, the already-flagged shallow-copy mutation bug at lines 528 and 618 remains the only correctness issue: opts["tools"].extend(session_context.tools) mutates the caller's original list (since dict(options) is a shallow copy) and will crash if options["tools"] is a non-list Sequence like a tuple. The existing unresolved review comments accurately describe this issue and the suggested fix (build a new list instead of mutating in place) is correct.

✓ Security Reliability

The PR correctly addresses the core bug of forwarding provider-contributed tools to session creation. The existing unresolved review comments about .extend() mutating the caller's tools list through the shallow-copied opts dict remain the primary reliability concern. No additional security or reliability issues were found beyond those already flaged.

✓ Test Coverage

The new tests cover provider tools in the non-streaming create path (with and without constructor tools) and in the streaming create path (provider-only). However, the _resume_session method received an identical production code change (combining self._tools with opts.get("tools")) and has zero new test coverage for provider-contributed tools. Since the resume path is exercised when session.service_session_id is already set, this is a realistic scenario (multi-turn conversations) that deserves a dedicated test.

✗ Design Approach

The fix addresses the reported gap, but the new session-tool merge path bypasses the repo's existing tool-merging contract and can silently register duplicate tool names when constructor tools overlap with runtime/provider tools. That is a design regression because the core agent merge logic treats duplicate names as an error rather than allowing ambiguous double-registration.

Flagged Issues

  • _agent.py now concatenates constructor tools with runtime/provider tools directly during session creation/resume, bypassing the repo's normal unique-merge path. The core framework (_agents.py:107-114) uses _append_unique_tools(..., duplicate_error_message="Tool names must be unique.") and core tests assert that duplicate tool names must raise. As written, a provider injecting a tool with the same name as a constructor tool will silently pass both through to Copilot session creation instead of failing fast.

Automated review by giles17's agents

Comment thread python/packages/github_copilot/tests/test_github_copilot_agent.py
@giles17 giles17 marked this pull request as draft May 12, 2026 14:28
Copilot and others added 3 commits May 12, 2026 18:04
- Replace in-place .extend() with fresh list creation in both
  _run_impl and _stream_updates paths to prevent mutating the
  caller-provided options['tools'] list (shallow copy issue)
- Also handles immutable Sequence types (e.g. tuple) correctly
- Add test for provider tools forwarded via _resume_session path

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@giles17 giles17 marked this pull request as ready for review May 12, 2026 18:54
Copy link
Copy Markdown

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Automated Code Review

Reviewers: 4 | Confidence: 93% | Result: All clear

Reviewed: Correctness, Security Reliability, Test Coverage, Design Approach


Automated review by giles17's agents

banksbeebrittany-bit
banksbeebrittany-bit approved these changes May 13, 2026
@giles17 giles17 added this pull request to the merge queue May 15, 2026
Merged via the queue into microsoft:main with commit 0d09d40 May 15, 2026
38 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Python: GitHubCopilotAgent ignores tools added by ContextProvider.before_run (e.g. SkillsProvider.load_skill / read_skill_resource)

5 participants