Skip to content
Closed
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
134 changes: 5 additions & 129 deletions dotnet/src/Generated/Rpc.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

32 changes: 29 additions & 3 deletions dotnet/src/Session.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1576,14 +1576,40 @@ public async Task AbortAsync(CancellationToken cancellationToken = default)
/// <code>
/// await session.SetModelAsync("gpt-4.1");
/// await session.SetModelAsync("claude-sonnet-4.6", "high");
/// await session.SetModelAsync("gpt-4.1", new SetModelOptions { ContextTier = ContextTier.LongContext });
/// </code>
/// </example>
public async Task SetModelAsync(string model, string? reasoningEffort, ModelCapabilitiesOverride? modelCapabilities = null, CancellationToken cancellationToken = default)
public Task SetModelAsync(string model, string? reasoningEffort, ModelCapabilitiesOverride? modelCapabilities = null, CancellationToken cancellationToken = default)
{
return SetModelAsync(
model,
new SetModelOptions
{
ReasoningEffort = reasoningEffort,
ModelCapabilities = modelCapabilities,
},
cancellationToken);
}

/// <summary>
/// Changes the model for this session.
/// The new model takes effect for the next message. Conversation history is preserved.
/// </summary>
/// <param name="model">Model ID to switch to (e.g., "gpt-4.1").</param>
/// <param name="options">Settings for the new model.</param>
/// <param name="cancellationToken">Optional cancellation token.</param>
public async Task SetModelAsync(string model, SetModelOptions options, CancellationToken cancellationToken = default)
{
ArgumentNullException.ThrowIfNull(model);
ThrowIfDisposed();

await Rpc.Model.SwitchToAsync(model, reasoningEffort, reasoningSummary: null, modelCapabilities: modelCapabilities, cancellationToken: cancellationToken);
await Rpc.Model.SwitchToAsync(
model,
options.ReasoningEffort,
options.ReasoningSummary,
options.ModelCapabilities,
options.ContextTier,
cancellationToken);
}

/// <summary>
Expand All @@ -1593,7 +1619,7 @@ public Task SetModelAsync(string model, CancellationToken cancellationToken = de
{
ThrowIfDisposed();

return SetModelAsync(model, reasoningEffort: null, modelCapabilities: null, cancellationToken);
return SetModelAsync(model, new SetModelOptions(), cancellationToken);
}

/// <summary>
Expand Down
28 changes: 28 additions & 0 deletions dotnet/src/Types.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2449,6 +2449,33 @@ public override void Write(Utf8JsonWriter writer, ContextTier value, JsonSeriali
}
}

/// <summary>
/// Optional settings for <see cref="CopilotSession.SetModelAsync(string, SetModelOptions, CancellationToken)"/>.
/// </summary>
public struct SetModelOptions
{
/// <summary>
/// Reasoning effort level for the new model.
/// </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>
/// Context window tier for models that support it.
/// </summary>
public ContextTier? ContextTier { get; set; }

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

/// <summary>
/// Shared configuration properties for creating or resuming a Copilot session.
/// Use <see cref="SessionConfig"/> when creating a new session, or
Expand Down Expand Up @@ -3556,6 +3583,7 @@ public sealed class SystemMessageTransformRpcResponse
[JsonSerializable(typeof(SessionListFilter))]
[JsonSerializable(typeof(SectionOverride))]
[JsonSerializable(typeof(SessionMetadata))]
[JsonSerializable(typeof(SetModelOptions))]
[JsonSerializable(typeof(SetForegroundSessionResponse))]
[JsonSerializable(typeof(SystemMessageConfig))]
[JsonSerializable(typeof(ToolBinaryResult))]
Expand Down
21 changes: 20 additions & 1 deletion dotnet/test/Unit/SerializationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ public void SendMessageRequest_CanSerializeRequestHeaders_WithSdkOptions()
("Mode", "enqueue"),
("RequestHeaders", new Dictionary<string, string> { ["X-Trace"] = "trace-value" }));

var json = JsonSerializer.Serialize(request, requestType, options);
var json = JsonSerializer.Serialize(request, requestType!, options);
using var document = JsonDocument.Parse(json);
var root = document.RootElement;
Assert.Equal("session-id", root.GetProperty("sessionId").GetString());
Expand Down Expand Up @@ -221,6 +221,25 @@ public void SessionRequests_CanSerializeContextTier_WithSdkOptions()
Assert.Equal("default", resumeDocument.RootElement.GetProperty("contextTier").GetString());
}

[Fact]
public void ModelSwitchToRequest_CanSerializeContextTier_WithSdkOptions()
{
var options = GetSerializerOptions();
var requestType = typeof(CopilotClient).Assembly.GetType("GitHub.Copilot.Rpc.ModelSwitchToRequest");
Assert.NotNull(requestType);
var request = CreateInternalRequest(
requestType!,
("ModelId", "gpt-4.1"),
("ReasoningSummary", ReasoningSummary.Detailed),
("ContextTier", ContextTier.LongContext));

var json = JsonSerializer.Serialize(request, requestType, options);
using var document = JsonDocument.Parse(json);
Assert.Equal("gpt-4.1", document.RootElement.GetProperty("modelId").GetString());
Assert.Equal("detailed", document.RootElement.GetProperty("reasoningSummary").GetString());
Assert.Equal("long_context", document.RootElement.GetProperty("contextTier").GetString());
}

[Fact]
public void SessionRequests_CanSerializePluginDirectoriesAndLargeOutput_WithSdkOptions()
{
Expand Down
24 changes: 6 additions & 18 deletions go/rpc/zrpc.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions go/session.go
Original file line number Diff line number Diff line change
Expand Up @@ -1495,6 +1495,9 @@ type SetModelOptions struct {
// ReasoningSummary sets the reasoning summary mode for the new model.
// Use ReasoningSummaryNone to suppress summary output regardless of whether reasoning is enabled.
ReasoningSummary *ReasoningSummary
// ContextTier pins the session to a context window tier for models that support it.
// Use ContextTierDefault or ContextTierLongContext for the currently known tiers.
ContextTier *ContextTier
// ModelCapabilities overrides individual model capabilities resolved by the runtime.
// Only non-nil fields are applied over the runtime-resolved capabilities.
ModelCapabilities *rpc.ModelCapabilitiesOverride
Expand All @@ -1516,6 +1519,7 @@ func (s *Session) SetModel(ctx context.Context, model string, opts *SetModelOpti
if opts != nil {
params.ReasoningEffort = opts.ReasoningEffort
params.ReasoningSummary = opts.ReasoningSummary
params.ContextTier = opts.ContextTier
params.ModelCapabilities = opts.ModelCapabilities
}
_, err := s.RPC.Model.SwitchTo(ctx, params)
Expand Down
Loading
Loading