Skip to content

Commit f086ca0

Browse files
Rename WebSocket handler types to CopilotWebSocketHandler + CopilotWebSocketForwarder
Unifies the WebSocket interception handler naming across all six SDKs so the protocol/contract is always CopilotWebSocketHandler and the default forwarding implementation is always CopilotWebSocketForwarder. - OO SDKs (Node, .NET, Java, Python): abstract CopilotWebSocketHandlerBase -> CopilotWebSocketHandler (protocol); concrete CopilotWebSocketHandler -> CopilotWebSocketForwarder (forwarder). Java files renamed accordingly. - Go/Rust: concrete ForwardingCopilotWebSocketHandler -> CopilotWebSocketForwarder (plus constructor/builder); the CopilotWebSocketHandler interface/trait is unchanged. Also rename the Rust CopilotRequestTransport::Websocket enum variant to WebSocket for proper-noun consistency. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent e120edb commit f086ca0

20 files changed

Lines changed: 355 additions & 356 deletions

dotnet/src/CopilotRequestHandler.cs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -113,11 +113,11 @@ public sealed class CopilotWebSocketCloseStatus
113113
/// to any upstream server on its own. Subclass it directly only to service a
114114
/// fully synthetic connection yourself. For the common case of mutating and
115115
/// forwarding traffic to the real upstream, subclass
116-
/// <see cref="CopilotWebSocketHandler"/> instead, which connects upstream and
116+
/// <see cref="CopilotWebSocketForwarder"/> instead, which connects upstream and
117117
/// forwards by default.
118118
/// </summary>
119119
[Experimental(Diagnostics.Experimental)]
120-
public abstract class CopilotWebSocketHandlerBase : IAsyncDisposable
120+
public abstract class CopilotWebSocketHandler : IAsyncDisposable
121121
{
122122
private readonly TaskCompletionSource<CopilotWebSocketCloseStatus> _completion =
123123
new(TaskCreationOptions.RunContinuationsAsynchronously);
@@ -132,7 +132,7 @@ public abstract class CopilotWebSocketHandlerBase : IAsyncDisposable
132132
/// <summary>
133133
/// Initializes a per-connection handler for the supplied request context.
134134
/// </summary>
135-
protected CopilotWebSocketHandlerBase(CopilotRequestContext context)
135+
protected CopilotWebSocketHandler(CopilotRequestContext context)
136136
{
137137
Context = context;
138138
_ = context.WebSocketResponse ?? throw new InvalidOperationException("WebSocket response bridge is not attached.");
@@ -195,11 +195,11 @@ public virtual async ValueTask DisposeAsync()
195195
/// <see cref="CopilotRequestHandler.OpenWebSocketAsync"/>. Override nothing to
196196
/// get full pass-through. To mutate traffic, subclass this type and override a
197197
/// send method, then call the base implementation to keep forwarding upstream.
198-
/// (Subclassing <see cref="CopilotWebSocketHandlerBase"/> instead would drop
198+
/// (Subclassing <see cref="CopilotWebSocketHandler"/> instead would drop
199199
/// forwarding entirely.)
200200
/// </summary>
201201
[Experimental(Diagnostics.Experimental)]
202-
public class CopilotWebSocketHandler : CopilotWebSocketHandlerBase
202+
public class CopilotWebSocketForwarder : CopilotWebSocketHandler
203203
{
204204
private readonly string _url;
205205
private readonly IReadOnlyDictionary<string, IReadOnlyList<string>> _headers;
@@ -212,7 +212,7 @@ public class CopilotWebSocketHandler : CopilotWebSocketHandlerBase
212212
/// demand using the supplied URL/headers (or the values from
213213
/// <paramref name="context"/> when omitted).
214214
/// </summary>
215-
public CopilotWebSocketHandler(
215+
public CopilotWebSocketForwarder(
216216
CopilotRequestContext context,
217217
string? url = null,
218218
IReadOnlyDictionary<string, IReadOnlyList<string>>? headers = null)
@@ -440,11 +440,11 @@ protected virtual Task<HttpResponseMessage> SendRequestAsync(HttpRequestMessage
440440

441441
/// <summary>
442442
/// Open the upstream WebSocket connection. Override to return a custom
443-
/// <see cref="CopilotWebSocketHandlerBase"/> or to construct a
444-
/// <see cref="CopilotWebSocketHandler"/> against a rewritten URL.
443+
/// <see cref="CopilotWebSocketHandler"/> or to construct a
444+
/// <see cref="CopilotWebSocketForwarder"/> against a rewritten URL.
445445
/// </summary>
446-
protected virtual Task<CopilotWebSocketHandlerBase> OpenWebSocketAsync(CopilotRequestContext ctx) =>
447-
Task.FromResult<CopilotWebSocketHandlerBase>(new CopilotWebSocketHandler(ctx));
446+
protected virtual Task<CopilotWebSocketHandler> OpenWebSocketAsync(CopilotRequestContext ctx) =>
447+
Task.FromResult<CopilotWebSocketHandler>(new CopilotWebSocketForwarder(ctx));
448448

449449
/// <summary>
450450
/// Entry point invoked by the adapter once per intercepted request. Routes to

dotnet/test/E2E/CopilotRequestWebSocketE2ETests.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ namespace GitHub.Copilot.Test.E2E;
2222
/// transports against an in-process fake upstream: model-layer GETs and the
2323
/// single-shot HTTP <c>/responses</c> call are forwarded over HTTP, while the
2424
/// main turn flows over a real WebSocket opened by a
25-
/// <see cref="CopilotWebSocketHandler"/>.
25+
/// <see cref="CopilotWebSocketForwarder"/>.
2626
/// </summary>
2727
/// <remarks>
2828
/// This is the regression test for the WebSocket upgrade deadlock: the runtime
@@ -101,7 +101,7 @@ internal sealed class HandlerCounters
101101
/// A <see cref="CopilotRequestHandler"/> that points every intercepted request at
102102
/// the in-process <see cref="FakeCopilotUpstream"/>: HTTP requests are rewritten
103103
/// and forwarded by the base class, and WebSocket connections are opened against
104-
/// the rewritten URL via a counting <see cref="CopilotWebSocketHandler"/>.
104+
/// the rewritten URL via a counting <see cref="CopilotWebSocketForwarder"/>.
105105
/// </summary>
106106
internal sealed class ForwardingUpstreamHandler(string upstreamBaseUrl, HandlerCounters counters) : CopilotRequestHandler
107107
{
@@ -114,10 +114,10 @@ protected override Task<HttpResponseMessage> SendRequestAsync(HttpRequestMessage
114114
return base.SendRequestAsync(request, ctx);
115115
}
116116

117-
protected override Task<CopilotWebSocketHandlerBase> OpenWebSocketAsync(CopilotRequestContext ctx)
117+
protected override Task<CopilotWebSocketHandler> OpenWebSocketAsync(CopilotRequestContext ctx)
118118
{
119119
var wsUrl = Rewrite(new Uri(ctx.Url)).ToString();
120-
return Task.FromResult<CopilotWebSocketHandlerBase>(new CountingForwardingWebSocketHandler(ctx, wsUrl, counters));
120+
return Task.FromResult<CopilotWebSocketHandler>(new CountingForwardingWebSocketHandler(ctx, wsUrl, counters));
121121
}
122122

123123
private Uri Rewrite(Uri original) => new UriBuilder(original)
@@ -135,7 +135,7 @@ internal sealed class CountingForwardingWebSocketHandler(
135135
CopilotRequestContext context,
136136
string url,
137137
HandlerCounters counters)
138-
: CopilotWebSocketHandler(context, url)
138+
: CopilotWebSocketForwarder(context, url)
139139
{
140140
public override Task SendRequestMessageAsync(CopilotWebSocketMessage message)
141141
{

go/copilot_request_handler.go

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ type CopilotRequestHandler struct {
108108
// used. RoundTrip is called directly, so redirects are not followed.
109109
Transport http.RoundTripper
110110
// OpenWebSocket returns a per-connection WebSocket handler. When nil a
111-
// transparent [ForwardingCopilotWebSocketHandler] to the request URL is opened.
111+
// transparent [CopilotWebSocketForwarder] to the request URL is opened.
112112
OpenWebSocket func(ctx *CopilotRequestContext) (CopilotWebSocketHandler, error)
113113
}
114114

@@ -124,7 +124,7 @@ type WebSocketResponseWriter interface {
124124

125125
// CopilotWebSocketHandler is a per-connection WebSocket handler returned by
126126
// [CopilotRequestHandler.OpenWebSocket]. The default implementation is
127-
// [ForwardingCopilotWebSocketHandler]; a full transport replacement implements
127+
// [CopilotWebSocketForwarder]; a full transport replacement implements
128128
// this interface directly.
129129
type CopilotWebSocketHandler interface {
130130
// Open establishes the connection and starts forwarding upstream→runtime
@@ -255,7 +255,7 @@ func (h *CopilotRequestHandler) handleWebSocket(rctx *CopilotRequestContext, sin
255255
if h.OpenWebSocket != nil {
256256
handler, err = h.OpenWebSocket(rctx)
257257
} else {
258-
handler = NewForwardingCopilotWebSocketHandler(rctx.URL, rctx.Headers)
258+
handler = NewCopilotWebSocketForwarder(rctx.URL, rctx.Headers)
259259
}
260260
if err != nil {
261261
return err
@@ -365,11 +365,11 @@ func (w *wsResponseWriter) fail(message string, code string) error {
365365
return w.sink.sinkError(message, code)
366366
}
367367

368-
// ForwardingCopilotWebSocketHandler is the default [CopilotWebSocketHandler]:
368+
// CopilotWebSocketForwarder is the default [CopilotWebSocketHandler]:
369369
// it dials the real upstream and runs a receive loop forwarding upstream→runtime
370370
// messages. Set OnSendRequestMessage / OnSendResponseMessage to observe,
371371
// transform, or drop messages in either direction.
372-
type ForwardingCopilotWebSocketHandler struct {
372+
type CopilotWebSocketForwarder struct {
373373
URL string
374374
Headers http.Header
375375
// OnSendRequestMessage observes or transforms each runtime→upstream frame.
@@ -390,13 +390,13 @@ type ForwardingCopilotWebSocketHandler struct {
390390
closeOnce sync.Once
391391
}
392392

393-
// NewForwardingCopilotWebSocketHandler creates a forwarding handler targeting
393+
// NewCopilotWebSocketForwarder creates a forwarding handler targeting
394394
// url with the given handshake headers.
395-
func NewForwardingCopilotWebSocketHandler(url string, headers http.Header) *ForwardingCopilotWebSocketHandler {
396-
return &ForwardingCopilotWebSocketHandler{URL: url, Headers: headers, done: make(chan struct{})}
395+
func NewCopilotWebSocketForwarder(url string, headers http.Header) *CopilotWebSocketForwarder {
396+
return &CopilotWebSocketForwarder{URL: url, Headers: headers, done: make(chan struct{})}
397397
}
398398

399-
func (f *ForwardingCopilotWebSocketHandler) Open(ctx context.Context, resp WebSocketResponseWriter) error {
399+
func (f *CopilotWebSocketForwarder) Open(ctx context.Context, resp WebSocketResponseWriter) error {
400400
f.resp = resp
401401
if f.done == nil {
402402
f.done = make(chan struct{})
@@ -412,7 +412,7 @@ func (f *ForwardingCopilotWebSocketHandler) Open(ctx context.Context, resp WebSo
412412
return nil
413413
}
414414

415-
func (f *ForwardingCopilotWebSocketHandler) dialHeaders() http.Header {
415+
func (f *CopilotWebSocketForwarder) dialHeaders() http.Header {
416416
out := http.Header{}
417417
for name, values := range f.Headers {
418418
if isForbiddenRequestHeader(name) {
@@ -425,7 +425,7 @@ func (f *ForwardingCopilotWebSocketHandler) dialHeaders() http.Header {
425425
return out
426426
}
427427

428-
func (f *ForwardingCopilotWebSocketHandler) receiveLoop(ctx context.Context) {
428+
func (f *CopilotWebSocketForwarder) receiveLoop(ctx context.Context) {
429429
defer close(f.done)
430430
for {
431431
typ, data, err := f.conn.Read(ctx)
@@ -455,7 +455,7 @@ func (f *ForwardingCopilotWebSocketHandler) receiveLoop(ctx context.Context) {
455455
}
456456
}
457457

458-
func (f *ForwardingCopilotWebSocketHandler) SendRequestMessage(ctx context.Context, msg CopilotWebSocketMessage) error {
458+
func (f *CopilotWebSocketForwarder) SendRequestMessage(ctx context.Context, msg CopilotWebSocketMessage) error {
459459
out := msg
460460
if f.OnSendRequestMessage != nil {
461461
transformed := f.OnSendRequestMessage(msg)
@@ -474,10 +474,10 @@ func (f *ForwardingCopilotWebSocketHandler) SendRequestMessage(ctx context.Conte
474474
return f.conn.Write(ctx, msgType, out.Data)
475475
}
476476

477-
func (f *ForwardingCopilotWebSocketHandler) Done() <-chan struct{} { return f.done }
478-
func (f *ForwardingCopilotWebSocketHandler) Err() error { return f.err }
477+
func (f *CopilotWebSocketForwarder) Done() <-chan struct{} { return f.done }
478+
func (f *CopilotWebSocketForwarder) Err() error { return f.err }
479479

480-
func (f *ForwardingCopilotWebSocketHandler) Close() error {
480+
func (f *CopilotWebSocketForwarder) Close() error {
481481
f.closeOnce.Do(func() {
482482
if f.conn != nil {
483483
_ = f.conn.Close(websocket.StatusNormalClosure, "")

go/internal/e2e/copilot_request_handler_e2e_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ func TestCopilotRequestHandler(t *testing.T) {
145145
}
146146
parsed.Scheme = wsBase.Scheme
147147
parsed.Host = wsBase.Host
148-
fwd := copilot.NewForwardingCopilotWebSocketHandler(parsed.String(), rctx.Headers)
148+
fwd := copilot.NewCopilotWebSocketForwarder(parsed.String(), rctx.Headers)
149149
fwd.OnSendRequestMessage = func(msg copilot.CopilotWebSocketMessage) *copilot.CopilotWebSocketMessage {
150150
counters.wsRequestMessages.Add(1)
151151
return &msg

java/src/main/java/com/github/copilot/CopilotRequestHandler.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
* model-layer HTTP and WebSocket traffic through this handler instead of
2727
* issuing the calls itself. Subclass and override {@link #sendRequest} to
2828
* mutate or replace HTTP calls, or {@link #openWebSocket} to mutate the
29-
* handshake or return a fully custom {@link CopilotWebSocketHandlerBase}.
29+
* handshake or return a fully custom {@link CopilotWebSocketHandler}.
3030
*
3131
* @since 1.0.0
3232
*/
@@ -89,8 +89,8 @@ protected HttpResponse<InputStream> sendRequest(HttpRequest request, CopilotRequ
8989
* @throws Exception
9090
* if the handler could not be created
9191
*/
92-
protected CopilotWebSocketHandlerBase openWebSocket(CopilotRequestContext ctx) throws Exception {
93-
return new CopilotWebSocketHandler(ctx);
92+
protected CopilotWebSocketHandler openWebSocket(CopilotRequestContext ctx) throws Exception {
93+
return new CopilotWebSocketForwarder(ctx);
9494
}
9595

9696
/**
@@ -160,7 +160,7 @@ private void handleWebSocket(LlmInferenceExchange exchange) throws Exception {
160160
LlmWebSocketResponseBridge bridge = new LlmWebSocketResponseBridge(exchange);
161161
ctx.setWebSocketResponse(bridge);
162162

163-
CopilotWebSocketHandlerBase handler = openWebSocket(ctx);
163+
CopilotWebSocketHandler handler = openWebSocket(ctx);
164164
try {
165165
handler.open();
166166

0 commit comments

Comments
 (0)