modular-voice-agent-sdk 1.0.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/README.md +102 -0
- package/USAGE.md +567 -0
- package/dist/backends/cloud/index.d.ts +7 -0
- package/dist/backends/cloud/index.d.ts.map +1 -0
- package/dist/backends/cloud/index.js +6 -0
- package/dist/backends/cloud/index.js.map +1 -0
- package/dist/backends/cloud/llm.d.ts +22 -0
- package/dist/backends/cloud/llm.d.ts.map +1 -0
- package/dist/backends/cloud/llm.js +234 -0
- package/dist/backends/cloud/llm.js.map +1 -0
- package/dist/backends/index.d.ts +2 -0
- package/dist/backends/index.d.ts.map +1 -0
- package/dist/backends/index.js +6 -0
- package/dist/backends/index.js.map +1 -0
- package/dist/backends/native/index.d.ts +5 -0
- package/dist/backends/native/index.d.ts.map +1 -0
- package/dist/backends/native/index.js +6 -0
- package/dist/backends/native/index.js.map +1 -0
- package/dist/backends/native/llm.d.ts +71 -0
- package/dist/backends/native/llm.d.ts.map +1 -0
- package/dist/backends/native/llm.js +435 -0
- package/dist/backends/native/llm.js.map +1 -0
- package/dist/backends/native/stt.d.ts +15 -0
- package/dist/backends/native/stt.d.ts.map +1 -0
- package/dist/backends/native/stt.js +94 -0
- package/dist/backends/native/stt.js.map +1 -0
- package/dist/backends/native/tts.d.ts +21 -0
- package/dist/backends/native/tts.d.ts.map +1 -0
- package/dist/backends/native/tts.js +105 -0
- package/dist/backends/native/tts.js.map +1 -0
- package/dist/backends/transformers/index.d.ts +4 -0
- package/dist/backends/transformers/index.d.ts.map +1 -0
- package/dist/backends/transformers/index.js +4 -0
- package/dist/backends/transformers/index.js.map +1 -0
- package/dist/backends/transformers/llm.d.ts +29 -0
- package/dist/backends/transformers/llm.d.ts.map +1 -0
- package/dist/backends/transformers/llm.js +117 -0
- package/dist/backends/transformers/llm.js.map +1 -0
- package/dist/backends/transformers/stt.d.ts +17 -0
- package/dist/backends/transformers/stt.d.ts.map +1 -0
- package/dist/backends/transformers/stt.js +43 -0
- package/dist/backends/transformers/stt.js.map +1 -0
- package/dist/backends/transformers/tts.d.ts +17 -0
- package/dist/backends/transformers/tts.d.ts.map +1 -0
- package/dist/backends/transformers/tts.js +40 -0
- package/dist/backends/transformers/tts.js.map +1 -0
- package/dist/cache.d.ts +37 -0
- package/dist/cache.d.ts.map +1 -0
- package/dist/cache.js +49 -0
- package/dist/cache.js.map +1 -0
- package/dist/cli.d.ts +11 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +392 -0
- package/dist/cli.js.map +1 -0
- package/dist/client/audio-player.d.ts +45 -0
- package/dist/client/audio-player.d.ts.map +1 -0
- package/dist/client/audio-player.js +90 -0
- package/dist/client/audio-player.js.map +1 -0
- package/dist/client/audio-recorder.d.ts +42 -0
- package/dist/client/audio-recorder.d.ts.map +1 -0
- package/dist/client/audio-recorder.js +128 -0
- package/dist/client/audio-recorder.js.map +1 -0
- package/dist/client/index.d.ts +34 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +33 -0
- package/dist/client/index.js.map +1 -0
- package/dist/client/protocol.d.ts +80 -0
- package/dist/client/protocol.d.ts.map +1 -0
- package/dist/client/protocol.js +29 -0
- package/dist/client/protocol.js.map +1 -0
- package/dist/client/voice-client.d.ts +249 -0
- package/dist/client/voice-client.d.ts.map +1 -0
- package/dist/client/voice-client.js +826 -0
- package/dist/client/voice-client.js.map +1 -0
- package/dist/client/web-speech-stt.d.ts +65 -0
- package/dist/client/web-speech-stt.d.ts.map +1 -0
- package/dist/client/web-speech-stt.js +122 -0
- package/dist/client/web-speech-stt.js.map +1 -0
- package/dist/client/web-speech-tts.d.ts +59 -0
- package/dist/client/web-speech-tts.d.ts.map +1 -0
- package/dist/client/web-speech-tts.js +145 -0
- package/dist/client/web-speech-tts.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/dist/server/encoding.d.ts +18 -0
- package/dist/server/encoding.d.ts.map +1 -0
- package/dist/server/encoding.js +41 -0
- package/dist/server/encoding.js.map +1 -0
- package/dist/server/handler.d.ts +86 -0
- package/dist/server/handler.d.ts.map +1 -0
- package/dist/server/handler.js +224 -0
- package/dist/server/handler.js.map +1 -0
- package/dist/server/index.d.ts +31 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +32 -0
- package/dist/server/index.js.map +1 -0
- package/dist/services/function-service.d.ts +17 -0
- package/dist/services/function-service.d.ts.map +1 -0
- package/dist/services/function-service.js +82 -0
- package/dist/services/function-service.js.map +1 -0
- package/dist/services/index.d.ts +4 -0
- package/dist/services/index.d.ts.map +1 -0
- package/dist/services/index.js +3 -0
- package/dist/services/index.js.map +1 -0
- package/dist/services/llm-logger.d.ts +136 -0
- package/dist/services/llm-logger.d.ts.map +1 -0
- package/dist/services/llm-logger.js +275 -0
- package/dist/services/llm-logger.js.map +1 -0
- package/dist/services/text-normalizer.d.ts +17 -0
- package/dist/services/text-normalizer.d.ts.map +1 -0
- package/dist/services/text-normalizer.js +100 -0
- package/dist/services/text-normalizer.js.map +1 -0
- package/dist/types.d.ts +195 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +48 -0
- package/dist/types.js.map +1 -0
- package/dist/voice-pipeline.d.ts +125 -0
- package/dist/voice-pipeline.d.ts.map +1 -0
- package/dist/voice-pipeline.js +390 -0
- package/dist/voice-pipeline.js.map +1 -0
- package/package.json +96 -0
- package/scripts/setup-binaries.sh +159 -0
- package/scripts/setup.sh +201 -0
|
@@ -0,0 +1,435 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Native LLM Pipeline (llama.cpp)
|
|
3
|
+
* Server-only - requires native binary (llama-completion)
|
|
4
|
+
*
|
|
5
|
+
* When tools are provided, uses GBNF grammar that allows either:
|
|
6
|
+
* - TOOL: [{"name": "...", "arguments": {...}}] for tool invocations
|
|
7
|
+
* - SAY: natural language for direct responses (streamable!)
|
|
8
|
+
*
|
|
9
|
+
* This allows real token streaming for text responses while maintaining
|
|
10
|
+
* structured tool calling when needed.
|
|
11
|
+
*/
|
|
12
|
+
import { spawn } from 'child_process';
|
|
13
|
+
import { existsSync, writeFileSync, unlinkSync } from 'fs';
|
|
14
|
+
import { tmpdir } from 'os';
|
|
15
|
+
import { join } from 'path';
|
|
16
|
+
import { LLMLogger, LLMConversationTracker } from '../../services';
|
|
17
|
+
export class NativeLLM {
|
|
18
|
+
config;
|
|
19
|
+
ready = false;
|
|
20
|
+
tracker;
|
|
21
|
+
constructor(config) {
|
|
22
|
+
this.config = config;
|
|
23
|
+
this.tracker = new LLMConversationTracker(new LLMLogger());
|
|
24
|
+
}
|
|
25
|
+
async initialize(_onProgress) {
|
|
26
|
+
console.log('Initializing native LLM (llama-completion)...');
|
|
27
|
+
if (!existsSync(this.config.binaryPath)) {
|
|
28
|
+
throw new Error(`llama-completion binary not found at: ${this.config.binaryPath}`);
|
|
29
|
+
}
|
|
30
|
+
if (!existsSync(this.config.modelPath)) {
|
|
31
|
+
throw new Error(`LLM model not found at: ${this.config.modelPath}`);
|
|
32
|
+
}
|
|
33
|
+
this.ready = true;
|
|
34
|
+
console.log(`Native LLM ready. Model: ${this.config.modelPath}`);
|
|
35
|
+
}
|
|
36
|
+
supportsTools() {
|
|
37
|
+
return true;
|
|
38
|
+
}
|
|
39
|
+
async generate(messages, options) {
|
|
40
|
+
if (!this.ready) {
|
|
41
|
+
throw new Error('LLM pipeline not initialized');
|
|
42
|
+
}
|
|
43
|
+
// If tools are provided, use grammar mode for guaranteed valid JSON
|
|
44
|
+
if (options?.tools && options.tools.length > 0) {
|
|
45
|
+
return this.generateWithGrammar(messages, options);
|
|
46
|
+
}
|
|
47
|
+
// No tools: regular freeform generation
|
|
48
|
+
return this.generateFreeform(messages, options);
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Build the tool system prompt
|
|
52
|
+
*/
|
|
53
|
+
buildToolSystemPrompt(tools) {
|
|
54
|
+
const toolsJson = JSON.stringify(tools.map(t => ({
|
|
55
|
+
type: 'function',
|
|
56
|
+
function: {
|
|
57
|
+
name: t.name,
|
|
58
|
+
description: t.description,
|
|
59
|
+
parameters: t.parameters,
|
|
60
|
+
},
|
|
61
|
+
})), null, 2);
|
|
62
|
+
return `
|
|
63
|
+
You have access to tools, but ONLY use them when explicitly needed:
|
|
64
|
+
<tools>${toolsJson}</tools>
|
|
65
|
+
|
|
66
|
+
IMPORTANT: Default to SAY for most interactions. Only use tools when the user EXPLICITLY asks for something the tool provides.
|
|
67
|
+
|
|
68
|
+
Response formats:
|
|
69
|
+
- SAY: Your natural language response — USE THIS BY DEFAULT for greetings, conversation, questions, explanations, and any response where you don't need external data.
|
|
70
|
+
- TOOL: [{"name": "tool_name", "arguments": {"arg1": "value1"}}] — ONLY use when the user specifically requests information that requires a tool (e.g., "what time is it?" needs get_current_time).
|
|
71
|
+
|
|
72
|
+
Examples of when NOT to use tools:
|
|
73
|
+
- "Hello" / "Hi" / "Hey" → just greet back with SAY:
|
|
74
|
+
- "How are you?" → respond naturally with SAY:
|
|
75
|
+
- "Tell me a joke" → respond with SAY:
|
|
76
|
+
- "What can you do?" → describe capabilities with SAY:`;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Generate with GBNF grammar constraint
|
|
80
|
+
* Allows either:
|
|
81
|
+
* - TOOL: [{...}] for tool invocations
|
|
82
|
+
* - SAY: text for streamable text responses
|
|
83
|
+
*/
|
|
84
|
+
async generateWithGrammar(messages, options) {
|
|
85
|
+
const tools = options.tools ?? [];
|
|
86
|
+
// Build grammar that allows say OR tool_call
|
|
87
|
+
const grammar = this.buildToolGrammar(tools);
|
|
88
|
+
// Write grammar to temp file (llama-completion needs a file path)
|
|
89
|
+
const grammarPath = join(tmpdir(), `grammar-${Date.now()}.gbnf`);
|
|
90
|
+
writeFileSync(grammarPath, grammar);
|
|
91
|
+
try {
|
|
92
|
+
const prompt = this.formatChatPromptWithTools(messages, tools);
|
|
93
|
+
// llama-completion args for clean non-interactive output
|
|
94
|
+
const args = [
|
|
95
|
+
'-m', this.config.modelPath,
|
|
96
|
+
'-n', String(this.config.maxNewTokens),
|
|
97
|
+
'--temp', String(this.config.temperature ?? 0.7),
|
|
98
|
+
'--grammar-file', grammarPath,
|
|
99
|
+
'--no-display-prompt', // Don't echo the prompt back
|
|
100
|
+
'--simple-io', // Clean output without ANSI codes
|
|
101
|
+
'-no-cnv', // Non-conversation mode (single completion)
|
|
102
|
+
'-p', prompt,
|
|
103
|
+
];
|
|
104
|
+
if (this.config.gpuLayers) {
|
|
105
|
+
args.push('-ngl', String(this.config.gpuLayers));
|
|
106
|
+
}
|
|
107
|
+
// Use streaming completion that handles both formats
|
|
108
|
+
const result = await this.runLlamaCompletionWithStreaming(args, messages, options);
|
|
109
|
+
return result;
|
|
110
|
+
}
|
|
111
|
+
finally {
|
|
112
|
+
// Clean up temp grammar file
|
|
113
|
+
try {
|
|
114
|
+
unlinkSync(grammarPath);
|
|
115
|
+
}
|
|
116
|
+
catch {
|
|
117
|
+
// Ignore cleanup errors
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Parse tool call output
|
|
123
|
+
* TOOL: [{"name": "...", "arguments": {...}}]
|
|
124
|
+
*/
|
|
125
|
+
parseToolCallOutput(output) {
|
|
126
|
+
// The output should already be just the JSON array (TOOL: prefix stripped)
|
|
127
|
+
const jsonStr = output.trim();
|
|
128
|
+
try {
|
|
129
|
+
const parsed = JSON.parse(jsonStr.trim());
|
|
130
|
+
// Handle array format
|
|
131
|
+
if (Array.isArray(parsed)) {
|
|
132
|
+
return parsed.filter(tc => tc && typeof tc.name === 'string');
|
|
133
|
+
}
|
|
134
|
+
// Handle single object format (legacy)
|
|
135
|
+
if (parsed && typeof parsed.name === 'string') {
|
|
136
|
+
return [parsed];
|
|
137
|
+
}
|
|
138
|
+
return null;
|
|
139
|
+
}
|
|
140
|
+
catch {
|
|
141
|
+
return null;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Build GBNF grammar that allows either:
|
|
146
|
+
* - TOOL: [{"name": "...", "arguments": {...}}]
|
|
147
|
+
* - SAY: free text
|
|
148
|
+
*/
|
|
149
|
+
buildToolGrammar(tools) {
|
|
150
|
+
// Build tool name alternatives: "get_weather" | "search"
|
|
151
|
+
const toolNames = tools.map(t => `"\\"${t.name}\\""`).join(' | ');
|
|
152
|
+
return `# Grammar allowing text responses OR tool calls
|
|
153
|
+
# Output: SAY: text OR TOOL: [json]
|
|
154
|
+
|
|
155
|
+
root ::= say-response | tool-call
|
|
156
|
+
|
|
157
|
+
# Say response - free form text (streamable)
|
|
158
|
+
say-response ::= "SAY:" ws text-content
|
|
159
|
+
text-content ::= text-char+
|
|
160
|
+
text-char ::= [a-zA-Z0-9 .,!?'\"():;\\n\\t\\r-]
|
|
161
|
+
|
|
162
|
+
# Tool call - structured JSON
|
|
163
|
+
tool-call ::= "TOOL:" ws tool-array
|
|
164
|
+
|
|
165
|
+
tool-array ::= "[" ws tool-obj ws "]"
|
|
166
|
+
|
|
167
|
+
tool-obj ::= "{" ws "\\"name\\":" ws tool-name "," ws "\\"arguments\\":" ws arguments ws "}"
|
|
168
|
+
|
|
169
|
+
tool-name ::= ${toolNames}
|
|
170
|
+
|
|
171
|
+
arguments ::= "{" ws (keyval ("," ws keyval)*)? ws "}"
|
|
172
|
+
keyval ::= string ":" ws value
|
|
173
|
+
|
|
174
|
+
value ::= string | number | bool | null | object | array
|
|
175
|
+
string ::= "\\"" chars "\\""
|
|
176
|
+
chars ::= char*
|
|
177
|
+
char ::= [^"\\\\\\x00-\\x1f] | "\\\\" escape
|
|
178
|
+
escape ::= ["\\\\/bfnrt] | "u" [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F]
|
|
179
|
+
number ::= "-"? ("0" | [1-9] [0-9]*) ("." [0-9]+)? ([eE] [+-]? [0-9]+)?
|
|
180
|
+
bool ::= "true" | "false"
|
|
181
|
+
null ::= "null"
|
|
182
|
+
object ::= "{" ws (keyval ("," ws keyval)*)? ws "}"
|
|
183
|
+
array ::= "[" ws (value ("," ws value)*)? ws "]"
|
|
184
|
+
|
|
185
|
+
ws ::= [ \\t\\n]*
|
|
186
|
+
`;
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Format chat prompt with tool definitions (for grammar mode)
|
|
190
|
+
* Uses ChatML format with tool instructions
|
|
191
|
+
*/
|
|
192
|
+
formatChatPromptWithTools(messages, tools) {
|
|
193
|
+
const toolSystemPrompt = this.buildToolSystemPrompt(tools);
|
|
194
|
+
let prompt = '';
|
|
195
|
+
for (const msg of messages) {
|
|
196
|
+
if (msg.role === 'system') {
|
|
197
|
+
// Combine system prompt with tool instructions
|
|
198
|
+
prompt += `<|im_start|>system\n${msg.content}\n\n${toolSystemPrompt}<|im_end|>\n`;
|
|
199
|
+
}
|
|
200
|
+
else if (msg.role === 'user') {
|
|
201
|
+
prompt += `<|im_start|>user\n${msg.content}<|im_end|>\n`;
|
|
202
|
+
}
|
|
203
|
+
else if (msg.role === 'assistant') {
|
|
204
|
+
const assistantMsg = msg;
|
|
205
|
+
if (assistantMsg.toolCalls && assistantMsg.toolCalls.length > 0) {
|
|
206
|
+
// Format tool calls
|
|
207
|
+
const toolCallJson = JSON.stringify(assistantMsg.toolCalls.map(tc => ({
|
|
208
|
+
name: tc.name,
|
|
209
|
+
arguments: tc.arguments,
|
|
210
|
+
})));
|
|
211
|
+
prompt += `<|im_start|>assistant\nTOOL: ${toolCallJson}<|im_end|>\n`;
|
|
212
|
+
}
|
|
213
|
+
else if (assistantMsg.content) {
|
|
214
|
+
// Format say response
|
|
215
|
+
prompt += `<|im_start|>assistant\nSAY: ${msg.content}<|im_end|>\n`;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
else if (msg.role === 'tool') {
|
|
219
|
+
prompt += `<|im_start|>tool\n${msg.content}<|im_end|>\n`;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
// If no system message was in history, add tool prompt as system
|
|
223
|
+
if (!messages.some(m => m.role === 'system')) {
|
|
224
|
+
prompt = `<|im_start|>system\n${toolSystemPrompt}<|im_end|>\n` + prompt;
|
|
225
|
+
}
|
|
226
|
+
prompt += '<|im_start|>assistant\n';
|
|
227
|
+
return prompt;
|
|
228
|
+
}
|
|
229
|
+
/** Special tokens to filter from output */
|
|
230
|
+
static SPECIAL_TOKENS = /\[end of text\]|<\|im_end\|>|<\|im_start\|>|<\|endoftext\|>/gi;
|
|
231
|
+
/**
|
|
232
|
+
* Run llama-completion and capture output
|
|
233
|
+
* Output goes to stdout, debug/timing info goes to stderr (ignored)
|
|
234
|
+
*/
|
|
235
|
+
runLlamaCompletion(args, messages, options) {
|
|
236
|
+
// Log the input messages (use conversation ID if provided, else default)
|
|
237
|
+
const conversationId = options?.conversationId ?? 'default';
|
|
238
|
+
this.tracker.logInput(conversationId, messages);
|
|
239
|
+
return new Promise((resolve, reject) => {
|
|
240
|
+
const proc = spawn(this.config.binaryPath, args, {
|
|
241
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
242
|
+
});
|
|
243
|
+
let output = '';
|
|
244
|
+
proc.stdout.on('data', (data) => {
|
|
245
|
+
const chunk = data.toString();
|
|
246
|
+
output += chunk;
|
|
247
|
+
// Stream tokens if callback provided, filtering out special markers
|
|
248
|
+
// llama.cpp sends special tokens as complete strings, not split across chunks
|
|
249
|
+
if (options?.onToken) {
|
|
250
|
+
const filtered = chunk.replace(NativeLLM.SPECIAL_TOKENS, '');
|
|
251
|
+
for (const char of filtered) {
|
|
252
|
+
options.onToken(char);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
});
|
|
256
|
+
proc.stderr.on('data', () => {
|
|
257
|
+
// Ignore stderr (Metal init messages, timing info, etc.)
|
|
258
|
+
});
|
|
259
|
+
proc.on('close', (code) => {
|
|
260
|
+
if (code !== 0) {
|
|
261
|
+
reject(new Error(`llama-completion exited with code ${code}`));
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
264
|
+
// Clean up output - remove special tokens
|
|
265
|
+
const cleaned = output.replace(NativeLLM.SPECIAL_TOKENS, '').trim();
|
|
266
|
+
this.tracker.logRawOutput(conversationId, cleaned);
|
|
267
|
+
resolve(cleaned);
|
|
268
|
+
});
|
|
269
|
+
proc.on('error', reject);
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Run llama-completion with smart streaming
|
|
274
|
+
* - SAY: streams tokens as they arrive
|
|
275
|
+
* - TOOL: buffers until complete, then parses
|
|
276
|
+
*/
|
|
277
|
+
runLlamaCompletionWithStreaming(args, messages, options) {
|
|
278
|
+
const conversationId = options?.conversationId ?? 'default';
|
|
279
|
+
this.tracker.logInput(conversationId, messages);
|
|
280
|
+
return new Promise((resolve, reject) => {
|
|
281
|
+
const proc = spawn(this.config.binaryPath, args, {
|
|
282
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
283
|
+
});
|
|
284
|
+
let buffer = '';
|
|
285
|
+
let mode = 'detecting';
|
|
286
|
+
let textContent = '';
|
|
287
|
+
let isStreaming = false;
|
|
288
|
+
const SAY_PREFIX = 'SAY:';
|
|
289
|
+
const TOOL_PREFIX = 'TOOL:';
|
|
290
|
+
proc.stdout.on('data', (data) => {
|
|
291
|
+
const chunk = data.toString().replace(NativeLLM.SPECIAL_TOKENS, '');
|
|
292
|
+
buffer += chunk;
|
|
293
|
+
// Detect mode from prefix
|
|
294
|
+
if (mode === 'detecting') {
|
|
295
|
+
// Trim leading whitespace for detection
|
|
296
|
+
const trimmed = buffer.trimStart();
|
|
297
|
+
if (trimmed.startsWith(SAY_PREFIX)) {
|
|
298
|
+
mode = 'say';
|
|
299
|
+
isStreaming = true;
|
|
300
|
+
// Remove everything up to and including SAY:
|
|
301
|
+
const sayIndex = buffer.indexOf(SAY_PREFIX);
|
|
302
|
+
buffer = buffer.slice(sayIndex + SAY_PREFIX.length).trimStart();
|
|
303
|
+
}
|
|
304
|
+
else if (trimmed.startsWith(TOOL_PREFIX)) {
|
|
305
|
+
mode = 'tool_call';
|
|
306
|
+
// Remove everything up to and including TOOL:
|
|
307
|
+
const toolIndex = buffer.indexOf(TOOL_PREFIX);
|
|
308
|
+
buffer = buffer.slice(toolIndex + TOOL_PREFIX.length).trimStart();
|
|
309
|
+
}
|
|
310
|
+
else if (trimmed.length >= TOOL_PREFIX.length) {
|
|
311
|
+
// Buffer is long enough but doesn't match expected prefixes
|
|
312
|
+
// This shouldn't happen with grammar, but handle gracefully
|
|
313
|
+
mode = 'say';
|
|
314
|
+
isStreaming = true;
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
// Stream say content (no closing tag needed - just stream everything)
|
|
318
|
+
if (mode === 'say' && isStreaming && options?.onToken) {
|
|
319
|
+
for (const char of buffer) {
|
|
320
|
+
options.onToken(char);
|
|
321
|
+
}
|
|
322
|
+
textContent += buffer;
|
|
323
|
+
buffer = '';
|
|
324
|
+
}
|
|
325
|
+
});
|
|
326
|
+
proc.stderr.on('data', () => {
|
|
327
|
+
// Ignore stderr
|
|
328
|
+
});
|
|
329
|
+
proc.on('close', (code) => {
|
|
330
|
+
if (code !== 0) {
|
|
331
|
+
reject(new Error(`llama-completion exited with code ${code}`));
|
|
332
|
+
return;
|
|
333
|
+
}
|
|
334
|
+
// Final processing based on mode
|
|
335
|
+
const fullOutput = (mode === 'say' ? SAY_PREFIX + ' ' : TOOL_PREFIX + ' ') +
|
|
336
|
+
(textContent || '') + buffer;
|
|
337
|
+
this.tracker.logRawOutput(conversationId, fullOutput.replace(NativeLLM.SPECIAL_TOKENS, '').trim());
|
|
338
|
+
if (mode === 'say') {
|
|
339
|
+
// Any remaining content in buffer
|
|
340
|
+
const remaining = buffer.trim();
|
|
341
|
+
if (remaining && options?.onToken) {
|
|
342
|
+
for (const char of remaining) {
|
|
343
|
+
options.onToken(char);
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
const finalContent = textContent + remaining;
|
|
347
|
+
resolve({
|
|
348
|
+
content: finalContent,
|
|
349
|
+
finishReason: 'stop',
|
|
350
|
+
});
|
|
351
|
+
}
|
|
352
|
+
else if (mode === 'tool_call') {
|
|
353
|
+
// Parse tool call JSON
|
|
354
|
+
const toolCalls = this.parseToolCallOutput(buffer);
|
|
355
|
+
if (toolCalls && toolCalls.length > 0) {
|
|
356
|
+
resolve({
|
|
357
|
+
content: '',
|
|
358
|
+
toolCalls: toolCalls.map((tc, i) => ({
|
|
359
|
+
id: `native-${Date.now()}-${i}-${Math.random().toString(36).slice(2, 9)}`,
|
|
360
|
+
name: tc.name,
|
|
361
|
+
arguments: tc.arguments || {},
|
|
362
|
+
})),
|
|
363
|
+
finishReason: 'tool_calls',
|
|
364
|
+
});
|
|
365
|
+
}
|
|
366
|
+
else {
|
|
367
|
+
// Failed to parse tool call
|
|
368
|
+
resolve({
|
|
369
|
+
content: buffer,
|
|
370
|
+
finishReason: 'stop',
|
|
371
|
+
});
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
else {
|
|
375
|
+
// Detection never completed - return raw buffer
|
|
376
|
+
resolve({
|
|
377
|
+
content: buffer,
|
|
378
|
+
finishReason: 'stop',
|
|
379
|
+
});
|
|
380
|
+
}
|
|
381
|
+
});
|
|
382
|
+
proc.on('error', reject);
|
|
383
|
+
});
|
|
384
|
+
}
|
|
385
|
+
/**
|
|
386
|
+
* Freeform generation (no grammar) - used when no tools are provided
|
|
387
|
+
*/
|
|
388
|
+
async generateFreeform(messages, options) {
|
|
389
|
+
const prompt = this.formatChatPrompt(messages);
|
|
390
|
+
// llama-completion args for clean non-interactive output
|
|
391
|
+
const args = [
|
|
392
|
+
'-m', this.config.modelPath,
|
|
393
|
+
'-n', String(this.config.maxNewTokens),
|
|
394
|
+
'--temp', String(this.config.temperature ?? 0.7),
|
|
395
|
+
'--no-display-prompt', // Don't echo the prompt back
|
|
396
|
+
'--simple-io', // Clean output without ANSI codes
|
|
397
|
+
'-no-cnv', // Non-conversation mode (single completion)
|
|
398
|
+
'-p', prompt,
|
|
399
|
+
];
|
|
400
|
+
if (this.config.gpuLayers) {
|
|
401
|
+
args.push('-ngl', String(this.config.gpuLayers));
|
|
402
|
+
}
|
|
403
|
+
const output = await this.runLlamaCompletion(args, messages, options);
|
|
404
|
+
return {
|
|
405
|
+
content: output,
|
|
406
|
+
finishReason: 'stop',
|
|
407
|
+
};
|
|
408
|
+
}
|
|
409
|
+
/**
|
|
410
|
+
* Format basic chat prompt (for non-tool mode)
|
|
411
|
+
*/
|
|
412
|
+
formatChatPrompt(messages) {
|
|
413
|
+
let prompt = '';
|
|
414
|
+
for (const msg of messages) {
|
|
415
|
+
if (msg.role === 'system') {
|
|
416
|
+
prompt += `<|im_start|>system\n${msg.content}<|im_end|>\n`;
|
|
417
|
+
}
|
|
418
|
+
else if (msg.role === 'user') {
|
|
419
|
+
prompt += `<|im_start|>user\n${msg.content}<|im_end|>\n`;
|
|
420
|
+
}
|
|
421
|
+
else if (msg.role === 'assistant') {
|
|
422
|
+
prompt += `<|im_start|>assistant\n${msg.content}<|im_end|>\n`;
|
|
423
|
+
}
|
|
424
|
+
else if (msg.role === 'tool') {
|
|
425
|
+
prompt += `<|im_start|>tool\n${msg.content}<|im_end|>\n`;
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
prompt += '<|im_start|>assistant\n';
|
|
429
|
+
return prompt;
|
|
430
|
+
}
|
|
431
|
+
isReady() {
|
|
432
|
+
return this.ready;
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
//# sourceMappingURL=llm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"llm.js","sourceRoot":"","sources":["../../../src/backends/native/llm.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Native STT Pipeline (whisper.cpp)
|
|
3
|
+
* Server-only - requires native binary
|
|
4
|
+
*/
|
|
5
|
+
import type { STTPipeline, NativeSTTConfig, ProgressCallback } from '../../types';
|
|
6
|
+
export declare class NativeSTT implements STTPipeline {
|
|
7
|
+
private config;
|
|
8
|
+
private ready;
|
|
9
|
+
constructor(config: NativeSTTConfig);
|
|
10
|
+
initialize(_onProgress?: ProgressCallback): Promise<void>;
|
|
11
|
+
transcribe(audio: Float32Array): Promise<string>;
|
|
12
|
+
isReady(): boolean;
|
|
13
|
+
private writeWav;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=stt.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stt.d.ts","sourceRoot":"","sources":["../../../src/backends/native/stt.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAElF,qBAAa,SAAU,YAAW,WAAW;IAC3C,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,KAAK,CAAS;gBAEV,MAAM,EAAE,eAAe;IAI7B,UAAU,CAAC,WAAW,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IAczD,UAAU,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC;IA6BtD,OAAO,IAAI,OAAO;IAIlB,OAAO,CAAC,QAAQ;CAkCjB"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Native STT Pipeline (whisper.cpp)
|
|
3
|
+
* Server-only - requires native binary
|
|
4
|
+
*/
|
|
5
|
+
import { execSync } from 'child_process';
|
|
6
|
+
import { writeFileSync, unlinkSync, existsSync } from 'fs';
|
|
7
|
+
import { join } from 'path';
|
|
8
|
+
export class NativeSTT {
|
|
9
|
+
config;
|
|
10
|
+
ready = false;
|
|
11
|
+
constructor(config) {
|
|
12
|
+
this.config = config;
|
|
13
|
+
}
|
|
14
|
+
async initialize(_onProgress) {
|
|
15
|
+
console.log('Initializing native STT (whisper.cpp)...');
|
|
16
|
+
if (!existsSync(this.config.binaryPath)) {
|
|
17
|
+
throw new Error(`whisper.cpp binary not found at: ${this.config.binaryPath}`);
|
|
18
|
+
}
|
|
19
|
+
if (!existsSync(this.config.modelPath)) {
|
|
20
|
+
throw new Error(`Whisper model not found at: ${this.config.modelPath}`);
|
|
21
|
+
}
|
|
22
|
+
this.ready = true;
|
|
23
|
+
console.log('Native STT ready.');
|
|
24
|
+
}
|
|
25
|
+
async transcribe(audio) {
|
|
26
|
+
if (!this.ready) {
|
|
27
|
+
throw new Error('STT pipeline not initialized');
|
|
28
|
+
}
|
|
29
|
+
const tempPath = join('/tmp', `whisper-${Date.now()}-${Math.random().toString(36).slice(2)}.wav`);
|
|
30
|
+
try {
|
|
31
|
+
this.writeWav(tempPath, audio, 16000);
|
|
32
|
+
const result = execSync(`"${this.config.binaryPath}" ` +
|
|
33
|
+
`-m "${this.config.modelPath}" ` +
|
|
34
|
+
`-l ${this.config.language} ` +
|
|
35
|
+
`--no-timestamps ` +
|
|
36
|
+
`--suppress-nst ` + // Suppress non-speech tokens like "(upbeat music)"
|
|
37
|
+
`-np ` + // No prints except results
|
|
38
|
+
`-f "${tempPath}"`, { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'] });
|
|
39
|
+
return result.trim();
|
|
40
|
+
}
|
|
41
|
+
finally {
|
|
42
|
+
if (existsSync(tempPath)) {
|
|
43
|
+
unlinkSync(tempPath);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
isReady() {
|
|
48
|
+
return this.ready;
|
|
49
|
+
}
|
|
50
|
+
writeWav(path, audio, sampleRate) {
|
|
51
|
+
const numChannels = 1;
|
|
52
|
+
const bitsPerSample = 16;
|
|
53
|
+
const byteRate = sampleRate * numChannels * (bitsPerSample / 8);
|
|
54
|
+
const blockAlign = numChannels * (bitsPerSample / 8);
|
|
55
|
+
const dataSize = audio.length * (bitsPerSample / 8);
|
|
56
|
+
const fileSize = 36 + dataSize;
|
|
57
|
+
const buffer = Buffer.alloc(44 + dataSize);
|
|
58
|
+
let offset = 0;
|
|
59
|
+
buffer.write('RIFF', offset);
|
|
60
|
+
offset += 4;
|
|
61
|
+
buffer.writeUInt32LE(fileSize, offset);
|
|
62
|
+
offset += 4;
|
|
63
|
+
buffer.write('WAVE', offset);
|
|
64
|
+
offset += 4;
|
|
65
|
+
buffer.write('fmt ', offset);
|
|
66
|
+
offset += 4;
|
|
67
|
+
buffer.writeUInt32LE(16, offset);
|
|
68
|
+
offset += 4;
|
|
69
|
+
buffer.writeUInt16LE(1, offset);
|
|
70
|
+
offset += 2;
|
|
71
|
+
buffer.writeUInt16LE(numChannels, offset);
|
|
72
|
+
offset += 2;
|
|
73
|
+
buffer.writeUInt32LE(sampleRate, offset);
|
|
74
|
+
offset += 4;
|
|
75
|
+
buffer.writeUInt32LE(byteRate, offset);
|
|
76
|
+
offset += 4;
|
|
77
|
+
buffer.writeUInt16LE(blockAlign, offset);
|
|
78
|
+
offset += 2;
|
|
79
|
+
buffer.writeUInt16LE(bitsPerSample, offset);
|
|
80
|
+
offset += 2;
|
|
81
|
+
buffer.write('data', offset);
|
|
82
|
+
offset += 4;
|
|
83
|
+
buffer.writeUInt32LE(dataSize, offset);
|
|
84
|
+
offset += 4;
|
|
85
|
+
for (let i = 0; i < audio.length; i++) {
|
|
86
|
+
const sample = Math.max(-1, Math.min(1, audio[i]));
|
|
87
|
+
const int16 = sample < 0 ? sample * 32768 : sample * 32767;
|
|
88
|
+
buffer.writeInt16LE(Math.round(int16), offset);
|
|
89
|
+
offset += 2;
|
|
90
|
+
}
|
|
91
|
+
writeFileSync(path, buffer);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=stt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stt.js","sourceRoot":"","sources":["../../../src/backends/native/stt.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAC3D,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAG5B,MAAM,OAAO,SAAS;IACZ,MAAM,CAAkB;IACxB,KAAK,GAAG,KAAK,CAAC;IAEtB,YAAY,MAAuB;QACjC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,WAA8B;QAC7C,OAAO,CAAC,GAAG,CAAC,0CAA0C,CAAC,CAAC;QAExD,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC;YACxC,MAAM,IAAI,KAAK,CAAC,oCAAoC,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC;QAChF,CAAC;QACD,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC;YACvC,MAAM,IAAI,KAAK,CAAC,+BAA+B,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC;QAC1E,CAAC;QAED,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QAClB,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;IACnC,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,KAAmB;QAClC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;YAChB,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;QAClD,CAAC;QAED,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,EAAE,WAAW,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QAElG,IAAI,CAAC;YACH,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;YAEtC,MAAM,MAAM,GAAG,QAAQ,CACrB,IAAI,IAAI,CAAC,MAAM,CAAC,UAAU,IAAI;gBAC9B,OAAO,IAAI,CAAC,MAAM,CAAC,SAAS,IAAI;gBAChC,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,GAAG;gBAC7B,kBAAkB;gBAClB,iBAAiB,GAAI,mDAAmD;gBACxE,MAAM,GAAe,2BAA2B;gBAChD,OAAO,QAAQ,GAAG,EAClB,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,CACvD,CAAC;YAEF,OAAO,MAAM,CAAC,IAAI,EAAE,CAAC;QACvB,CAAC;gBAAS,CAAC;YACT,IAAI,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACzB,UAAU,CAAC,QAAQ,CAAC,CAAC;YACvB,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO;QACL,OAAO,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC;IAEO,QAAQ,CAAC,IAAY,EAAE,KAAmB,EAAE,UAAkB;QACpE,MAAM,WAAW,GAAG,CAAC,CAAC;QACtB,MAAM,aAAa,GAAG,EAAE,CAAC;QACzB,MAAM,QAAQ,GAAG,UAAU,GAAG,WAAW,GAAG,CAAC,aAAa,GAAG,CAAC,CAAC,CAAC;QAChE,MAAM,UAAU,GAAG,WAAW,GAAG,CAAC,aAAa,GAAG,CAAC,CAAC,CAAC;QACrD,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,aAAa,GAAG,CAAC,CAAC,CAAC;QACpD,MAAM,QAAQ,GAAG,EAAE,GAAG,QAAQ,CAAC;QAE/B,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,EAAE,GAAG,QAAQ,CAAC,CAAC;QAC3C,IAAI,MAAM,GAAG,CAAC,CAAC;QAEf,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAAC,MAAM,IAAI,CAAC,CAAC;QAC1C,MAAM,CAAC,aAAa,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAAC,MAAM,IAAI,CAAC,CAAC;QACpD,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAAC,MAAM,IAAI,CAAC,CAAC;QAC1C,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAAC,MAAM,IAAI,CAAC,CAAC;QAC1C,MAAM,CAAC,aAAa,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;QAAC,MAAM,IAAI,CAAC,CAAC;QAC9C,MAAM,CAAC,aAAa,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;QAAC,MAAM,IAAI,CAAC,CAAC;QAC7C,MAAM,CAAC,aAAa,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;QAAC,MAAM,IAAI,CAAC,CAAC;QACvD,MAAM,CAAC,aAAa,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;QAAC,MAAM,IAAI,CAAC,CAAC;QACtD,MAAM,CAAC,aAAa,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAAC,MAAM,IAAI,CAAC,CAAC;QACpD,MAAM,CAAC,aAAa,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;QAAC,MAAM,IAAI,CAAC,CAAC;QACtD,MAAM,CAAC,aAAa,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;QAAC,MAAM,IAAI,CAAC,CAAC;QACzD,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAAC,MAAM,IAAI,CAAC,CAAC;QAC1C,MAAM,CAAC,aAAa,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAAC,MAAM,IAAI,CAAC,CAAC;QAEpD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACtC,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACnD,MAAM,KAAK,GAAG,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,MAAM,GAAG,KAAK,CAAC;YAC3D,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,CAAC;YAC/C,MAAM,IAAI,CAAC,CAAC;QACd,CAAC;QAED,aAAa,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC9B,CAAC;CACF"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Native TTS Pipeline (sherpa-onnx)
|
|
3
|
+
* Server-only - requires sherpa-onnx binary
|
|
4
|
+
*
|
|
5
|
+
* Uses sherpa-onnx-offline-tts which supports Piper ONNX models.
|
|
6
|
+
* See: https://github.com/k2-fsa/sherpa-onnx
|
|
7
|
+
*/
|
|
8
|
+
import type { TTSPipeline, SherpaOnnxTTSConfig, ProgressCallback, AudioPlayable } from '../../types';
|
|
9
|
+
export declare class NativeTTS implements TTSPipeline {
|
|
10
|
+
private config;
|
|
11
|
+
private ready;
|
|
12
|
+
private modelPath;
|
|
13
|
+
private tokensPath;
|
|
14
|
+
private dataDir;
|
|
15
|
+
constructor(config: SherpaOnnxTTSConfig);
|
|
16
|
+
initialize(_onProgress?: ProgressCallback): Promise<void>;
|
|
17
|
+
synthesize(text: string): Promise<AudioPlayable>;
|
|
18
|
+
private parseWav;
|
|
19
|
+
isReady(): boolean;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=tts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tts.d.ts","sourceRoot":"","sources":["../../../src/backends/native/tts.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,OAAO,KAAK,EAAE,WAAW,EAAE,mBAAmB,EAAE,gBAAgB,EAAe,aAAa,EAAE,MAAM,aAAa,CAAC;AAGlH,qBAAa,SAAU,YAAW,WAAW;IAC3C,OAAO,CAAC,MAAM,CAAsB;IACpC,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,SAAS,CAAc;IAC/B,OAAO,CAAC,UAAU,CAAc;IAChC,OAAO,CAAC,OAAO,CAAc;gBAEjB,MAAM,EAAE,mBAAmB;IAQjC,UAAU,CAAC,WAAW,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IAuCzD,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IAmCtD,OAAO,CAAC,QAAQ;IAsBhB,OAAO,IAAI,OAAO;CAGnB"}
|