From badeeb91fe2934c3f3451e5b39632381b966a17b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=96=E7=95=8C?= Date: Sat, 14 Mar 2026 16:07:58 +0800 Subject: [PATCH] service/ocm: add default OpenAI-Beta header and log websocket error body The upstream OpenAI WebSocket endpoint requires the OpenAI-Beta: responses_websockets=2026-02-06 header. Set it automatically when the client doesn't provide it. Also capture and log the response body on non-429 WebSocket handshake failures to surface the actual error from upstream. --- service/ocm/service_websocket.go | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/service/ocm/service_websocket.go b/service/ocm/service_websocket.go index 365472f59..21b25bafc 100644 --- a/service/ocm/service_websocket.go +++ b/service/ocm/service_websocket.go @@ -99,6 +99,7 @@ func (s *Service) handleWebSocket( upstreamBufferedReader *bufio.Reader upstreamResponseHeaders http.Header statusCode int + statusResponseBody string ) for { @@ -135,9 +136,13 @@ func (s *Service) handleWebSocket( if accountID := selectedCredential.ocmGetAccountID(); accountID != "" { upstreamHeaders.Set("ChatGPT-Account-Id", accountID) } + if upstreamHeaders.Get("OpenAI-Beta") == "" { + upstreamHeaders.Set("OpenAI-Beta", "responses_websockets=2026-02-06") + } upstreamResponseHeaders = make(http.Header) statusCode = 0 + statusResponseBody = "" upstreamDialer := ws.Dialer{ NetDial: func(ctx context.Context, network, addr string) (net.Conn, error) { return selectedCredential.ocmDialer().DialContext(ctx, network, M.ParseSocksaddr(addr)) @@ -162,6 +167,10 @@ func (s *Service) handleWebSocket( if readErr == nil { upstreamResponseHeaders = http.Header(mimeHeader) } + body, readErr := io.ReadAll(io.LimitReader(bufferedResponse, 4096)) + if readErr == nil && len(body) > 0 { + statusResponseBody = string(body) + } }, OnHeader: func(key, value []byte) error { upstreamResponseHeaders.Add(string(key), string(value)) @@ -185,7 +194,11 @@ func (s *Service) handleWebSocket( selectedCredential = nextCredential continue } - s.logger.Error("dial upstream websocket: ", err) + if statusCode > 0 && statusResponseBody != "" { + s.logger.Error("dial upstream websocket: status ", statusCode, " body: ", statusResponseBody) + } else { + s.logger.Error("dial upstream websocket: ", err) + } writeJSONError(w, r, http.StatusBadGateway, "api_error", "upstream websocket connection failed") return }