Skip to content

Commit c70d632

Browse files
Update runtime to 1.0.12-0 (#927)
1 parent 3bcca2a commit c70d632

File tree

14 files changed

+106
-66
lines changed

14 files changed

+106
-66
lines changed

dotnet/src/Generated/SessionEvents.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1069,6 +1069,11 @@ public partial class SessionStartData
10691069
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
10701070
[JsonPropertyName("alreadyInUse")]
10711071
public bool? AlreadyInUse { get; set; }
1072+
1073+
/// <summary>Whether this session supports remote steering via Mission Control.</summary>
1074+
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
1075+
[JsonPropertyName("steerable")]
1076+
public bool? Steerable { get; set; }
10721077
}
10731078

10741079
/// <summary>Session resume metadata including current context and event count.</summary>

dotnet/test/Harness/TestHelper.cs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ public static class TestHelper
88
{
99
public static async Task<AssistantMessageEvent?> GetFinalAssistantMessageAsync(
1010
CopilotSession session,
11-
TimeSpan? timeout = null)
11+
TimeSpan? timeout = null,
12+
bool alreadyIdle = false)
1213
{
1314
var tcs = new TaskCompletionSource<AssistantMessageEvent>(TaskCreationOptions.RunContinuationsAsynchronously);
1415
using var cts = new CancellationTokenSource(timeout ?? TimeSpan.FromSeconds(60));
@@ -42,7 +43,7 @@ async void CheckExistingMessages()
4243
{
4344
try
4445
{
45-
var existing = await GetExistingFinalResponseAsync(session);
46+
var existing = await GetExistingFinalResponseAsync(session, alreadyIdle);
4647
if (existing != null) tcs.TrySetResult(existing);
4748
}
4849
catch (Exception ex)
@@ -52,7 +53,7 @@ async void CheckExistingMessages()
5253
}
5354
}
5455

55-
private static async Task<AssistantMessageEvent?> GetExistingFinalResponseAsync(CopilotSession session)
56+
private static async Task<AssistantMessageEvent?> GetExistingFinalResponseAsync(CopilotSession session, bool alreadyIdle)
5657
{
5758
var messages = (await session.GetMessagesAsync()).ToList();
5859

@@ -62,7 +63,7 @@ async void CheckExistingMessages()
6263
var error = currentTurn.OfType<SessionErrorEvent>().FirstOrDefault();
6364
if (error != null) throw new Exception(error.Data.Message ?? "session error");
6465

65-
var idleIdx = currentTurn.FindIndex(m => m is SessionIdleEvent);
66+
var idleIdx = alreadyIdle ? currentTurn.Count : currentTurn.FindIndex(m => m is SessionIdleEvent);
6667
if (idleIdx == -1) return null;
6768

6869
for (var i = idleIdx - 1; i >= 0; i--)

dotnet/test/SessionTests.cs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ public async Task Should_Resume_A_Session_Using_The_Same_Client()
196196
var session2 = await ResumeSessionAsync(sessionId);
197197
Assert.Equal(sessionId, session2.SessionId);
198198

199-
var answer2 = await TestHelper.GetFinalAssistantMessageAsync(session2);
199+
var answer2 = await TestHelper.GetFinalAssistantMessageAsync(session2, alreadyIdle: true);
200200
Assert.NotNull(answer2);
201201
Assert.Contains("2", answer2!.Data.Content ?? string.Empty);
202202

@@ -336,8 +336,10 @@ public async Task Should_Receive_Session_Events()
336336
// Events must be dispatched serially — never more than one handler invocation at a time.
337337
Assert.Equal(1, maxConcurrent);
338338

339-
// Verify the assistant response contains the expected answer
340-
var assistantMessage = await TestHelper.GetFinalAssistantMessageAsync(session);
339+
// Verify the assistant response contains the expected answer.
340+
// session.idle is ephemeral and not in getEvents(), but we already
341+
// confirmed idle via the live event handler above.
342+
var assistantMessage = await TestHelper.GetFinalAssistantMessageAsync(session, alreadyIdle: true);
341343
Assert.NotNull(assistantMessage);
342344
Assert.Contains("300", assistantMessage!.Data.Content);
343345

go/generated_session_events.go

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

go/internal/e2e/session_test.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -407,7 +407,7 @@ func TestSession(t *testing.T) {
407407
t.Errorf("Expected resumed session ID to match, got %q vs %q", session2.SessionID, sessionID)
408408
}
409409

410-
answer2, err := testharness.GetFinalAssistantMessage(t.Context(), session2)
410+
answer2, err := testharness.GetFinalAssistantMessage(t.Context(), session2, true)
411411
if err != nil {
412412
t.Fatalf("Failed to get assistant message from resumed session: %v", err)
413413
}
@@ -713,8 +713,10 @@ func TestSession(t *testing.T) {
713713
t.Error("Expected to receive session.idle event")
714714
}
715715

716-
// Verify the assistant response contains the expected answer
717-
assistantMessage, err := testharness.GetFinalAssistantMessage(t.Context(), session)
716+
// Verify the assistant response contains the expected answer.
717+
// session.idle is ephemeral and not in GetMessages(), but we already
718+
// confirmed idle via the live event handler above.
719+
assistantMessage, err := testharness.GetFinalAssistantMessage(t.Context(), session, true)
718720
if err != nil {
719721
t.Fatalf("Failed to get assistant message: %v", err)
720722
}

go/internal/e2e/testharness/helper.go

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@ import (
99
)
1010

1111
// GetFinalAssistantMessage waits for and returns the final assistant message from a session turn.
12-
func GetFinalAssistantMessage(ctx context.Context, session *copilot.Session) (*copilot.SessionEvent, error) {
12+
// If alreadyIdle is true, skip waiting for session.idle (useful for resumed sessions where the
13+
// idle event was ephemeral and not persisted in the event history).
14+
func GetFinalAssistantMessage(ctx context.Context, session *copilot.Session, alreadyIdle ...bool) (*copilot.SessionEvent, error) {
1315
result := make(chan *copilot.SessionEvent, 1)
1416
errCh := make(chan error, 1)
1517

@@ -34,8 +36,9 @@ func GetFinalAssistantMessage(ctx context.Context, session *copilot.Session) (*c
3436
defer unsubscribe()
3537

3638
// Also check existing messages in case the response already arrived
39+
isAlreadyIdle := len(alreadyIdle) > 0 && alreadyIdle[0]
3740
go func() {
38-
existing, err := getExistingFinalResponse(ctx, session)
41+
existing, err := getExistingFinalResponse(ctx, session, isAlreadyIdle)
3942
if err != nil {
4043
errCh <- err
4144
return
@@ -90,7 +93,7 @@ func GetNextEventOfType(session *copilot.Session, eventType copilot.SessionEvent
9093
}
9194
}
9295

93-
func getExistingFinalResponse(ctx context.Context, session *copilot.Session) (*copilot.SessionEvent, error) {
96+
func getExistingFinalResponse(ctx context.Context, session *copilot.Session, alreadyIdle bool) (*copilot.SessionEvent, error) {
9497
messages, err := session.GetMessages(ctx)
9598
if err != nil {
9699
return nil, err
@@ -125,10 +128,14 @@ func getExistingFinalResponse(ctx context.Context, session *copilot.Session) (*c
125128

126129
// Find session.idle and get last assistant message before it
127130
sessionIdleIndex := -1
128-
for i, msg := range currentTurnMessages {
129-
if msg.Type == "session.idle" {
130-
sessionIdleIndex = i
131-
break
131+
if alreadyIdle {
132+
sessionIdleIndex = len(currentTurnMessages)
133+
} else {
134+
for i, msg := range currentTurnMessages {
135+
if msg.Type == "session.idle" {
136+
sessionIdleIndex = i
137+
break
138+
}
132139
}
133140
}
134141

nodejs/package-lock.json

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

nodejs/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@
5656
"author": "GitHub",
5757
"license": "MIT",
5858
"dependencies": {
59-
"@github/copilot": "^1.0.11",
59+
"@github/copilot": "^1.0.12-0",
6060
"vscode-jsonrpc": "^8.2.1",
6161
"zod": "^4.3.6"
6262
},

nodejs/src/generated/session-events.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,10 @@ export type SessionEvent =
9191
* Whether the session was already in use by another client at start time
9292
*/
9393
alreadyInUse?: boolean;
94+
/**
95+
* Whether this session supports remote steering via Mission Control
96+
*/
97+
steerable?: boolean;
9498
};
9599
}
96100
| {

nodejs/test/e2e/harness/sdkTestHelper.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,13 @@
55
import { AssistantMessageEvent, CopilotSession, SessionEvent } from "../../../src";
66

77
export async function getFinalAssistantMessage(
8-
session: CopilotSession
8+
session: CopilotSession,
9+
{ alreadyIdle = false }: { alreadyIdle?: boolean } = {}
910
): Promise<AssistantMessageEvent> {
1011
// We don't know whether the answer has already arrived or not, so race both possibilities
1112
return new Promise<AssistantMessageEvent>(async (resolve, reject) => {
1213
getFutureFinalResponse(session).then(resolve).catch(reject);
13-
getExistingFinalResponse(session)
14+
getExistingFinalResponse(session, alreadyIdle)
1415
.then((msg) => {
1516
if (msg) {
1617
resolve(msg);
@@ -21,7 +22,8 @@ export async function getFinalAssistantMessage(
2122
}
2223

2324
function getExistingFinalResponse(
24-
session: CopilotSession
25+
session: CopilotSession,
26+
alreadyIdle: boolean = false
2527
): Promise<AssistantMessageEvent | undefined> {
2628
return new Promise<AssistantMessageEvent | undefined>(async (resolve, reject) => {
2729
const messages = await session.getMessages();
@@ -37,9 +39,9 @@ function getExistingFinalResponse(
3739
return;
3840
}
3941

40-
const sessionIdleMessageIndex = currentTurnMessages.findIndex(
41-
(m) => m.type === "session.idle"
42-
);
42+
const sessionIdleMessageIndex = alreadyIdle
43+
? currentTurnMessages.length
44+
: currentTurnMessages.findIndex((m) => m.type === "session.idle");
4345
if (sessionIdleMessageIndex !== -1) {
4446
const lastAssistantMessage = currentTurnMessages
4547
.slice(0, sessionIdleMessageIndex)

0 commit comments

Comments
 (0)