speechflow 0.9.4 → 0.9.7
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/CHANGELOG.md +19 -0
- package/README.md +227 -54
- package/dst/speechflow-node-a2a-ffmpeg.d.ts +13 -0
- package/dst/speechflow-node-a2a-ffmpeg.js +152 -0
- package/dst/speechflow-node-a2a-wav.d.ts +11 -0
- package/dst/speechflow-node-a2a-wav.js +170 -0
- package/dst/speechflow-node-a2t-deepgram.d.ts +12 -0
- package/dst/speechflow-node-a2t-deepgram.js +220 -0
- package/dst/speechflow-node-deepgram.d.ts +3 -1
- package/dst/speechflow-node-deepgram.js +86 -22
- package/dst/speechflow-node-deepl.d.ts +3 -1
- package/dst/speechflow-node-deepl.js +25 -20
- package/dst/speechflow-node-device.d.ts +3 -1
- package/dst/speechflow-node-device.js +53 -2
- package/dst/speechflow-node-elevenlabs.d.ts +4 -1
- package/dst/speechflow-node-elevenlabs.js +88 -49
- package/dst/speechflow-node-ffmpeg.d.ts +3 -1
- package/dst/speechflow-node-ffmpeg.js +42 -4
- package/dst/speechflow-node-file.d.ts +3 -1
- package/dst/speechflow-node-file.js +84 -13
- package/dst/speechflow-node-format.d.ts +11 -0
- package/dst/speechflow-node-format.js +80 -0
- package/dst/speechflow-node-gemma.d.ts +3 -1
- package/dst/speechflow-node-gemma.js +84 -23
- package/dst/speechflow-node-mqtt.d.ts +13 -0
- package/dst/speechflow-node-mqtt.js +181 -0
- package/dst/speechflow-node-opus.d.ts +12 -0
- package/dst/speechflow-node-opus.js +135 -0
- package/dst/speechflow-node-subtitle.d.ts +12 -0
- package/dst/speechflow-node-subtitle.js +96 -0
- package/dst/speechflow-node-t2a-elevenlabs.d.ts +13 -0
- package/dst/speechflow-node-t2a-elevenlabs.js +182 -0
- package/dst/speechflow-node-t2t-deepl.d.ts +12 -0
- package/dst/speechflow-node-t2t-deepl.js +133 -0
- package/dst/speechflow-node-t2t-format.d.ts +11 -0
- package/dst/speechflow-node-t2t-format.js +80 -0
- package/dst/speechflow-node-t2t-gemma.d.ts +13 -0
- package/dst/speechflow-node-t2t-gemma.js +213 -0
- package/dst/speechflow-node-t2t-opus.d.ts +12 -0
- package/dst/speechflow-node-t2t-opus.js +135 -0
- package/dst/speechflow-node-t2t-subtitle.d.ts +12 -0
- package/dst/speechflow-node-t2t-subtitle.js +96 -0
- package/dst/speechflow-node-trace.d.ts +11 -0
- package/dst/speechflow-node-trace.js +88 -0
- package/dst/speechflow-node-wav.d.ts +11 -0
- package/dst/speechflow-node-wav.js +170 -0
- package/dst/speechflow-node-websocket.d.ts +3 -1
- package/dst/speechflow-node-websocket.js +149 -49
- package/dst/speechflow-node-whisper-common.d.ts +34 -0
- package/dst/speechflow-node-whisper-common.js +7 -0
- package/dst/speechflow-node-whisper-ggml.d.ts +1 -0
- package/dst/speechflow-node-whisper-ggml.js +97 -0
- package/dst/speechflow-node-whisper-onnx.d.ts +1 -0
- package/dst/speechflow-node-whisper-onnx.js +131 -0
- package/dst/speechflow-node-whisper-worker-ggml.d.ts +1 -0
- package/dst/speechflow-node-whisper-worker-ggml.js +97 -0
- package/dst/speechflow-node-whisper-worker-onnx.d.ts +1 -0
- package/dst/speechflow-node-whisper-worker-onnx.js +131 -0
- package/dst/speechflow-node-whisper-worker.d.ts +1 -0
- package/dst/speechflow-node-whisper-worker.js +116 -0
- package/dst/speechflow-node-whisper-worker2.d.ts +1 -0
- package/dst/speechflow-node-whisper-worker2.js +82 -0
- package/dst/speechflow-node-whisper.d.ts +19 -0
- package/dst/speechflow-node-whisper.js +604 -0
- package/dst/speechflow-node-x2x-trace.d.ts +11 -0
- package/dst/speechflow-node-x2x-trace.js +88 -0
- package/dst/speechflow-node-xio-device.d.ts +13 -0
- package/dst/speechflow-node-xio-device.js +205 -0
- package/dst/speechflow-node-xio-file.d.ts +11 -0
- package/dst/speechflow-node-xio-file.js +176 -0
- package/dst/speechflow-node-xio-mqtt.d.ts +13 -0
- package/dst/speechflow-node-xio-mqtt.js +181 -0
- package/dst/speechflow-node-xio-websocket.d.ts +13 -0
- package/dst/speechflow-node-xio-websocket.js +275 -0
- package/dst/speechflow-node.d.ts +25 -7
- package/dst/speechflow-node.js +74 -9
- package/dst/speechflow-utils.d.ts +23 -0
- package/dst/speechflow-utils.js +194 -0
- package/dst/speechflow.js +146 -43
- package/etc/biome.jsonc +12 -4
- package/etc/stx.conf +65 -0
- package/package.d/@ericedouard+vad-node-realtime+0.2.0.patch +18 -0
- package/package.json +49 -31
- package/sample.yaml +61 -23
- package/src/lib.d.ts +6 -1
- package/src/{speechflow-node-ffmpeg.ts → speechflow-node-a2a-ffmpeg.ts} +10 -4
- package/src/speechflow-node-a2a-wav.ts +143 -0
- package/src/speechflow-node-a2t-deepgram.ts +199 -0
- package/src/speechflow-node-t2a-elevenlabs.ts +160 -0
- package/src/{speechflow-node-deepl.ts → speechflow-node-t2t-deepl.ts} +36 -25
- package/src/speechflow-node-t2t-format.ts +85 -0
- package/src/{speechflow-node-gemma.ts → speechflow-node-t2t-gemma.ts} +89 -25
- package/src/speechflow-node-t2t-opus.ts +111 -0
- package/src/speechflow-node-t2t-subtitle.ts +101 -0
- package/src/speechflow-node-x2x-trace.ts +92 -0
- package/src/{speechflow-node-device.ts → speechflow-node-xio-device.ts} +25 -3
- package/src/speechflow-node-xio-file.ts +153 -0
- package/src/speechflow-node-xio-mqtt.ts +154 -0
- package/src/speechflow-node-xio-websocket.ts +248 -0
- package/src/speechflow-node.ts +78 -13
- package/src/speechflow-utils.ts +212 -0
- package/src/speechflow.ts +150 -43
- package/etc/nps.yaml +0 -40
- package/src/speechflow-node-deepgram.ts +0 -133
- package/src/speechflow-node-elevenlabs.ts +0 -116
- package/src/speechflow-node-file.ts +0 -108
- package/src/speechflow-node-websocket.ts +0 -179
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
** SpeechFlow - Speech Processing Flow Graph
|
|
3
|
-
** Copyright (c) 2024-2025 Dr. Ralf S. Engelschall <rse@engelschall.com>
|
|
4
|
-
** Licensed under GPL 3.0 <https://spdx.org/licenses/GPL-3.0-only>
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
/* standard dependencies */
|
|
8
|
-
import fs from "node:fs"
|
|
9
|
-
import Stream from "node:stream"
|
|
10
|
-
|
|
11
|
-
/* internal dependencies */
|
|
12
|
-
import SpeechFlowNode from "./speechflow-node"
|
|
13
|
-
|
|
14
|
-
/* SpeechFlow node for file access */
|
|
15
|
-
export default class SpeechFlowNodeFile extends SpeechFlowNode {
|
|
16
|
-
/* declare official node name */
|
|
17
|
-
public static name = "file"
|
|
18
|
-
|
|
19
|
-
/* construct node */
|
|
20
|
-
constructor (id: string, opts: { [ id: string ]: any }, args: any[]) {
|
|
21
|
-
super(id, opts, args)
|
|
22
|
-
|
|
23
|
-
/* declare node configuration parameters */
|
|
24
|
-
this.configure({
|
|
25
|
-
path: { type: "string", pos: 0 },
|
|
26
|
-
mode: { type: "string", pos: 1, val: "r", match: /^(?:r|w|rw)$/ },
|
|
27
|
-
type: { type: "string", pos: 2, val: "audio", match: /^(?:audio|text)$/ }
|
|
28
|
-
})
|
|
29
|
-
|
|
30
|
-
/* declare node input/output format */
|
|
31
|
-
if (this.params.mode === "rw") {
|
|
32
|
-
this.input = this.params.type
|
|
33
|
-
this.output = this.params.type
|
|
34
|
-
}
|
|
35
|
-
else if (this.params.mode === "r") {
|
|
36
|
-
this.input = "none"
|
|
37
|
-
this.output = this.params.type
|
|
38
|
-
}
|
|
39
|
-
else if (this.params.mode === "w") {
|
|
40
|
-
this.input = this.params.type
|
|
41
|
-
this.output = "none"
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/* open node */
|
|
46
|
-
async open () {
|
|
47
|
-
const encoding = this.params.type === "text" ? this.config.textEncoding : "binary"
|
|
48
|
-
if (this.params.mode === "rw") {
|
|
49
|
-
if (this.params.path === "-") {
|
|
50
|
-
/* standard I/O */
|
|
51
|
-
process.stdin.setEncoding(encoding)
|
|
52
|
-
process.stdout.setEncoding(encoding)
|
|
53
|
-
this.stream = Stream.Duplex.from({
|
|
54
|
-
readable: process.stdin,
|
|
55
|
-
writable: process.stdout
|
|
56
|
-
})
|
|
57
|
-
}
|
|
58
|
-
else {
|
|
59
|
-
/* file I/O */
|
|
60
|
-
this.stream = Stream.Duplex.from({
|
|
61
|
-
readable: fs.createReadStream(this.params.path, { encoding }),
|
|
62
|
-
writable: fs.createWriteStream(this.params.path, { encoding })
|
|
63
|
-
})
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
else if (this.params.mode === "r") {
|
|
67
|
-
if (this.params.path === "-") {
|
|
68
|
-
/* standard I/O */
|
|
69
|
-
process.stdin.setEncoding(encoding)
|
|
70
|
-
this.stream = process.stdin
|
|
71
|
-
}
|
|
72
|
-
else {
|
|
73
|
-
/* file I/O */
|
|
74
|
-
this.stream = fs.createReadStream(this.params.path, { encoding })
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
else if (this.params.mode === "w") {
|
|
78
|
-
if (this.params.path === "-") {
|
|
79
|
-
/* standard I/O */
|
|
80
|
-
process.stdout.setEncoding(encoding)
|
|
81
|
-
this.stream = process.stdout
|
|
82
|
-
}
|
|
83
|
-
else {
|
|
84
|
-
/* file I/O */
|
|
85
|
-
this.stream = fs.createWriteStream(this.params.path, { encoding })
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
else
|
|
89
|
-
throw new Error(`invalid file mode "${this.params.mode}"`)
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
/* close node */
|
|
93
|
-
async close () {
|
|
94
|
-
/* shutdown stream */
|
|
95
|
-
if (this.stream !== null) {
|
|
96
|
-
await new Promise<void>((resolve) => {
|
|
97
|
-
if (this.stream instanceof Stream.Writable || this.stream instanceof Stream.Duplex)
|
|
98
|
-
this.stream.end(() => { resolve() })
|
|
99
|
-
else
|
|
100
|
-
resolve()
|
|
101
|
-
})
|
|
102
|
-
if (this.params.path !== "-")
|
|
103
|
-
this.stream.destroy()
|
|
104
|
-
this.stream = null
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
|
|
@@ -1,179 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
** SpeechFlow - Speech Processing Flow Graph
|
|
3
|
-
** Copyright (c) 2024-2025 Dr. Ralf S. Engelschall <rse@engelschall.com>
|
|
4
|
-
** Licensed under GPL 3.0 <https://spdx.org/licenses/GPL-3.0-only>
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
/* standard dependencies */
|
|
8
|
-
import Stream from "node:stream"
|
|
9
|
-
|
|
10
|
-
/* external dependencies */
|
|
11
|
-
import ws from "ws"
|
|
12
|
-
import ReconnWebsocket, { ErrorEvent } from "@opensumi/reconnecting-websocket"
|
|
13
|
-
|
|
14
|
-
/* internal dependencies */
|
|
15
|
-
import SpeechFlowNode from "./speechflow-node"
|
|
16
|
-
|
|
17
|
-
/* SpeechFlow node for Websocket networking */
|
|
18
|
-
export default class SpeechFlowNodeWebsocket extends SpeechFlowNode {
|
|
19
|
-
/* declare official node name */
|
|
20
|
-
public static name = "websocket"
|
|
21
|
-
|
|
22
|
-
/* internal state */
|
|
23
|
-
private server: ws.WebSocketServer | null = null
|
|
24
|
-
private client: WebSocket | null = null
|
|
25
|
-
|
|
26
|
-
/* construct node */
|
|
27
|
-
constructor (id: string, opts: { [ id: string ]: any }, args: any[]) {
|
|
28
|
-
super(id, opts, args)
|
|
29
|
-
|
|
30
|
-
/* declare node configuration parameters */
|
|
31
|
-
this.configure({
|
|
32
|
-
listen: { type: "string", val: "", match: /^(?:|ws:\/\/(.+?):(\d+))$/ },
|
|
33
|
-
connect: { type: "string", val: "", match: /^(?:|ws:\/\/(.+?):(\d+)(?:\/.*)?)$/ },
|
|
34
|
-
type: { type: "string", val: "text", match: /^(?:audio|text)$/ }
|
|
35
|
-
})
|
|
36
|
-
|
|
37
|
-
/* sanity check usage */
|
|
38
|
-
if (this.params.listen !== "" && this.params.connect !== "")
|
|
39
|
-
throw new Error("Websocket node cannot listen and connect at the same time")
|
|
40
|
-
else if (this.params.listen === "" && this.params.connect === "")
|
|
41
|
-
throw new Error("Websocket node requires either listen or connect mode")
|
|
42
|
-
|
|
43
|
-
/* declare node input/output format */
|
|
44
|
-
if (this.params.listen !== "") {
|
|
45
|
-
this.input = "none"
|
|
46
|
-
this.output = this.params.type
|
|
47
|
-
}
|
|
48
|
-
else if (this.params.connect !== "") {
|
|
49
|
-
this.input = this.params.type
|
|
50
|
-
this.output = "none"
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
/* open node */
|
|
55
|
-
async open () {
|
|
56
|
-
if (this.params.listen !== "") {
|
|
57
|
-
/* listen locally on a Websocket port */
|
|
58
|
-
const url = new URL(this.params.listen)
|
|
59
|
-
let websocket: ws.WebSocket | null = null
|
|
60
|
-
const server = new ws.WebSocketServer({
|
|
61
|
-
host: url.hostname,
|
|
62
|
-
port: Number.parseInt(url.port),
|
|
63
|
-
path: url.pathname
|
|
64
|
-
})
|
|
65
|
-
server.on("listening", () => {
|
|
66
|
-
this.log("info", `listening on URL ${this.params.listen}`)
|
|
67
|
-
})
|
|
68
|
-
server.on("connection", (ws, request) => {
|
|
69
|
-
this.log("info", `connection opened on URL ${this.params.listen}`)
|
|
70
|
-
websocket = ws
|
|
71
|
-
})
|
|
72
|
-
server.on("close", () => {
|
|
73
|
-
this.log("info", `connection closed on URL ${this.params.listen}`)
|
|
74
|
-
websocket = null
|
|
75
|
-
})
|
|
76
|
-
server.on("error", (error) => {
|
|
77
|
-
this.log("error", `error on URL ${this.params.listen}: ${error.message}`)
|
|
78
|
-
websocket = null
|
|
79
|
-
})
|
|
80
|
-
const textEncoding = this.config.textEncoding
|
|
81
|
-
this.stream = new Stream.Duplex({
|
|
82
|
-
write (chunk: Buffer, encoding, callback) {
|
|
83
|
-
const data = chunk.buffer.slice(chunk.byteOffset, chunk.byteOffset + chunk.byteLength)
|
|
84
|
-
if (websocket !== null) {
|
|
85
|
-
websocket.send(data, (error) => {
|
|
86
|
-
if (error) callback(error)
|
|
87
|
-
else callback()
|
|
88
|
-
})
|
|
89
|
-
}
|
|
90
|
-
else
|
|
91
|
-
callback(new Error("still no Websocket connection available"))
|
|
92
|
-
},
|
|
93
|
-
read (size: number) {
|
|
94
|
-
if (websocket !== null) {
|
|
95
|
-
websocket.once("message", (data, isBinary) => {
|
|
96
|
-
this.push(data, isBinary ? "binary" : textEncoding)
|
|
97
|
-
})
|
|
98
|
-
}
|
|
99
|
-
else
|
|
100
|
-
throw new Error("still no Websocket connection available")
|
|
101
|
-
}
|
|
102
|
-
})
|
|
103
|
-
}
|
|
104
|
-
else if (this.params.connect !== "") {
|
|
105
|
-
/* connect remotely to a Websocket port */
|
|
106
|
-
this.client = new ReconnWebsocket(this.params.connect, [], {
|
|
107
|
-
WebSocket: ws,
|
|
108
|
-
WebSocketOptions: {},
|
|
109
|
-
reconnectionDelayGrowFactor: 1.3,
|
|
110
|
-
maxReconnectionDelay: 4000,
|
|
111
|
-
minReconnectionDelay: 1000,
|
|
112
|
-
connectionTimeout: 4000,
|
|
113
|
-
minUptime: 5000
|
|
114
|
-
})
|
|
115
|
-
this.client.addEventListener("open", (ev: Event) => {
|
|
116
|
-
this.log("info", `connection opened on URL ${this.params.connect}`)
|
|
117
|
-
})
|
|
118
|
-
this.client.addEventListener("close", (ev: Event) => {
|
|
119
|
-
this.log("info", `connection closed on URL ${this.params.connect}`)
|
|
120
|
-
})
|
|
121
|
-
this.client.addEventListener("error", (ev: ErrorEvent) => {
|
|
122
|
-
this.log("error", `error on URL ${this.params.connect}: ${ev.error.message}`)
|
|
123
|
-
})
|
|
124
|
-
const client = this.client
|
|
125
|
-
client.binaryType = "arraybuffer"
|
|
126
|
-
const textEncoding = this.config.textEncoding
|
|
127
|
-
this.stream = new Stream.Duplex({
|
|
128
|
-
write (chunk: Buffer, encoding, callback) {
|
|
129
|
-
const data = chunk.buffer.slice(chunk.byteOffset, chunk.byteOffset + chunk.byteLength)
|
|
130
|
-
if (client.OPEN) {
|
|
131
|
-
client.send(data)
|
|
132
|
-
callback()
|
|
133
|
-
}
|
|
134
|
-
else
|
|
135
|
-
callback(new Error("still no Websocket connection available"))
|
|
136
|
-
},
|
|
137
|
-
read (size: number) {
|
|
138
|
-
if (client.OPEN) {
|
|
139
|
-
client.addEventListener("message", (ev: MessageEvent) => {
|
|
140
|
-
if (ev.data instanceof ArrayBuffer)
|
|
141
|
-
this.push(ev.data, "binary")
|
|
142
|
-
else
|
|
143
|
-
this.push(ev.data, textEncoding)
|
|
144
|
-
}, { once: true })
|
|
145
|
-
}
|
|
146
|
-
else
|
|
147
|
-
throw new Error("still no Websocket connection available")
|
|
148
|
-
}
|
|
149
|
-
})
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
/* close node */
|
|
154
|
-
async close () {
|
|
155
|
-
/* close Websocket server */
|
|
156
|
-
if (this.server !== null) {
|
|
157
|
-
await new Promise<void>((resolve, reject) => {
|
|
158
|
-
this.server!.close((error) => {
|
|
159
|
-
if (error) reject(error)
|
|
160
|
-
else resolve()
|
|
161
|
-
})
|
|
162
|
-
})
|
|
163
|
-
this.server = null
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
/* close Websocket client */
|
|
167
|
-
if (this.client !== null) {
|
|
168
|
-
this.client!.close()
|
|
169
|
-
this.client = null
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
/* close stream */
|
|
173
|
-
if (this.stream !== null) {
|
|
174
|
-
this.stream.destroy()
|
|
175
|
-
this.stream = null
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
|