speechflow 2.4.0 → 2.4.1
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 +85 -0
- package/.ase/service.yaml +1 -0
- package/CHANGELOG.md +16 -2
- package/package.json +3 -3
- package/speechflow-cli/dst/speechflow-main-api.js +8 -1
- package/speechflow-cli/dst/speechflow-main-api.js.map +1 -1
- package/speechflow-cli/dst/speechflow-node-a2a-mute.js +5 -1
- package/speechflow-cli/dst/speechflow-node-a2a-mute.js.map +1 -1
- package/speechflow-cli/dst/speechflow-node-t2t-google.js +3 -0
- package/speechflow-cli/dst/speechflow-node-t2t-google.js.map +1 -1
- package/speechflow-cli/dst/speechflow-node-t2t-proofread.js +17 -9
- package/speechflow-cli/dst/speechflow-node-t2t-proofread.js.map +1 -1
- package/speechflow-cli/dst/speechflow-node-t2t-sentence.js +20 -3
- package/speechflow-cli/dst/speechflow-node-t2t-sentence.js.map +1 -1
- package/speechflow-cli/dst/speechflow-util-llm.js +1 -1
- package/speechflow-cli/dst/speechflow-util-llm.js.map +1 -1
- package/speechflow-cli/etc/oxlint.jsonc +1 -0
- package/speechflow-cli/etc/stx.conf +2 -2
- package/speechflow-cli/package.json +11 -8
- package/speechflow-cli/src/speechflow-main-api.ts +8 -1
- package/speechflow-cli/src/speechflow-node-a2a-mute.ts +6 -1
- package/speechflow-cli/src/speechflow-node-t2t-google.ts +3 -0
- package/speechflow-cli/src/speechflow-node-t2t-proofread.ts +17 -9
- package/speechflow-cli/src/speechflow-node-t2t-sentence.ts +21 -3
- package/speechflow-cli/src/speechflow-util-llm.ts +1 -1
- package/speechflow-ui-db/etc/stx.conf +2 -2
- package/speechflow-ui-db/package.json +5 -5
- package/speechflow-ui-st/dst/index.css +1 -1
- package/speechflow-ui-st/etc/stx.conf +2 -2
- package/speechflow-ui-st/package.json +5 -5
- package/speechflow-ui-st/src/app.vue +3 -3
- /package/speechflow-cli/package.d/{@typescript-eslint+typescript-estree+8.59.3.patch → @typescript-eslint+typescript-estree+8.60.0.patch} +0 -0
- /package/speechflow-ui-db/package.d/{@typescript-eslint+typescript-estree+8.59.3.patch → @typescript-eslint+typescript-estree+8.60.0.patch} +0 -0
- /package/speechflow-ui-st/package.d/{@typescript-eslint+typescript-estree+8.59.3.patch → @typescript-eslint+typescript-estree+8.60.0.patch} +0 -0
|
@@ -26,15 +26,15 @@
|
|
|
26
26
|
"deepl-node": "1.27.0",
|
|
27
27
|
"@elevenlabs/elevenlabs-js": "2.49.1",
|
|
28
28
|
"get-stream": "9.0.1",
|
|
29
|
-
"@dotenvx/dotenvx": "1.69.
|
|
29
|
+
"@dotenvx/dotenvx": "1.69.2",
|
|
30
30
|
"speex-resampler": "3.0.1",
|
|
31
31
|
"@sapphi-red/speex-preprocess-wasm": "0.4.0",
|
|
32
32
|
"@shiguredo/rnnoise-wasm": "2025.1.5",
|
|
33
33
|
"sherpa-onnx": "1.12.25",
|
|
34
34
|
"axios": "1.16.1",
|
|
35
|
-
"@aws-sdk/client-transcribe-streaming": "3.
|
|
36
|
-
"@aws-sdk/client-translate": "3.
|
|
37
|
-
"@aws-sdk/client-polly": "3.
|
|
35
|
+
"@aws-sdk/client-transcribe-streaming": "3.1057.0",
|
|
36
|
+
"@aws-sdk/client-translate": "3.1057.0",
|
|
37
|
+
"@aws-sdk/client-polly": "3.1057.0",
|
|
38
38
|
"@google-cloud/translate": "9.4.1",
|
|
39
39
|
"@google-cloud/speech": "7.3.1",
|
|
40
40
|
"@google-cloud/text-to-speech": "6.4.1",
|
|
@@ -91,9 +91,9 @@
|
|
|
91
91
|
"eslint-plugin-promise": "7.3.0",
|
|
92
92
|
"eslint-plugin-import": "2.32.0",
|
|
93
93
|
"eslint-plugin-node": "11.1.0",
|
|
94
|
-
"typescript-eslint": "8.
|
|
95
|
-
"@typescript-eslint/eslint-plugin": "8.
|
|
96
|
-
"@typescript-eslint/parser": "8.
|
|
94
|
+
"typescript-eslint": "8.60.0",
|
|
95
|
+
"@typescript-eslint/eslint-plugin": "8.60.0",
|
|
96
|
+
"@typescript-eslint/parser": "8.60.0",
|
|
97
97
|
"oxlint": "1.67.0",
|
|
98
98
|
"oxlint-plugin-complexity": "2.1.3",
|
|
99
99
|
"eslint-plugin-oxlint": "1.67.0",
|
|
@@ -136,7 +136,10 @@
|
|
|
136
136
|
"!@deepgram/sdk",
|
|
137
137
|
"!sherpa-onnx",
|
|
138
138
|
"!eslint",
|
|
139
|
-
"!@eslint/js"
|
|
139
|
+
"!@eslint/js",
|
|
140
|
+
"!@google/genai",
|
|
141
|
+
"!@huggingface/transformers",
|
|
142
|
+
"!@soundtouchjs/audio-worklet"
|
|
140
143
|
],
|
|
141
144
|
"engines": {
|
|
142
145
|
"node": ">=22.0.0"
|
|
@@ -64,7 +64,14 @@ export class APIServer {
|
|
|
64
64
|
if (req.request !== "COMMAND")
|
|
65
65
|
throw new Error("invalid external request (command expected)")
|
|
66
66
|
const name = req.node as string
|
|
67
|
-
const argList = req.args as any[]
|
|
67
|
+
const argList = (req.args as any[]).map((arg) => {
|
|
68
|
+
if (arg === "true" || arg === "false")
|
|
69
|
+
return (arg === "true")
|
|
70
|
+
else if (arg.match(/^\d+$/))
|
|
71
|
+
return Number.parseInt(arg, 10)
|
|
72
|
+
else
|
|
73
|
+
return arg
|
|
74
|
+
})
|
|
68
75
|
const foundNode = graph.findGraphNode(name)
|
|
69
76
|
if (foundNode === undefined) {
|
|
70
77
|
this.cli.log("warning", `external request failed: no such node <${name}>`)
|
|
@@ -31,7 +31,9 @@ export default class SpeechFlowNodeA2AMute extends SpeechFlowNode {
|
|
|
31
31
|
super(id, cfg, opts, args)
|
|
32
32
|
|
|
33
33
|
/* declare node configuration parameters */
|
|
34
|
-
this.configure({
|
|
34
|
+
this.configure({
|
|
35
|
+
muteMode: { type: "string", val: "none", pos: 0, match: /^(?:none|silenced|unplugged)$/ }
|
|
36
|
+
})
|
|
35
37
|
|
|
36
38
|
/* declare node input/output format */
|
|
37
39
|
this.input = "audio"
|
|
@@ -75,6 +77,9 @@ export default class SpeechFlowNodeA2AMute extends SpeechFlowNode {
|
|
|
75
77
|
/* clear destruction flag */
|
|
76
78
|
this.closing = false
|
|
77
79
|
|
|
80
|
+
/* determine initial mute mode */
|
|
81
|
+
this.muteMode = this.params.muteMode as MuteMode
|
|
82
|
+
|
|
78
83
|
/* establish a transform stream */
|
|
79
84
|
const self = this
|
|
80
85
|
this.stream = new Stream.Transform({
|
|
@@ -86,6 +86,7 @@ export default class SpeechFlowNodeT2TGoogle extends SpeechFlowNode {
|
|
|
86
86
|
})
|
|
87
87
|
|
|
88
88
|
/* establish a transform stream and connect it to Google Translate */
|
|
89
|
+
const self = this
|
|
89
90
|
this.stream = new Stream.Transform({
|
|
90
91
|
readableObjectMode: true,
|
|
91
92
|
writableObjectMode: true,
|
|
@@ -99,7 +100,9 @@ export default class SpeechFlowNodeT2TGoogle extends SpeechFlowNode {
|
|
|
99
100
|
callback()
|
|
100
101
|
}
|
|
101
102
|
else {
|
|
103
|
+
self.log("info", `receive text (${chunk.kind}): "${chunk.payload}"`)
|
|
102
104
|
translate(chunk.payload).then((payload) => {
|
|
105
|
+
self.log("info", `send text (${chunk.kind}): "${payload}"`)
|
|
103
106
|
const chunkNew = chunk.clone()
|
|
104
107
|
chunkNew.payload = payload
|
|
105
108
|
this.push(chunkNew)
|
|
@@ -119,12 +119,14 @@ export default class SpeechFlowNodeT2TProofread extends SpeechFlowNode {
|
|
|
119
119
|
const cfg = this.setup[this.params.lang]
|
|
120
120
|
if (!cfg)
|
|
121
121
|
throw new Error(`unsupported language: ${this.params.lang}`)
|
|
122
|
-
this.log("info", `
|
|
123
|
-
|
|
122
|
+
this.log("info", `input: "${text}"`)
|
|
123
|
+
const output = await llm.complete({
|
|
124
124
|
system: cfg.systemPrompt,
|
|
125
125
|
messages: cfg.chat,
|
|
126
126
|
prompt: text
|
|
127
127
|
})
|
|
128
|
+
this.log("info", `output: "${output}"`)
|
|
129
|
+
return output
|
|
128
130
|
}
|
|
129
131
|
|
|
130
132
|
/* establish a transform stream and connect it to LLM */
|
|
@@ -141,14 +143,20 @@ export default class SpeechFlowNodeT2TProofread extends SpeechFlowNode {
|
|
|
141
143
|
callback()
|
|
142
144
|
}
|
|
143
145
|
else {
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
146
|
+
if (chunk.kind === "final") {
|
|
147
|
+
proofread(chunk.payload).then((payload) => {
|
|
148
|
+
const chunkNew = chunk.clone()
|
|
149
|
+
chunkNew.payload = payload
|
|
150
|
+
this.push(chunkNew)
|
|
151
|
+
callback()
|
|
152
|
+
}).catch((error: unknown) => {
|
|
153
|
+
callback(util.ensureError(error))
|
|
154
|
+
})
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
this.push(chunk)
|
|
148
158
|
callback()
|
|
149
|
-
}
|
|
150
|
-
callback(util.ensureError(error))
|
|
151
|
-
})
|
|
159
|
+
}
|
|
152
160
|
}
|
|
153
161
|
},
|
|
154
162
|
final (callback) {
|
|
@@ -324,12 +324,30 @@ export default class SpeechFlowNodeT2TSentence extends SpeechFlowNode {
|
|
|
324
324
|
return
|
|
325
325
|
}
|
|
326
326
|
if (element.chunk.kind === "intermediate") {
|
|
327
|
-
|
|
328
|
-
|
|
327
|
+
/* the trailing element is a (speculative) intermediate chunk:
|
|
328
|
+
if the newly arrived chunk carries the very same intermediate
|
|
329
|
+
payload (Deepgram re-sends identical intermediates), treat it
|
|
330
|
+
as a no-op to avoid churning the queue (delete+append) and
|
|
331
|
+
re-emitting an unchanged preview */
|
|
332
|
+
if (chunk.kind === "intermediate"
|
|
333
|
+
&& (element.chunk.payload as string) === (chunk.payload as string)) {
|
|
334
|
+
self.lastChunkTime = Date.now()
|
|
335
|
+
callback()
|
|
336
|
+
return
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
/* remove the trailing intermediate silently, so the
|
|
340
|
+
transient half-mutated queue (intermediate deleted, but
|
|
341
|
+
replacement not yet appended) does NOT emit a "write"
|
|
342
|
+
event and trigger a premature flush that would emit a
|
|
343
|
+
truncated preview and oscillate the dashboard preview */
|
|
344
|
+
self.queue.silently(() => {
|
|
345
|
+
self.queueRecv.walk(-1)
|
|
346
|
+
self.queueRecv.delete()
|
|
347
|
+
})
|
|
329
348
|
}
|
|
330
349
|
}
|
|
331
350
|
}
|
|
332
|
-
previewedPayload = ""
|
|
333
351
|
self.queueRecv.append({ type: "text-frame", chunk, complete: false })
|
|
334
352
|
self.lastChunkTime = Date.now()
|
|
335
353
|
callback()
|
|
@@ -24,8 +24,8 @@ lint-watch
|
|
|
24
24
|
lint
|
|
25
25
|
check-dependencies && \
|
|
26
26
|
vue-tsc --project etc/tsc-client.json --noEmit && \
|
|
27
|
-
oxlint --config etc/oxlint.jsonc src
|
|
28
|
-
eslint --config etc/eslint.mjs src
|
|
27
|
+
oxlint --config etc/oxlint.jsonc src && \
|
|
28
|
+
eslint --config etc/eslint.mjs src && \
|
|
29
29
|
stylelint --config etc/stylelint.yaml src/*.styl src/*.vue && \
|
|
30
30
|
htmllint --rc etc/htmllint.json src/*.html
|
|
31
31
|
|
|
@@ -26,11 +26,11 @@
|
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
28
|
"vite": "7.3.1",
|
|
29
|
-
"typescript-eslint": "8.
|
|
30
|
-
"@typescript-eslint/eslint-plugin": "8.
|
|
31
|
-
"@typescript-eslint/parser": "8.
|
|
29
|
+
"typescript-eslint": "8.60.0",
|
|
30
|
+
"@typescript-eslint/eslint-plugin": "8.60.0",
|
|
31
|
+
"@typescript-eslint/parser": "8.60.0",
|
|
32
32
|
"@vitejs/plugin-vue": "6.0.7",
|
|
33
|
-
"@rollup/plugin-yaml": "
|
|
33
|
+
"@rollup/plugin-yaml": "5.0.0",
|
|
34
34
|
"vite-plugin-node-polyfills": "0.28.0",
|
|
35
35
|
"vite-svg-loader": "5.1.1",
|
|
36
36
|
"@liuli-util/vite-plugin-node": "0.10.0",
|
|
@@ -62,7 +62,7 @@
|
|
|
62
62
|
"postcss-html": "1.8.1",
|
|
63
63
|
"stylus": "0.64.0",
|
|
64
64
|
"typescript": "6.0.3",
|
|
65
|
-
"vue-tsc": "3.3.
|
|
65
|
+
"vue-tsc": "3.3.3",
|
|
66
66
|
"delay-cli": "3.0.0",
|
|
67
67
|
"cross-env": "10.1.0",
|
|
68
68
|
"serve": "14.2.6",
|