Skip to content

Commit 4018d92

Browse files
github-actions[bot]stephentoubdmytrostruk
authored
Update @github/copilot to 1.0.57-4 (#1522)
* Update @github/copilot to 1.0.57-4 - Updated nodejs and test harness dependencies - Re-ran code generators - Formatted generated code * Added context tier to set model method * Fixed tests * Small fix --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Stephen Toub <stoub@microsoft.com> Co-authored-by: Dmytro Struk <13853051+dmytrostruk@users.noreply.github.com>
1 parent a488081 commit 4018d92

21 files changed

Lines changed: 314 additions & 95 deletions

File tree

dotnet/src/Generated/Rpc.cs

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dotnet/src/Session.cs

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1576,14 +1576,40 @@ public async Task AbortAsync(CancellationToken cancellationToken = default)
15761576
/// <code>
15771577
/// await session.SetModelAsync("gpt-4.1");
15781578
/// await session.SetModelAsync("claude-sonnet-4.6", "high");
1579+
/// await session.SetModelAsync("gpt-4.1", new SetModelOptions { ContextTier = ContextTier.LongContext });
15791580
/// </code>
15801581
/// </example>
1581-
public async Task SetModelAsync(string model, string? reasoningEffort, ModelCapabilitiesOverride? modelCapabilities = null, CancellationToken cancellationToken = default)
1582+
public Task SetModelAsync(string model, string? reasoningEffort, ModelCapabilitiesOverride? modelCapabilities = null, CancellationToken cancellationToken = default)
1583+
{
1584+
return SetModelAsync(
1585+
model,
1586+
new SetModelOptions
1587+
{
1588+
ReasoningEffort = reasoningEffort,
1589+
ModelCapabilities = modelCapabilities,
1590+
},
1591+
cancellationToken);
1592+
}
1593+
1594+
/// <summary>
1595+
/// Changes the model for this session.
1596+
/// The new model takes effect for the next message. Conversation history is preserved.
1597+
/// </summary>
1598+
/// <param name="model">Model ID to switch to (e.g., "gpt-4.1").</param>
1599+
/// <param name="options">Settings for the new model.</param>
1600+
/// <param name="cancellationToken">Optional cancellation token.</param>
1601+
public async Task SetModelAsync(string model, SetModelOptions options, CancellationToken cancellationToken = default)
15821602
{
15831603
ArgumentNullException.ThrowIfNull(model);
15841604
ThrowIfDisposed();
15851605

1586-
await Rpc.Model.SwitchToAsync(model, reasoningEffort, reasoningSummary: null, modelCapabilities: modelCapabilities, cancellationToken: cancellationToken);
1606+
await Rpc.Model.SwitchToAsync(
1607+
model,
1608+
options.ReasoningEffort,
1609+
options.ReasoningSummary,
1610+
options.ModelCapabilities,
1611+
options.ContextTier,
1612+
cancellationToken);
15871613
}
15881614

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

1596-
return SetModelAsync(model, reasoningEffort: null, modelCapabilities: null, cancellationToken);
1622+
return SetModelAsync(model, new SetModelOptions(), cancellationToken);
15971623
}
15981624

15991625
/// <summary>

dotnet/src/Types.cs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2390,6 +2390,34 @@ public sealed class CloudSessionOptions
23902390
public CloudSessionRepository? Repository { get; set; }
23912391
}
23922392

2393+
/// <summary>
2394+
/// Optional settings for <see cref="CopilotSession.SetModelAsync(string, SetModelOptions, CancellationToken)"/>.
2395+
/// </summary>
2396+
public struct SetModelOptions
2397+
{
2398+
/// <summary>
2399+
/// Reasoning effort level for the new model.
2400+
/// </summary>
2401+
public string? ReasoningEffort { get; set; }
2402+
2403+
/// <summary>
2404+
/// Reasoning summary mode for models that support configurable reasoning summaries.
2405+
/// </summary>
2406+
/// <remarks>
2407+
/// Use <see cref="ReasoningSummary.None"/> to suppress summary output regardless of whether reasoning is enabled.
2408+
/// </remarks>
2409+
public ReasoningSummary? ReasoningSummary { get; set; }
2410+
2411+
/// <summary>
2412+
/// Explicit context window tier for models that support it.
2413+
/// Leave unset to use normal model behavior with no explicit tier.
2414+
/// </summary>
2415+
public ContextTier? ContextTier { get; set; }
2416+
2417+
/// <summary>Per-property overrides for model capabilities, deep-merged over runtime defaults.</summary>
2418+
public ModelCapabilitiesOverride? ModelCapabilities { get; set; }
2419+
}
2420+
23932421
/// <summary>
23942422
/// Shared configuration properties for creating or resuming a Copilot session.
23952423
/// Use <see cref="SessionConfig"/> when creating a new session, or

go/rpc/zrpc.go

Lines changed: 2 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

go/session.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1495,6 +1495,9 @@ type SetModelOptions struct {
14951495
// ReasoningSummary sets the reasoning summary mode for the new model.
14961496
// Use ReasoningSummaryNone to suppress summary output regardless of whether reasoning is enabled.
14971497
ReasoningSummary *ReasoningSummary
1498+
// ContextTier explicitly selects a context window tier for models that support it.
1499+
// Leave nil to use normal model behavior with no explicit tier.
1500+
ContextTier *ContextTier
14981501
// ModelCapabilities overrides individual model capabilities resolved by the runtime.
14991502
// Only non-nil fields are applied over the runtime-resolved capabilities.
15001503
ModelCapabilities *rpc.ModelCapabilitiesOverride
@@ -1516,6 +1519,7 @@ func (s *Session) SetModel(ctx context.Context, model string, opts *SetModelOpti
15161519
if opts != nil {
15171520
params.ReasoningEffort = opts.ReasoningEffort
15181521
params.ReasoningSummary = opts.ReasoningSummary
1522+
params.ContextTier = opts.ContextTier
15191523
params.ModelCapabilities = opts.ModelCapabilities
15201524
}
15211525
_, err := s.RPC.Model.SwitchTo(ctx, params)

go/session_test.go

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,20 @@
11
package copilot
22

33
import (
4+
"bufio"
5+
"context"
46
"encoding/json"
57
"fmt"
8+
"io"
9+
"strconv"
610
"strings"
711
"sync"
812
"sync/atomic"
913
"testing"
1014
"time"
15+
16+
"github.com/github/copilot-sdk/go/internal/jsonrpc2"
17+
"github.com/github/copilot-sdk/go/rpc"
1118
)
1219

1320
// newTestSession creates a session with an event channel and starts the consumer goroutine.
@@ -30,6 +37,136 @@ func ptr[T any](value T) *T {
3037
return &value
3138
}
3239

40+
func TestSession_SetModelForwardsContextTier(t *testing.T) {
41+
tier := ContextTierLongContext
42+
params := captureSetModelRequest(t, &SetModelOptions{ContextTier: &tier})
43+
44+
if params["sessionId"] != "session-1" {
45+
t.Fatalf("expected sessionId session-1, got %v", params["sessionId"])
46+
}
47+
if params["modelId"] != "gpt-4.1" {
48+
t.Fatalf("expected modelId gpt-4.1, got %v", params["modelId"])
49+
}
50+
if params["contextTier"] != "long_context" {
51+
t.Fatalf("expected contextTier long_context, got %v", params["contextTier"])
52+
}
53+
}
54+
55+
func TestSession_SetModelOmitsContextTierWhenUnset(t *testing.T) {
56+
params := captureSetModelRequest(t, nil)
57+
58+
if _, ok := params["contextTier"]; ok {
59+
t.Fatalf("expected contextTier to be omitted, got %v", params["contextTier"])
60+
}
61+
}
62+
63+
func captureSetModelRequest(t *testing.T, opts *SetModelOptions) map[string]any {
64+
t.Helper()
65+
66+
stdinR, stdinW := io.Pipe()
67+
stdoutR, stdoutW := io.Pipe()
68+
defer stdinR.Close()
69+
defer stdinW.Close()
70+
defer stdoutR.Close()
71+
defer stdoutW.Close()
72+
73+
client := jsonrpc2.NewClient(stdinW, stdoutR)
74+
client.Start()
75+
defer client.Stop()
76+
77+
paramsCh := make(chan map[string]any, 1)
78+
errCh := make(chan error, 1)
79+
80+
go func() {
81+
frame, err := readTestJSONRPCFrame(stdinR)
82+
if err != nil {
83+
errCh <- err
84+
return
85+
}
86+
87+
var request struct {
88+
ID json.RawMessage `json:"id"`
89+
Method string `json:"method"`
90+
Params map[string]any `json:"params"`
91+
}
92+
if err := json.Unmarshal(frame, &request); err != nil {
93+
errCh <- err
94+
return
95+
}
96+
if request.Method != "session.model.switchTo" {
97+
errCh <- fmt.Errorf("expected session.model.switchTo, got %s", request.Method)
98+
return
99+
}
100+
101+
paramsCh <- request.Params
102+
103+
response := map[string]any{
104+
"jsonrpc": "2.0",
105+
"id": json.RawMessage(request.ID),
106+
"result": map[string]any{},
107+
}
108+
data, err := json.Marshal(response)
109+
if err != nil {
110+
errCh <- err
111+
return
112+
}
113+
if _, err := fmt.Fprintf(stdoutW, "Content-Length: %d\r\n\r\n%s", len(data), data); err != nil {
114+
errCh <- err
115+
return
116+
}
117+
}()
118+
119+
session := &Session{
120+
SessionID: "session-1",
121+
client: client,
122+
RPC: rpc.NewSessionRpc(client, "session-1"),
123+
}
124+
if err := session.SetModel(context.Background(), "gpt-4.1", opts); err != nil {
125+
t.Fatalf("SetModel failed: %v", err)
126+
}
127+
128+
select {
129+
case params := <-paramsCh:
130+
return params
131+
case err := <-errCh:
132+
t.Fatal(err)
133+
case <-time.After(2 * time.Second):
134+
t.Fatal("timed out waiting for session.model.switchTo request")
135+
}
136+
return nil
137+
}
138+
139+
func readTestJSONRPCFrame(r io.Reader) ([]byte, error) {
140+
reader := bufio.NewReader(r)
141+
var contentLength int
142+
for {
143+
line, err := reader.ReadString('\n')
144+
if err != nil {
145+
return nil, err
146+
}
147+
line = strings.TrimSpace(line)
148+
if line == "" {
149+
break
150+
}
151+
name, value, ok := strings.Cut(line, ":")
152+
if !ok {
153+
return nil, fmt.Errorf("invalid header line %q", line)
154+
}
155+
if name == "Content-Length" {
156+
contentLength, err = strconv.Atoi(strings.TrimSpace(value))
157+
if err != nil {
158+
return nil, err
159+
}
160+
}
161+
}
162+
if contentLength == 0 {
163+
return nil, fmt.Errorf("missing Content-Length header")
164+
}
165+
data := make([]byte, contentLength)
166+
_, err := io.ReadFull(reader, data)
167+
return data, err
168+
}
169+
33170
func TestSession_On(t *testing.T) {
34171
t.Run("multiple handlers all receive events", func(t *testing.T) {
35172
session, cleanup := newTestSession()

0 commit comments

Comments
 (0)