@runappsai/sdk 0.6.10 → 0.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +36 -2
- package/dist/audio.d.ts +7 -1
- package/dist/audio.d.ts.map +1 -1
- package/dist/audio.js +6 -0
- package/dist/audio.js.map +1 -1
- package/dist/client.d.ts +3 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +4 -0
- package/dist/client.js.map +1 -1
- package/dist/events.d.ts +2 -0
- package/dist/events.d.ts.map +1 -1
- package/dist/events.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/realtime.d.ts +144 -0
- package/dist/realtime.d.ts.map +1 -0
- package/dist/realtime.js +364 -0
- package/dist/realtime.js.map +1 -0
- package/dist/sdk.umd.js +3 -3
- package/dist/sdk.umd.js.map +1 -1
- package/dist/transport.d.ts +2 -0
- package/dist/transport.d.ts.map +1 -1
- package/dist/transport.js +4 -0
- package/dist/transport.js.map +1 -1
- package/package.json +1 -1
- package/src/audio.ts +12 -1
- package/src/client.ts +4 -0
- package/src/events.ts +2 -0
- package/src/index.ts +17 -0
- package/src/realtime.ts +457 -0
- package/src/transport.ts +5 -0
package/dist/realtime.js
ADDED
|
@@ -0,0 +1,364 @@
|
|
|
1
|
+
import { newRequestId } from "./events.js";
|
|
2
|
+
const OPEN = 1;
|
|
3
|
+
const CLOSE_TIMEOUT_MS = 10_000;
|
|
4
|
+
/**
|
|
5
|
+
* A live realtime session. Listen with `on(type, handler)` (or iterate
|
|
6
|
+
* it with `for await`), talk with `appendAudio()` / `say()`, and end it
|
|
7
|
+
* with `close()`.
|
|
8
|
+
*/
|
|
9
|
+
export class RealtimeSession {
|
|
10
|
+
ws;
|
|
11
|
+
/** The upstream session id (from `session.created`); pass it as
|
|
12
|
+
* `session.id` to a later session to continue the conversation. */
|
|
13
|
+
sessionId = "";
|
|
14
|
+
/** Settles when the socket closes, however that happens. */
|
|
15
|
+
closed;
|
|
16
|
+
handlers = new Map();
|
|
17
|
+
usage = null;
|
|
18
|
+
resolveClosed;
|
|
19
|
+
isClosed = false;
|
|
20
|
+
queue = [];
|
|
21
|
+
waiters = [];
|
|
22
|
+
iterating = false;
|
|
23
|
+
/** @internal */
|
|
24
|
+
constructor(ws) {
|
|
25
|
+
this.ws = ws;
|
|
26
|
+
this.closed = new Promise((resolve) => {
|
|
27
|
+
this.resolveClosed = resolve;
|
|
28
|
+
});
|
|
29
|
+
ws.addEventListener("message", (ev) => {
|
|
30
|
+
if (typeof ev.data !== "string")
|
|
31
|
+
return;
|
|
32
|
+
let event;
|
|
33
|
+
try {
|
|
34
|
+
event = JSON.parse(ev.data);
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
if (!event || typeof event.type !== "string")
|
|
40
|
+
return;
|
|
41
|
+
if (event.type === "session.created") {
|
|
42
|
+
const id = event.session?.id;
|
|
43
|
+
if (typeof id === "string")
|
|
44
|
+
this.sessionId = id;
|
|
45
|
+
}
|
|
46
|
+
else if (event.type === "gateway.usage") {
|
|
47
|
+
this.usage = event.usage ?? null;
|
|
48
|
+
}
|
|
49
|
+
this.dispatch(event);
|
|
50
|
+
});
|
|
51
|
+
ws.addEventListener("close", (ev) => {
|
|
52
|
+
if (this.isClosed)
|
|
53
|
+
return;
|
|
54
|
+
this.isClosed = true;
|
|
55
|
+
for (const w of this.waiters.splice(0))
|
|
56
|
+
w({ value: undefined, done: true });
|
|
57
|
+
this.resolveClosed({ code: ev.code ?? 1006, reason: ev.reason ?? "", usage: this.usage });
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Subscribe to events of one type, or `"*"` for all of them. Returns
|
|
62
|
+
* the unsubscribe function.
|
|
63
|
+
*/
|
|
64
|
+
on(type, handler) {
|
|
65
|
+
let set = this.handlers.get(type);
|
|
66
|
+
if (!set) {
|
|
67
|
+
set = new Set();
|
|
68
|
+
this.handlers.set(type, set);
|
|
69
|
+
}
|
|
70
|
+
set.add(handler);
|
|
71
|
+
return () => set.delete(handler);
|
|
72
|
+
}
|
|
73
|
+
/** Send a raw protocol event. */
|
|
74
|
+
send(event) {
|
|
75
|
+
if (this.ws.readyState !== OPEN)
|
|
76
|
+
throw new Error("runapps: realtime session is closed");
|
|
77
|
+
this.ws.send(JSON.stringify(event));
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Stream a chunk of microphone audio: 16-bit little-endian PCM, 16 kHz
|
|
81
|
+
* mono (`pcm16FromFloat32` converts Web Audio samples). Send ~20 ms
|
|
82
|
+
* (640 bytes) at a time, as it is captured.
|
|
83
|
+
*/
|
|
84
|
+
appendAudio(pcm16) {
|
|
85
|
+
this.send({ type: "input_audio_buffer.append", audio: bytesToBase64(asBytes(pcm16)) });
|
|
86
|
+
}
|
|
87
|
+
/** Tell the model the user has finished speaking (skips end-of-speech detection). */
|
|
88
|
+
commitAudio() {
|
|
89
|
+
this.send({ type: "input_audio_buffer.commit" });
|
|
90
|
+
}
|
|
91
|
+
/** The microphone is off: stops the model waiting on audio. */
|
|
92
|
+
mute() {
|
|
93
|
+
this.send({ type: "input_audio_mute.commit" });
|
|
94
|
+
}
|
|
95
|
+
/** The microphone is back on. */
|
|
96
|
+
unmute() {
|
|
97
|
+
this.send({ type: "input_audio_unmute.commit" });
|
|
98
|
+
}
|
|
99
|
+
/** Have the model speak `text` (a greeting, or a scripted line). */
|
|
100
|
+
say(text) {
|
|
101
|
+
this.send({ type: "speech_text_buffer.commit", text });
|
|
102
|
+
}
|
|
103
|
+
/** Interrupt the model's current reply. */
|
|
104
|
+
cancelResponse() {
|
|
105
|
+
this.send({ type: "response.cancel" });
|
|
106
|
+
}
|
|
107
|
+
/** Change session settings mid-session (instructions, voice, tools, …). */
|
|
108
|
+
update(session) {
|
|
109
|
+
this.send({ type: "session.update", session });
|
|
110
|
+
}
|
|
111
|
+
/** Answer a `response.function_call_arguments.done` tool call. */
|
|
112
|
+
sendFunctionResult(callId, output) {
|
|
113
|
+
this.send({
|
|
114
|
+
type: "conversation.item.create",
|
|
115
|
+
items: [{ call_id: callId, role: "tool", content: [{ type: "input_text", text: output }] }],
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* End the session: asks the model to close, waits for the server to
|
|
120
|
+
* hang up (so the closing `gateway.usage` arrives), and resolves with
|
|
121
|
+
* how it ended, including the cost.
|
|
122
|
+
*/
|
|
123
|
+
async close() {
|
|
124
|
+
if (!this.isClosed && this.ws.readyState === OPEN) {
|
|
125
|
+
try {
|
|
126
|
+
this.send({ type: "session.close" });
|
|
127
|
+
}
|
|
128
|
+
catch {
|
|
129
|
+
// already closing
|
|
130
|
+
}
|
|
131
|
+
const timer = setTimeout(() => this.ws.close(1000, "client timeout"), CLOSE_TIMEOUT_MS);
|
|
132
|
+
try {
|
|
133
|
+
return await this.closed;
|
|
134
|
+
}
|
|
135
|
+
finally {
|
|
136
|
+
clearTimeout(timer);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
if (!this.isClosed)
|
|
140
|
+
this.ws.close(1000);
|
|
141
|
+
return this.closed;
|
|
142
|
+
}
|
|
143
|
+
/** Iterate events until the session closes. */
|
|
144
|
+
[Symbol.asyncIterator]() {
|
|
145
|
+
this.iterating = true;
|
|
146
|
+
return {
|
|
147
|
+
next: () => {
|
|
148
|
+
const event = this.queue.shift();
|
|
149
|
+
if (event)
|
|
150
|
+
return Promise.resolve({ value: event, done: false });
|
|
151
|
+
if (this.isClosed)
|
|
152
|
+
return Promise.resolve({ value: undefined, done: true });
|
|
153
|
+
return new Promise((resolve) => this.waiters.push(resolve));
|
|
154
|
+
},
|
|
155
|
+
return: () => {
|
|
156
|
+
this.iterating = false;
|
|
157
|
+
this.queue = [];
|
|
158
|
+
return Promise.resolve({ value: undefined, done: true });
|
|
159
|
+
},
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
dispatch(event) {
|
|
163
|
+
for (const type of [event.type, "*"]) {
|
|
164
|
+
const set = this.handlers.get(type);
|
|
165
|
+
if (!set)
|
|
166
|
+
continue;
|
|
167
|
+
for (const h of [...set]) {
|
|
168
|
+
try {
|
|
169
|
+
h(event);
|
|
170
|
+
}
|
|
171
|
+
catch (err) {
|
|
172
|
+
// A broken handler must not stop the others or the session.
|
|
173
|
+
setTimeout(() => {
|
|
174
|
+
throw err;
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
if (this.iterating) {
|
|
180
|
+
const w = this.waiters.shift();
|
|
181
|
+
if (w)
|
|
182
|
+
w({ value: event, done: false });
|
|
183
|
+
else
|
|
184
|
+
this.queue.push(event);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
export class RealtimeService {
|
|
189
|
+
transport;
|
|
190
|
+
events;
|
|
191
|
+
constructor(transport, events) {
|
|
192
|
+
this.transport = transport;
|
|
193
|
+
this.events = events;
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Open a realtime voice session. Resolves once the model has accepted
|
|
197
|
+
* it (`session.created`); rejects if the connection fails first.
|
|
198
|
+
*/
|
|
199
|
+
async connect(options = {}) {
|
|
200
|
+
const WS = options.WebSocket ?? globalThis.WebSocket;
|
|
201
|
+
if (!WS) {
|
|
202
|
+
throw new Error("runapps: no WebSocket available — pass `WebSocket` (e.g. from the `ws` package) on Node < 22");
|
|
203
|
+
}
|
|
204
|
+
const token = await this.transport.bearerToken();
|
|
205
|
+
const ws = new WS(realtimeURL(this.transport.baseURL, options), ["realtime", "runapps-key." + token]);
|
|
206
|
+
const session = new RealtimeSession(ws);
|
|
207
|
+
const model = options.model ?? "";
|
|
208
|
+
const id = newRequestId();
|
|
209
|
+
const startedAt = Date.now();
|
|
210
|
+
this.events.emit("request:start", { id, model, capability: "realtime", startedAt, streaming: true });
|
|
211
|
+
try {
|
|
212
|
+
await new Promise((resolve, reject) => {
|
|
213
|
+
const timer = setTimeout(() => {
|
|
214
|
+
fail(new Error("runapps: realtime session did not open in time"));
|
|
215
|
+
ws.close(1000, "open timeout");
|
|
216
|
+
}, options.timeoutMs ?? 15_000);
|
|
217
|
+
const onAbort = () => {
|
|
218
|
+
fail(new Error("runapps: realtime connect aborted"));
|
|
219
|
+
ws.close(1000, "aborted");
|
|
220
|
+
};
|
|
221
|
+
options.signal?.addEventListener("abort", onAbort, { once: true });
|
|
222
|
+
let settled = false;
|
|
223
|
+
function fail(err) {
|
|
224
|
+
if (settled)
|
|
225
|
+
return;
|
|
226
|
+
settled = true;
|
|
227
|
+
clearTimeout(timer);
|
|
228
|
+
options.signal?.removeEventListener("abort", onAbort);
|
|
229
|
+
reject(err);
|
|
230
|
+
}
|
|
231
|
+
const offCreated = session.on("session.created", () => {
|
|
232
|
+
if (settled)
|
|
233
|
+
return;
|
|
234
|
+
settled = true;
|
|
235
|
+
clearTimeout(timer);
|
|
236
|
+
options.signal?.removeEventListener("abort", onAbort);
|
|
237
|
+
offCreated();
|
|
238
|
+
offError();
|
|
239
|
+
resolve();
|
|
240
|
+
});
|
|
241
|
+
// An error before the session opens is fatal to connect().
|
|
242
|
+
const offError = session.on("error", (ev) => {
|
|
243
|
+
const e = (ev.error ?? {});
|
|
244
|
+
fail(new Error(`runapps: realtime error: ${e.message ?? JSON.stringify(ev)}`));
|
|
245
|
+
});
|
|
246
|
+
ws.addEventListener("open", () => {
|
|
247
|
+
ws.send(JSON.stringify(openingEvent(options)));
|
|
248
|
+
});
|
|
249
|
+
void session.closed.then((info) => {
|
|
250
|
+
// A refused handshake (bad key, unknown model, low balance) reaches
|
|
251
|
+
// a WebSocket client only as 1006 — the HTTP status is hidden.
|
|
252
|
+
const hint = info.code === 1006 ? " — check the API key, the model name and the account balance" : "";
|
|
253
|
+
fail(new Error(`runapps: realtime connection closed (${info.code}${info.reason ? " " + info.reason : ""})${hint}`));
|
|
254
|
+
});
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
catch (err) {
|
|
258
|
+
try {
|
|
259
|
+
ws.close(1000, "connect failed");
|
|
260
|
+
}
|
|
261
|
+
catch {
|
|
262
|
+
// already closed
|
|
263
|
+
}
|
|
264
|
+
this.events.emit("request:error", {
|
|
265
|
+
id,
|
|
266
|
+
model,
|
|
267
|
+
capability: "realtime",
|
|
268
|
+
latencyMs: Date.now() - startedAt,
|
|
269
|
+
error: err,
|
|
270
|
+
});
|
|
271
|
+
throw err;
|
|
272
|
+
}
|
|
273
|
+
void session.closed.then((info) => {
|
|
274
|
+
this.events.emit("request:end", {
|
|
275
|
+
id,
|
|
276
|
+
model,
|
|
277
|
+
capability: "realtime",
|
|
278
|
+
latencyMs: Date.now() - startedAt,
|
|
279
|
+
totalTokens: info.usage?.output_tokens ?? 0,
|
|
280
|
+
...(info.usage?.total_cost !== undefined && { costUSD: info.usage.total_cost }),
|
|
281
|
+
});
|
|
282
|
+
});
|
|
283
|
+
return session;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
function openingEvent(options) {
|
|
287
|
+
const event = { type: "session.create", session: options.session ?? {} };
|
|
288
|
+
if (options.extension)
|
|
289
|
+
event.extension = options.extension;
|
|
290
|
+
return event;
|
|
291
|
+
}
|
|
292
|
+
function realtimeURL(baseURL, options) {
|
|
293
|
+
const u = new URL(baseURL.replace(/\/+$/, "") + "/v1/realtime");
|
|
294
|
+
u.protocol = u.protocol === "http:" ? "ws:" : "wss:";
|
|
295
|
+
for (const [k, v] of Object.entries(options.query ?? {}))
|
|
296
|
+
u.searchParams.set(k, v);
|
|
297
|
+
if (options.model)
|
|
298
|
+
u.searchParams.set("model", options.model);
|
|
299
|
+
if (options.maxCost !== undefined && options.maxCost > 0)
|
|
300
|
+
u.searchParams.set("max_cost", String(options.maxCost));
|
|
301
|
+
return u.toString();
|
|
302
|
+
}
|
|
303
|
+
/* ------------------------------------------------------------------ */
|
|
304
|
+
/* PCM helpers */
|
|
305
|
+
/* ------------------------------------------------------------------ */
|
|
306
|
+
/**
|
|
307
|
+
* Convert Web Audio samples (Float32, -1…1) at `sampleRate` to 16-bit PCM
|
|
308
|
+
* at `targetRate` (16 kHz, what realtime input expects), resampling
|
|
309
|
+
* linearly when the rates differ.
|
|
310
|
+
*/
|
|
311
|
+
export function pcm16FromFloat32(samples, sampleRate, targetRate = 16000) {
|
|
312
|
+
const ratio = sampleRate / targetRate;
|
|
313
|
+
const n = ratio === 1 ? samples.length : Math.floor(samples.length / ratio);
|
|
314
|
+
const out = new Int16Array(n);
|
|
315
|
+
for (let i = 0; i < n; i++) {
|
|
316
|
+
let s;
|
|
317
|
+
if (ratio === 1) {
|
|
318
|
+
s = samples[i];
|
|
319
|
+
}
|
|
320
|
+
else {
|
|
321
|
+
const pos = i * ratio;
|
|
322
|
+
const j = Math.floor(pos);
|
|
323
|
+
const frac = pos - j;
|
|
324
|
+
const a = samples[j];
|
|
325
|
+
const b = samples[Math.min(j + 1, samples.length - 1)];
|
|
326
|
+
s = a + (b - a) * frac;
|
|
327
|
+
}
|
|
328
|
+
s = Math.max(-1, Math.min(1, s));
|
|
329
|
+
out[i] = s < 0 ? s * 0x8000 : s * 0x7fff;
|
|
330
|
+
}
|
|
331
|
+
return out;
|
|
332
|
+
}
|
|
333
|
+
/** Convert 16-bit little-endian PCM bytes (e.g. a decoded audio delta) to Float32 samples for Web Audio. */
|
|
334
|
+
export function float32FromPCM16(bytes) {
|
|
335
|
+
const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
336
|
+
const out = new Float32Array(bytes.byteLength >> 1);
|
|
337
|
+
for (let i = 0; i < out.length; i++)
|
|
338
|
+
out[i] = view.getInt16(i * 2, true) / 0x8000;
|
|
339
|
+
return out;
|
|
340
|
+
}
|
|
341
|
+
/** Base64-encode bytes (audio for `input_audio_buffer.append`). */
|
|
342
|
+
export function bytesToBase64(bytes) {
|
|
343
|
+
let bin = "";
|
|
344
|
+
for (let i = 0; i < bytes.length; i += 0x8000) {
|
|
345
|
+
bin += String.fromCharCode(...bytes.subarray(i, i + 0x8000));
|
|
346
|
+
}
|
|
347
|
+
return btoa(bin);
|
|
348
|
+
}
|
|
349
|
+
/** Decode base64 (e.g. `response.output_audio.delta`'s `delta`) to bytes. */
|
|
350
|
+
export function base64ToBytes(b64) {
|
|
351
|
+
const bin = atob(b64);
|
|
352
|
+
const out = new Uint8Array(bin.length);
|
|
353
|
+
for (let i = 0; i < bin.length; i++)
|
|
354
|
+
out[i] = bin.charCodeAt(i);
|
|
355
|
+
return out;
|
|
356
|
+
}
|
|
357
|
+
function asBytes(v) {
|
|
358
|
+
if (v instanceof Uint8Array)
|
|
359
|
+
return v;
|
|
360
|
+
if (v instanceof ArrayBuffer)
|
|
361
|
+
return new Uint8Array(v);
|
|
362
|
+
return new Uint8Array(v.buffer, v.byteOffset, v.byteLength);
|
|
363
|
+
}
|
|
364
|
+
//# sourceMappingURL=realtime.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"realtime.js","sourceRoot":"","sources":["../src/realtime.ts"],"names":[],"mappings":"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"}
|