fix: stop forcing copilot session ids

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
David Kaya
2026-03-28 12:52:52 +01:00
co-authored by Copilot
parent e13e3b818a
commit f459cc7291
2 changed files with 83 additions and 26 deletions
@@ -45,32 +45,13 @@ internal sealed class CopilotAgentBundle : IAsyncDisposable
CopilotClient client = new(clientOptions);
await client.StartAsync(cancellationToken).ConfigureAwait(false);
SessionConfig sessionConfig = new()
{
SessionId = CopilotManagedSessionIds.Build(command.SessionId, definition.Id),
Model = definition.Model,
ReasoningEffort = definition.ReasoningEffort,
SystemMessage = new SystemMessageConfig
{
Content = AgentInstructionComposer.Compose(
command.Pattern,
definition,
agentIndex,
command.WorkspaceKind,
command.Mode),
},
WorkingDirectory = command.ProjectPath,
OnPermissionRequest = (request, invocation) => onPermissionRequest(definition, request, invocation),
OnUserInputRequest = (request, invocation) => onUserInputRequest(definition, request, invocation),
Hooks = CopilotSessionHooks.Create(command, definition),
OnEvent = evt => onSessionEvent?.Invoke(definition, evt),
Streaming = true,
CustomAgents = CreateCustomAgents(definition.Copilot?.CustomAgents),
Agent = NormalizeOptionalString(definition.Copilot?.Agent),
SkillDirectories = CreateStringList(definition.Copilot?.SkillDirectories),
DisabledSkills = CreateStringList(definition.Copilot?.DisabledSkills),
InfiniteSessions = CreateInfiniteSessions(definition.Copilot?.InfiniteSessions),
};
SessionConfig sessionConfig = CreateSessionConfig(
command,
definition,
agentIndex,
(request, invocation) => onPermissionRequest(definition, request, invocation),
(request, invocation) => onUserInputRequest(definition, request, invocation),
evt => onSessionEvent?.Invoke(definition, evt));
ApplySessionTooling(sessionConfig, toolingBundle?.McpServers, toolingBundle?.Tools);
@@ -91,6 +72,43 @@ internal sealed class CopilotAgentBundle : IAsyncDisposable
return bundle;
}
internal static SessionConfig CreateSessionConfig(
RunTurnCommandDto command,
PatternAgentDefinitionDto definition,
int agentIndex,
PermissionRequestHandler? onPermissionRequest = null,
UserInputHandler? onUserInputRequest = null,
SessionEventHandler? onSessionEvent = null)
{
// Let the Copilot SDK allocate session IDs. Explicit custom SessionId values currently
// cause turns to complete without assistant output, even for simple single-agent prompts.
return new SessionConfig
{
Model = definition.Model,
ReasoningEffort = definition.ReasoningEffort,
SystemMessage = new SystemMessageConfig
{
Content = AgentInstructionComposer.Compose(
command.Pattern,
definition,
agentIndex,
command.WorkspaceKind,
command.Mode),
},
WorkingDirectory = command.ProjectPath,
OnPermissionRequest = onPermissionRequest,
OnUserInputRequest = onUserInputRequest,
Hooks = CopilotSessionHooks.Create(command, definition),
OnEvent = onSessionEvent,
Streaming = true,
CustomAgents = CreateCustomAgents(definition.Copilot?.CustomAgents),
Agent = NormalizeOptionalString(definition.Copilot?.Agent),
SkillDirectories = CreateStringList(definition.Copilot?.SkillDirectories),
DisabledSkills = CreateStringList(definition.Copilot?.DisabledSkills),
InfiniteSessions = CreateInfiniteSessions(definition.Copilot?.InfiniteSessions),
};
}
internal static void ApplySessionTooling(
SessionConfig sessionConfig,
Dictionary<string, object>? mcpServers,
@@ -202,6 +202,45 @@ public sealed class CopilotAgentBundleTests
Assert.Equal(0.9, config.BufferExhaustionThreshold);
}
[Fact]
public void CreateSessionConfig_DoesNotForceSessionId()
{
RunTurnCommandDto command = new()
{
SessionId = "session-1",
ProjectPath = @"C:\workspace\project",
WorkspaceKind = "project",
Mode = "interactive",
Pattern = new PatternDefinitionDto
{
Id = "pattern-1",
Name = "Pattern",
Mode = "single",
Availability = "available",
Agents =
[
new PatternAgentDefinitionDto
{
Id = "agent-1",
Name = "Primary",
Model = "gpt-5.4",
Instructions = "Help.",
},
],
},
};
SessionConfig sessionConfig = CopilotAgentBundle.CreateSessionConfig(
command,
command.Pattern.Agents[0],
agentIndex: 0);
Assert.Null(sessionConfig.SessionId);
Assert.Equal(@"C:\workspace\project", sessionConfig.WorkingDirectory);
Assert.True(sessionConfig.Streaming);
Assert.NotNull(sessionConfig.Hooks);
}
[Fact]
public async Task CopilotSessionHooks_Create_UsesApprovalPolicyForPreToolUse()
{