(options: ConnectResponsesWebSocketOptions)
| 69 | } |
| 70 | |
| 71 | export function connectResponsesWebSocket(options: ConnectResponsesWebSocketOptions) { |
| 72 | return new Promise<WebSocket>((resolve, reject) => { |
| 73 | if (options.signal?.aborted) { |
| 74 | reject(abortError(options.signal)) |
| 75 | return |
| 76 | } |
| 77 | |
| 78 | const headers: Record<string, string> = { |
| 79 | ...options.headers, |
| 80 | "openai-beta": options.headers["openai-beta"] ?? PROTOCOL_HEADER, |
| 81 | } |
| 82 | delete headers["content-length"] |
| 83 | |
| 84 | // Bun does not apply HTTP(S)_PROXY to WebSockets unless the proxy is supplied explicitly. |
| 85 | const proxy = |
| 86 | typeof Bun === "undefined" |
| 87 | ? undefined |
| 88 | : ProxyEnv.getProxyForUrl(options.url.replace(/^wss:/, "https:").replace(/^ws:/, "http:")) |
| 89 | const connect = { headers, ...(proxy ? { proxy } : {}) } |
| 90 | const socket = new WebSocket(options.url, connect) |
| 91 | const timeout = options.timeout |
| 92 | ? setTimeout(() => { |
| 93 | cleanup() |
| 94 | socket.on("error", () => {}) |
| 95 | socket.terminate() |
| 96 | reject(new Error("WebSocket connect timed out")) |
| 97 | }, options.timeout) |
| 98 | : undefined |
| 99 | |
| 100 | function cleanup() { |
| 101 | if (timeout) clearTimeout(timeout) |
| 102 | socket.off("open", onOpen) |
| 103 | socket.off("error", onError) |
| 104 | socket.off("close", onClose) |
| 105 | options.signal?.removeEventListener("abort", onAbort) |
| 106 | } |
| 107 | |
| 108 | function onOpen() { |
| 109 | cleanup() |
| 110 | resolve(socket) |
| 111 | } |
| 112 | |
| 113 | function onError(error: unknown) { |
| 114 | socket.on("error", () => {}) |
| 115 | cleanup() |
| 116 | reject(error instanceof Error ? error : new Error(errorMessage(error), { cause: error })) |
| 117 | } |
| 118 | |
| 119 | function onClose(code: number, reason: Buffer) { |
| 120 | cleanup() |
| 121 | reject(new Error(closeMessage("WebSocket closed before open", code, reason))) |
| 122 | } |
| 123 | |
| 124 | function onAbort() { |
| 125 | cleanup() |
| 126 | socket.on("error", () => {}) |
| 127 | socket.terminate() |
| 128 | reject(abortError(options.signal)) |
nothing calls this directly
no test coverage detected