-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Expand file tree
/
Copy pathTestHelper.cs
More file actions
101 lines (83 loc) · 3.44 KB
/
Copy pathTestHelper.cs
File metadata and controls
101 lines (83 loc) · 3.44 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
*--------------------------------------------------------------------------------------------*/
namespace GitHub.Copilot.SDK.Test.Harness;
public static class TestHelper
{
public static async Task<AssistantMessageEvent?> GetFinalAssistantMessageAsync(
CopilotSession session,
TimeSpan? timeout = null)
{
var tcs = new TaskCompletionSource<AssistantMessageEvent>();
using var cts = new CancellationTokenSource(timeout ?? TimeSpan.FromSeconds(60));
AssistantMessageEvent? finalAssistantMessage = null;
using var subscription = session.On(evt =>
{
switch (evt)
{
case AssistantMessageEvent msg:
finalAssistantMessage = msg;
break;
case SessionIdleEvent when finalAssistantMessage != null:
tcs.TrySetResult(finalAssistantMessage);
break;
case SessionErrorEvent error:
tcs.TrySetException(new Exception(error.Data.Message ?? "session error"));
break;
}
});
// Check existing messages
CheckExistingMessages();
cts.Token.Register(() => tcs.TrySetException(new TimeoutException("Timeout waiting for assistant message")));
return await tcs.Task;
async void CheckExistingMessages()
{
try
{
var existing = await GetExistingFinalResponseAsync(session);
if (existing != null) tcs.TrySetResult(existing);
}
catch (Exception ex)
{
tcs.TrySetException(ex);
}
}
}
private static async Task<AssistantMessageEvent?> GetExistingFinalResponseAsync(CopilotSession session)
{
var messages = (await session.GetMessagesAsync()).ToList();
var lastUserIdx = messages.FindLastIndex(m => m is UserMessageEvent);
var currentTurn = lastUserIdx < 0 ? messages : messages.Skip(lastUserIdx).ToList();
var error = currentTurn.OfType<SessionErrorEvent>().FirstOrDefault();
if (error != null) throw new Exception(error.Data.Message ?? "session error");
var idleIdx = currentTurn.FindIndex(m => m is SessionIdleEvent);
if (idleIdx == -1) return null;
for (var i = idleIdx - 1; i >= 0; i--)
{
if (currentTurn[i] is AssistantMessageEvent msg)
return msg;
}
return null;
}
public static async Task<T> GetNextEventOfTypeAsync<T>(
CopilotSession session,
TimeSpan? timeout = null) where T : SessionEvent
{
var tcs = new TaskCompletionSource<T>();
using var cts = new CancellationTokenSource(timeout ?? TimeSpan.FromSeconds(60));
using var subscription = session.On(evt =>
{
if (evt is T matched)
{
tcs.TrySetResult(matched);
}
else if (evt is SessionErrorEvent error)
{
tcs.TrySetException(new Exception(error.Data.Message ?? "session error"));
}
});
cts.Token.Register(() => tcs.TrySetException(
new TimeoutException($"Timeout waiting for event of type '{typeof(T).Name}'")));
return await tcs.Task;
}
}