Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 16 additions & 4 deletions dotnet/src/Client.cs
Original file line number Diff line number Diff line change
Expand Up @@ -852,6 +852,7 @@ public async Task<CopilotSession> CreateSessionAsync(SessionConfig config, Cance
localSessionId,
config.ClientName,
config.ReasoningEffort,
config.ReasoningSummary,
config.Tools?.Select(ToolDefinition.FromAIFunction).ToList(),
wireSystemMessage,
toolFilter.AvailableTools,
Expand All @@ -871,7 +872,7 @@ public async Task<CopilotSession> CreateSessionAsync(SessionConfig config, Cance
config.CustomAgents,
config.DefaultAgent,
config.Agent,
config.ConfigDir,
config.ConfigDirectory,
config.EnableConfigDiscovery,
config.SkillDirectories,
config.DisabledSkills,
Expand All @@ -885,6 +886,8 @@ public async Task<CopilotSession> CreateSessionAsync(SessionConfig config, Cance
RemoteSession: config.RemoteSession,
Cloud: config.Cloud,
InstructionDirectories: config.InstructionDirectories,
PluginDirectories: config.PluginDirectories,
LargeOutput: config.LargeOutput,
Canvases: config.Canvases,
RequestCanvasRenderer: config.RequestCanvasRenderer,
RequestExtensions: config.RequestExtensions,
Expand Down Expand Up @@ -1032,6 +1035,7 @@ public async Task<CopilotSession> ResumeSessionAsync(string sessionId, ResumeSes
config.ClientName,
config.Model,
config.ReasoningEffort,
config.ReasoningSummary,
config.Tools?.Select(ToolDefinition.FromAIFunction).ToList(),
wireSystemMessage,
toolFilter.AvailableTools,
Expand All @@ -1044,7 +1048,7 @@ public async Task<CopilotSession> ResumeSessionAsync(string sessionId, ResumeSes
config.OnAutoModeSwitchRequest != null ? true : null,
hasHooks ? true : null,
config.WorkingDirectory,
config.ConfigDir,
config.ConfigDirectory,
config.EnableConfigDiscovery,
config.SuppressResumeEvent is true ? true : null,
config.Streaming is true ? true : null,
Expand All @@ -1066,6 +1070,8 @@ public async Task<CopilotSession> ResumeSessionAsync(string sessionId, ResumeSes
RemoteSession: config.RemoteSession,
ContinuePendingWork: config.ContinuePendingWork,
InstructionDirectories: config.InstructionDirectories,
PluginDirectories: config.PluginDirectories,
LargeOutput: config.LargeOutput,
Canvases: config.Canvases,
RequestCanvasRenderer: config.RequestCanvasRenderer,
RequestExtensions: config.RequestExtensions,
Expand Down Expand Up @@ -2145,6 +2151,7 @@ internal record CreateSessionRequest(
string? SessionId,
string? ClientName,
string? ReasoningEffort,
ReasoningSummary? ReasoningSummary,
IList<ToolDefinition>? Tools,
SystemMessageConfig? SystemMessage,
IList<string>? AvailableTools,
Expand All @@ -2164,7 +2171,7 @@ internal record CreateSessionRequest(
IList<CustomAgentConfig>? CustomAgents,
DefaultAgentConfig? DefaultAgent,
string? Agent,
string? ConfigDir,
[property: JsonPropertyName("configDir")] string? ConfigDirectory,
bool? EnableConfigDiscovery,
IList<string>? SkillDirectories,
IList<string>? DisabledSkills,
Expand All @@ -2178,6 +2185,8 @@ internal record CreateSessionRequest(
RemoteSessionMode? RemoteSession = null,
CloudSessionOptions? Cloud = null,
IList<string>? InstructionDirectories = null,
IList<string>? PluginDirectories = null,
LargeToolOutputConfig? LargeOutput = null,
#pragma warning disable GHCP001
IList<CanvasDeclaration>? Canvases = null,
bool? RequestCanvasRenderer = null,
Expand Down Expand Up @@ -2216,6 +2225,7 @@ internal record ResumeSessionRequest(
string? ClientName,
string? Model,
string? ReasoningEffort,
ReasoningSummary? ReasoningSummary,
IList<ToolDefinition>? Tools,
SystemMessageConfig? SystemMessage,
IList<string>? AvailableTools,
Expand All @@ -2228,7 +2238,7 @@ internal record ResumeSessionRequest(
bool? RequestAutoModeSwitch,
bool? Hooks,
string? WorkingDirectory,
string? ConfigDir,
[property: JsonPropertyName("configDir")] string? ConfigDirectory,
bool? EnableConfigDiscovery,
bool? SuppressResumeEvent,
bool? Streaming,
Expand All @@ -2250,6 +2260,8 @@ internal record ResumeSessionRequest(
RemoteSessionMode? RemoteSession = null,
bool? ContinuePendingWork = null,
IList<string>? InstructionDirectories = null,
IList<string>? PluginDirectories = null,
LargeToolOutputConfig? LargeOutput = null,
#pragma warning disable GHCP001
IList<CanvasDeclaration>? Canvases = null,
bool? RequestCanvasRenderer = null,
Expand Down
65 changes: 63 additions & 2 deletions dotnet/src/Types.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2293,6 +2293,37 @@ public sealed class InfiniteSessionConfig
public double? BufferExhaustionThreshold { get; set; }
}

/// <summary>
/// Configuration for handling large tool outputs.
/// </summary>
/// <remarks>
/// When a tool produces output exceeding the configured size, the output is
/// written to a temp file and a reference is returned to the model instead of
/// returning to it the full payload.
/// </remarks>
public sealed class LargeToolOutputConfig
{
/// <summary>
/// Whether large output handling is enabled.
/// </summary>
/// <remarks>The default value is <see langword="true"/>.</remarks>
[JsonPropertyName("enabled")]
public bool? Enabled { get; set; }

/// <summary>
/// Maximum size in bytes before output is written to a temp file.
/// </summary>
[JsonPropertyName("maxSizeBytes")]
public long? MaxSizeBytes { get; set; }

/// <summary>
/// Directory to write temp files to.
/// </summary>
/// <remarks>The default value is the OS temp directory.</remarks>
[JsonPropertyName("outputDir")]
public string? OutputDirectory { get; set; }
}

/// <summary>
/// GitHub repository metadata to associate with a cloud session.
/// </summary>
Expand Down Expand Up @@ -2340,7 +2371,7 @@ protected SessionConfigBase(SessionConfigBase? other)
AvailableTools = other.AvailableTools is not null ? [.. other.AvailableTools] : null;
ClientName = other.ClientName;
Commands = other.Commands is not null ? [.. other.Commands] : null;
ConfigDir = other.ConfigDir;
ConfigDirectory = other.ConfigDirectory;
CustomAgents = other.CustomAgents is not null ? [.. other.CustomAgents] : null;
DefaultAgent = other.DefaultAgent;
Agent = other.Agent;
Expand All @@ -2349,6 +2380,7 @@ protected SessionConfigBase(SessionConfigBase? other)
ExcludedTools = other.ExcludedTools is not null ? [.. other.ExcludedTools] : null;
Hooks = other.Hooks;
InfiniteSessions = other.InfiniteSessions;
LargeOutput = other.LargeOutput;
McpServers = other.McpServers is not null
? (other.McpServers is Dictionary<string, McpServerConfig> dict
? new Dictionary<string, McpServerConfig>(dict, dict.Comparer)
Expand All @@ -2369,6 +2401,7 @@ protected SessionConfigBase(SessionConfigBase? other)
CoauthorEnabled = other.CoauthorEnabled;
ManageScheduleEnabled = other.ManageScheduleEnabled;
ReasoningEffort = other.ReasoningEffort;
ReasoningSummary = other.ReasoningSummary;
CreateSessionFsProvider = other.CreateSessionFsProvider;
GitHubToken = other.GitHubToken;
RemoteSession = other.RemoteSession;
Expand All @@ -2380,6 +2413,7 @@ protected SessionConfigBase(SessionConfigBase? other)
CanvasHandler = other.CanvasHandler;
#pragma warning restore GHCP001
SkillDirectories = other.SkillDirectories is not null ? [.. other.SkillDirectories] : null;
PluginDirectories = other.PluginDirectories is not null ? [.. other.PluginDirectories] : null;
InstructionDirectories = other.InstructionDirectories is not null ? [.. other.InstructionDirectories] : null;
Streaming = other.Streaming;
IncludeSubAgentStreamingEvents = other.IncludeSubAgentStreamingEvents;
Expand All @@ -2401,14 +2435,22 @@ protected SessionConfigBase(SessionConfigBase? other)
/// </summary>
public string? ReasoningEffort { get; set; }

/// <summary>
/// Reasoning summary mode for models that support configurable reasoning summaries.
/// </summary>
/// <remarks>
/// Use <see cref="ReasoningSummary.None"/> to suppress summary output regardless of whether reasoning is enabled.
/// </remarks>
public ReasoningSummary? ReasoningSummary { get; set; }

/// <summary>Per-property overrides for model capabilities, deep-merged over runtime defaults.</summary>
public ModelCapabilitiesOverride? ModelCapabilities { get; set; }

/// <summary>
/// Override the default configuration directory location.
/// When specified, the session will use this directory for storing config and state.
/// </summary>
public string? ConfigDir { get; set; }
public string? ConfigDirectory { get; set; }

/// <summary>
/// When <see langword="true"/>, automatically discovers MCP server configurations
Expand Down Expand Up @@ -2557,6 +2599,17 @@ protected SessionConfigBase(SessionConfigBase? other)
/// <summary>Directories to load skills from.</summary>
public IList<string>? SkillDirectories { get; set; }

/// <summary>
/// Local filesystem paths to Open Plugins-format directories
/// (https://open-plugins.com/) to load for this session.
/// </summary>
/// <remarks>
/// Relative paths resolve against <see cref="WorkingDirectory"/> (or the
/// runtime cwd if unset). Treated as an explicit opt-in: plugin agents
/// and rules load even when <see cref="EnableConfigDiscovery"/> is false.
/// </remarks>
public IList<string>? PluginDirectories { get; set; }

/// <summary>Additional directories to search for custom instruction files.</summary>
public IList<string>? InstructionDirectories { get; set; }

Expand All @@ -2569,6 +2622,14 @@ protected SessionConfigBase(SessionConfigBase? other)
/// </summary>
public InfiniteSessionConfig? InfiniteSessions { get; set; }

/// <summary>
/// Configuration for handling large tool outputs. When a tool produces
/// output exceeding the configured size, the output is written to a temp
/// file and a reference is returned to the model instead of the full
/// payload.
/// </summary>
public LargeToolOutputConfig? LargeOutput { get; set; }

/// <summary>
/// Optional event handler registered on the session before the session.create / session.resume
/// RPC is issued, ensuring early events are delivered.
Expand Down
2 changes: 1 addition & 1 deletion dotnet/test/E2E/ClientE2ETests.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/*---------------------------------------------------------------------------------------------
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
*--------------------------------------------------------------------------------------------*/

Expand Down
2 changes: 1 addition & 1 deletion dotnet/test/E2E/ClientOptionsE2ETests.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/*---------------------------------------------------------------------------------------------
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
*--------------------------------------------------------------------------------------------*/

Expand Down
2 changes: 1 addition & 1 deletion dotnet/test/E2E/SessionE2ETests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -550,7 +550,7 @@ public async Task SendAndWait_Throws_OperationCanceledException_When_Token_Cance
public async Task Should_Create_Session_With_Custom_Config_Dir()
{
var customConfigDir = Path.Join(Ctx.HomeDir, "custom-config");
var session = await CreateSessionAsync(new SessionConfig { ConfigDir = customConfigDir });
var session = await CreateSessionAsync(new SessionConfig { ConfigDirectory = customConfigDir });

Assert.Matches(@"^[a-f0-9-]+$", session.SessionId);

Expand Down
41 changes: 38 additions & 3 deletions dotnet/test/Unit/CloneTests.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/*---------------------------------------------------------------------------------------------
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
*--------------------------------------------------------------------------------------------*/

Expand Down Expand Up @@ -68,7 +68,8 @@ public void SessionConfig_Clone_CopiesAllProperties()
ClientName = "my-app",
Model = "gpt-4",
ReasoningEffort = "high",
ConfigDir = "/config",
ReasoningSummary = ReasoningSummary.Detailed,
ConfigDirectory = "/config",
AvailableTools = ["tool1", "tool2"],
ExcludedTools = ["tool3"],
WorkingDirectory = "/workspace",
Expand All @@ -91,6 +92,8 @@ public void SessionConfig_Clone_CopiesAllProperties()
SkillDirectories = ["/skills"],
InstructionDirectories = ["/instructions"],
DisabledSkills = ["skill1"],
PluginDirectories = ["/plugins"],
LargeOutput = new LargeToolOutputConfig { Enabled = true, MaxSizeBytes = 2048, OutputDirectory = "/tmp/out" },
OnExitPlanModeRequest = static (_, _) => Task.FromResult(new ExitPlanModeResult()),
OnAutoModeSwitchRequest = static (_, _) => Task.FromResult(AutoModeSwitchResponse.No),
};
Expand All @@ -101,7 +104,8 @@ public void SessionConfig_Clone_CopiesAllProperties()
Assert.Equal(original.ClientName, clone.ClientName);
Assert.Equal(original.Model, clone.Model);
Assert.Equal(original.ReasoningEffort, clone.ReasoningEffort);
Assert.Equal(original.ConfigDir, clone.ConfigDir);
Assert.Equal(original.ReasoningSummary, clone.ReasoningSummary);
Assert.Equal(original.ConfigDirectory, clone.ConfigDirectory);
Assert.Equal(original.AvailableTools, clone.AvailableTools);
Assert.Equal(original.ExcludedTools, clone.ExcludedTools);
Assert.Equal(original.WorkingDirectory, clone.WorkingDirectory);
Expand All @@ -117,6 +121,8 @@ public void SessionConfig_Clone_CopiesAllProperties()
Assert.Equal(original.SkillDirectories, clone.SkillDirectories);
Assert.Equal(original.InstructionDirectories, clone.InstructionDirectories);
Assert.Equal(original.DisabledSkills, clone.DisabledSkills);
Assert.Equal(original.PluginDirectories, clone.PluginDirectories);
Assert.Same(original.LargeOutput, clone.LargeOutput);
Assert.Same(original.OnExitPlanModeRequest, clone.OnExitPlanModeRequest);
Assert.Same(original.OnAutoModeSwitchRequest, clone.OnAutoModeSwitchRequest);
}
Expand Down Expand Up @@ -356,6 +362,35 @@ public void ResumeSessionConfig_Clone_CopiesContinuePendingWork()
Assert.True(clone.ContinuePendingWork);
}

[Fact]
public void ResumeSessionConfig_Clone_CopiesReasoningSummary()
{
var original = new ResumeSessionConfig
{
ReasoningSummary = ReasoningSummary.None,
};

var clone = original.Clone();

Assert.Equal(original.ReasoningSummary, clone.ReasoningSummary);
}

[Fact]
public void ResumeSessionConfig_Clone_CopiesPluginDirectoriesAndLargeOutput()
{
var largeOutput = new LargeToolOutputConfig { Enabled = false, MaxSizeBytes = 4096, OutputDirectory = "/tmp/resume" };
var original = new ResumeSessionConfig
{
PluginDirectories = ["/resume/plugins"],
LargeOutput = largeOutput,
};

var clone = original.Clone();

Assert.Equal(original.PluginDirectories, clone.PluginDirectories);
Assert.Same(original.LargeOutput, clone.LargeOutput);
}

[Fact]
public void ResumeSessionConfig_Clone_PreservesContinuePendingWorkDefault()
{
Expand Down
Loading
Loading