@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/LICENSE.md +6 -4
- package/dist/_types/@internal_voice/dist/_types/@internal_ai-sdk-v5/dist/index.d.ts +110 -221
- package/dist/_types/@internal_voice/dist/_types/@internal_core/dist/base/index.d.ts +27 -27
- package/dist/_types/@internal_voice/dist/_types/@internal_core/dist/index-Biaf3BmX.d.ts +319 -0
- package/dist/_types/@internal_voice/dist/_types/@internal_core/dist/request-context/index.d.ts +167 -95
- package/dist/_types/@internal_voice/dist/_types/@internal_core/dist/types/index.d.ts +4 -2
- package/dist/_types/@internal_voice/dist/voice/composite-voice.d.ts +1 -1
- package/dist/docs/SKILL.md +4 -5
- package/dist/docs/assets/SOURCE_MAP.json +1 -1
- package/dist/docs/references/{reference-voice-deepgram.md → integrations-voice-deepgram.md} +4 -0
- package/dist/docs/references/{docs-voice-overview.md → reference-voice-overview.md} +93 -135
- package/dist/index.cjs +526 -454
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +525 -452
- package/dist/index.js.map +1 -1
- package/dist/voices.d.ts +2 -2
- package/dist/voices.d.ts.map +1 -1
- package/package.json +17 -17
- package/CHANGELOG.md +0 -1779
- package/dist/_types/@internal_voice/dist/_types/@internal_core/dist/logger/index.d.ts +0 -217
- package/dist/docs/references/docs-agents-adding-voice.md +0 -381
package/dist/index.cjs
CHANGED
|
@@ -1,466 +1,538 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
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
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
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
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
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
|
-
|
|
237
|
+
//#endregion
|
|
238
|
+
//#region ../../packages/_internal-core/dist/base/index.js
|
|
122
239
|
var MastraBase = class {
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
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
|
-
|
|
272
|
+
//#endregion
|
|
273
|
+
//#region ../../packages/_internals/voice/dist/aisdk-C_K-VCwq.js
|
|
161
274
|
var MastraVoice = class extends MastraBase {
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
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
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
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
|
-
|
|
398
|
+
//#endregion
|
|
399
|
+
//#region src/index.ts
|
|
284
400
|
var DeepgramVoice = class extends MastraVoice {
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
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
|
-
|
|
537
|
+
|
|
466
538
|
//# sourceMappingURL=index.cjs.map
|