Skip to content

Commit e120edb

Browse files
Go: carry frame type through WebSocket intercept callbacks + add message helpers
Addresses two cross-SDK consistency gaps on the Go request-handler API flagged in review: - Widen OnSendRequestMessage / OnSendResponseMessage from func([]byte) []byte to func(CopilotWebSocketMessage) *CopilotWebSocketMessage so callbacks can inspect and change a frame's text/binary type, matching the CopilotWebSocketMessage-based hooks in the .NET, Rust, and Java SDKs. Returning nil still drops the frame, preserving existing semantics. - Add Text(), NewTextMessage(), and NewBinaryMessage() convenience helpers to CopilotWebSocketMessage, mirroring the factory/getter helpers the other strongly-typed SDKs provide. This is a new experimental API, so aligning the shape now avoids a later breaking change. Updates the lone internal call site in the e2e handler test. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent eb0dafe commit e120edb

2 files changed

Lines changed: 38 additions & 19 deletions

File tree

go/copilot_request_handler.go

Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,19 @@ type CopilotWebSocketMessage struct {
8181
Binary bool
8282
}
8383

84+
// Text decodes the frame payload as a UTF-8 string.
85+
func (m CopilotWebSocketMessage) Text() string { return string(m.Data) }
86+
87+
// NewTextMessage creates a text-frame message from a UTF-8 string.
88+
func NewTextMessage(text string) CopilotWebSocketMessage {
89+
return CopilotWebSocketMessage{Data: []byte(text), Binary: false}
90+
}
91+
92+
// NewBinaryMessage creates a binary-frame message from raw bytes.
93+
func NewBinaryMessage(data []byte) CopilotWebSocketMessage {
94+
return CopilotWebSocketMessage{Data: data, Binary: true}
95+
}
96+
8497
// CopilotRequestHandler is the idiomatic handler for intercepting or replacing
8598
// LLM inference requests. HTTP requests are forwarded through Transport (an
8699
// [http.RoundTripper]); supply a custom RoundTripper to mutate the request,
@@ -360,11 +373,15 @@ type ForwardingCopilotWebSocketHandler struct {
360373
URL string
361374
Headers http.Header
362375
// OnSendRequestMessage observes or transforms each runtime→upstream frame.
363-
// Return nil to drop the frame.
364-
OnSendRequestMessage func(data []byte) []byte
376+
// The frame type (text vs binary) is available via the message's Binary
377+
// field and may be changed in the returned message. Return nil to drop the
378+
// frame.
379+
OnSendRequestMessage func(msg CopilotWebSocketMessage) *CopilotWebSocketMessage
365380
// OnSendResponseMessage observes or transforms each upstream→runtime frame.
366-
// Return nil to drop the frame.
367-
OnSendResponseMessage func(data []byte) []byte
381+
// The frame type (text vs binary) is available via the message's Binary
382+
// field and may be changed in the returned message. Return nil to drop the
383+
// frame.
384+
OnSendResponseMessage func(msg CopilotWebSocketMessage) *CopilotWebSocketMessage
368385

369386
conn *websocket.Conn
370387
resp WebSocketResponseWriter
@@ -422,37 +439,39 @@ func (f *ForwardingCopilotWebSocketHandler) receiveLoop(ctx context.Context) {
422439
}
423440
return
424441
}
425-
out := data
442+
out := CopilotWebSocketMessage{Data: data, Binary: typ == websocket.MessageBinary}
426443
if f.OnSendResponseMessage != nil {
427-
out = f.OnSendResponseMessage(data)
428-
if out == nil {
444+
transformed := f.OnSendResponseMessage(out)
445+
if transformed == nil {
429446
continue
430447
}
448+
out = *transformed
431449
}
432-
if typ == websocket.MessageBinary {
433-
_ = f.resp.SendBinary(out)
450+
if out.Binary {
451+
_ = f.resp.SendBinary(out.Data)
434452
} else {
435-
_ = f.resp.SendText(out)
453+
_ = f.resp.SendText(out.Data)
436454
}
437455
}
438456
}
439457

440458
func (f *ForwardingCopilotWebSocketHandler) SendRequestMessage(ctx context.Context, msg CopilotWebSocketMessage) error {
441-
out := msg.Data
459+
out := msg
442460
if f.OnSendRequestMessage != nil {
443-
out = f.OnSendRequestMessage(msg.Data)
444-
if out == nil {
461+
transformed := f.OnSendRequestMessage(msg)
462+
if transformed == nil {
445463
return nil
446464
}
465+
out = *transformed
447466
}
448467
if f.conn == nil {
449468
return nil
450469
}
451470
msgType := websocket.MessageText
452-
if msg.Binary {
471+
if out.Binary {
453472
msgType = websocket.MessageBinary
454473
}
455-
return f.conn.Write(ctx, msgType, out)
474+
return f.conn.Write(ctx, msgType, out.Data)
456475
}
457476

458477
func (f *ForwardingCopilotWebSocketHandler) Done() <-chan struct{} { return f.done }

go/internal/e2e/copilot_request_handler_e2e_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -146,13 +146,13 @@ func TestCopilotRequestHandler(t *testing.T) {
146146
parsed.Scheme = wsBase.Scheme
147147
parsed.Host = wsBase.Host
148148
fwd := copilot.NewForwardingCopilotWebSocketHandler(parsed.String(), rctx.Headers)
149-
fwd.OnSendRequestMessage = func(data []byte) []byte {
149+
fwd.OnSendRequestMessage = func(msg copilot.CopilotWebSocketMessage) *copilot.CopilotWebSocketMessage {
150150
counters.wsRequestMessages.Add(1)
151-
return data
151+
return &msg
152152
}
153-
fwd.OnSendResponseMessage = func(data []byte) []byte {
153+
fwd.OnSendResponseMessage = func(msg copilot.CopilotWebSocketMessage) *copilot.CopilotWebSocketMessage {
154154
counters.wsResponseMessages.Add(1)
155-
return data
155+
return &msg
156156
}
157157
return fwd, nil
158158
},

0 commit comments

Comments
 (0)