@mastra/voice-openai-realtime 0.2.0-alpha.2 → 0.2.0-alpha.3
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/.turbo/turbo-build.log +7 -7
- package/CHANGELOG.md +11 -0
- package/dist/_tsup-dts-rollup.d.cts +2 -1
- package/dist/_tsup-dts-rollup.d.ts +2 -1
- package/dist/index.cjs +26 -22
- package/dist/index.js +26 -22
- package/package.json +2 -2
- package/src/index.ts +20 -16
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
|
|
2
|
-
> @mastra/voice-openai-realtime@0.2.0-alpha.
|
|
2
|
+
> @mastra/voice-openai-realtime@0.2.0-alpha.3 build /home/runner/work/mastra/mastra/voice/openai-realtime-api
|
|
3
3
|
> tsup src/index.ts --format esm,cjs --experimental-dts --clean --treeshake
|
|
4
4
|
|
|
5
5
|
[34mCLI[39m Building entry: src/index.ts
|
|
6
6
|
[34mCLI[39m Using tsconfig: tsconfig.json
|
|
7
7
|
[34mCLI[39m tsup v8.4.0
|
|
8
8
|
[34mTSC[39m Build start
|
|
9
|
-
[32mTSC[39m ⚡️ Build success in
|
|
9
|
+
[32mTSC[39m ⚡️ Build success in 10105ms
|
|
10
10
|
[34mDTS[39m Build start
|
|
11
11
|
[34mCLI[39m Target: es2022
|
|
12
12
|
Analysis will use the bundled TypeScript version 5.8.2
|
|
13
13
|
[36mWriting package typings: /home/runner/work/mastra/mastra/voice/openai-realtime-api/dist/_tsup-dts-rollup.d.ts[39m
|
|
14
14
|
Analysis will use the bundled TypeScript version 5.8.2
|
|
15
15
|
[36mWriting package typings: /home/runner/work/mastra/mastra/voice/openai-realtime-api/dist/_tsup-dts-rollup.d.cts[39m
|
|
16
|
-
[32mDTS[39m ⚡️ Build success in
|
|
16
|
+
[32mDTS[39m ⚡️ Build success in 11772ms
|
|
17
17
|
[34mCLI[39m Cleaning output folder
|
|
18
18
|
[34mESM[39m Build start
|
|
19
19
|
[34mCJS[39m Build start
|
|
20
|
-
[32mESM[39m [1mdist/index.js [22m[32m18.
|
|
21
|
-
[32mESM[39m ⚡️ Build success in
|
|
22
|
-
[32mCJS[39m [1mdist/index.cjs [22m[32m18.
|
|
23
|
-
[32mCJS[39m ⚡️ Build success in
|
|
20
|
+
[32mESM[39m [1mdist/index.js [22m[32m18.72 KB[39m
|
|
21
|
+
[32mESM[39m ⚡️ Build success in 762ms
|
|
22
|
+
[32mCJS[39m [1mdist/index.cjs [22m[32m18.77 KB[39m
|
|
23
|
+
[32mCJS[39m ⚡️ Build success in 764ms
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# @mastra/voice-openai-realtime
|
|
2
2
|
|
|
3
|
+
## 0.2.0-alpha.3
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 9aaa64b: Don't connect the ws connection until connect is called
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- Updated dependencies [9ee4293]
|
|
12
|
+
- @mastra/core@0.8.4-alpha.2
|
|
13
|
+
|
|
3
14
|
## 0.2.0-alpha.2
|
|
4
15
|
|
|
5
16
|
### Minor Changes
|
|
@@ -43,7 +43,8 @@ export declare type OpenAIExecuteFunction = (args: any) => Promise<any>;
|
|
|
43
43
|
* ```
|
|
44
44
|
*/
|
|
45
45
|
export declare class OpenAIRealtimeVoice extends MastraVoice {
|
|
46
|
-
private
|
|
46
|
+
private options;
|
|
47
|
+
private ws?;
|
|
47
48
|
private state;
|
|
48
49
|
private client;
|
|
49
50
|
private events;
|
|
@@ -43,7 +43,8 @@ export declare type OpenAIExecuteFunction = (args: any) => Promise<any>;
|
|
|
43
43
|
* ```
|
|
44
44
|
*/
|
|
45
45
|
export declare class OpenAIRealtimeVoice extends MastraVoice {
|
|
46
|
-
private
|
|
46
|
+
private options;
|
|
47
|
+
private ws?;
|
|
47
48
|
private state;
|
|
48
49
|
private client;
|
|
49
50
|
private events;
|
package/dist/index.cjs
CHANGED
|
@@ -76,15 +76,6 @@ var DEFAULT_URL = "wss://api.openai.com/v1/realtime";
|
|
|
76
76
|
var DEFAULT_MODEL = "gpt-4o-mini-realtime-preview-2024-12-17";
|
|
77
77
|
var VOICES = ["alloy", "ash", "ballad", "coral", "echo", "sage", "shimmer", "verse"];
|
|
78
78
|
var OpenAIRealtimeVoice = class extends voice.MastraVoice {
|
|
79
|
-
ws;
|
|
80
|
-
state;
|
|
81
|
-
client;
|
|
82
|
-
events;
|
|
83
|
-
instructions;
|
|
84
|
-
tools;
|
|
85
|
-
debug;
|
|
86
|
-
queue = [];
|
|
87
|
-
transcriber;
|
|
88
79
|
/**
|
|
89
80
|
* Creates a new instance of OpenAIRealtimeVoice.
|
|
90
81
|
*
|
|
@@ -108,22 +99,23 @@ var OpenAIRealtimeVoice = class extends voice.MastraVoice {
|
|
|
108
99
|
*/
|
|
109
100
|
constructor(options = {}) {
|
|
110
101
|
super();
|
|
111
|
-
|
|
112
|
-
const apiKey = options.apiKey || process.env.OPENAI_API_KEY;
|
|
113
|
-
this.ws = new ws.WebSocket(url, void 0, {
|
|
114
|
-
headers: {
|
|
115
|
-
Authorization: "Bearer " + apiKey,
|
|
116
|
-
"OpenAI-Beta": "realtime=v1"
|
|
117
|
-
}
|
|
118
|
-
});
|
|
102
|
+
this.options = options;
|
|
119
103
|
this.client = new events.EventEmitter();
|
|
120
104
|
this.state = "close";
|
|
121
105
|
this.events = {};
|
|
122
106
|
this.speaker = options.speaker || DEFAULT_VOICE;
|
|
123
107
|
this.transcriber = options.transcriber || DEFAULT_TRANSCRIBER;
|
|
124
108
|
this.debug = options.debug || false;
|
|
125
|
-
this.setupEventListeners();
|
|
126
109
|
}
|
|
110
|
+
ws;
|
|
111
|
+
state;
|
|
112
|
+
client;
|
|
113
|
+
events;
|
|
114
|
+
instructions;
|
|
115
|
+
tools;
|
|
116
|
+
debug;
|
|
117
|
+
queue = [];
|
|
118
|
+
transcriber;
|
|
127
119
|
/**
|
|
128
120
|
* Returns a list of available voice speakers.
|
|
129
121
|
*
|
|
@@ -300,7 +292,7 @@ var OpenAIRealtimeVoice = class extends voice.MastraVoice {
|
|
|
300
292
|
}
|
|
301
293
|
waitForOpen() {
|
|
302
294
|
return new Promise((resolve) => {
|
|
303
|
-
this.ws
|
|
295
|
+
this.ws?.on("open", resolve);
|
|
304
296
|
});
|
|
305
297
|
}
|
|
306
298
|
waitForSessionCreated() {
|
|
@@ -321,6 +313,15 @@ var OpenAIRealtimeVoice = class extends voice.MastraVoice {
|
|
|
321
313
|
* ```
|
|
322
314
|
*/
|
|
323
315
|
async connect() {
|
|
316
|
+
const url = `${this.options.url || DEFAULT_URL}?model=${this.options.model || DEFAULT_MODEL}`;
|
|
317
|
+
const apiKey = this.options.apiKey || process.env.OPENAI_API_KEY;
|
|
318
|
+
this.ws = new ws.WebSocket(url, void 0, {
|
|
319
|
+
headers: {
|
|
320
|
+
Authorization: "Bearer " + apiKey,
|
|
321
|
+
"OpenAI-Beta": "realtime=v1"
|
|
322
|
+
}
|
|
323
|
+
});
|
|
324
|
+
this.setupEventListeners();
|
|
324
325
|
await this.waitForOpen();
|
|
325
326
|
await this.waitForSessionCreated();
|
|
326
327
|
const openaiTools = transformTools(this.tools);
|
|
@@ -466,6 +467,9 @@ var OpenAIRealtimeVoice = class extends voice.MastraVoice {
|
|
|
466
467
|
}
|
|
467
468
|
setupEventListeners() {
|
|
468
469
|
const speakerStreams = /* @__PURE__ */ new Map();
|
|
470
|
+
if (!this.ws) {
|
|
471
|
+
throw new Error("WebSocket not initialized");
|
|
472
|
+
}
|
|
469
473
|
this.ws.on("message", (message) => {
|
|
470
474
|
const data = JSON.parse(message.toString());
|
|
471
475
|
this.client.emit(data.type, data);
|
|
@@ -478,7 +482,7 @@ var OpenAIRealtimeVoice = class extends voice.MastraVoice {
|
|
|
478
482
|
this.emit("session.created", ev);
|
|
479
483
|
const queue = this.queue.splice(0, this.queue.length);
|
|
480
484
|
for (const ev2 of queue) {
|
|
481
|
-
this.ws
|
|
485
|
+
this.ws?.send(JSON.stringify(ev2));
|
|
482
486
|
}
|
|
483
487
|
});
|
|
484
488
|
this.client.on("session.updated", (ev) => {
|
|
@@ -589,10 +593,10 @@ var OpenAIRealtimeVoice = class extends voice.MastraVoice {
|
|
|
589
593
|
return btoa(binary);
|
|
590
594
|
}
|
|
591
595
|
sendEvent(type, data) {
|
|
592
|
-
if (this.ws.readyState !== this.ws.OPEN) {
|
|
596
|
+
if (!this.ws || this.ws.readyState !== this.ws.OPEN) {
|
|
593
597
|
this.queue.push({ type, ...data });
|
|
594
598
|
} else {
|
|
595
|
-
this.ws
|
|
599
|
+
this.ws?.send(
|
|
596
600
|
JSON.stringify({
|
|
597
601
|
type,
|
|
598
602
|
...data
|
package/dist/index.js
CHANGED
|
@@ -74,15 +74,6 @@ var DEFAULT_URL = "wss://api.openai.com/v1/realtime";
|
|
|
74
74
|
var DEFAULT_MODEL = "gpt-4o-mini-realtime-preview-2024-12-17";
|
|
75
75
|
var VOICES = ["alloy", "ash", "ballad", "coral", "echo", "sage", "shimmer", "verse"];
|
|
76
76
|
var OpenAIRealtimeVoice = class extends MastraVoice {
|
|
77
|
-
ws;
|
|
78
|
-
state;
|
|
79
|
-
client;
|
|
80
|
-
events;
|
|
81
|
-
instructions;
|
|
82
|
-
tools;
|
|
83
|
-
debug;
|
|
84
|
-
queue = [];
|
|
85
|
-
transcriber;
|
|
86
77
|
/**
|
|
87
78
|
* Creates a new instance of OpenAIRealtimeVoice.
|
|
88
79
|
*
|
|
@@ -106,22 +97,23 @@ var OpenAIRealtimeVoice = class extends MastraVoice {
|
|
|
106
97
|
*/
|
|
107
98
|
constructor(options = {}) {
|
|
108
99
|
super();
|
|
109
|
-
|
|
110
|
-
const apiKey = options.apiKey || process.env.OPENAI_API_KEY;
|
|
111
|
-
this.ws = new WebSocket(url, void 0, {
|
|
112
|
-
headers: {
|
|
113
|
-
Authorization: "Bearer " + apiKey,
|
|
114
|
-
"OpenAI-Beta": "realtime=v1"
|
|
115
|
-
}
|
|
116
|
-
});
|
|
100
|
+
this.options = options;
|
|
117
101
|
this.client = new EventEmitter();
|
|
118
102
|
this.state = "close";
|
|
119
103
|
this.events = {};
|
|
120
104
|
this.speaker = options.speaker || DEFAULT_VOICE;
|
|
121
105
|
this.transcriber = options.transcriber || DEFAULT_TRANSCRIBER;
|
|
122
106
|
this.debug = options.debug || false;
|
|
123
|
-
this.setupEventListeners();
|
|
124
107
|
}
|
|
108
|
+
ws;
|
|
109
|
+
state;
|
|
110
|
+
client;
|
|
111
|
+
events;
|
|
112
|
+
instructions;
|
|
113
|
+
tools;
|
|
114
|
+
debug;
|
|
115
|
+
queue = [];
|
|
116
|
+
transcriber;
|
|
125
117
|
/**
|
|
126
118
|
* Returns a list of available voice speakers.
|
|
127
119
|
*
|
|
@@ -298,7 +290,7 @@ var OpenAIRealtimeVoice = class extends MastraVoice {
|
|
|
298
290
|
}
|
|
299
291
|
waitForOpen() {
|
|
300
292
|
return new Promise((resolve) => {
|
|
301
|
-
this.ws
|
|
293
|
+
this.ws?.on("open", resolve);
|
|
302
294
|
});
|
|
303
295
|
}
|
|
304
296
|
waitForSessionCreated() {
|
|
@@ -319,6 +311,15 @@ var OpenAIRealtimeVoice = class extends MastraVoice {
|
|
|
319
311
|
* ```
|
|
320
312
|
*/
|
|
321
313
|
async connect() {
|
|
314
|
+
const url = `${this.options.url || DEFAULT_URL}?model=${this.options.model || DEFAULT_MODEL}`;
|
|
315
|
+
const apiKey = this.options.apiKey || process.env.OPENAI_API_KEY;
|
|
316
|
+
this.ws = new WebSocket(url, void 0, {
|
|
317
|
+
headers: {
|
|
318
|
+
Authorization: "Bearer " + apiKey,
|
|
319
|
+
"OpenAI-Beta": "realtime=v1"
|
|
320
|
+
}
|
|
321
|
+
});
|
|
322
|
+
this.setupEventListeners();
|
|
322
323
|
await this.waitForOpen();
|
|
323
324
|
await this.waitForSessionCreated();
|
|
324
325
|
const openaiTools = transformTools(this.tools);
|
|
@@ -464,6 +465,9 @@ var OpenAIRealtimeVoice = class extends MastraVoice {
|
|
|
464
465
|
}
|
|
465
466
|
setupEventListeners() {
|
|
466
467
|
const speakerStreams = /* @__PURE__ */ new Map();
|
|
468
|
+
if (!this.ws) {
|
|
469
|
+
throw new Error("WebSocket not initialized");
|
|
470
|
+
}
|
|
467
471
|
this.ws.on("message", (message) => {
|
|
468
472
|
const data = JSON.parse(message.toString());
|
|
469
473
|
this.client.emit(data.type, data);
|
|
@@ -476,7 +480,7 @@ var OpenAIRealtimeVoice = class extends MastraVoice {
|
|
|
476
480
|
this.emit("session.created", ev);
|
|
477
481
|
const queue = this.queue.splice(0, this.queue.length);
|
|
478
482
|
for (const ev2 of queue) {
|
|
479
|
-
this.ws
|
|
483
|
+
this.ws?.send(JSON.stringify(ev2));
|
|
480
484
|
}
|
|
481
485
|
});
|
|
482
486
|
this.client.on("session.updated", (ev) => {
|
|
@@ -587,10 +591,10 @@ var OpenAIRealtimeVoice = class extends MastraVoice {
|
|
|
587
591
|
return btoa(binary);
|
|
588
592
|
}
|
|
589
593
|
sendEvent(type, data) {
|
|
590
|
-
if (this.ws.readyState !== this.ws.OPEN) {
|
|
594
|
+
if (!this.ws || this.ws.readyState !== this.ws.OPEN) {
|
|
591
595
|
this.queue.push({ type, ...data });
|
|
592
596
|
} else {
|
|
593
|
-
this.ws
|
|
597
|
+
this.ws?.send(
|
|
594
598
|
JSON.stringify({
|
|
595
599
|
type,
|
|
596
600
|
...data
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mastra/voice-openai-realtime",
|
|
3
|
-
"version": "0.2.0-alpha.
|
|
3
|
+
"version": "0.2.0-alpha.3",
|
|
4
4
|
"description": "Mastra OpenAI Realtime API integration",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"openai-realtime-api": "^1.0.7",
|
|
24
24
|
"ws": "^8.18.1",
|
|
25
25
|
"zod-to-json-schema": "^3.24.5",
|
|
26
|
-
"@mastra/core": "^0.8.4-alpha.
|
|
26
|
+
"@mastra/core": "^0.8.4-alpha.2"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
29
|
"@microsoft/api-extractor": "^7.52.2",
|
package/src/index.ts
CHANGED
|
@@ -106,7 +106,7 @@ type RealtimeClientServerEventMap = {
|
|
|
106
106
|
* ```
|
|
107
107
|
*/
|
|
108
108
|
export class OpenAIRealtimeVoice extends MastraVoice {
|
|
109
|
-
private ws
|
|
109
|
+
private ws?: WebSocket;
|
|
110
110
|
private state: 'close' | 'open';
|
|
111
111
|
private client: EventEmitter<RealtimeClientServerEventMap>;
|
|
112
112
|
private events: EventMap;
|
|
@@ -138,7 +138,7 @@ export class OpenAIRealtimeVoice extends MastraVoice {
|
|
|
138
138
|
* ```
|
|
139
139
|
*/
|
|
140
140
|
constructor(
|
|
141
|
-
options: {
|
|
141
|
+
private options: {
|
|
142
142
|
model?: string;
|
|
143
143
|
url?: string;
|
|
144
144
|
apiKey?: string;
|
|
@@ -149,22 +149,12 @@ export class OpenAIRealtimeVoice extends MastraVoice {
|
|
|
149
149
|
) {
|
|
150
150
|
super();
|
|
151
151
|
|
|
152
|
-
const url = `${options.url || DEFAULT_URL}?model=${options.model || DEFAULT_MODEL}`;
|
|
153
|
-
const apiKey = options.apiKey || process.env.OPENAI_API_KEY;
|
|
154
|
-
this.ws = new WebSocket(url, undefined, {
|
|
155
|
-
headers: {
|
|
156
|
-
Authorization: 'Bearer ' + apiKey,
|
|
157
|
-
'OpenAI-Beta': 'realtime=v1',
|
|
158
|
-
},
|
|
159
|
-
});
|
|
160
|
-
|
|
161
152
|
this.client = new EventEmitter();
|
|
162
153
|
this.state = 'close';
|
|
163
154
|
this.events = {} as EventMap;
|
|
164
155
|
this.speaker = options.speaker || DEFAULT_VOICE;
|
|
165
156
|
this.transcriber = options.transcriber || DEFAULT_TRANSCRIBER;
|
|
166
157
|
this.debug = options.debug || false;
|
|
167
|
-
this.setupEventListeners();
|
|
168
158
|
}
|
|
169
159
|
|
|
170
160
|
/**
|
|
@@ -355,7 +345,7 @@ export class OpenAIRealtimeVoice extends MastraVoice {
|
|
|
355
345
|
|
|
356
346
|
waitForOpen() {
|
|
357
347
|
return new Promise(resolve => {
|
|
358
|
-
this.ws
|
|
348
|
+
this.ws?.on('open', resolve);
|
|
359
349
|
});
|
|
360
350
|
}
|
|
361
351
|
|
|
@@ -378,6 +368,16 @@ export class OpenAIRealtimeVoice extends MastraVoice {
|
|
|
378
368
|
* ```
|
|
379
369
|
*/
|
|
380
370
|
async connect() {
|
|
371
|
+
const url = `${this.options.url || DEFAULT_URL}?model=${this.options.model || DEFAULT_MODEL}`;
|
|
372
|
+
const apiKey = this.options.apiKey || process.env.OPENAI_API_KEY;
|
|
373
|
+
this.ws = new WebSocket(url, undefined, {
|
|
374
|
+
headers: {
|
|
375
|
+
Authorization: 'Bearer ' + apiKey,
|
|
376
|
+
'OpenAI-Beta': 'realtime=v1',
|
|
377
|
+
},
|
|
378
|
+
});
|
|
379
|
+
|
|
380
|
+
this.setupEventListeners();
|
|
381
381
|
await this.waitForOpen();
|
|
382
382
|
await this.waitForSessionCreated();
|
|
383
383
|
|
|
@@ -534,6 +534,10 @@ export class OpenAIRealtimeVoice extends MastraVoice {
|
|
|
534
534
|
private setupEventListeners(): void {
|
|
535
535
|
const speakerStreams = new Map<string, StreamWithId>();
|
|
536
536
|
|
|
537
|
+
if (!this.ws) {
|
|
538
|
+
throw new Error('WebSocket not initialized');
|
|
539
|
+
}
|
|
540
|
+
|
|
537
541
|
this.ws.on('message', message => {
|
|
538
542
|
const data = JSON.parse(message.toString());
|
|
539
543
|
this.client.emit(data.type, data);
|
|
@@ -549,7 +553,7 @@ export class OpenAIRealtimeVoice extends MastraVoice {
|
|
|
549
553
|
|
|
550
554
|
const queue = this.queue.splice(0, this.queue.length);
|
|
551
555
|
for (const ev of queue) {
|
|
552
|
-
this.ws
|
|
556
|
+
this.ws?.send(JSON.stringify(ev));
|
|
553
557
|
}
|
|
554
558
|
});
|
|
555
559
|
this.client.on('session.updated', ev => {
|
|
@@ -669,10 +673,10 @@ export class OpenAIRealtimeVoice extends MastraVoice {
|
|
|
669
673
|
}
|
|
670
674
|
|
|
671
675
|
private sendEvent(type: string, data: any) {
|
|
672
|
-
if (this.ws.readyState !== this.ws.OPEN) {
|
|
676
|
+
if (!this.ws || this.ws.readyState !== this.ws.OPEN) {
|
|
673
677
|
this.queue.push({ type: type, ...data });
|
|
674
678
|
} else {
|
|
675
|
-
this.ws
|
|
679
|
+
this.ws?.send(
|
|
676
680
|
JSON.stringify({
|
|
677
681
|
type: type,
|
|
678
682
|
...data,
|