Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
8 changes: 7 additions & 1 deletion dotnet/src/Session.cs
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ public async Task<string> SendAsync(MessageOptions options, CancellationToken ca
/// <param name="cancellationToken">A <see cref="CancellationToken"/> that can be used to cancel the operation.</param>
/// <returns>A task that resolves with the final assistant message event, or null if none was received.</returns>
/// <exception cref="TimeoutException">Thrown if the timeout is reached before the session becomes idle.</exception>
/// <exception cref="OperationCanceledException">Thrown if the <paramref name="cancellationToken"/> is cancelled.</exception>
/// <exception cref="InvalidOperationException">Thrown if the session has been disposed.</exception>
/// <remarks>
/// <para>
Expand Down Expand Up @@ -201,7 +202,12 @@ void Handler(SessionEvent evt)
cts.CancelAfter(effectiveTimeout);

using var registration = cts.Token.Register(() =>
tcs.TrySetException(new TimeoutException($"SendAndWaitAsync timed out after {effectiveTimeout}")));
{
if (cancellationToken.IsCancellationRequested)
tcs.TrySetCanceled(cancellationToken);
else
tcs.TrySetException(new TimeoutException($"SendAndWaitAsync timed out after {effectiveTimeout}"));
});
return await tcs.Task;
}

Expand Down
17 changes: 17 additions & 0 deletions dotnet/test/SessionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,23 @@ public async Task SendAndWait_Throws_On_Timeout()
Assert.Contains("timed out", ex.Message);
}

[Fact]
public async Task SendAndWait_Throws_OperationCanceledException_When_Token_Cancelled()
Copy link

Copilot AI Feb 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Method name uses Token_Cancelled (double-l). In .NET APIs and the rest of the framework, the standard spelling is Canceled (single-l), e.g. OperationCanceledException / CancellationToken. Consider renaming the test (and corresponding snapshot filename) to ..._When_Token_Canceled for consistency/searchability.

Suggested change
public async Task SendAndWait_Throws_OperationCanceledException_When_Token_Cancelled()
public async Task SendAndWait_Throws_OperationCanceledException_When_Token_Canceled()

Copilot uses AI. Check for mistakes.
{
var session = await Client.CreateSessionAsync();

using var cts = new CancellationTokenSource();

// Cancel before any response can arrive
var sendTask = session.SendAndWaitAsync(
new MessageOptions { Prompt = "Run 'sleep 2 && echo done'" },
cancellationToken: cts.Token);

cts.Cancel();

await Assert.ThrowsAsync<OperationCanceledException>(() => sendTask);
}

[Fact]
public async Task Should_Create_Session_With_Custom_Config_Dir()
{
Expand Down
Loading