Keep AutoDetect channel open after provisional SSE failure (#1768)

Copilot-Session: c0e71f8e-9302-4c6b-835d-223dec24d37d
This commit is contained in:
Pranav Senthilnathan 2026-07-29 12:31:53 -07:00 • committed by GitHub
commit f8e9e1d23f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -23,6 +23,7 @@ internal sealed partial class SseClientSessionTransport : TransportBase
private Task? _receiveTask;
private readonly ILogger _logger;
private readonly TaskCompletionSource<bool> _connectionEstablished;
private volatile bool _sseAdopted;
/// <summary>
/// SSE transport for a single session. Unlike stdio it does not launch a process, but connects to an existing server.
@ -107,6 +108,8 @@ internal sealed partial class SseClientSessionTransport : TransportBase
throw HttpResponseMessageExtensions.CreateHttpRequestException(response, responseBody);
}
_sseAdopted = true;
}
private async Task CloseAsync()
@ -129,7 +132,7 @@ internal sealed partial class SseClientSessionTransport : TransportBase
}
finally
{
SetDisconnected(new ClientTransportClosedException(new HttpClientCompletionDetails()));
SetSseDisconnected(new ClientTransportClosedException(new HttpClientCompletionDetails()));
}
}
@ -190,7 +193,7 @@ internal sealed partial class SseClientSessionTransport : TransportBase
}
else
{
SetDisconnected(new ClientTransportClosedException(new HttpClientCompletionDetails
SetSseDisconnected(new ClientTransportClosedException(new HttpClientCompletionDetails
{
HttpStatusCode = failureStatusCode,
Exception = ex,
@ -202,7 +205,18 @@ internal sealed partial class SseClientSessionTransport : TransportBase
}
finally
{
SetDisconnected(new ClientTransportClosedException(new HttpClientCompletionDetails()));
SetSseDisconnected(new ClientTransportClosedException(new HttpClientCompletionDetails()));
}
}
private void SetSseDisconnected(Exception error)
{
// If AutoDetect is still probing SSE, leave its shared message channel open so it can
// retry with another transport. A successful POST means SSE was selected and owns the
// channel from that point on, matching Streamable HTTP's adoption behavior.
if (_options.TransportMode is not HttpTransportMode.AutoDetect || _sseAdopted)
{
SetDisconnected(error);
}
}