diff --git a/dotnet/src/Client.cs b/dotnet/src/Client.cs index 68d48f8..8c61c73 100644 --- a/dotnet/src/Client.cs +++ b/dotnet/src/Client.cs @@ -759,12 +759,13 @@ public async ValueTask DisposeAsync() private class RpcHandler(CopilotClient client) { [JsonRpcMethod("session.event")] - public void OnSessionEvent(SessionEventNotification notification) + public void OnSessionEvent(string sessionId, + JsonElement? @event) { - var session = client.GetSession(notification.SessionId); - if (session != null && notification.Event != null) + var session = client.GetSession(sessionId); + if (session != null && @event != null) { - var evt = SessionEvent.FromJson(notification.Event.ToString()); + var evt = SessionEvent.FromJson(@event.Value.GetRawText()); session.DispatchEvent(evt); } } @@ -957,10 +958,6 @@ private record DeleteSessionResponse( private record ListSessionsResponse( List Sessions); - private record SessionEventNotification( - string SessionId, - JToken? Event); - private record ToolCallResponse( ToolResultObject? Result); diff --git a/dotnet/test/SessionTests.cs b/dotnet/test/SessionTests.cs index 4b87fc3..f3425c6 100644 --- a/dotnet/test/SessionTests.cs +++ b/dotnet/test/SessionTests.cs @@ -285,4 +285,36 @@ public async Task Should_Pass_Streaming_Option_To_Session_Creation() Assert.NotNull(assistantMessage); Assert.Contains("2", assistantMessage!.Data.Content); } + + [Fact] + public async Task Should_SessionEvt_Subscribed() + { + var session = await Client.CreateSessionAsync(); + var receivedEvents = new List(); + var idleReceived = new TaskCompletionSource(); + + session.On(evt => + { + receivedEvents.Add(evt); + if (evt is SessionIdleEvent) + { + idleReceived.TrySetResult(true); + } + }); + + // Send a message to trigger events + await session.SendAsync(new MessageOptions { Prompt = "Hello!" }); + + // Wait for session to become idle (indicating message processing is complete) + var completed = await Task.WhenAny(idleReceived.Task, Task.Delay(TimeSpan.FromSeconds(60))); + Assert.Equal(idleReceived.Task, completed); + + // Should have received multiple events (user message, assistant message, idle, etc.) + Assert.NotEmpty(receivedEvents); + Assert.Contains(receivedEvents, evt => evt is UserMessageEvent); + Assert.Contains(receivedEvents, evt => evt is AssistantMessageEvent); + Assert.Contains(receivedEvents, evt => evt is SessionIdleEvent); + + await session.DisposeAsync(); + } }