@mastra/voice-deepgram 0.13.0 → 0.13.1-alpha.0

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/dist/index.cjs CHANGED
@@ -1,466 +1,538 @@
1
- 'use strict';
2
-
3
- var stream = require('stream');
4
- var sdk = require('@deepgram/sdk');
5
-
6
- // src/index.ts
7
-
8
- // ../../packages/_internal-core/dist/chunk-3M4SEWMI.js
9
- var RegisteredLogger = {
10
- LLM: "LLM"};
11
- var LogLevel = {
12
- DEBUG: "debug",
13
- INFO: "info",
14
- WARN: "warn",
15
- ERROR: "error"};
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ let stream = require("stream");
3
+ let _deepgram_sdk = require("@deepgram/sdk");
4
+ //#region ../../packages/_internal-core/dist/logger/index.js
5
+ /**
6
+ * Export a tracked exception through the adapter sink, mirroring the
7
+ * DualLogger dual-write shape (`errorId`/`domain`/`category`/`details`/`cause`
8
+ * when present on a MastraError-like value). Never throws into the caller.
9
+ */
10
+ function exportTrackedException(ctx, error, metadata) {
11
+ if (!ctx?.options.export) return;
12
+ try {
13
+ const mastraError = error;
14
+ ctx.getLogSink()?.error(error.message, {
15
+ ...mastraError.id !== void 0 ? { errorId: mastraError.id } : {},
16
+ ...mastraError.domain !== void 0 ? { domain: mastraError.domain } : {},
17
+ ...mastraError.category !== void 0 ? { category: mastraError.category } : {},
18
+ ...mastraError.details !== void 0 ? { details: mastraError.details } : {},
19
+ ...error.cause instanceof Error ? { cause: error.cause.message } : {},
20
+ ...metadata
21
+ });
22
+ } catch {}
23
+ }
24
+ /**
25
+ * Adapt IMastraLogger's variadic args into the structured `data` payload of
26
+ * an exported log record. Extracts the first plain object as data,
27
+ * serializes an Error arg, and collects remaining primitives under `args`
28
+ * so the derived record preserves all context from the native call.
29
+ */
30
+ function buildLogRecordData(args) {
31
+ const objectData = args.find((arg) => arg !== null && typeof arg === "object" && !Array.isArray(arg) && !(arg instanceof Error));
32
+ const errorArg = args.find((arg) => arg instanceof Error);
33
+ const extraArgs = args.filter((arg) => arg !== objectData && arg !== errorArg);
34
+ if (!objectData && !errorArg && extraArgs.length === 0) return void 0;
35
+ return {
36
+ ...objectData ?? {},
37
+ ...errorArg ? { error: {
38
+ name: errorArg.name,
39
+ message: errorArg.message,
40
+ stack: errorArg.stack
41
+ } } : {},
42
+ ...extraArgs.length > 0 ? { args: extraArgs } : {}
43
+ };
44
+ }
45
+ const RegisteredLogger = {
46
+ AGENT: "AGENT",
47
+ OBSERVABILITY: "OBSERVABILITY",
48
+ AUTH: "AUTH",
49
+ BROWSER: "BROWSER",
50
+ NETWORK: "NETWORK",
51
+ WORKFLOW: "WORKFLOW",
52
+ LLM: "LLM",
53
+ TTS: "TTS",
54
+ VOICE: "VOICE",
55
+ VECTOR: "VECTOR",
56
+ BUNDLER: "BUNDLER",
57
+ DEPLOYER: "DEPLOYER",
58
+ MEMORY: "MEMORY",
59
+ STORAGE: "STORAGE",
60
+ EMBEDDINGS: "EMBEDDINGS",
61
+ MCP_SERVER: "MCP_SERVER",
62
+ SERVER_CACHE: "SERVER_CACHE",
63
+ SERVER: "SERVER",
64
+ WORKSPACE: "WORKSPACE",
65
+ CHANNEL: "CHANNEL"
66
+ };
67
+ const LogLevel = {
68
+ DEBUG: "debug",
69
+ INFO: "info",
70
+ WARN: "warn",
71
+ ERROR: "error",
72
+ NONE: "silent"
73
+ };
16
74
  var MastraLogger = class {
17
- name;
18
- level;
19
- transports;
20
- constructor(options = {}) {
21
- this.name = options.name || "Mastra";
22
- this.level = options.level || LogLevel.ERROR;
23
- this.transports = new Map(Object.entries(options.transports || {}));
24
- }
25
- getTransports() {
26
- return this.transports;
27
- }
28
- trackException(_error, _metadata) {
29
- }
30
- async listLogs(transportId, params) {
31
- if (!transportId || !this.transports.has(transportId)) {
32
- return { logs: [], total: 0, page: params?.page ?? 1, perPage: params?.perPage ?? 100, hasMore: false };
33
- }
34
- return this.transports.get(transportId).listLogs?.(params) ?? {
35
- logs: [],
36
- total: 0,
37
- page: params?.page ?? 1,
38
- perPage: params?.perPage ?? 100,
39
- hasMore: false
40
- };
41
- }
42
- async listLogsByRunId({
43
- transportId,
44
- runId,
45
- fromDate,
46
- toDate,
47
- logLevel,
48
- filters,
49
- page,
50
- perPage
51
- }) {
52
- if (!transportId || !this.transports.has(transportId) || !runId) {
53
- return { logs: [], total: 0, page: page ?? 1, perPage: perPage ?? 100, hasMore: false };
54
- }
55
- return this.transports.get(transportId).listLogsByRunId?.({ runId, fromDate, toDate, logLevel, filters, page, perPage }) ?? {
56
- logs: [],
57
- total: 0,
58
- page: page ?? 1,
59
- perPage: perPage ?? 100,
60
- hasMore: false
61
- };
62
- }
75
+ name;
76
+ level;
77
+ transports;
78
+ constructor(options = {}) {
79
+ this.name = options.name || "Mastra";
80
+ this.level = options.level || LogLevel.ERROR;
81
+ this.transports = new Map(Object.entries(options.transports || {}));
82
+ }
83
+ getTransports() {
84
+ return this.transports;
85
+ }
86
+ trackException(_error, _metadata) {}
87
+ async listLogs(transportId, params) {
88
+ if (!transportId || !this.transports.has(transportId)) return {
89
+ logs: [],
90
+ total: 0,
91
+ page: params?.page ?? 1,
92
+ perPage: params?.perPage ?? 100,
93
+ hasMore: false
94
+ };
95
+ return this.transports.get(transportId).listLogs?.(params) ?? {
96
+ logs: [],
97
+ total: 0,
98
+ page: params?.page ?? 1,
99
+ perPage: params?.perPage ?? 100,
100
+ hasMore: false
101
+ };
102
+ }
103
+ async listLogsByRunId({ transportId, runId, fromDate, toDate, logLevel, filters, page, perPage }) {
104
+ if (!transportId || !this.transports.has(transportId) || !runId) return {
105
+ logs: [],
106
+ total: 0,
107
+ page: page ?? 1,
108
+ perPage: perPage ?? 100,
109
+ hasMore: false
110
+ };
111
+ return this.transports.get(transportId).listLogsByRunId?.({
112
+ runId,
113
+ fromDate,
114
+ toDate,
115
+ logLevel,
116
+ filters,
117
+ page,
118
+ perPage
119
+ }) ?? {
120
+ logs: [],
121
+ total: 0,
122
+ page: page ?? 1,
123
+ perPage: perPage ?? 100,
124
+ hasMore: false
125
+ };
126
+ }
63
127
  };
64
- var ConsoleLogger = class _ConsoleLogger extends MastraLogger {
65
- component;
66
- filter;
67
- constructor(options = {}) {
68
- super(options);
69
- this.component = options.component;
70
- this.filter = options.filter;
71
- }
72
- child(componentOrBindings) {
73
- const component = typeof componentOrBindings === "string" ? componentOrBindings : componentOrBindings?.component ?? this.component;
74
- return new _ConsoleLogger({
75
- name: this.name,
76
- level: this.level,
77
- component,
78
- filter: this.filter
79
- });
80
- }
81
- shouldLog(level, message, args) {
82
- if (!this.filter) return true;
83
- try {
84
- return this.filter({ component: this.component, level, message, args });
85
- } catch (e) {
86
- console.error(`[Logger] Filter error for component=${this.component} level=${level}:`, e);
87
- return true;
88
- }
89
- }
90
- prefix() {
91
- return this.component ? `[${this.component}] ` : "";
92
- }
93
- debug(message, ...args) {
94
- if (this.level === LogLevel.DEBUG && this.shouldLog(LogLevel.DEBUG, message, args)) {
95
- console.info(`${this.prefix()}${message}`, ...args);
96
- }
97
- }
98
- info(message, ...args) {
99
- if ((this.level === LogLevel.INFO || this.level === LogLevel.DEBUG) && this.shouldLog(LogLevel.INFO, message, args)) {
100
- console.info(`${this.prefix()}${message}`, ...args);
101
- }
102
- }
103
- warn(message, ...args) {
104
- if ((this.level === LogLevel.WARN || this.level === LogLevel.INFO || this.level === LogLevel.DEBUG) && this.shouldLog(LogLevel.WARN, message, args)) {
105
- console.warn(`${this.prefix()}${message}`, ...args);
106
- }
107
- }
108
- error(message, ...args) {
109
- if ((this.level === LogLevel.ERROR || this.level === LogLevel.WARN || this.level === LogLevel.INFO || this.level === LogLevel.DEBUG) && this.shouldLog(LogLevel.ERROR, message, args)) {
110
- console.error(`${this.prefix()}${message}`, ...args);
111
- }
112
- }
113
- async listLogs(_transportId, _params) {
114
- return { logs: [], total: 0, page: _params?.page ?? 1, perPage: _params?.perPage ?? 100, hasMore: false };
115
- }
116
- async listLogsByRunId(_args) {
117
- return { logs: [], total: 0, page: _args.page ?? 1, perPage: _args.perPage ?? 100, hasMore: false };
118
- }
128
+ var ConsoleLogger = class ConsoleLogger extends MastraLogger {
129
+ component;
130
+ filter;
131
+ #adapterContext;
132
+ constructor(options = {}) {
133
+ super(options);
134
+ this.component = options.component;
135
+ this.filter = options.filter;
136
+ }
137
+ /**
138
+ * Adapter hook (see `AdaptableLogger`): enables native trace correlation
139
+ * (trace_id/span_id appended to console output) and observability export
140
+ * derived from the same record. Called by Mastra during setup.
141
+ */
142
+ __attachObservability(ctx) {
143
+ this.#adapterContext = ctx;
144
+ }
145
+ child(componentOrBindings) {
146
+ const component = typeof componentOrBindings === "string" ? componentOrBindings : componentOrBindings?.component ?? this.component;
147
+ const child = new ConsoleLogger({
148
+ name: this.name,
149
+ level: this.level,
150
+ component,
151
+ filter: this.filter
152
+ });
153
+ if (this.#adapterContext) child.__attachObservability(this.#adapterContext);
154
+ return child;
155
+ }
156
+ /**
157
+ * Native-record correlation: when a span is active, append the trace
158
+ * fields object to the console args so every destination sees them.
159
+ */
160
+ #correlate(args) {
161
+ const ctx = this.#adapterContext;
162
+ if (!ctx?.options.correlation) return args;
163
+ try {
164
+ const fields = ctx.resolveTraceFields();
165
+ return fields ? [...args, fields] : args;
166
+ } catch {
167
+ return args;
168
+ }
169
+ }
170
+ /**
171
+ * Export the record derived from the same native call to observability.
172
+ * Mirrors DualLogger semantics: export is independent of the console
173
+ * level filter, and never throws into the caller.
174
+ */
175
+ #export(level, message, args) {
176
+ const ctx = this.#adapterContext;
177
+ if (!ctx?.options.export) return;
178
+ try {
179
+ ctx.getLogSink()?.[level](message, buildLogRecordData(args));
180
+ } catch {}
181
+ }
182
+ shouldLog(level, message, args) {
183
+ if (!this.filter) return true;
184
+ try {
185
+ return this.filter({
186
+ component: this.component,
187
+ level,
188
+ message,
189
+ args
190
+ });
191
+ } catch (e) {
192
+ console.error(`[Logger] Filter error for component=${this.component} level=${level}:`, e);
193
+ return true;
194
+ }
195
+ }
196
+ prefix() {
197
+ return this.component ? `[${this.component}] ` : "";
198
+ }
199
+ debug(message, ...args) {
200
+ if (this.level === LogLevel.DEBUG && this.shouldLog(LogLevel.DEBUG, message, args)) console.info(`${this.prefix()}${message}`, ...this.#correlate(args));
201
+ this.#export("debug", message, args);
202
+ }
203
+ info(message, ...args) {
204
+ if ((this.level === LogLevel.INFO || this.level === LogLevel.DEBUG) && this.shouldLog(LogLevel.INFO, message, args)) console.info(`${this.prefix()}${message}`, ...this.#correlate(args));
205
+ this.#export("info", message, args);
206
+ }
207
+ warn(message, ...args) {
208
+ if ((this.level === LogLevel.WARN || this.level === LogLevel.INFO || this.level === LogLevel.DEBUG) && this.shouldLog(LogLevel.WARN, message, args)) console.warn(`${this.prefix()}${message}`, ...this.#correlate(args));
209
+ this.#export("warn", message, args);
210
+ }
211
+ error(message, ...args) {
212
+ if ((this.level === LogLevel.ERROR || this.level === LogLevel.WARN || this.level === LogLevel.INFO || this.level === LogLevel.DEBUG) && this.shouldLog(LogLevel.ERROR, message, args)) console.error(`${this.prefix()}${message}`, ...this.#correlate(args));
213
+ this.#export("error", message, args);
214
+ }
215
+ trackException(error, metadata) {
216
+ exportTrackedException(this.#adapterContext, error, metadata);
217
+ }
218
+ async listLogs(_transportId, _params) {
219
+ return {
220
+ logs: [],
221
+ total: 0,
222
+ page: _params?.page ?? 1,
223
+ perPage: _params?.perPage ?? 100,
224
+ hasMore: false
225
+ };
226
+ }
227
+ async listLogsByRunId(_args) {
228
+ return {
229
+ logs: [],
230
+ total: 0,
231
+ page: _args.page ?? 1,
232
+ perPage: _args.perPage ?? 100,
233
+ hasMore: false
234
+ };
235
+ }
119
236
  };
120
-
121
- // ../../packages/_internal-core/dist/base/index.js
237
+ //#endregion
238
+ //#region ../../packages/_internal-core/dist/base/index.js
122
239
  var MastraBase = class {
123
- component = RegisteredLogger.LLM;
124
- logger;
125
- name;
126
- #rawConfig;
127
- constructor({
128
- component,
129
- name,
130
- rawConfig
131
- }) {
132
- this.component = component || RegisteredLogger.LLM;
133
- this.name = name;
134
- this.#rawConfig = rawConfig;
135
- this.logger = new ConsoleLogger({ name: `${this.component} - ${this.name}` });
136
- }
137
- /**
138
- * Returns the raw storage configuration this primitive was created from,
139
- * or undefined if it was created from code.
140
- */
141
- toRawConfig() {
142
- return this.#rawConfig;
143
- }
144
- /**
145
- * Sets the raw storage configuration for this primitive.
146
- * @internal
147
- */
148
- __setRawConfig(rawConfig) {
149
- this.#rawConfig = rawConfig;
150
- }
151
- /**
152
- * Set the logger for the agent
153
- * @param logger
154
- */
155
- __setLogger(logger) {
156
- this.logger = "child" in logger && typeof logger.child === "function" ? logger.child({ component: this.component }) : logger;
157
- }
240
+ component = RegisteredLogger.LLM;
241
+ logger;
242
+ name;
243
+ #rawConfig;
244
+ constructor({ component, name, rawConfig }) {
245
+ this.component = component || RegisteredLogger.LLM;
246
+ this.name = name;
247
+ this.#rawConfig = rawConfig;
248
+ this.logger = new ConsoleLogger({ name: `${this.component} - ${this.name}` });
249
+ }
250
+ /**
251
+ * Returns the raw storage configuration this primitive was created from,
252
+ * or undefined if it was created from code.
253
+ */
254
+ toRawConfig() {
255
+ return this.#rawConfig;
256
+ }
257
+ /**
258
+ * Sets the raw storage configuration for this primitive.
259
+ * @internal
260
+ */
261
+ __setRawConfig(rawConfig) {
262
+ this.#rawConfig = rawConfig;
263
+ }
264
+ /**
265
+ * Set the logger for the agent
266
+ * @param logger
267
+ */
268
+ __setLogger(logger) {
269
+ this.logger = "child" in logger && typeof logger.child === "function" ? logger.child({ component: this.component }) : logger;
270
+ }
158
271
  };
159
-
160
- // ../../packages/_internals/voice/dist/chunk-NWNKSBZV.js
272
+ //#endregion
273
+ //#region ../../packages/_internals/voice/dist/aisdk-C_K-VCwq.js
161
274
  var MastraVoice = class extends MastraBase {
162
- listeningModel;
163
- speechModel;
164
- speaker;
165
- realtimeConfig;
166
- constructor({ listeningModel, speechModel, speaker, realtimeConfig, name } = {}) {
167
- super({
168
- component: "VOICE",
169
- name
170
- });
171
- this.listeningModel = listeningModel;
172
- this.speechModel = speechModel;
173
- this.speaker = speaker;
174
- this.realtimeConfig = realtimeConfig;
175
- }
176
- /**
177
- * Custom serialization for tracing/observability spans.
178
- * Excludes `apiKey` from listeningModel / speechModel / realtimeConfig
179
- * and any provider-specific state held by subclasses. Subclasses that
180
- * need to expose additional non-sensitive fields can override.
181
- */
182
- serializeForSpan() {
183
- return {
184
- component: "VOICE",
185
- name: this.name,
186
- speaker: this.speaker,
187
- listeningModel: this.listeningModel ? { name: this.listeningModel.name } : void 0,
188
- speechModel: this.speechModel ? { name: this.speechModel.name } : void 0,
189
- realtimeModel: this.realtimeConfig?.model
190
- };
191
- }
192
- updateConfig(_options) {
193
- this.logger.debug("updateConfig not implemented by this voice provider");
194
- }
195
- /**
196
- * Initializes a WebSocket or WebRTC connection for real-time communication
197
- * @returns Promise that resolves when the connection is established
198
- */
199
- async connect(_options) {
200
- this.logger.debug("connect not implemented by this voice provider");
201
- }
202
- /**
203
- * Relay audio data to the voice provider for real-time processing
204
- * @param audioData Audio data to relay
205
- */
206
- async send(_audioData) {
207
- this.logger.debug("relay not implemented by this voice provider");
208
- }
209
- /**
210
- * Trigger voice providers to respond
211
- */
212
- async answer(_options) {
213
- this.logger.debug("answer not implemented by this voice provider");
214
- }
215
- /**
216
- * Equip the voice provider with instructions
217
- * @param instructions Instructions to add
218
- */
219
- addInstructions(_instructions) {
220
- }
221
- /**
222
- * Equip the voice provider with tools
223
- * @param tools Array of tools to add
224
- */
225
- addTools(_tools) {
226
- }
227
- /**
228
- * Disconnect from the WebSocket or WebRTC connection
229
- */
230
- close() {
231
- this.logger.debug("close not implemented by this voice provider");
232
- }
233
- /**
234
- * Register an event listener
235
- * @param event Event name (e.g., 'speaking', 'writing', 'error')
236
- * @param callback Callback function that receives event data
237
- */
238
- on(_event, _callback) {
239
- this.logger.debug("on not implemented by this voice provider");
240
- }
241
- /**
242
- * Remove an event listener
243
- * @param event Event name (e.g., 'speaking', 'writing', 'error')
244
- * @param callback Callback function to remove
245
- */
246
- off(_event, _callback) {
247
- this.logger.debug("off not implemented by this voice provider");
248
- }
249
- /**
250
- * Get available speakers/voices
251
- * @returns Array of available voice IDs and their metadata
252
- */
253
- getSpeakers() {
254
- this.logger.debug("getSpeakers not implemented by this voice provider");
255
- return Promise.resolve([]);
256
- }
257
- /**
258
- * Get available speakers/voices
259
- * @returns Array of available voice IDs and their metadata
260
- */
261
- getListener() {
262
- this.logger.debug("getListener not implemented by this voice provider");
263
- return Promise.resolve({ enabled: false });
264
- }
275
+ listeningModel;
276
+ speechModel;
277
+ speaker;
278
+ realtimeConfig;
279
+ constructor({ listeningModel, speechModel, speaker, realtimeConfig, name } = {}) {
280
+ super({
281
+ component: "VOICE",
282
+ name
283
+ });
284
+ this.listeningModel = listeningModel;
285
+ this.speechModel = speechModel;
286
+ this.speaker = speaker;
287
+ this.realtimeConfig = realtimeConfig;
288
+ }
289
+ /**
290
+ * Custom serialization for tracing/observability spans.
291
+ * Excludes `apiKey` from listeningModel / speechModel / realtimeConfig
292
+ * and any provider-specific state held by subclasses. Subclasses that
293
+ * need to expose additional non-sensitive fields can override.
294
+ */
295
+ serializeForSpan() {
296
+ return {
297
+ component: "VOICE",
298
+ name: this.name,
299
+ speaker: this.speaker,
300
+ listeningModel: this.listeningModel ? { name: this.listeningModel.name } : void 0,
301
+ speechModel: this.speechModel ? { name: this.speechModel.name } : void 0,
302
+ realtimeModel: this.realtimeConfig?.model
303
+ };
304
+ }
305
+ updateConfig(_options) {
306
+ this.logger.debug("updateConfig not implemented by this voice provider");
307
+ }
308
+ /**
309
+ * Initializes a WebSocket or WebRTC connection for real-time communication
310
+ * @returns Promise that resolves when the connection is established
311
+ */
312
+ async connect(_options) {
313
+ this.logger.debug("connect not implemented by this voice provider");
314
+ }
315
+ /**
316
+ * Relay audio data to the voice provider for real-time processing
317
+ * @param audioData Audio data to relay
318
+ */
319
+ async send(_audioData) {
320
+ this.logger.debug("relay not implemented by this voice provider");
321
+ }
322
+ /**
323
+ * Trigger voice providers to respond
324
+ */
325
+ async answer(_options) {
326
+ this.logger.debug("answer not implemented by this voice provider");
327
+ }
328
+ /**
329
+ * Equip the voice provider with instructions
330
+ * @param instructions Instructions to add
331
+ */
332
+ addInstructions(_instructions) {}
333
+ /**
334
+ * Equip the voice provider with tools
335
+ * @param tools Array of tools to add
336
+ */
337
+ addTools(_tools) {}
338
+ /**
339
+ * Disconnect from the WebSocket or WebRTC connection
340
+ */
341
+ close() {
342
+ this.logger.debug("close not implemented by this voice provider");
343
+ }
344
+ /**
345
+ * Register an event listener
346
+ * @param event Event name (e.g., 'speaking', 'writing', 'error')
347
+ * @param callback Callback function that receives event data
348
+ */
349
+ on(_event, _callback) {
350
+ this.logger.debug("on not implemented by this voice provider");
351
+ }
352
+ /**
353
+ * Remove an event listener
354
+ * @param event Event name (e.g., 'speaking', 'writing', 'error')
355
+ * @param callback Callback function to remove
356
+ */
357
+ off(_event, _callback) {
358
+ this.logger.debug("off not implemented by this voice provider");
359
+ }
360
+ /**
361
+ * Get available speakers/voices
362
+ * @returns Array of available voice IDs and their metadata
363
+ */
364
+ getSpeakers() {
365
+ this.logger.debug("getSpeakers not implemented by this voice provider");
366
+ return Promise.resolve([]);
367
+ }
368
+ /**
369
+ * Get available speakers/voices
370
+ * @returns Array of available voice IDs and their metadata
371
+ */
372
+ getListener() {
373
+ this.logger.debug("getListener not implemented by this voice provider");
374
+ return Promise.resolve({ enabled: false });
375
+ }
265
376
  };
266
-
267
- // src/voices.ts
268
- var DEEPGRAM_VOICES = [
269
- "asteria-en",
270
- "luna-en",
271
- "stella-en",
272
- "athena-en",
273
- "hera-en",
274
- "orion-en",
275
- "arcas-en",
276
- "perseus-en",
277
- "angus-en",
278
- "orpheus-en",
279
- "helios-en",
280
- "zeus-en"
377
+ //#endregion
378
+ //#region src/voices.ts
379
+ /**
380
+ * List of available Deepgram voice models for text-to-speech
381
+ * Each voice is designed for specific use cases and languages
382
+ * Format: {name}-{language} (e.g. asteria-en)
383
+ */
384
+ const DEEPGRAM_VOICES = [
385
+ "asteria-en",
386
+ "luna-en",
387
+ "stella-en",
388
+ "athena-en",
389
+ "hera-en",
390
+ "orion-en",
391
+ "arcas-en",
392
+ "perseus-en",
393
+ "angus-en",
394
+ "orpheus-en",
395
+ "helios-en",
396
+ "zeus-en"
281
397
  ];
282
-
283
- // src/index.ts
398
+ //#endregion
399
+ //#region src/index.ts
284
400
  var DeepgramVoice = class extends MastraVoice {
285
- speechClient;
286
- listeningClient;
287
- storedSpeechModel;
288
- storedListeningModel;
289
- storedSpeaker;
290
- constructor({
291
- speechModel,
292
- listeningModel,
293
- speaker
294
- } = {}) {
295
- const defaultApiKey = process.env.DEEPGRAM_API_KEY;
296
- const defaultSpeechModel = {
297
- name: "aura",
298
- apiKey: defaultApiKey
299
- };
300
- const defaultListeningModel = {
301
- name: "nova",
302
- apiKey: defaultApiKey
303
- };
304
- super({
305
- speechModel: {
306
- name: speechModel?.name ?? defaultSpeechModel.name,
307
- apiKey: speechModel?.apiKey ?? defaultSpeechModel.apiKey
308
- },
309
- listeningModel: {
310
- name: listeningModel?.name ?? defaultListeningModel.name,
311
- apiKey: listeningModel?.apiKey ?? defaultListeningModel.apiKey
312
- },
313
- speaker
314
- });
315
- this.storedSpeechModel = {
316
- name: speechModel?.name ?? defaultSpeechModel.name,
317
- apiKey: speechModel?.apiKey ?? defaultSpeechModel.apiKey
318
- };
319
- this.storedListeningModel = {
320
- name: listeningModel?.name ?? defaultListeningModel.name,
321
- apiKey: listeningModel?.apiKey ?? defaultListeningModel.apiKey
322
- };
323
- const speechApiKey = speechModel?.apiKey || defaultApiKey;
324
- const listeningApiKey = listeningModel?.apiKey || defaultApiKey;
325
- if (!speechApiKey && !listeningApiKey) {
326
- throw new Error("At least one of DEEPGRAM_API_KEY, speechModel.apiKey, or listeningModel.apiKey must be set");
327
- }
328
- if (speechApiKey) {
329
- this.speechClient = sdk.createClient(speechApiKey);
330
- }
331
- if (listeningApiKey) {
332
- this.listeningClient = sdk.createClient(listeningApiKey);
333
- }
334
- this.storedSpeaker = speaker || "asteria-en";
335
- }
336
- async getSpeakers() {
337
- return DEEPGRAM_VOICES.map((voice) => ({
338
- voiceId: voice
339
- }));
340
- }
341
- async speak(input, options) {
342
- if (!this.speechClient) {
343
- throw new Error("Deepgram speech client not configured");
344
- }
345
- let text;
346
- if (typeof input !== "string") {
347
- const chunks = [];
348
- for await (const chunk of input) {
349
- if (typeof chunk === "string") {
350
- chunks.push(Buffer.from(chunk));
351
- } else {
352
- chunks.push(chunk);
353
- }
354
- }
355
- text = Buffer.concat(chunks).toString("utf-8");
356
- } else {
357
- text = input;
358
- }
359
- if (text.trim().length === 0) {
360
- throw new Error("Input text is empty");
361
- }
362
- const baseModel = this.storedSpeechModel?.name;
363
- const speakerId = options?.speaker || this.storedSpeaker;
364
- const modelName = baseModel && speakerId ? speakerId.startsWith(`${baseModel}-`) ? speakerId : `${baseModel}-${speakerId}` : baseModel || speakerId;
365
- const speakClient = this.speechClient.speak;
366
- const response = await speakClient.request(
367
- { text },
368
- {
369
- model: modelName,
370
- ...Object.fromEntries(Object.entries(options ?? {}).filter(([k]) => k !== "speaker"))
371
- }
372
- );
373
- const webStream = await response.getStream();
374
- if (!webStream) {
375
- throw new Error("No stream returned from Deepgram");
376
- }
377
- const reader = webStream.getReader();
378
- const nodeStream = new stream.PassThrough();
379
- (async () => {
380
- try {
381
- while (true) {
382
- const { done, value } = await reader.read();
383
- if (done) {
384
- nodeStream.end();
385
- break;
386
- }
387
- nodeStream.write(value);
388
- }
389
- } catch (error) {
390
- nodeStream.destroy(error);
391
- }
392
- })().catch((error) => {
393
- nodeStream.destroy(error);
394
- });
395
- return nodeStream;
396
- }
397
- /**
398
- * Checks if listening capabilities are enabled.
399
- *
400
- * @returns {Promise<{ enabled: boolean }>}
401
- */
402
- async getListener() {
403
- return { enabled: true };
404
- }
405
- /**
406
- * Transcribes audio with optional speaker diarization.
407
- *
408
- * @param audioStream - Audio input stream
409
- * @param options - Transcription options (diarize, language, etc.)
410
- * @returns Promise resolving to:
411
- * - transcript: Full transcript string
412
- * - words: Array of word objects with timing and confidence
413
- * - raw: Complete Deepgram API response
414
- * - speakerSegments: (when diarize=true) Array of {word, speaker, start, end}
415
- */
416
- async listen(audioStream, options) {
417
- if (!this.listeningClient) {
418
- throw new Error("Deepgram listening client not configured");
419
- }
420
- const chunks = [];
421
- for await (const chunk of audioStream) {
422
- if (typeof chunk === "string") {
423
- chunks.push(Buffer.from(chunk));
424
- } else {
425
- chunks.push(chunk);
426
- }
427
- }
428
- const buffer = Buffer.concat(chunks);
429
- const { diarize, diarize_speaker_count: _, ...restOptions } = options ?? {};
430
- const { result, error } = await this.listeningClient.listen.prerecorded.transcribeFile(buffer, {
431
- ...restOptions,
432
- model: this.storedListeningModel?.name,
433
- diarize
434
- });
435
- if (error) {
436
- throw error;
437
- }
438
- const channel = result.results?.channels?.[0];
439
- const alt = channel?.alternatives?.[0];
440
- if (!alt) {
441
- return {
442
- transcript: "",
443
- words: [],
444
- raw: result
445
- };
446
- }
447
- const response = {
448
- transcript: alt.transcript,
449
- words: alt.words,
450
- raw: result
451
- };
452
- if (diarize && alt.words) {
453
- response.speakerSegments = alt.words.map((w) => ({
454
- word: w.word,
455
- speaker: w.speaker,
456
- start: w.start,
457
- end: w.end
458
- }));
459
- }
460
- return response;
461
- }
401
+ speechClient;
402
+ listeningClient;
403
+ storedSpeechModel;
404
+ storedListeningModel;
405
+ storedSpeaker;
406
+ constructor({ speechModel, listeningModel, speaker } = {}) {
407
+ const defaultApiKey = process.env.DEEPGRAM_API_KEY;
408
+ const defaultSpeechModel = {
409
+ name: "aura",
410
+ apiKey: defaultApiKey
411
+ };
412
+ const defaultListeningModel = {
413
+ name: "nova",
414
+ apiKey: defaultApiKey
415
+ };
416
+ super({
417
+ speechModel: {
418
+ name: speechModel?.name ?? defaultSpeechModel.name,
419
+ apiKey: speechModel?.apiKey ?? defaultSpeechModel.apiKey
420
+ },
421
+ listeningModel: {
422
+ name: listeningModel?.name ?? defaultListeningModel.name,
423
+ apiKey: listeningModel?.apiKey ?? defaultListeningModel.apiKey
424
+ },
425
+ speaker
426
+ });
427
+ this.storedSpeechModel = {
428
+ name: speechModel?.name ?? defaultSpeechModel.name,
429
+ apiKey: speechModel?.apiKey ?? defaultSpeechModel.apiKey
430
+ };
431
+ this.storedListeningModel = {
432
+ name: listeningModel?.name ?? defaultListeningModel.name,
433
+ apiKey: listeningModel?.apiKey ?? defaultListeningModel.apiKey
434
+ };
435
+ const speechApiKey = speechModel?.apiKey || defaultApiKey;
436
+ const listeningApiKey = listeningModel?.apiKey || defaultApiKey;
437
+ if (!speechApiKey && !listeningApiKey) throw new Error("At least one of DEEPGRAM_API_KEY, speechModel.apiKey, or listeningModel.apiKey must be set");
438
+ if (speechApiKey) this.speechClient = (0, _deepgram_sdk.createClient)(speechApiKey);
439
+ if (listeningApiKey) this.listeningClient = (0, _deepgram_sdk.createClient)(listeningApiKey);
440
+ this.storedSpeaker = speaker || "asteria-en";
441
+ }
442
+ async getSpeakers() {
443
+ return DEEPGRAM_VOICES.map((voice) => ({ voiceId: voice }));
444
+ }
445
+ async speak(input, options) {
446
+ if (!this.speechClient) throw new Error("Deepgram speech client not configured");
447
+ let text;
448
+ if (typeof input !== "string") {
449
+ const chunks = [];
450
+ for await (const chunk of input) if (typeof chunk === "string") chunks.push(Buffer.from(chunk));
451
+ else chunks.push(chunk);
452
+ text = Buffer.concat(chunks).toString("utf-8");
453
+ } else text = input;
454
+ if (text.trim().length === 0) throw new Error("Input text is empty");
455
+ const baseModel = this.storedSpeechModel?.name;
456
+ const speakerId = options?.speaker || this.storedSpeaker;
457
+ const modelName = baseModel && speakerId ? speakerId.startsWith(`${baseModel}-`) ? speakerId : `${baseModel}-${speakerId}` : baseModel || speakerId;
458
+ const webStream = await (await this.speechClient.speak.request({ text }, {
459
+ model: modelName,
460
+ ...Object.fromEntries(Object.entries(options ?? {}).filter(([k]) => k !== "speaker"))
461
+ })).getStream();
462
+ if (!webStream) throw new Error("No stream returned from Deepgram");
463
+ const reader = webStream.getReader();
464
+ const nodeStream = new stream.PassThrough();
465
+ (async () => {
466
+ try {
467
+ while (true) {
468
+ const { done, value } = await reader.read();
469
+ if (done) {
470
+ nodeStream.end();
471
+ break;
472
+ }
473
+ nodeStream.write(value);
474
+ }
475
+ } catch (error) {
476
+ nodeStream.destroy(error);
477
+ }
478
+ })().catch((error) => {
479
+ nodeStream.destroy(error);
480
+ });
481
+ return nodeStream;
482
+ }
483
+ /**
484
+ * Checks if listening capabilities are enabled.
485
+ *
486
+ * @returns {Promise<{ enabled: boolean }>}
487
+ */
488
+ async getListener() {
489
+ return { enabled: true };
490
+ }
491
+ /**
492
+ * Transcribes audio with optional speaker diarization.
493
+ *
494
+ * @param audioStream - Audio input stream
495
+ * @param options - Transcription options (diarize, language, etc.)
496
+ * @returns Promise resolving to:
497
+ * - transcript: Full transcript string
498
+ * - words: Array of word objects with timing and confidence
499
+ * - raw: Complete Deepgram API response
500
+ * - speakerSegments: (when diarize=true) Array of {word, speaker, start, end}
501
+ */
502
+ async listen(audioStream, options) {
503
+ if (!this.listeningClient) throw new Error("Deepgram listening client not configured");
504
+ const chunks = [];
505
+ for await (const chunk of audioStream) if (typeof chunk === "string") chunks.push(Buffer.from(chunk));
506
+ else chunks.push(chunk);
507
+ const buffer = Buffer.concat(chunks);
508
+ const { diarize, diarize_speaker_count: _, ...restOptions } = options ?? {};
509
+ const { result, error } = await this.listeningClient.listen.prerecorded.transcribeFile(buffer, {
510
+ ...restOptions,
511
+ model: this.storedListeningModel?.name,
512
+ diarize
513
+ });
514
+ if (error) throw error;
515
+ const alt = (result.results?.channels?.[0])?.alternatives?.[0];
516
+ if (!alt) return {
517
+ transcript: "",
518
+ words: [],
519
+ raw: result
520
+ };
521
+ const response = {
522
+ transcript: alt.transcript,
523
+ words: alt.words,
524
+ raw: result
525
+ };
526
+ if (diarize && alt.words) response.speakerSegments = alt.words.map((w) => ({
527
+ word: w.word,
528
+ speaker: w.speaker,
529
+ start: w.start,
530
+ end: w.end
531
+ }));
532
+ return response;
533
+ }
462
534
  };
463
-
535
+ //#endregion
464
536
  exports.DeepgramVoice = DeepgramVoice;
465
- //# sourceMappingURL=index.cjs.map
537
+
466
538
  //# sourceMappingURL=index.cjs.map