feat: Passwordless cross-device authentication

- Arkitektur: docs/auth/passwordless-architecture.md
- Backend: iom/quixzoom-auth-service/ (FastAPI + Redis)
- Webb: quixzoom-market-pages/se/login/ (QR-kod + polling)
- App: iom/quixzoom-app/src/features/auth/ (push + deep links)

Flöde: QR-kod → app-godkännande → webb-inloggad
This commit is contained in:
Bernt
2026-07-07 07:11:50 +00:00
parent 4aa984ad74
commit 6989a98d75
61843 changed files with 5491611 additions and 872231 deletions
+2
View File
@@ -0,0 +1,2 @@
export { OpenAIRealtimeError } from "./internal-base.mjs";
//# sourceMappingURL=index.d.mts.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"index.d.mts","sourceRoot":"","sources":["../../src/beta/realtime/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,4BAAwB"}
+2
View File
@@ -0,0 +1,2 @@
export { OpenAIRealtimeError } from "./internal-base.js";
//# sourceMappingURL=index.d.ts.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/beta/realtime/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,2BAAwB"}
+6
View File
@@ -0,0 +1,6 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.OpenAIRealtimeError = void 0;
var internal_base_1 = require("./internal-base.js");
Object.defineProperty(exports, "OpenAIRealtimeError", { enumerable: true, get: function () { return internal_base_1.OpenAIRealtimeError; } });
//# sourceMappingURL=index.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/beta/realtime/index.ts"],"names":[],"mappings":";;;AAAA,oDAAsD;AAA7C,oHAAA,mBAAmB,OAAA"}
+2
View File
@@ -0,0 +1,2 @@
export { OpenAIRealtimeError } from "./internal-base.mjs";
//# sourceMappingURL=index.mjs.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"index.mjs","sourceRoot":"","sources":["../../src/beta/realtime/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,4BAAwB"}
+58
View File
@@ -0,0 +1,58 @@
import { RealtimeClientEvent, RealtimeServerEvent, ErrorEvent } from "../../resources/beta/realtime/realtime.mjs";
import { EventEmitter } from "../../lib/EventEmitter.mjs";
import { OpenAIError } from "../../error.mjs";
import OpenAI, { AzureOpenAI } from "../../index.mjs";
export declare class OpenAIRealtimeError extends OpenAIError {
/**
* The error data that the API sent back in an `error` event.
*/
error?: ErrorEvent.Error | undefined;
/**
* The unique ID of the server event.
*/
event_id?: string | undefined;
constructor(message: string, event: ErrorEvent | null);
}
type Simplify<T> = {
[KeyType in keyof T]: T[KeyType];
} & {};
type RealtimeEvents = Simplify<{
event: (event: RealtimeServerEvent) => void;
error: (error: OpenAIRealtimeError) => void;
} & {
[EventType in Exclude<RealtimeServerEvent['type'], 'error'>]: (event: Extract<RealtimeServerEvent, {
type: EventType;
}>) => unknown;
}>;
export declare abstract class OpenAIRealtimeEmitter extends EventEmitter<RealtimeEvents> {
/**
* Send an event to the API.
*/
abstract send(event: RealtimeClientEvent): void;
/**
* Close the websocket connection.
*/
abstract close(props?: {
code: number;
reason: string;
}): void;
protected _onError(event: null, message: string, cause: any): void;
protected _onError(event: ErrorEvent, message?: string | undefined): void;
}
export declare function isAzure(client: Pick<OpenAI, 'apiKey' | 'baseURL'>): client is AzureOpenAI;
export type RealtimeConnectionConfig = {
/**
* Start a new Realtime session using the given model.
*/
model: string;
callID?: undefined;
} | {
model?: undefined;
/**
* Attach to an in-progress Realtime call over a sideband control connection.
*/
callID: string;
};
export declare function buildRealtimeURL(client: Pick<OpenAI, 'apiKey' | 'baseURL'>, connection: string | RealtimeConnectionConfig): URL;
export {};
//# sourceMappingURL=internal-base.d.mts.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"internal-base.d.mts","sourceRoot":"","sources":["../../src/beta/realtime/internal-base.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,UAAU,EAAE,mDAA+C;AAC9G,OAAO,EAAE,YAAY,EAAE,mCAA+B;AACtD,OAAO,EAAE,WAAW,EAAE,wBAAoB;AAC1C,OAAO,MAAM,EAAE,EAAE,WAAW,EAAE,wBAAoB;AAElD,qBAAa,mBAAoB,SAAQ,WAAW;IAClD;;OAEG;IACH,KAAK,CAAC,EAAE,UAAU,CAAC,KAAK,GAAG,SAAS,CAAC;IAErC;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;gBAElB,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,IAAI;CAMtD;AAED,KAAK,QAAQ,CAAC,CAAC,IAAI;KAAG,OAAO,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC;CAAE,GAAG,EAAE,CAAC;AAE7D,KAAK,cAAc,GAAG,QAAQ,CAC5B;IACE,KAAK,EAAE,CAAC,KAAK,EAAE,mBAAmB,KAAK,IAAI,CAAC;IAC5C,KAAK,EAAE,CAAC,KAAK,EAAE,mBAAmB,KAAK,IAAI,CAAC;CAC7C,GAAG;KACD,SAAS,IAAI,OAAO,CAAC,mBAAmB,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,GAAG,CAC5D,KAAK,EAAE,OAAO,CAAC,mBAAmB,EAAE;QAAE,IAAI,EAAE,SAAS,CAAA;KAAE,CAAC,KACrD,OAAO;CACb,CACF,CAAC;AAEF,8BAAsB,qBAAsB,SAAQ,YAAY,CAAC,cAAc,CAAC;IAC9E;;OAEG;IACH,QAAQ,CAAC,IAAI,CAAC,KAAK,EAAE,mBAAmB,GAAG,IAAI;IAE/C;;OAEG;IACH,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAE9D,SAAS,CAAC,QAAQ,CAAC,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,IAAI;IAClE,SAAS,CAAC,QAAQ,CAAC,KAAK,EAAE,UAAU,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI;CAyB1E;AAED,wBAAgB,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,QAAQ,GAAG,SAAS,CAAC,GAAG,MAAM,IAAI,WAAW,CAEzF;AAED,MAAM,MAAM,wBAAwB,GAChC;IACE;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,SAAS,CAAC;CACpB,GACD;IACE,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEN,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,QAAQ,GAAG,SAAS,CAAC,EAC1C,UAAU,EAAE,MAAM,GAAG,wBAAwB,GAC5C,GAAG,CA+BL"}
+58
View File
@@ -0,0 +1,58 @@
import { RealtimeClientEvent, RealtimeServerEvent, ErrorEvent } from "../../resources/beta/realtime/realtime.js";
import { EventEmitter } from "../../lib/EventEmitter.js";
import { OpenAIError } from "../../error.js";
import OpenAI, { AzureOpenAI } from "../../index.js";
export declare class OpenAIRealtimeError extends OpenAIError {
/**
* The error data that the API sent back in an `error` event.
*/
error?: ErrorEvent.Error | undefined;
/**
* The unique ID of the server event.
*/
event_id?: string | undefined;
constructor(message: string, event: ErrorEvent | null);
}
type Simplify<T> = {
[KeyType in keyof T]: T[KeyType];
} & {};
type RealtimeEvents = Simplify<{
event: (event: RealtimeServerEvent) => void;
error: (error: OpenAIRealtimeError) => void;
} & {
[EventType in Exclude<RealtimeServerEvent['type'], 'error'>]: (event: Extract<RealtimeServerEvent, {
type: EventType;
}>) => unknown;
}>;
export declare abstract class OpenAIRealtimeEmitter extends EventEmitter<RealtimeEvents> {
/**
* Send an event to the API.
*/
abstract send(event: RealtimeClientEvent): void;
/**
* Close the websocket connection.
*/
abstract close(props?: {
code: number;
reason: string;
}): void;
protected _onError(event: null, message: string, cause: any): void;
protected _onError(event: ErrorEvent, message?: string | undefined): void;
}
export declare function isAzure(client: Pick<OpenAI, 'apiKey' | 'baseURL'>): client is AzureOpenAI;
export type RealtimeConnectionConfig = {
/**
* Start a new Realtime session using the given model.
*/
model: string;
callID?: undefined;
} | {
model?: undefined;
/**
* Attach to an in-progress Realtime call over a sideband control connection.
*/
callID: string;
};
export declare function buildRealtimeURL(client: Pick<OpenAI, 'apiKey' | 'baseURL'>, connection: string | RealtimeConnectionConfig): URL;
export {};
//# sourceMappingURL=internal-base.d.ts.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"internal-base.d.ts","sourceRoot":"","sources":["../../src/beta/realtime/internal-base.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,UAAU,EAAE,kDAA+C;AAC9G,OAAO,EAAE,YAAY,EAAE,kCAA+B;AACtD,OAAO,EAAE,WAAW,EAAE,uBAAoB;AAC1C,OAAO,MAAM,EAAE,EAAE,WAAW,EAAE,uBAAoB;AAElD,qBAAa,mBAAoB,SAAQ,WAAW;IAClD;;OAEG;IACH,KAAK,CAAC,EAAE,UAAU,CAAC,KAAK,GAAG,SAAS,CAAC;IAErC;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;gBAElB,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,IAAI;CAMtD;AAED,KAAK,QAAQ,CAAC,CAAC,IAAI;KAAG,OAAO,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC;CAAE,GAAG,EAAE,CAAC;AAE7D,KAAK,cAAc,GAAG,QAAQ,CAC5B;IACE,KAAK,EAAE,CAAC,KAAK,EAAE,mBAAmB,KAAK,IAAI,CAAC;IAC5C,KAAK,EAAE,CAAC,KAAK,EAAE,mBAAmB,KAAK,IAAI,CAAC;CAC7C,GAAG;KACD,SAAS,IAAI,OAAO,CAAC,mBAAmB,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,GAAG,CAC5D,KAAK,EAAE,OAAO,CAAC,mBAAmB,EAAE;QAAE,IAAI,EAAE,SAAS,CAAA;KAAE,CAAC,KACrD,OAAO;CACb,CACF,CAAC;AAEF,8BAAsB,qBAAsB,SAAQ,YAAY,CAAC,cAAc,CAAC;IAC9E;;OAEG;IACH,QAAQ,CAAC,IAAI,CAAC,KAAK,EAAE,mBAAmB,GAAG,IAAI;IAE/C;;OAEG;IACH,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAE9D,SAAS,CAAC,QAAQ,CAAC,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,IAAI;IAClE,SAAS,CAAC,QAAQ,CAAC,KAAK,EAAE,UAAU,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI;CAyB1E;AAED,wBAAgB,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,QAAQ,GAAG,SAAS,CAAC,GAAG,MAAM,IAAI,WAAW,CAEzF;AAED,MAAM,MAAM,wBAAwB,GAChC;IACE;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,SAAS,CAAC;CACpB,GACD;IACE,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEN,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,QAAQ,GAAG,SAAS,CAAC,EAC1C,UAAU,EAAE,MAAM,GAAG,wBAAwB,GAC5C,GAAG,CA+BL"}
+71
View File
@@ -0,0 +1,71 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.OpenAIRealtimeEmitter = exports.OpenAIRealtimeError = void 0;
exports.isAzure = isAzure;
exports.buildRealtimeURL = buildRealtimeURL;
const EventEmitter_1 = require("../../lib/EventEmitter.js");
const error_1 = require("../../error.js");
const index_1 = require("../../index.js");
class OpenAIRealtimeError extends error_1.OpenAIError {
constructor(message, event) {
super(message);
this.error = event?.error;
this.event_id = event?.event_id;
}
}
exports.OpenAIRealtimeError = OpenAIRealtimeError;
class OpenAIRealtimeEmitter extends EventEmitter_1.EventEmitter {
_onError(event, message, cause) {
message =
event?.error ?
`${event.error.message} code=${event.error.code} param=${event.error.param} type=${event.error.type} event_id=${event.error.event_id}`
: message ?? 'unknown error';
if (!this._hasListener('error')) {
const error = new OpenAIRealtimeError(message +
`\n\nTo resolve these unhandled rejection errors you should bind an \`error\` callback, e.g. \`rt.on('error', (error) => ...)\` `, event);
// @ts-ignore
error.cause = cause;
Promise.reject(error);
return;
}
const error = new OpenAIRealtimeError(message, event);
// @ts-ignore
error.cause = cause;
this._emit('error', error);
}
}
exports.OpenAIRealtimeEmitter = OpenAIRealtimeEmitter;
function isAzure(client) {
return client instanceof index_1.AzureOpenAI;
}
function buildRealtimeURL(client, connection) {
const config = typeof connection === 'string' ? { model: connection } : connection;
const baseURL = client.baseURL;
const azure = isAzure(client);
const hasModel = !!config.model;
const hasCallID = !!config.callID;
const path = '/realtime';
const url = new URL(baseURL + (baseURL.endsWith('/') ? path.slice(1) : path));
if (hasModel === hasCallID) {
throw new Error('Pass exactly one of `model` or `callID` when opening a Realtime WebSocket.');
}
url.protocol = 'wss';
// Sideband control connections attach to an existing call via `call_id`.
if (azure) {
if (hasCallID) {
throw new Error('Azure `callID` connections require the stable Realtime helpers.');
}
url.searchParams.set('api-version', client.apiVersion);
url.searchParams.set('deployment', config.model);
}
else {
if (hasCallID) {
url.searchParams.set('call_id', config.callID);
}
else {
url.searchParams.set('model', config.model);
}
}
return url;
}
//# sourceMappingURL=internal-base.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"internal-base.js","sourceRoot":"","sources":["../../src/beta/realtime/internal-base.ts"],"names":[],"mappings":"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"}
+64
View File
@@ -0,0 +1,64 @@
import { EventEmitter } from "../../lib/EventEmitter.mjs";
import { OpenAIError } from "../../error.mjs";
import { AzureOpenAI } from "../../index.mjs";
export class OpenAIRealtimeError extends OpenAIError {
constructor(message, event) {
super(message);
this.error = event?.error;
this.event_id = event?.event_id;
}
}
export class OpenAIRealtimeEmitter extends EventEmitter {
_onError(event, message, cause) {
message =
event?.error ?
`${event.error.message} code=${event.error.code} param=${event.error.param} type=${event.error.type} event_id=${event.error.event_id}`
: message ?? 'unknown error';
if (!this._hasListener('error')) {
const error = new OpenAIRealtimeError(message +
`\n\nTo resolve these unhandled rejection errors you should bind an \`error\` callback, e.g. \`rt.on('error', (error) => ...)\` `, event);
// @ts-ignore
error.cause = cause;
Promise.reject(error);
return;
}
const error = new OpenAIRealtimeError(message, event);
// @ts-ignore
error.cause = cause;
this._emit('error', error);
}
}
export function isAzure(client) {
return client instanceof AzureOpenAI;
}
export function buildRealtimeURL(client, connection) {
const config = typeof connection === 'string' ? { model: connection } : connection;
const baseURL = client.baseURL;
const azure = isAzure(client);
const hasModel = !!config.model;
const hasCallID = !!config.callID;
const path = '/realtime';
const url = new URL(baseURL + (baseURL.endsWith('/') ? path.slice(1) : path));
if (hasModel === hasCallID) {
throw new Error('Pass exactly one of `model` or `callID` when opening a Realtime WebSocket.');
}
url.protocol = 'wss';
// Sideband control connections attach to an existing call via `call_id`.
if (azure) {
if (hasCallID) {
throw new Error('Azure `callID` connections require the stable Realtime helpers.');
}
url.searchParams.set('api-version', client.apiVersion);
url.searchParams.set('deployment', config.model);
}
else {
if (hasCallID) {
url.searchParams.set('call_id', config.callID);
}
else {
url.searchParams.set('model', config.model);
}
}
return url;
}
//# sourceMappingURL=internal-base.mjs.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"internal-base.mjs","sourceRoot":"","sources":["../../src/beta/realtime/internal-base.ts"],"names":[],"mappings":"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"}
+34
View File
@@ -0,0 +1,34 @@
import { AzureOpenAI, OpenAI } from "../../index.mjs";
import type { RealtimeClientEvent } from "../../resources/beta/realtime/realtime.mjs";
import { OpenAIRealtimeEmitter, type RealtimeConnectionConfig } from "./internal-base.mjs";
type _WebSocket = typeof globalThis extends ({
WebSocket: infer ws extends abstract new (...args: any) => any;
}) ? InstanceType<ws> : any;
export declare class OpenAIRealtimeWebSocket extends OpenAIRealtimeEmitter {
url: URL;
socket: _WebSocket;
constructor(props: RealtimeConnectionConfig & {
dangerouslyAllowBrowser?: boolean;
/**
* Callback to mutate the URL, needed for Azure.
* @internal
*/
onURL?: (url: URL) => void;
/** Indicates the token was resolved by the factory just before connecting. @internal */
__resolvedApiKey?: boolean;
}, client?: Pick<OpenAI, 'apiKey' | 'baseURL'>);
static create(client: Pick<OpenAI, 'apiKey' | 'baseURL' | '_callApiKey'>, props: RealtimeConnectionConfig & {
dangerouslyAllowBrowser?: boolean;
}): Promise<OpenAIRealtimeWebSocket>;
static azure(client: Pick<AzureOpenAI, '_callApiKey' | 'apiVersion' | 'apiKey' | 'baseURL' | 'deploymentName'>, options?: {
deploymentName?: string;
dangerouslyAllowBrowser?: boolean;
}): Promise<OpenAIRealtimeWebSocket>;
send(event: RealtimeClientEvent): void;
close(props?: {
code: number;
reason: string;
}): void;
}
export {};
//# sourceMappingURL=websocket.d.mts.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"websocket.d.mts","sourceRoot":"","sources":["../../src/beta/realtime/websocket.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,wBAAoB;AAElD,OAAO,KAAK,EAAE,mBAAmB,EAAuB,mDAA+C;AACvG,OAAO,EACL,qBAAqB,EAGrB,KAAK,wBAAwB,EAC9B,4BAAwB;AAOzB,KAAK,UAAU,GACb,OAAO,UAAU,SAAS,CACxB;IACE,SAAS,EAAE,MAAM,EAAE,SAAS,QAAQ,MAAM,GAAG,IAAI,EAAE,GAAG,KAAK,GAAG,CAAC;CAChE,CACF,GAEC,YAAY,CAAC,EAAE,CAAC,GAChB,GAAG,CAAC;AAER,qBAAa,uBAAwB,SAAQ,qBAAqB;IAChE,GAAG,EAAE,GAAG,CAAC;IACT,MAAM,EAAE,UAAU,CAAC;gBAGjB,KAAK,EAAE,wBAAwB,GAAG;QAChC,uBAAuB,CAAC,EAAE,OAAO,CAAC;QAClC;;;WAGG;QACH,KAAK,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,IAAI,CAAC;QAC3B,wFAAwF;QACxF,gBAAgB,CAAC,EAAE,OAAO,CAAC;KAC5B,EACD,MAAM,CAAC,EAAE,IAAI,CAAC,MAAM,EAAE,QAAQ,GAAG,SAAS,CAAC;WAsEhC,MAAM,CACjB,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,QAAQ,GAAG,SAAS,GAAG,aAAa,CAAC,EAC1D,KAAK,EAAE,wBAAwB,GAAG;QAAE,uBAAuB,CAAC,EAAE,OAAO,CAAA;KAAE,GACtE,OAAO,CAAC,uBAAuB,CAAC;WAItB,KAAK,CAChB,MAAM,EAAE,IAAI,CAAC,WAAW,EAAE,aAAa,GAAG,YAAY,GAAG,QAAQ,GAAG,SAAS,GAAG,gBAAgB,CAAC,EACjG,OAAO,GAAE;QAAE,cAAc,CAAC,EAAE,MAAM,CAAC;QAAC,uBAAuB,CAAC,EAAE,OAAO,CAAA;KAAO,GAC3E,OAAO,CAAC,uBAAuB,CAAC;IA8BnC,IAAI,CAAC,KAAK,EAAE,mBAAmB;IAQ/B,KAAK,CAAC,KAAK,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE;CAO/C"}
+34
View File
@@ -0,0 +1,34 @@
import { AzureOpenAI, OpenAI } from "../../index.js";
import type { RealtimeClientEvent } from "../../resources/beta/realtime/realtime.js";
import { OpenAIRealtimeEmitter, type RealtimeConnectionConfig } from "./internal-base.js";
type _WebSocket = typeof globalThis extends ({
WebSocket: infer ws extends abstract new (...args: any) => any;
}) ? InstanceType<ws> : any;
export declare class OpenAIRealtimeWebSocket extends OpenAIRealtimeEmitter {
url: URL;
socket: _WebSocket;
constructor(props: RealtimeConnectionConfig & {
dangerouslyAllowBrowser?: boolean;
/**
* Callback to mutate the URL, needed for Azure.
* @internal
*/
onURL?: (url: URL) => void;
/** Indicates the token was resolved by the factory just before connecting. @internal */
__resolvedApiKey?: boolean;
}, client?: Pick<OpenAI, 'apiKey' | 'baseURL'>);
static create(client: Pick<OpenAI, 'apiKey' | 'baseURL' | '_callApiKey'>, props: RealtimeConnectionConfig & {
dangerouslyAllowBrowser?: boolean;
}): Promise<OpenAIRealtimeWebSocket>;
static azure(client: Pick<AzureOpenAI, '_callApiKey' | 'apiVersion' | 'apiKey' | 'baseURL' | 'deploymentName'>, options?: {
deploymentName?: string;
dangerouslyAllowBrowser?: boolean;
}): Promise<OpenAIRealtimeWebSocket>;
send(event: RealtimeClientEvent): void;
close(props?: {
code: number;
reason: string;
}): void;
}
export {};
//# sourceMappingURL=websocket.d.ts.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"websocket.d.ts","sourceRoot":"","sources":["../../src/beta/realtime/websocket.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,uBAAoB;AAElD,OAAO,KAAK,EAAE,mBAAmB,EAAuB,kDAA+C;AACvG,OAAO,EACL,qBAAqB,EAGrB,KAAK,wBAAwB,EAC9B,2BAAwB;AAOzB,KAAK,UAAU,GACb,OAAO,UAAU,SAAS,CACxB;IACE,SAAS,EAAE,MAAM,EAAE,SAAS,QAAQ,MAAM,GAAG,IAAI,EAAE,GAAG,KAAK,GAAG,CAAC;CAChE,CACF,GAEC,YAAY,CAAC,EAAE,CAAC,GAChB,GAAG,CAAC;AAER,qBAAa,uBAAwB,SAAQ,qBAAqB;IAChE,GAAG,EAAE,GAAG,CAAC;IACT,MAAM,EAAE,UAAU,CAAC;gBAGjB,KAAK,EAAE,wBAAwB,GAAG;QAChC,uBAAuB,CAAC,EAAE,OAAO,CAAC;QAClC;;;WAGG;QACH,KAAK,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,IAAI,CAAC;QAC3B,wFAAwF;QACxF,gBAAgB,CAAC,EAAE,OAAO,CAAC;KAC5B,EACD,MAAM,CAAC,EAAE,IAAI,CAAC,MAAM,EAAE,QAAQ,GAAG,SAAS,CAAC;WAsEhC,MAAM,CACjB,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,QAAQ,GAAG,SAAS,GAAG,aAAa,CAAC,EAC1D,KAAK,EAAE,wBAAwB,GAAG;QAAE,uBAAuB,CAAC,EAAE,OAAO,CAAA;KAAE,GACtE,OAAO,CAAC,uBAAuB,CAAC;WAItB,KAAK,CAChB,MAAM,EAAE,IAAI,CAAC,WAAW,EAAE,aAAa,GAAG,YAAY,GAAG,QAAQ,GAAG,SAAS,GAAG,gBAAgB,CAAC,EACjG,OAAO,GAAE;QAAE,cAAc,CAAC,EAAE,MAAM,CAAC;QAAC,uBAAuB,CAAC,EAAE,OAAO,CAAA;KAAO,GAC3E,OAAO,CAAC,uBAAuB,CAAC;IA8BnC,IAAI,CAAC,KAAK,EAAE,mBAAmB;IAQ/B,KAAK,CAAC,KAAK,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE;CAO/C"}
+114
View File
@@ -0,0 +1,114 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.OpenAIRealtimeWebSocket = void 0;
const index_1 = require("../../index.js");
const error_1 = require("../../error.js");
const internal_base_1 = require("./internal-base.js");
const detect_platform_1 = require("../../internal/detect-platform.js");
class OpenAIRealtimeWebSocket extends internal_base_1.OpenAIRealtimeEmitter {
constructor(props, client) {
super();
const hasProvider = typeof client?._options?.apiKey === 'function';
const dangerouslyAllowBrowser = props.dangerouslyAllowBrowser ??
client?._options?.dangerouslyAllowBrowser ??
(client?.apiKey?.startsWith('ek_') ? true : null);
if (!dangerouslyAllowBrowser && (0, detect_platform_1.isRunningInBrowser)()) {
throw new error_1.OpenAIError("It looks like you're running in a browser-like environment.\n\nThis is disabled by default, as it risks exposing your secret API credentials to attackers.\n\nYou can avoid this error by creating an ephemeral session token:\nhttps://platform.openai.com/docs/api-reference/realtime-sessions\n");
}
client ?? (client = new index_1.OpenAI({ dangerouslyAllowBrowser }));
if (hasProvider && !props?.__resolvedApiKey) {
throw new Error([
'Cannot open Realtime WebSocket with a function-based apiKey.',
'Use the .create() method so that the key is resolved before connecting.',
].join('\n'));
}
this.url = (0, internal_base_1.buildRealtimeURL)(client, props);
props.onURL?.(this.url);
// @ts-ignore
this.socket = new WebSocket(this.url.toString(), [
'realtime',
...((0, internal_base_1.isAzure)(client) ? [] : [`openai-insecure-api-key.${client.apiKey}`]),
'openai-beta.realtime-v1',
]);
this.socket.addEventListener('message', (websocketEvent) => {
const event = (() => {
try {
return JSON.parse(websocketEvent.data.toString());
}
catch (err) {
this._onError(null, 'could not parse websocket event', err);
return null;
}
})();
if (event) {
this._emit('event', event);
if (event.type === 'error') {
this._onError(event);
}
else {
// @ts-expect-error TS isn't smart enough to get the relationship right here
this._emit(event.type, event);
}
}
});
this.socket.addEventListener('error', (event) => {
this._onError(null, event.message, null);
});
if ((0, internal_base_1.isAzure)(client)) {
if (this.url.searchParams.get('Authorization') !== null) {
this.url.searchParams.set('Authorization', '<REDACTED>');
}
else {
this.url.searchParams.set('api-key', '<REDACTED>');
}
}
}
static async create(client, props) {
return new OpenAIRealtimeWebSocket({ ...props, __resolvedApiKey: await client._callApiKey() }, client);
}
static async azure(client, options = {}) {
const isApiKeyProvider = await client._callApiKey();
const apiKey = client.apiKey;
if (!apiKey) {
throw new Error('Azure OpenAI Realtime requires an API key');
}
const azureApiKey = apiKey;
function onURL(url) {
if (isApiKeyProvider) {
url.searchParams.set('Authorization', `Bearer ${azureApiKey}`);
}
else {
url.searchParams.set('api-key', azureApiKey);
}
}
const deploymentName = options.deploymentName ?? client.deploymentName;
if (!deploymentName) {
throw new Error('No deployment name provided');
}
const { dangerouslyAllowBrowser } = options;
return new OpenAIRealtimeWebSocket({
model: deploymentName,
onURL,
...(dangerouslyAllowBrowser ? { dangerouslyAllowBrowser } : {}),
__resolvedApiKey: isApiKeyProvider,
}, client);
}
send(event) {
try {
this.socket.send(JSON.stringify(event));
}
catch (err) {
this._onError(null, 'could not send data', err);
}
}
close(props) {
try {
this.socket.close(props?.code ?? 1000, props?.reason ?? 'OK');
}
catch (err) {
this._onError(null, 'could not close the connection', err);
}
}
}
exports.OpenAIRealtimeWebSocket = OpenAIRealtimeWebSocket;
//# sourceMappingURL=websocket.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"websocket.js","sourceRoot":"","sources":["../../src/beta/realtime/websocket.ts"],"names":[],"mappings":"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"}
+110
View File
@@ -0,0 +1,110 @@
import { OpenAI } from "../../index.mjs";
import { OpenAIError } from "../../error.mjs";
import { OpenAIRealtimeEmitter, buildRealtimeURL, isAzure, } from "./internal-base.mjs";
import { isRunningInBrowser } from "../../internal/detect-platform.mjs";
export class OpenAIRealtimeWebSocket extends OpenAIRealtimeEmitter {
constructor(props, client) {
super();
const hasProvider = typeof client?._options?.apiKey === 'function';
const dangerouslyAllowBrowser = props.dangerouslyAllowBrowser ??
client?._options?.dangerouslyAllowBrowser ??
(client?.apiKey?.startsWith('ek_') ? true : null);
if (!dangerouslyAllowBrowser && isRunningInBrowser()) {
throw new OpenAIError("It looks like you're running in a browser-like environment.\n\nThis is disabled by default, as it risks exposing your secret API credentials to attackers.\n\nYou can avoid this error by creating an ephemeral session token:\nhttps://platform.openai.com/docs/api-reference/realtime-sessions\n");
}
client ?? (client = new OpenAI({ dangerouslyAllowBrowser }));
if (hasProvider && !props?.__resolvedApiKey) {
throw new Error([
'Cannot open Realtime WebSocket with a function-based apiKey.',
'Use the .create() method so that the key is resolved before connecting.',
].join('\n'));
}
this.url = buildRealtimeURL(client, props);
props.onURL?.(this.url);
// @ts-ignore
this.socket = new WebSocket(this.url.toString(), [
'realtime',
...(isAzure(client) ? [] : [`openai-insecure-api-key.${client.apiKey}`]),
'openai-beta.realtime-v1',
]);
this.socket.addEventListener('message', (websocketEvent) => {
const event = (() => {
try {
return JSON.parse(websocketEvent.data.toString());
}
catch (err) {
this._onError(null, 'could not parse websocket event', err);
return null;
}
})();
if (event) {
this._emit('event', event);
if (event.type === 'error') {
this._onError(event);
}
else {
// @ts-expect-error TS isn't smart enough to get the relationship right here
this._emit(event.type, event);
}
}
});
this.socket.addEventListener('error', (event) => {
this._onError(null, event.message, null);
});
if (isAzure(client)) {
if (this.url.searchParams.get('Authorization') !== null) {
this.url.searchParams.set('Authorization', '<REDACTED>');
}
else {
this.url.searchParams.set('api-key', '<REDACTED>');
}
}
}
static async create(client, props) {
return new OpenAIRealtimeWebSocket({ ...props, __resolvedApiKey: await client._callApiKey() }, client);
}
static async azure(client, options = {}) {
const isApiKeyProvider = await client._callApiKey();
const apiKey = client.apiKey;
if (!apiKey) {
throw new Error('Azure OpenAI Realtime requires an API key');
}
const azureApiKey = apiKey;
function onURL(url) {
if (isApiKeyProvider) {
url.searchParams.set('Authorization', `Bearer ${azureApiKey}`);
}
else {
url.searchParams.set('api-key', azureApiKey);
}
}
const deploymentName = options.deploymentName ?? client.deploymentName;
if (!deploymentName) {
throw new Error('No deployment name provided');
}
const { dangerouslyAllowBrowser } = options;
return new OpenAIRealtimeWebSocket({
model: deploymentName,
onURL,
...(dangerouslyAllowBrowser ? { dangerouslyAllowBrowser } : {}),
__resolvedApiKey: isApiKeyProvider,
}, client);
}
send(event) {
try {
this.socket.send(JSON.stringify(event));
}
catch (err) {
this._onError(null, 'could not send data', err);
}
}
close(props) {
try {
this.socket.close(props?.code ?? 1000, props?.reason ?? 'OK');
}
catch (err) {
this._onError(null, 'could not close the connection', err);
}
}
}
//# sourceMappingURL=websocket.mjs.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"websocket.mjs","sourceRoot":"","sources":["../../src/beta/realtime/websocket.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,MAAM,EAAE,wBAAoB;AAClD,OAAO,EAAE,WAAW,EAAE,wBAAoB;AAE1C,OAAO,EACL,qBAAqB,EACrB,gBAAgB,EAChB,OAAO,GAER,4BAAwB;AACzB,OAAO,EAAE,kBAAkB,EAAE,2CAAuC;AAgBpE,MAAM,OAAO,uBAAwB,SAAQ,qBAAqB;IAIhE,YACE,KASC,EACD,MAA2C;QAE3C,KAAK,EAAE,CAAC;QACR,MAAM,WAAW,GAAG,OAAQ,MAAc,EAAE,QAAQ,EAAE,MAAM,KAAK,UAAU,CAAC;QAC5E,MAAM,uBAAuB,GAC3B,KAAK,CAAC,uBAAuB;YAC5B,MAAc,EAAE,QAAQ,EAAE,uBAAuB;YAClD,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACpD,IAAI,CAAC,uBAAuB,IAAI,kBAAkB,EAAE,EAAE,CAAC;YACrD,MAAM,IAAI,WAAW,CACnB,oSAAoS,CACrS,CAAC;QACJ,CAAC;QAED,MAAM,KAAN,MAAM,GAAK,IAAI,MAAM,CAAC,EAAE,uBAAuB,EAAE,CAAC,EAAC;QAEnD,IAAI,WAAW,IAAI,CAAC,KAAK,EAAE,gBAAgB,EAAE,CAAC;YAC5C,MAAM,IAAI,KAAK,CACb;gBACE,8DAA8D;gBAC9D,yEAAyE;aAC1E,CAAC,IAAI,CAAC,IAAI,CAAC,CACb,CAAC;QACJ,CAAC;QAED,IAAI,CAAC,GAAG,GAAG,gBAAgB,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAC3C,KAAK,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAExB,aAAa;QACb,IAAI,CAAC,MAAM,GAAG,IAAI,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE;YAC/C,UAAU;YACV,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,2BAA2B,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;YACxE,yBAAyB;SAC1B,CAAC,CAAC;QAEH,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE,CAAC,cAA4B,EAAE,EAAE;YACvE,MAAM,KAAK,GAAG,CAAC,GAAG,EAAE;gBAClB,IAAI,CAAC;oBACH,OAAO,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAwB,CAAC;gBAC3E,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,iCAAiC,EAAE,GAAG,CAAC,CAAC;oBAC5D,OAAO,IAAI,CAAC;gBACd,CAAC;YACH,CAAC,CAAC,EAAE,CAAC;YAEL,IAAI,KAAK,EAAE,CAAC;gBACV,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;gBAE3B,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;oBAC3B,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;gBACvB,CAAC;qBAAM,CAAC;oBACN,4EAA4E;oBAC5E,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;gBAChC,CAAC;YACH,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,CAAC,KAAU,EAAE,EAAE;YACnD,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QAC3C,CAAC,CAAC,CAAC;QAEH,IAAI,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YACpB,IAAI,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,eAAe,CAAC,KAAK,IAAI,EAAE,CAAC;gBACxD,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,eAAe,EAAE,YAAY,CAAC,CAAC;YAC3D,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;YACrD,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,MAAM,CACjB,MAA0D,EAC1D,KAAuE;QAEvE,OAAO,IAAI,uBAAuB,CAAC,EAAE,GAAG,KAAK,EAAE,gBAAgB,EAAE,MAAM,MAAM,CAAC,WAAW,EAAE,EAAE,EAAE,MAAM,CAAC,CAAC;IACzG,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,KAAK,CAChB,MAAiG,EACjG,UAA0E,EAAE;QAE5E,MAAM,gBAAgB,GAAG,MAAM,MAAM,CAAC,WAAW,EAAE,CAAC;QACpD,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;QAC7B,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;QAC/D,CAAC;QACD,MAAM,WAAW,GAAG,MAAM,CAAC;QAC3B,SAAS,KAAK,CAAC,GAAQ;YACrB,IAAI,gBAAgB,EAAE,CAAC;gBACrB,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,eAAe,EAAE,UAAU,WAAW,EAAE,CAAC,CAAC;YACjE,CAAC;iBAAM,CAAC;gBACN,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;YAC/C,CAAC;QACH,CAAC;QACD,MAAM,cAAc,GAAG,OAAO,CAAC,cAAc,IAAI,MAAM,CAAC,cAAc,CAAC;QACvE,IAAI,CAAC,cAAc,EAAE,CAAC;YACpB,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;QACjD,CAAC;QACD,MAAM,EAAE,uBAAuB,EAAE,GAAG,OAAO,CAAC;QAC5C,OAAO,IAAI,uBAAuB,CAChC;YACE,KAAK,EAAE,cAAc;YACrB,KAAK;YACL,GAAG,CAAC,uBAAuB,CAAC,CAAC,CAAC,EAAE,uBAAuB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC/D,gBAAgB,EAAE,gBAAgB;SACnC,EACD,MAAM,CACP,CAAC;IACJ,CAAC;IAED,IAAI,CAAC,KAA0B;QAC7B,IAAI,CAAC;YACH,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;QAC1C,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,qBAAqB,EAAE,GAAG,CAAC,CAAC;QAClD,CAAC;IACH,CAAC;IAED,KAAK,CAAC,KAAwC;QAC5C,IAAI,CAAC;YACH,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,IAAI,IAAI,IAAI,EAAE,KAAK,EAAE,MAAM,IAAI,IAAI,CAAC,CAAC;QAChE,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,gCAAgC,EAAE,GAAG,CAAC,CAAC;QAC7D,CAAC;IACH,CAAC;CACF"}
+25
View File
@@ -0,0 +1,25 @@
import * as WS from 'ws';
import { AzureOpenAI, OpenAI } from "../../index.mjs";
import type { RealtimeClientEvent } from "../../resources/beta/realtime/realtime.mjs";
import { OpenAIRealtimeEmitter, type RealtimeConnectionConfig } from "./internal-base.mjs";
export declare class OpenAIRealtimeWS extends OpenAIRealtimeEmitter {
url: URL;
socket: WS.WebSocket;
constructor(props: RealtimeConnectionConfig & {
options?: WS.ClientOptions | undefined;
/** @internal */ __resolvedApiKey?: boolean;
}, client?: Pick<OpenAI, 'apiKey' | 'baseURL'>);
static create(client: Pick<OpenAI, 'apiKey' | 'baseURL' | '_callApiKey'>, props: RealtimeConnectionConfig & {
options?: WS.ClientOptions | undefined;
}): Promise<OpenAIRealtimeWS>;
static azure(client: Pick<AzureOpenAI, '_callApiKey' | 'apiVersion' | 'apiKey' | 'baseURL' | 'deploymentName'>, props?: {
deploymentName?: string;
options?: WS.ClientOptions | undefined;
}): Promise<OpenAIRealtimeWS>;
send(event: RealtimeClientEvent): void;
close(props?: {
code: number;
reason: string;
}): void;
}
//# sourceMappingURL=ws.d.mts.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"ws.d.mts","sourceRoot":"","sources":["../../src/beta/realtime/ws.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,wBAAoB;AAClD,OAAO,KAAK,EAAE,mBAAmB,EAAuB,mDAA+C;AACvG,OAAO,EACL,qBAAqB,EAGrB,KAAK,wBAAwB,EAC9B,4BAAwB;AAEzB,qBAAa,gBAAiB,SAAQ,qBAAqB;IACzD,GAAG,EAAE,GAAG,CAAC;IACT,MAAM,EAAE,EAAE,CAAC,SAAS,CAAC;gBAGnB,KAAK,EAAE,wBAAwB,GAAG;QAChC,OAAO,CAAC,EAAE,EAAE,CAAC,aAAa,GAAG,SAAS,CAAC;QACvC,gBAAgB,CAAC,gBAAgB,CAAC,EAAE,OAAO,CAAC;KAC7C,EACD,MAAM,CAAC,EAAE,IAAI,CAAC,MAAM,EAAE,QAAQ,GAAG,SAAS,CAAC;WAkDhC,MAAM,CACjB,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,QAAQ,GAAG,SAAS,GAAG,aAAa,CAAC,EAC1D,KAAK,EAAE,wBAAwB,GAAG;QAAE,OAAO,CAAC,EAAE,EAAE,CAAC,aAAa,GAAG,SAAS,CAAA;KAAE,GAC3E,OAAO,CAAC,gBAAgB,CAAC;WAIf,KAAK,CAChB,MAAM,EAAE,IAAI,CAAC,WAAW,EAAE,aAAa,GAAG,YAAY,GAAG,QAAQ,GAAG,SAAS,GAAG,gBAAgB,CAAC,EACjG,KAAK,GAAE;QAAE,cAAc,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,EAAE,CAAC,aAAa,GAAG,SAAS,CAAA;KAAO,GAC9E,OAAO,CAAC,gBAAgB,CAAC;IA0B5B,IAAI,CAAC,KAAK,EAAE,mBAAmB;IAQ/B,KAAK,CAAC,KAAK,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE;CAO/C"}
+25
View File
@@ -0,0 +1,25 @@
import * as WS from 'ws';
import { AzureOpenAI, OpenAI } from "../../index.js";
import type { RealtimeClientEvent } from "../../resources/beta/realtime/realtime.js";
import { OpenAIRealtimeEmitter, type RealtimeConnectionConfig } from "./internal-base.js";
export declare class OpenAIRealtimeWS extends OpenAIRealtimeEmitter {
url: URL;
socket: WS.WebSocket;
constructor(props: RealtimeConnectionConfig & {
options?: WS.ClientOptions | undefined;
/** @internal */ __resolvedApiKey?: boolean;
}, client?: Pick<OpenAI, 'apiKey' | 'baseURL'>);
static create(client: Pick<OpenAI, 'apiKey' | 'baseURL' | '_callApiKey'>, props: RealtimeConnectionConfig & {
options?: WS.ClientOptions | undefined;
}): Promise<OpenAIRealtimeWS>;
static azure(client: Pick<AzureOpenAI, '_callApiKey' | 'apiVersion' | 'apiKey' | 'baseURL' | 'deploymentName'>, props?: {
deploymentName?: string;
options?: WS.ClientOptions | undefined;
}): Promise<OpenAIRealtimeWS>;
send(event: RealtimeClientEvent): void;
close(props?: {
code: number;
reason: string;
}): void;
}
//# sourceMappingURL=ws.d.ts.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"ws.d.ts","sourceRoot":"","sources":["../../src/beta/realtime/ws.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,uBAAoB;AAClD,OAAO,KAAK,EAAE,mBAAmB,EAAuB,kDAA+C;AACvG,OAAO,EACL,qBAAqB,EAGrB,KAAK,wBAAwB,EAC9B,2BAAwB;AAEzB,qBAAa,gBAAiB,SAAQ,qBAAqB;IACzD,GAAG,EAAE,GAAG,CAAC;IACT,MAAM,EAAE,EAAE,CAAC,SAAS,CAAC;gBAGnB,KAAK,EAAE,wBAAwB,GAAG;QAChC,OAAO,CAAC,EAAE,EAAE,CAAC,aAAa,GAAG,SAAS,CAAC;QACvC,gBAAgB,CAAC,gBAAgB,CAAC,EAAE,OAAO,CAAC;KAC7C,EACD,MAAM,CAAC,EAAE,IAAI,CAAC,MAAM,EAAE,QAAQ,GAAG,SAAS,CAAC;WAkDhC,MAAM,CACjB,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,QAAQ,GAAG,SAAS,GAAG,aAAa,CAAC,EAC1D,KAAK,EAAE,wBAAwB,GAAG;QAAE,OAAO,CAAC,EAAE,EAAE,CAAC,aAAa,GAAG,SAAS,CAAA;KAAE,GAC3E,OAAO,CAAC,gBAAgB,CAAC;WAIf,KAAK,CAChB,MAAM,EAAE,IAAI,CAAC,WAAW,EAAE,aAAa,GAAG,YAAY,GAAG,QAAQ,GAAG,SAAS,GAAG,gBAAgB,CAAC,EACjG,KAAK,GAAE;QAAE,cAAc,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,EAAE,CAAC,aAAa,GAAG,SAAS,CAAA;KAAO,GAC9E,OAAO,CAAC,gBAAgB,CAAC;IA0B5B,IAAI,CAAC,KAAK,EAAE,mBAAmB;IAQ/B,KAAK,CAAC,KAAK,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE;CAO/C"}
+96
View File
@@ -0,0 +1,96 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.OpenAIRealtimeWS = void 0;
const tslib_1 = require("../../internal/tslib.js");
const WS = tslib_1.__importStar(require("ws"));
const index_1 = require("../../index.js");
const internal_base_1 = require("./internal-base.js");
class OpenAIRealtimeWS extends internal_base_1.OpenAIRealtimeEmitter {
constructor(props, client) {
super();
client ?? (client = new index_1.OpenAI());
const hasProvider = typeof client?._options?.apiKey === 'function';
if (hasProvider && !props.__resolvedApiKey) {
throw new Error([
'Cannot open Realtime WebSocket with a function-based apiKey.',
'Use the .create() method so that the key is resolved before connecting.',
].join('\n'));
}
this.url = (0, internal_base_1.buildRealtimeURL)(client, props);
this.socket = new WS.WebSocket(this.url, {
...props.options,
headers: {
...props.options?.headers,
...((0, internal_base_1.isAzure)(client) && !props.__resolvedApiKey ? {} : { Authorization: `Bearer ${client.apiKey}` }),
'OpenAI-Beta': 'realtime=v1',
},
});
this.socket.on('message', (wsEvent) => {
const event = (() => {
try {
return JSON.parse(wsEvent.toString());
}
catch (err) {
this._onError(null, 'could not parse websocket event', err);
return null;
}
})();
if (event) {
this._emit('event', event);
if (event.type === 'error') {
this._onError(event);
}
else {
// @ts-expect-error TS isn't smart enough to get the relationship right here
this._emit(event.type, event);
}
}
});
this.socket.on('error', (err) => {
this._onError(null, err.message, err);
});
}
static async create(client, props) {
return new OpenAIRealtimeWS({ ...props, __resolvedApiKey: await client._callApiKey() }, client);
}
static async azure(client, props = {}) {
const isApiKeyProvider = await client._callApiKey();
const apiKey = client.apiKey;
if (!apiKey) {
throw new Error('Azure OpenAI Realtime requires an API key');
}
const deploymentName = props.deploymentName ?? client.deploymentName;
if (!deploymentName) {
throw new Error('No deployment name provided');
}
return new OpenAIRealtimeWS({
model: deploymentName,
options: {
...props.options,
headers: {
...props.options?.headers,
...(isApiKeyProvider ? {} : { 'api-key': apiKey }),
},
},
__resolvedApiKey: isApiKeyProvider,
}, client);
}
send(event) {
try {
this.socket.send(JSON.stringify(event));
}
catch (err) {
this._onError(null, 'could not send data', err);
}
}
close(props) {
try {
this.socket.close(props?.code ?? 1000, props?.reason ?? 'OK');
}
catch (err) {
this._onError(null, 'could not close the connection', err);
}
}
}
exports.OpenAIRealtimeWS = OpenAIRealtimeWS;
//# sourceMappingURL=ws.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"ws.js","sourceRoot":"","sources":["../../src/beta/realtime/ws.ts"],"names":[],"mappings":"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"}
+91
View File
@@ -0,0 +1,91 @@
import * as WS from 'ws';
import { OpenAI } from "../../index.mjs";
import { OpenAIRealtimeEmitter, buildRealtimeURL, isAzure, } from "./internal-base.mjs";
export class OpenAIRealtimeWS extends OpenAIRealtimeEmitter {
constructor(props, client) {
super();
client ?? (client = new OpenAI());
const hasProvider = typeof client?._options?.apiKey === 'function';
if (hasProvider && !props.__resolvedApiKey) {
throw new Error([
'Cannot open Realtime WebSocket with a function-based apiKey.',
'Use the .create() method so that the key is resolved before connecting.',
].join('\n'));
}
this.url = buildRealtimeURL(client, props);
this.socket = new WS.WebSocket(this.url, {
...props.options,
headers: {
...props.options?.headers,
...(isAzure(client) && !props.__resolvedApiKey ? {} : { Authorization: `Bearer ${client.apiKey}` }),
'OpenAI-Beta': 'realtime=v1',
},
});
this.socket.on('message', (wsEvent) => {
const event = (() => {
try {
return JSON.parse(wsEvent.toString());
}
catch (err) {
this._onError(null, 'could not parse websocket event', err);
return null;
}
})();
if (event) {
this._emit('event', event);
if (event.type === 'error') {
this._onError(event);
}
else {
// @ts-expect-error TS isn't smart enough to get the relationship right here
this._emit(event.type, event);
}
}
});
this.socket.on('error', (err) => {
this._onError(null, err.message, err);
});
}
static async create(client, props) {
return new OpenAIRealtimeWS({ ...props, __resolvedApiKey: await client._callApiKey() }, client);
}
static async azure(client, props = {}) {
const isApiKeyProvider = await client._callApiKey();
const apiKey = client.apiKey;
if (!apiKey) {
throw new Error('Azure OpenAI Realtime requires an API key');
}
const deploymentName = props.deploymentName ?? client.deploymentName;
if (!deploymentName) {
throw new Error('No deployment name provided');
}
return new OpenAIRealtimeWS({
model: deploymentName,
options: {
...props.options,
headers: {
...props.options?.headers,
...(isApiKeyProvider ? {} : { 'api-key': apiKey }),
},
},
__resolvedApiKey: isApiKeyProvider,
}, client);
}
send(event) {
try {
this.socket.send(JSON.stringify(event));
}
catch (err) {
this._onError(null, 'could not send data', err);
}
}
close(props) {
try {
this.socket.close(props?.code ?? 1000, props?.reason ?? 'OK');
}
catch (err) {
this._onError(null, 'could not close the connection', err);
}
}
}
//# sourceMappingURL=ws.mjs.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"ws.mjs","sourceRoot":"","sources":["../../src/beta/realtime/ws.ts"],"names":[],"mappings":"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"}