Skip to content

Add GitHub Copilot agent provider - #346

Merged
qmuntal merged 2 commits into
mainfrom
copilot-provider
Jun 25, 2026
Merged

Add GitHub Copilot agent provider#346
qmuntal merged 2 commits into
mainfrom
copilot-provider

Conversation

@qmuntal

@qmuntal qmuntal commented Jun 24, 2026

Copy link
Copy Markdown
Member

Summary

Adds a GitHub Copilot-backed agent provider for Go using the official github.com/github/copilot-sdk/go SDK.

This includes session creation and resume support, streaming and non-streaming response projection, tool declaration and execution result handling, attachment support for DataContent, session error handling, and a runnable GitHub Copilot provider sample.

The change also adds RawContent support for provider-specific content and extends internal/jsonx with fallback-aware discriminated union unmarshalling so unknown or missing content types can round-trip as raw content instead of failing.

Details

  • Adds agent/provider/copilotagent
  • Creates and resumes Copilot SDK sessions
  • Stores Copilot session IDs via framework session service IDs
  • Projects assistant deltas, final assistant messages, usage, tool start, tool complete, idle, and error events
  • Maps framework tools to Copilot tools
  • Sends DataContent as temporary file attachments
  • Adds blackbox tests using a fake JSON-RPC Copilot runtime
  • Adds examples/02-agents/providers/github-copilot
  • Adds message.RawContent
  • Adds jsonx.UnmarshalDiscriminatedUnionSliceWithFallback
  • Adds fallback behavior for message.Contents when content Type is missing or unknown

Validation

go test ./internal/jsonx ./message ./agent/provider/copilotagent ./examples/02-agents/providers/github-copilot

Add a GitHub Copilot-backed agent provider using the official Copilot SDK, including session creation and resume, streaming and non-streaming event projection, tool declarations and results, data attachments, and session error handling.

Add RawContent support with jsonx fallback unmarshalling for unknown or missing content types, plus a GitHub Copilot sample and blackbox provider tests.
Copilot AI review requested due to automatic review settings June 24, 2026 09:47
@qmuntal
qmuntal requested a review from a team as a code owner June 24, 2026 09:47

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR adds a new GitHub Copilot-backed provider implementation for the agent framework, along with message/content model extensions to safely round-trip provider-specific or forward-compatible content without failing JSON decoding.

Changes:

  • Added agent/provider/copilotagent provider that creates/resumes Copilot SDK sessions, streams events into framework ResponseUpdates, maps framework tools to Copilot tools, and sends DataContent as file attachments.
  • Added message.RawContent and updated message.Contents JSON unmarshalling to fall back to raw content when Type is missing or unknown.
  • Extended internal/jsonx with UnmarshalDiscriminatedUnionSliceWithFallback and added tests for fallback behavior.
Show a summary per file
File Description
message/content.go Adds RawContent and uses fallback-aware union unmarshalling for Contents.
message/content_test.go Adds coverage for missing/unknown Type decoding to RawContent and round-tripping.
internal/jsonx/jsonx.go Adds UnmarshalDiscriminatedUnionSliceWithFallback and refactors existing helper to use it.
internal/jsonx/jsonx_test.go Adds tests for fallback behavior and unsupported-type rejection.
agent/provider/copilotagent/copilot.go Implements the Copilot provider: session lifecycle, event projection, tool mapping, and attachments.
agent/provider/copilotagent/copilot_test.go Adds blackbox-style tests using a fake JSON-RPC runtime for session + event mapping behaviors.
examples/02-agents/providers/github-copilot/main.go Adds a runnable Copilot provider example with permission prompting.
go.mod Adds the Copilot SDK dependency (and websocket indirect).
go.sum Adds checksums for the new dependencies.

Copilot's findings

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

  • Files reviewed: 8/9 changed files
  • Comments generated: 4

Comment thread internal/jsonx/jsonx.go
Comment thread agent/provider/copilotagent/copilot.go
Comment thread agent/provider/copilotagent/copilot.go
Comment thread agent/provider/copilotagent/copilot.go
@github-actions

This comment has been minimized.

Fix golangci-lint findings, make Copilot session event delivery non-blocking while preserving event order, avoid duplicate attachment temp paths, and distinguish missing discriminators from zero-value discriminators in jsonx fallback unmarshalling.
@github-actions

Copy link
Copy Markdown
Contributor

Cross-Repo Parity Review — GitHub Copilot Agent Provider

Compared against microsoft/agent-framework (.NET: Microsoft.Agents.AI.GitHub.Copilot, Python: agent_framework_github_copilot).

Summary

This PR is well-aligned with the upstream .NET and Python implementations. The core behavioral contract matches across all three SDKs and no blocking cross-repo divergences were found.


What was reviewed

Aspect Go (this PR) .NET Python Assessment
Streaming default true true true ✅ Consistent
Delta event → TextContent ✅ Consistent
Final AssistantMessage in streaming mode → raw RawContent{RawRepresentation: event} AIContent{RawRepresentation: assistantMessage} not emitted ✅ Go ↔ .NET aligned
Final AssistantMessage in non-streaming → TextContent send_and_wait path ✅ Consistent
ToolExecutionStartFunctionCallContent ✅ Consistent
ToolExecutionCompleteFunctionResultContent ✅ Consistent
AssistantUsageUsageContent ❌ not implemented Go/.NET ahead; not a Go divergence
Session idle/error → raw update + signal ❌ no raw update emitted Go/.NET ahead; not a Go divergence
AdditionalCounts keys (CacheWriteTokens, Cost, Duration) ✅ matches .NET's nameof(...) strings n/a ✅ Consistent
Prompt building (text-only join) msg.String() → text m.Text message.text ✅ Consistent
Instructions via SessionConfig.SystemMessage separate path ✅ Go ↔ .NET aligned
Session resume via ServiceID / SessionId ✅ Consistent
DataContent → temp file attachment ✅ (similar) ✅ Consistent
Sample placement (02-agents/providers/github-copilot) ✅ Consistent

Notes

message.RawContent is a new public type. This is the correct Go-idiomatic design: because Go uses interfaces rather than inheritance, a concrete type is needed to represent provider-specific content with no structured framework equivalent. The upstream .NET uses AIContent { RawRepresentation = event } (the MEAI base class directly); the concept is semantically identical.

Contents.UnmarshalJSON fallback (via UnmarshalDiscriminatedUnionSliceWithFallback): this changes deserialization from "error on unknown type" to "preserve as RawContent." This is a leniency improvement consistent with how MEAI handles unknown discriminators — no parity concern.

Duration in UsageContent.AdditionalCounts: The .NET implementation explicitly converts a TimeSpan to (long)duration.TotalMilliseconds. The Go implementation stores *data.Duration (an int64) directly. If the Go Copilot SDK's Duration field is already expressed in milliseconds, the values are consistent; if it uses a different unit, they would silently diverge for anyone reading this key. Worth confirming the Go SDK's unit convention matches the .NET mapping.

Generated by Go API Consistency Review Agent for issue #346 · 777.2 AIC · ⌖ 12.7 AIC · ⊞ 26.7K ·

@qmuntal
qmuntal enabled auto-merge June 25, 2026 07:26
@qmuntal
qmuntal added this pull request to the merge queue Jun 25, 2026
@qmuntal
qmuntal removed this pull request from the merge queue due to a manual request Jun 25, 2026
@qmuntal
qmuntal added this pull request to the merge queue Jun 25, 2026
Merged via the queue into main with commit 7ca9105 Jun 25, 2026
17 checks passed
@qmuntal
qmuntal deleted the copilot-provider branch June 25, 2026 08:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants