UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

133 lines (132 loc) 4.44 kB
import { s as sleepWithAbort } from "./src-BQ327IOM.js"; import "./realtime-voice-provider-CoGArOTN.js"; import { u as openAIQuicksilverAuthHeaders } from "./realtime-quicksilver-wire-0W0-YPkD.js"; //#region extensions/openai/realtime-quicksilver-sideband.ts const SIDEBAND_CONNECT_TIMEOUT_MS = 15e3; const SIDEBAND_CONNECT_ATTEMPTS = 5; const SIDEBAND_RETRY_BASE_MS = 200; const EARLY_FRAME_MAX = 32; const EARLY_FRAME_MAX_BYTES = 1048576; const SIDEBAND_MAX_PAYLOAD_BYTES = 16777216; function rawDataByteLength(data) { if (Array.isArray(data)) return data.reduce((total, chunk) => total + chunk.byteLength, 0); return data.byteLength; } function waitForSocketOpen(params) { return new Promise((resolve, reject) => { let settled = false; let opened = false; let terminalEvent; const detachTerminalListeners = () => { params.socket.off("error", onError); params.socket.off("close", onClose); return terminalEvent; }; const finish = (error) => { if (settled) return; settled = true; clearTimeout(timeout); params.signal.removeEventListener("abort", onAbort); params.socket.off("open", onOpen); if (error) { detachTerminalListeners(); reject(error); } else resolve({ detachTerminalListeners }); }; const onOpen = () => { opened = true; finish(); }; const onError = (error) => { if (opened) { terminalEvent ??= { kind: "error", error }; return; } finish(error); }; const onClose = (code, reason) => { if (opened) { terminalEvent ??= { kind: "close", code: code ?? 1006, reason: reason?.toString("utf8") ?? "" }; return; } finish(/* @__PURE__ */ new Error("GPT-Live sideband closed during startup")); }; const onAbort = () => finish(params.signal.reason instanceof Error ? params.signal.reason : /* @__PURE__ */ new Error("GPT-Live session stopped during startup")); const timeout = setTimeout(() => finish(/* @__PURE__ */ new Error("GPT-Live sideband connection timed out")), SIDEBAND_CONNECT_TIMEOUT_MS); timeout.unref?.(); params.socket.once("open", onOpen); params.socket.on("error", onError); params.socket.on("close", onClose); params.signal.addEventListener("abort", onAbort, { once: true }); if (params.signal.aborted) onAbort(); }); } async function connectOpenAIQuicksilverSideband(params, runtime) { let lastError = /* @__PURE__ */ new Error("GPT-Live sideband connection failed"); for (let attempt = 0; attempt < SIDEBAND_CONNECT_ATTEMPTS; attempt += 1) { if (params.signal.aborted) throw params.signal.reason; const socket = params.createSocket(params.url, { headers: openAIQuicksilverAuthHeaders(params.auth, params.requestIds, runtime), maxPayload: SIDEBAND_MAX_PAYLOAD_BYTES }); const bufferedFrames = []; let bufferedBytes = 0; const bufferFrame = (data, isBinary) => { const frameBytes = rawDataByteLength(data); if (bufferedFrames.length >= EARLY_FRAME_MAX || bufferedBytes + frameBytes > EARLY_FRAME_MAX_BYTES) { socket.off("message", bufferFrame); socket.close(1009, "sideband startup buffer exceeded"); return; } bufferedBytes += frameBytes; bufferedFrames.push({ data, isBinary }); }; socket.on("message", bufferFrame); try { const openHandoff = await waitForSocketOpen({ socket, signal: params.signal }); if (params.signal.aborted) { socket.off("message", bufferFrame); openHandoff.detachTerminalListeners(); socket.on("error", () => {}); socket.close(1e3, "sideband startup stopped"); throw params.signal.reason; } return { socket, bufferedFrames, detachBuffer: () => { socket.off("message", bufferFrame); return openHandoff.detachTerminalListeners(); } }; } catch (error) { lastError = error; socket.off("message", bufferFrame); socket.on("error", () => {}); try { socket.close(1e3, "retrying sideband"); } catch {} if (params.signal.aborted) throw params.signal.reason; if (attempt + 1 < SIDEBAND_CONNECT_ATTEMPTS) await sleepWithAbort(SIDEBAND_RETRY_BASE_MS * 2 ** attempt, params.signal, { ref: false }).catch(() => { const reason = params.signal.reason; throw reason instanceof Error ? reason : new Error(reason === void 0 ? "GPT-Live session stopped" : String(reason), { cause: reason }); }); } } throw lastError; } //#endregion export { connectOpenAIQuicksilverSideband as t };