.NET: [BREAKING] .NET: Bump GitHub.Copilot.SDK to 1.0.0-beta.3 and forward session config properties (incl. per-session GitHubToken)#5735
Conversation
…operties - Bump SDK from 1.0.0-beta.2 to 1.0.0-beta.3 - Forward newly-added SessionConfig/ResumeSessionConfig properties through CopySessionConfig and CopyResumeSessionConfig: SessionId, ClientName, ModelCapabilities, OnElicitationRequest, OnEvent, EnableConfigDiscovery, IncludeSubAgentStreamingEvents, DefaultAgent, Agent, Commands, CreateSessionFsHandler, GitHubToken (per-session token) - Make sessionConfig non-nullable on the SessionConfig constructor (SDK 1.0.0-beta.x requires SessionConfig.OnPermissionRequest, so SessionConfig itself is required) - Make onPermissionRequest a required (non-nullable) parameter on the tools/instructions constructor and the corresponding AsAIAgent extension overload - Remove fallback throw in RunCoreStreamingAsync since _sessionConfig is now non-nullable - Update unit tests, integration tests, and sample for the new required-param signatures
There was a problem hiding this comment.
Pull request overview
Updates the .NET GitHub Copilot agent integration to align with GitHub.Copilot.SDK 1.0.0-beta.3, ensuring newly introduced SDK SessionConfig fields (notably per-session GitHubToken) are preserved when creating/resuming sessions, and updating the public API to require permission handling configuration in line with the SDK’s requirements.
Changes:
- Bump
GitHub.Copilot.SDKfrom1.0.0-beta.2to1.0.0-beta.3. - Make agent/extension construction require either a
SessionConfig(now non-nullable) or an explicitOnPermissionRequesthandler, and update call sites accordingly. - Expand
CopySessionConfig/CopyResumeSessionConfigto forward additional SDK properties, includingGitHubToken.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| dotnet/Directory.Packages.props | Bumps GitHub.Copilot.SDK to 1.0.0-beta.3. |
| dotnet/src/Microsoft.Agents.AI.GitHub.Copilot/GitHubCopilotAgent.cs | Requires non-null SessionConfig, adds required permission-handler constructor, and forwards new SDK session configuration properties. |
| dotnet/src/Microsoft.Agents.AI.GitHub.Copilot/CopilotClientExtensions.cs | Updates AsAIAgent overloads to match new required permission/session-config requirements. |
| dotnet/tests/Microsoft.Agents.AI.GitHub.Copilot.UnitTests/GitHubCopilotAgentTests.cs | Updates unit tests for new ctor signatures; adds assertions for GitHubToken forwarding and null-arg validation. |
| dotnet/tests/Microsoft.Agents.AI.GitHub.Copilot.UnitTests/CopilotClientExtensionsTests.cs | Updates extension-method tests for new overloads and required permission/session-config inputs. |
| dotnet/tests/Microsoft.Agents.AI.GitHub.Copilot.IntegrationTests/GitHubCopilotAgentTests.cs | Updates integration tests to provide required permission handling/session config. |
Comments suppressed due to low confidence (3)
dotnet/src/Microsoft.Agents.AI.GitHub.Copilot/GitHubCopilotAgent.cs:55
- The
SessionConfig-based constructor only checkssessionConfigfor null, but does not validate the SDK-requiredsessionConfig.OnPermissionRequest. Callers can still pass a non-nullSessionConfigwith a nullOnPermissionRequest, which will defer the failure toCreateSessionAsync/ResumeSessionAsync(and may fail silently per PR description). Consider throwingArgumentException/ArgumentNullExceptionwhensessionConfig.OnPermissionRequestis null to surface the requirement at construction time.
public GitHubCopilotAgent(
CopilotClient copilotClient,
SessionConfig sessionConfig,
bool ownsClient = false,
string? id = null,
string? name = null,
string? description = null)
{
_ = Throw.IfNull(copilotClient);
_ = Throw.IfNull(sessionConfig);
this._copilotClient = copilotClient;
this._sessionConfig = sessionConfig;
this._ownsClient = ownsClient;
dotnet/src/Microsoft.Agents.AI.GitHub.Copilot/CopilotClientExtensions.cs:47
AsAIAgent(SessionConfig sessionConfig, ...)doesn’t validate thatsessionConfig.OnPermissionRequestis set, even though the XML docs state it’s required by the SDK. Adding an explicit guard (and preferably an argument-name-specific exception) would prevent confusing runtime behavior when callers construct aSessionConfigbut forget to set the permission handler.
public static AIAgent AsAIAgent(
this CopilotClient client,
SessionConfig sessionConfig,
bool ownsClient = false,
string? id = null,
string? name = null,
string? description = null)
{
Throw.IfNull(client);
return new GitHubCopilotAgent(client, sessionConfig, ownsClient, id, name, description);
}
dotnet/src/Microsoft.Agents.AI.GitHub.Copilot/GitHubCopilotAgent.cs:166
sessionConfigis copied unconditionally before the create/resume branch, but the copied instance is only used on theCreateSessionAsyncpath. When resuming (typedSession.SessionId != null), this performs an unnecessary allocation/copy each run. Consider movingCopySessionConfig(_sessionConfig)into theelsebranch (or only when creating a new session).
// Ensure the client is started
await this.EnsureClientStartedAsync(cancellationToken).ConfigureAwait(false);
// Create or resume a session with streaming enabled
SessionConfig sessionConfig = CopySessionConfig(this._sessionConfig);
CopilotSession copilotSession;
if (typedSession.SessionId is not null)
{
copilotSession = await this._copilotClient.ResumeSessionAsync(
typedSession.SessionId,
this.CreateResumeConfig(),
cancellationToken).ConfigureAwait(false);
}
else
{
copilotSession = await this._copilotClient.CreateSessionAsync(sessionConfig, cancellationToken).ConfigureAwait(false);
typedSession.SessionId = copilotSession.SessionId;
}
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 6 out of 6 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (3)
dotnet/src/Microsoft.Agents.AI.GitHub.Copilot/GitHubCopilotAgent.cs:55
- The SessionConfig-based constructor enforces
sessionConfigis non-null, but it does not validatesessionConfig.OnPermissionRequest. Since the SDK requires this handler for Create/Resume, consider throwingArgumentNullException(or similar) whensessionConfig.OnPermissionRequestis null to fail fast with a clear error.
public GitHubCopilotAgent(
CopilotClient copilotClient,
SessionConfig sessionConfig,
bool ownsClient = false,
string? id = null,
string? name = null,
string? description = null)
{
_ = Throw.IfNull(copilotClient);
_ = Throw.IfNull(sessionConfig);
this._copilotClient = copilotClient;
this._sessionConfig = sessionConfig;
this._ownsClient = ownsClient;
dotnet/src/Microsoft.Agents.AI.GitHub.Copilot/CopilotClientExtensions.cs:47
AsAIAgent(this CopilotClient client, SessionConfig sessionConfig, ...)only null-checksclient. Even with a non-nullable parameter, callers can still passnull!at runtime; addThrow.IfNull(sessionConfig)(and ideally validatesessionConfig.OnPermissionRequest) so the extension method fails with a clearArgumentNullExceptioninstead of deferring to deeper code.
public static AIAgent AsAIAgent(
this CopilotClient client,
SessionConfig sessionConfig,
bool ownsClient = false,
string? id = null,
string? name = null,
string? description = null)
{
Throw.IfNull(client);
return new GitHubCopilotAgent(client, sessionConfig, ownsClient, id, name, description);
}
dotnet/src/Microsoft.Agents.AI.GitHub.Copilot/GitHubCopilotAgent.cs:165
RunCoreStreamingAsyncalways allocates a copiedSessionConfigbefore checking whether it will resume an existing session. WhentypedSession.SessionIdis non-null, that copy isn't used; consider movingCopySessionConfig(...)into the create-session branch to avoid an unnecessary allocation per run when resuming.
// Ensure the client is started
await this.EnsureClientStartedAsync(cancellationToken).ConfigureAwait(false);
// Create or resume a session with streaming enabled
SessionConfig sessionConfig = CopySessionConfig(this._sessionConfig);
CopilotSession copilotSession;
if (typedSession.SessionId is not null)
{
copilotSession = await this._copilotClient.ResumeSessionAsync(
typedSession.SessionId,
this.CreateResumeConfig(),
cancellationToken).ConfigureAwait(false);
}
else
{
copilotSession = await this._copilotClient.CreateSessionAsync(sessionConfig, cancellationToken).ConfigureAwait(false);
typedSession.SessionId = copilotSession.SessionId;
Motivation and Context
Microsoft.Agents.AI.GitHub.Copilotwas already updated toGitHub.Copilot.SDK 1.0.0-beta.2in #5699, but theCopySessionConfig/CopyResumeSessionConfighelpers were never updated to forward the new SDK properties — most importantlySessionConfig.GitHubTokenfor per-session GitHub identity (multitenant scenarios where different sessions on the same CLI server use different GitHub accounts/Copilot plans).Any caller that sets
GitHubTokenon theSessionConfigthey pass to the agent today silently has it dropped when the agent constructs its internalSessionConfigforCreateSessionAsync/ResumeSessionAsync.This PR also:
1.0.0-beta.3).SessionConfigandOnPermissionRequestrequired parameters on the agent constructors andAsAIAgentextensions, since the SDK now requiresSessionConfig.OnPermissionRequeston everyCreateSessionAsync/ResumeSessionAsynccall (silently failing today if the caller forgets).Description
SDK version bump:
GitHub.Copilot.SDK1.0.0-beta.2→1.0.0-beta.3inDirectory.Packages.propsProperty forwarding through
CopySessionConfig/CopyResumeSessionConfig:Newly-forwarded SDK properties:
SessionId,ClientName,ModelCapabilities,OnElicitationRequest,OnEvent,EnableConfigDiscovery,IncludeSubAgentStreamingEvents,DefaultAgent,Agent,Commands,CreateSessionFsHandler,GitHubToken.API surface —
OnPermissionRequestis now required (matches SDK requirement):GitHubCopilotAgent(CopilotClient, SessionConfig, ...)—sessionConfigis now non-nullable. The SDK requiresSessionConfig.OnPermissionRequest, so requiringSessionConfigitself surfaces the requirement at construction time.GitHubCopilotAgent(CopilotClient, PermissionRequestHandler, ..., tools, instructions)— replaces the previoustools/instructionsconstructor.onPermissionRequestis a required (non-nullable) param positioned before the optional ones.CopilotClientExtensions.AsAIAgentoverloads mirror the same.throwpath inRunCoreStreamingAsyncsince_sessionConfigcan no longer be null.Tests:
GitHubTokenassertion added to both copy tests.SessionConfigconstructor.Contribution Checklist
[BREAKING]prefix added. Consumers using the previous optional-sessionConfig/tools+instructionsconstructors will need to update call sites.