speechflow 2.3.0 → 2.4.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/.ase/service.log +10272 -0
- package/.claude/CLAUDE.md +1 -0
- package/AGENTS.md +1 -1
- package/CHANGELOG.md +38 -0
- package/README.md +10 -37
- package/package.json +7 -7
- package/speechflow-cli/dst/speechflow-main-graph.js +14 -5
- package/speechflow-cli/dst/speechflow-main-graph.js.map +1 -1
- package/speechflow-cli/dst/speechflow-node-a2a-compressor-wt.js +10 -9
- package/speechflow-cli/dst/speechflow-node-a2a-compressor-wt.js.map +1 -1
- package/speechflow-cli/dst/speechflow-node-a2a-compressor.js +17 -2
- package/speechflow-cli/dst/speechflow-node-a2a-compressor.js.map +1 -1
- package/speechflow-cli/dst/speechflow-node-a2a-expander-wt.js +7 -8
- package/speechflow-cli/dst/speechflow-node-a2a-expander-wt.js.map +1 -1
- package/speechflow-cli/dst/speechflow-node-a2a-ffmpeg.js +5 -5
- package/speechflow-cli/dst/speechflow-node-a2a-ffmpeg.js.map +1 -1
- package/speechflow-cli/dst/speechflow-node-a2a-filler.js +5 -0
- package/speechflow-cli/dst/speechflow-node-a2a-filler.js.map +1 -1
- package/speechflow-cli/dst/speechflow-node-a2a-gender.js +1 -4
- package/speechflow-cli/dst/speechflow-node-a2a-gender.js.map +1 -1
- package/speechflow-cli/dst/speechflow-node-a2a-meter.js +1 -1
- package/speechflow-cli/dst/speechflow-node-a2a-meter.js.map +1 -1
- package/speechflow-cli/dst/speechflow-node-a2t-amazon.js +8 -3
- package/speechflow-cli/dst/speechflow-node-a2t-amazon.js.map +1 -1
- package/speechflow-cli/dst/speechflow-node-a2t-deepgram.d.ts +7 -0
- package/speechflow-cli/dst/speechflow-node-a2t-deepgram.js +145 -62
- package/speechflow-cli/dst/speechflow-node-a2t-deepgram.js.map +1 -1
- package/speechflow-cli/dst/speechflow-node-a2t-google.d.ts +1 -0
- package/speechflow-cli/dst/speechflow-node-a2t-google.js +16 -5
- package/speechflow-cli/dst/speechflow-node-a2t-google.js.map +1 -1
- package/speechflow-cli/dst/speechflow-node-a2t-openai.js +10 -4
- package/speechflow-cli/dst/speechflow-node-a2t-openai.js.map +1 -1
- package/speechflow-cli/dst/speechflow-node-t2a-kokoro.js +3 -1
- package/speechflow-cli/dst/speechflow-node-t2a-kokoro.js.map +1 -1
- package/speechflow-cli/dst/speechflow-node-t2a-supertonic.js +1 -0
- package/speechflow-cli/dst/speechflow-node-t2a-supertonic.js.map +1 -1
- package/speechflow-cli/dst/speechflow-node-t2t-opus.js +9 -1
- package/speechflow-cli/dst/speechflow-node-t2t-opus.js.map +1 -1
- package/speechflow-cli/dst/{speechflow-node-t2t-spellcheck.d.ts → speechflow-node-t2t-proofread.d.ts} +1 -1
- package/speechflow-cli/dst/{speechflow-node-t2t-spellcheck.js → speechflow-node-t2t-proofread.js} +38 -54
- package/speechflow-cli/dst/speechflow-node-t2t-proofread.js.map +1 -0
- package/speechflow-cli/dst/speechflow-node-t2t-sentence.d.ts +3 -0
- package/speechflow-cli/dst/speechflow-node-t2t-sentence.js +195 -59
- package/speechflow-cli/dst/speechflow-node-t2t-sentence.js.map +1 -1
- package/speechflow-cli/dst/speechflow-node-t2t-summary.js +1 -1
- package/speechflow-cli/dst/speechflow-node-t2t-summary.js.map +1 -1
- package/speechflow-cli/dst/speechflow-node-t2t-translate.js +1 -1
- package/speechflow-cli/dst/speechflow-node-t2t-translate.js.map +1 -1
- package/speechflow-cli/dst/speechflow-node-xio-device.js +4 -1
- package/speechflow-cli/dst/speechflow-node-xio-device.js.map +1 -1
- package/speechflow-cli/dst/speechflow-node-xio-exec.js +8 -5
- package/speechflow-cli/dst/speechflow-node-xio-exec.js.map +1 -1
- package/speechflow-cli/dst/speechflow-node-xio-webrtc.d.ts +1 -0
- package/speechflow-cli/dst/speechflow-node-xio-webrtc.js +6 -1
- package/speechflow-cli/dst/speechflow-node-xio-webrtc.js.map +1 -1
- package/speechflow-cli/dst/speechflow-node-xio-websocket.js +14 -4
- package/speechflow-cli/dst/speechflow-node-xio-websocket.js.map +1 -1
- package/speechflow-cli/dst/speechflow-util-audio.js +11 -9
- package/speechflow-cli/dst/speechflow-util-audio.js.map +1 -1
- package/speechflow-cli/dst/speechflow-util-llm.d.ts +1 -0
- package/speechflow-cli/dst/speechflow-util-llm.js +18 -4
- package/speechflow-cli/dst/speechflow-util-llm.js.map +1 -1
- package/speechflow-cli/dst/speechflow-util-misc.js +28 -14
- package/speechflow-cli/dst/speechflow-util-misc.js.map +1 -1
- package/speechflow-cli/dst/speechflow-util-queue.d.ts +4 -0
- package/speechflow-cli/dst/speechflow-util-queue.js +41 -0
- package/speechflow-cli/dst/speechflow-util-queue.js.map +1 -1
- package/speechflow-cli/dst/speechflow.js.map +1 -1
- package/speechflow-cli/etc/oxlint.jsonc +9 -2
- package/speechflow-cli/package.d/{@typescript-eslint+typescript-estree+8.57.2.patch → @typescript-eslint+typescript-estree+8.59.3.patch} +1 -1
- package/speechflow-cli/package.json +30 -30
- package/speechflow-cli/src/speechflow-main-graph.ts +14 -5
- package/speechflow-cli/src/speechflow-node-a2a-compressor-wt.ts +12 -9
- package/speechflow-cli/src/speechflow-node-a2a-compressor.ts +23 -7
- package/speechflow-cli/src/speechflow-node-a2a-expander-wt.ts +7 -8
- package/speechflow-cli/src/speechflow-node-a2a-ffmpeg.ts +6 -6
- package/speechflow-cli/src/speechflow-node-a2a-filler.ts +6 -0
- package/speechflow-cli/src/speechflow-node-a2a-gender.ts +3 -6
- package/speechflow-cli/src/speechflow-node-a2a-meter.ts +1 -1
- package/speechflow-cli/src/speechflow-node-a2t-amazon.ts +12 -3
- package/speechflow-cli/src/speechflow-node-a2t-deepgram.ts +156 -66
- package/speechflow-cli/src/speechflow-node-a2t-google.ts +18 -5
- package/speechflow-cli/src/speechflow-node-a2t-openai.ts +10 -4
- package/speechflow-cli/src/speechflow-node-t2a-kokoro.ts +3 -1
- package/speechflow-cli/src/speechflow-node-t2a-supertonic.ts +1 -0
- package/speechflow-cli/src/speechflow-node-t2t-opus.ts +9 -1
- package/speechflow-cli/src/{speechflow-node-t2t-spellcheck.ts → speechflow-node-t2t-proofread.ts} +46 -59
- package/speechflow-cli/src/speechflow-node-t2t-sentence.ts +214 -61
- package/speechflow-cli/src/speechflow-node-t2t-summary.ts +1 -1
- package/speechflow-cli/src/speechflow-node-t2t-translate.ts +1 -1
- package/speechflow-cli/src/speechflow-node-xio-device.ts +4 -1
- package/speechflow-cli/src/speechflow-node-xio-exec.ts +9 -6
- package/speechflow-cli/src/speechflow-node-xio-webrtc.ts +7 -1
- package/speechflow-cli/src/speechflow-node-xio-websocket.ts +14 -4
- package/speechflow-cli/src/speechflow-util-audio.ts +12 -10
- package/speechflow-cli/src/speechflow-util-llm.ts +20 -4
- package/speechflow-cli/src/speechflow-util-misc.ts +33 -16
- package/speechflow-cli/src/speechflow-util-queue.ts +43 -0
- package/speechflow-cli/src/speechflow.ts +1 -0
- package/speechflow-ui-db/dst/index.js +19 -16
- package/speechflow-ui-db/etc/oxlint.jsonc +0 -1
- package/speechflow-ui-db/package.d/{@typescript-eslint+typescript-estree+8.57.2.patch → @typescript-eslint+typescript-estree+8.59.3.patch} +1 -1
- package/speechflow-ui-db/package.json +15 -15
- package/speechflow-ui-st/dst/index.js +33 -33
- package/speechflow-ui-st/etc/oxlint.jsonc +2 -2
- package/speechflow-ui-st/package.d/{@typescript-eslint+typescript-estree+8.57.2.patch → @typescript-eslint+typescript-estree+8.59.3.patch} +1 -1
- package/speechflow-ui-st/package.json +15 -15
- package/.claude/settings.local.json +0 -3
- package/speechflow-cli/dst/speechflow-node-t2t-punctuation.d.ts +0 -13
- package/speechflow-cli/dst/speechflow-node-t2t-punctuation.js +0 -219
- package/speechflow-cli/dst/speechflow-node-t2t-punctuation.js.map +0 -1
- package/speechflow-cli/dst/speechflow-node-t2t-spellcheck.js.map +0 -1
- package/speechflow-cli/src/speechflow-node-t2t-punctuation.ts +0 -200
|
@@ -7,6 +7,9 @@
|
|
|
7
7
|
/* standard dependencies */
|
|
8
8
|
import EventEmitter from "node:events"
|
|
9
9
|
|
|
10
|
+
/* internal dependencies */
|
|
11
|
+
import * as util from "./speechflow-util-misc"
|
|
12
|
+
|
|
10
13
|
/* external dependencies */
|
|
11
14
|
import OpenAI from "openai"
|
|
12
15
|
import Anthropic from "@anthropic-ai/sdk"
|
|
@@ -28,6 +31,7 @@ export type LLMConfig = {
|
|
|
28
31
|
temperature?: number
|
|
29
32
|
maxTokens?: number
|
|
30
33
|
cacheDir?: string
|
|
34
|
+
thinking?: boolean
|
|
31
35
|
}
|
|
32
36
|
export type LLMCompleteOptions = {
|
|
33
37
|
system?: string
|
|
@@ -61,6 +65,7 @@ export class LLM extends EventEmitter {
|
|
|
61
65
|
temperature: 0.7,
|
|
62
66
|
maxTokens: 1024,
|
|
63
67
|
cacheDir: "",
|
|
68
|
+
thinking: false,
|
|
64
69
|
...config
|
|
65
70
|
} as Required<LLMConfig>
|
|
66
71
|
|
|
@@ -252,7 +257,8 @@ export class LLM extends EventEmitter {
|
|
|
252
257
|
max_tokens: this.config.maxTokens,
|
|
253
258
|
temperature: this.config.temperature,
|
|
254
259
|
system: systemMessage?.content,
|
|
255
|
-
messages: chatMessages as Anthropic.MessageParam[]
|
|
260
|
+
messages: chatMessages as Anthropic.MessageParam[],
|
|
261
|
+
...(!this.config.thinking ? { thinking: { type: "disabled" } } : {})
|
|
256
262
|
}).catch((err) => {
|
|
257
263
|
throw new Error(`failed to perform Anthropic chat completion: ${err}`, { cause: err })
|
|
258
264
|
})
|
|
@@ -281,7 +287,8 @@ export class LLM extends EventEmitter {
|
|
|
281
287
|
config: {
|
|
282
288
|
maxOutputTokens: this.config.maxTokens,
|
|
283
289
|
temperature: this.config.temperature,
|
|
284
|
-
...(systemInstruction ? { systemInstruction } : {})
|
|
290
|
+
...(systemInstruction ? { systemInstruction } : {}),
|
|
291
|
+
...(!this.config.thinking ? { thinkingConfig: { thinkingBudget: 0 } } : {})
|
|
285
292
|
}
|
|
286
293
|
}).catch((err) => {
|
|
287
294
|
throw new Error(`failed to perform Google chat completion: ${err}`, { cause: err })
|
|
@@ -300,6 +307,7 @@ export class LLM extends EventEmitter {
|
|
|
300
307
|
model: this.config.model,
|
|
301
308
|
messages,
|
|
302
309
|
keep_alive: "10m",
|
|
310
|
+
think: this.config.thinking,
|
|
303
311
|
options: {
|
|
304
312
|
num_predict: this.config.maxTokens,
|
|
305
313
|
temperature: this.config.temperature
|
|
@@ -353,8 +361,16 @@ export class LLM extends EventEmitter {
|
|
|
353
361
|
this.ollama?.abort()
|
|
354
362
|
this.ollama = null
|
|
355
363
|
}
|
|
356
|
-
else if (this.config.provider === "transformers") {
|
|
357
|
-
|
|
364
|
+
else if (this.config.provider === "transformers" && this.transformer !== null) {
|
|
365
|
+
const ac = new AbortController()
|
|
366
|
+
await Promise.race([
|
|
367
|
+
this.transformer.dispose(),
|
|
368
|
+
util.timeout(5000, "transformer dispose timeout", ac.signal)
|
|
369
|
+
]).finally(() => {
|
|
370
|
+
ac.abort()
|
|
371
|
+
}).catch((error) => {
|
|
372
|
+
this.log("warning", `error during transformer cleanup: ${error}`)
|
|
373
|
+
})
|
|
358
374
|
this.transformer = null
|
|
359
375
|
}
|
|
360
376
|
this.initialized = false
|
|
@@ -46,35 +46,52 @@ export const deepClone = (value: any): any => {
|
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
/* sleep: wait a duration of time and then resolve */
|
|
49
|
-
export function sleep (durationMs: number, signal?: AbortSignal) {
|
|
49
|
+
export function sleep (durationMs: number, signal?: AbortSignal): Promise<void> {
|
|
50
50
|
return new Promise<void>((resolve) => {
|
|
51
|
-
const ac
|
|
52
|
-
|
|
53
|
-
|
|
51
|
+
const ac: AbortController | undefined =
|
|
52
|
+
signal !== undefined ? new AbortController() : undefined
|
|
53
|
+
let timer: ReturnType<typeof setTimeout> | null = setTimeout(() => {
|
|
54
|
+
timer = null
|
|
55
|
+
if (signal !== undefined)
|
|
56
|
+
ac!.abort()
|
|
54
57
|
resolve()
|
|
55
58
|
}, durationMs)
|
|
56
59
|
timer.unref()
|
|
57
|
-
if (signal !== undefined)
|
|
58
|
-
signal.
|
|
59
|
-
clearTimeout(timer)
|
|
60
|
+
if (signal !== undefined) {
|
|
61
|
+
if (signal.aborted)
|
|
60
62
|
resolve()
|
|
61
|
-
|
|
63
|
+
else
|
|
64
|
+
signal.addEventListener("abort", () => {
|
|
65
|
+
if (timer !== null)
|
|
66
|
+
clearTimeout(timer)
|
|
67
|
+
resolve()
|
|
68
|
+
}, { once: true, signal: ac!.signal })
|
|
69
|
+
}
|
|
62
70
|
})
|
|
63
71
|
}
|
|
64
72
|
|
|
65
73
|
/* timeout: wait a duration of time and then reject */
|
|
66
|
-
export function timeout (durationMs: number, info = "timeout", signal?: AbortSignal) {
|
|
74
|
+
export function timeout (durationMs: number, info = "timeout", signal?: AbortSignal): Promise<never> {
|
|
67
75
|
return new Promise<never>((resolve, reject) => {
|
|
68
|
-
const ac
|
|
69
|
-
|
|
70
|
-
|
|
76
|
+
const ac: AbortController | undefined =
|
|
77
|
+
signal !== undefined ? new AbortController() : undefined
|
|
78
|
+
let timer: ReturnType<typeof setTimeout> | null = setTimeout(() => {
|
|
79
|
+
timer = null
|
|
80
|
+
if (signal !== undefined)
|
|
81
|
+
ac!.abort()
|
|
71
82
|
reject(new Error(info))
|
|
72
83
|
}, durationMs)
|
|
73
84
|
timer.unref()
|
|
74
|
-
if (signal !== undefined)
|
|
75
|
-
signal.
|
|
76
|
-
clearTimeout(timer)
|
|
85
|
+
if (signal !== undefined) {
|
|
86
|
+
if (signal.aborted)
|
|
77
87
|
resolve(undefined as never)
|
|
78
|
-
|
|
88
|
+
else
|
|
89
|
+
signal.addEventListener("abort", () => {
|
|
90
|
+
if (timer !== null)
|
|
91
|
+
clearTimeout(timer)
|
|
92
|
+
resolve(undefined as never)
|
|
93
|
+
}, { once: true, signal: ac!.signal })
|
|
94
|
+
}
|
|
79
95
|
})
|
|
80
96
|
}
|
|
97
|
+
|
|
@@ -48,6 +48,15 @@ export class QueuePointer<T extends QueueElement> extends EventEmitter {
|
|
|
48
48
|
silent (silence: boolean) {
|
|
49
49
|
this.silence = silence
|
|
50
50
|
}
|
|
51
|
+
silently<R> (fn: () => R): R {
|
|
52
|
+
this.silence = true
|
|
53
|
+
try {
|
|
54
|
+
return fn()
|
|
55
|
+
}
|
|
56
|
+
finally {
|
|
57
|
+
this.silence = false
|
|
58
|
+
}
|
|
59
|
+
}
|
|
51
60
|
|
|
52
61
|
/* notify about operation */
|
|
53
62
|
notify (event: string, info: any) {
|
|
@@ -171,12 +180,14 @@ export class QueuePointer<T extends QueueElement> extends EventEmitter {
|
|
|
171
180
|
}
|
|
172
181
|
insert (element: T) {
|
|
173
182
|
this.queue.elements.splice(this.index, 0, element)
|
|
183
|
+
this.queue.adjustPointers(this, this.index, "insert")
|
|
174
184
|
this.queue.notify("write", { start: this.index, end: this.index, op: "insert" })
|
|
175
185
|
}
|
|
176
186
|
delete () {
|
|
177
187
|
if (this.index >= this.queue.elements.length)
|
|
178
188
|
throw new Error("cannot delete after last element")
|
|
179
189
|
this.queue.elements.splice(this.index, 1)
|
|
190
|
+
this.queue.adjustPointers(this, this.index, "delete")
|
|
180
191
|
this.queue.notify("write", { start: this.index, end: this.index, op: "delete" })
|
|
181
192
|
}
|
|
182
193
|
}
|
|
@@ -193,6 +204,15 @@ export class Queue<T extends QueueElement> extends EventEmitter {
|
|
|
193
204
|
silent (silence: boolean) {
|
|
194
205
|
this.silence = silence
|
|
195
206
|
}
|
|
207
|
+
silently<R> (fn: () => R): R {
|
|
208
|
+
this.silence = true
|
|
209
|
+
try {
|
|
210
|
+
return fn()
|
|
211
|
+
}
|
|
212
|
+
finally {
|
|
213
|
+
this.silence = false
|
|
214
|
+
}
|
|
215
|
+
}
|
|
196
216
|
notify (event: string, info: any) {
|
|
197
217
|
if (!this.silence)
|
|
198
218
|
this.emit(event, info)
|
|
@@ -207,6 +227,24 @@ export class Queue<T extends QueueElement> extends EventEmitter {
|
|
|
207
227
|
throw new Error("pointer does not exist")
|
|
208
228
|
this.pointers.delete(name)
|
|
209
229
|
}
|
|
230
|
+
|
|
231
|
+
/* adjust all sibling pointer positions (after insert/delete splice)
|
|
232
|
+
NOTICE: for insert, pointers AT the index are shifted forward to preserve
|
|
233
|
+
their pointer-to-element binding; for delete, pointers AT the index are
|
|
234
|
+
intentionally NOT adjusted, causing them to silently advance to the next
|
|
235
|
+
element (which shifted into the deleted position). */
|
|
236
|
+
adjustPointers (exclude: QueuePointer<T>, index: number, op: "insert" | "delete"): void {
|
|
237
|
+
for (const pointer of this.pointers.values()) {
|
|
238
|
+
if (pointer === exclude)
|
|
239
|
+
continue
|
|
240
|
+
const pos = pointer.position()
|
|
241
|
+
if (op === "insert" && pos >= index)
|
|
242
|
+
pointer.position(pos + 1)
|
|
243
|
+
else if (op === "delete" && pos > index)
|
|
244
|
+
pointer.position(pos - 1)
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
210
248
|
trim (): void {
|
|
211
249
|
/* determine minimum pointer position */
|
|
212
250
|
let min = this.elements.length
|
|
@@ -227,6 +265,11 @@ export class Queue<T extends QueueElement> extends EventEmitter {
|
|
|
227
265
|
this.notify("write", { start: 0, end: min, op: "trim" })
|
|
228
266
|
}
|
|
229
267
|
}
|
|
268
|
+
clear (): void {
|
|
269
|
+
this.elements.length = 0
|
|
270
|
+
for (const pointer of this.pointers.values())
|
|
271
|
+
pointer.position(0)
|
|
272
|
+
}
|
|
230
273
|
}
|
|
231
274
|
|
|
232
275
|
/* meta store */
|