speechflow 2.0.0 → 2.0.2

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.
Files changed (150) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +4 -4
  3. package/package.json +4 -4
  4. package/speechflow-cli/dst/speechflow-main-api.js.map +1 -1
  5. package/speechflow-cli/dst/speechflow-main-cli.js +1 -0
  6. package/speechflow-cli/dst/speechflow-main-cli.js.map +1 -1
  7. package/speechflow-cli/dst/speechflow-main-graph.js +2 -4
  8. package/speechflow-cli/dst/speechflow-main-graph.js.map +1 -1
  9. package/speechflow-cli/dst/speechflow-main-nodes.js +1 -0
  10. package/speechflow-cli/dst/speechflow-main-nodes.js.map +1 -1
  11. package/speechflow-cli/dst/speechflow-node-a2a-compressor-wt.js +1 -0
  12. package/speechflow-cli/dst/speechflow-node-a2a-compressor-wt.js.map +1 -1
  13. package/speechflow-cli/dst/speechflow-node-a2a-compressor.js +7 -9
  14. package/speechflow-cli/dst/speechflow-node-a2a-compressor.js.map +1 -1
  15. package/speechflow-cli/dst/speechflow-node-a2a-expander-wt.js +1 -0
  16. package/speechflow-cli/dst/speechflow-node-a2a-expander-wt.js.map +1 -1
  17. package/speechflow-cli/dst/speechflow-node-a2a-expander.js +8 -9
  18. package/speechflow-cli/dst/speechflow-node-a2a-expander.js.map +1 -1
  19. package/speechflow-cli/dst/speechflow-node-a2a-filler.js +2 -0
  20. package/speechflow-cli/dst/speechflow-node-a2a-filler.js.map +1 -1
  21. package/speechflow-cli/dst/speechflow-node-a2a-gender.js +1 -1
  22. package/speechflow-cli/dst/speechflow-node-a2a-gender.js.map +1 -1
  23. package/speechflow-cli/dst/speechflow-node-a2a-meter.js +1 -1
  24. package/speechflow-cli/dst/speechflow-node-a2a-pitch.js +11 -9
  25. package/speechflow-cli/dst/speechflow-node-a2a-pitch.js.map +1 -1
  26. package/speechflow-cli/dst/speechflow-node-a2a-rnnoise-wt.js +1 -0
  27. package/speechflow-cli/dst/speechflow-node-a2a-rnnoise-wt.js.map +1 -1
  28. package/speechflow-cli/dst/speechflow-node-a2a-rnnoise.js.map +1 -1
  29. package/speechflow-cli/dst/speechflow-node-a2a-speex.js +4 -2
  30. package/speechflow-cli/dst/speechflow-node-a2a-speex.js.map +1 -1
  31. package/speechflow-cli/dst/speechflow-node-a2a-vad.js +19 -22
  32. package/speechflow-cli/dst/speechflow-node-a2a-vad.js.map +1 -1
  33. package/speechflow-cli/dst/speechflow-node-a2a-wav.js +7 -0
  34. package/speechflow-cli/dst/speechflow-node-a2a-wav.js.map +1 -1
  35. package/speechflow-cli/dst/speechflow-node-a2t-amazon.d.ts +0 -1
  36. package/speechflow-cli/dst/speechflow-node-a2t-amazon.js +2 -11
  37. package/speechflow-cli/dst/speechflow-node-a2t-amazon.js.map +1 -1
  38. package/speechflow-cli/dst/speechflow-node-a2t-google.d.ts +0 -1
  39. package/speechflow-cli/dst/speechflow-node-a2t-google.js +0 -6
  40. package/speechflow-cli/dst/speechflow-node-a2t-google.js.map +1 -1
  41. package/speechflow-cli/dst/speechflow-node-a2t-openai.js +6 -1
  42. package/speechflow-cli/dst/speechflow-node-a2t-openai.js.map +1 -1
  43. package/speechflow-cli/dst/speechflow-node-t2a-amazon.d.ts +1 -1
  44. package/speechflow-cli/dst/speechflow-node-t2a-amazon.js +27 -7
  45. package/speechflow-cli/dst/speechflow-node-t2a-amazon.js.map +1 -1
  46. package/speechflow-cli/dst/speechflow-node-t2a-elevenlabs.d.ts +1 -1
  47. package/speechflow-cli/dst/speechflow-node-t2a-elevenlabs.js +5 -3
  48. package/speechflow-cli/dst/speechflow-node-t2a-elevenlabs.js.map +1 -1
  49. package/speechflow-cli/dst/speechflow-node-t2a-google.js +1 -4
  50. package/speechflow-cli/dst/speechflow-node-t2a-google.js.map +1 -1
  51. package/speechflow-cli/dst/speechflow-node-t2a-kokoro.d.ts +1 -1
  52. package/speechflow-cli/dst/speechflow-node-t2a-kokoro.js +27 -6
  53. package/speechflow-cli/dst/speechflow-node-t2a-kokoro.js.map +1 -1
  54. package/speechflow-cli/dst/speechflow-node-t2a-openai.js +1 -4
  55. package/speechflow-cli/dst/speechflow-node-t2a-openai.js.map +1 -1
  56. package/speechflow-cli/dst/speechflow-node-t2a-supertonic.d.ts +2 -3
  57. package/speechflow-cli/dst/speechflow-node-t2a-supertonic.js +97 -459
  58. package/speechflow-cli/dst/speechflow-node-t2a-supertonic.js.map +1 -1
  59. package/speechflow-cli/dst/speechflow-node-t2t-amazon.js +0 -2
  60. package/speechflow-cli/dst/speechflow-node-t2t-amazon.js.map +1 -1
  61. package/speechflow-cli/dst/speechflow-node-t2t-deepl.js.map +1 -1
  62. package/speechflow-cli/dst/speechflow-node-t2t-google.js.map +1 -1
  63. package/speechflow-cli/dst/speechflow-node-t2t-opus.js +18 -16
  64. package/speechflow-cli/dst/speechflow-node-t2t-opus.js.map +1 -1
  65. package/speechflow-cli/dst/speechflow-node-t2t-punctuation.js +2 -3
  66. package/speechflow-cli/dst/speechflow-node-t2t-punctuation.js.map +1 -1
  67. package/speechflow-cli/dst/speechflow-node-t2t-spellcheck.js +2 -3
  68. package/speechflow-cli/dst/speechflow-node-t2t-spellcheck.js.map +1 -1
  69. package/speechflow-cli/dst/speechflow-node-t2t-subtitle.js +5 -2
  70. package/speechflow-cli/dst/speechflow-node-t2t-subtitle.js.map +1 -1
  71. package/speechflow-cli/dst/speechflow-node-t2t-summary.js +2 -3
  72. package/speechflow-cli/dst/speechflow-node-t2t-summary.js.map +1 -1
  73. package/speechflow-cli/dst/speechflow-node-t2t-translate.js +1 -2
  74. package/speechflow-cli/dst/speechflow-node-t2t-translate.js.map +1 -1
  75. package/speechflow-cli/dst/speechflow-node-x2x-filter.js +2 -0
  76. package/speechflow-cli/dst/speechflow-node-x2x-filter.js.map +1 -1
  77. package/speechflow-cli/dst/speechflow-node-xio-exec.js +1 -0
  78. package/speechflow-cli/dst/speechflow-node-xio-exec.js.map +1 -1
  79. package/speechflow-cli/dst/speechflow-node-xio-file.js +3 -5
  80. package/speechflow-cli/dst/speechflow-node-xio-file.js.map +1 -1
  81. package/speechflow-cli/dst/speechflow-node-xio-mqtt.js.map +1 -1
  82. package/speechflow-cli/dst/speechflow-node-xio-vban.js.map +1 -1
  83. package/speechflow-cli/dst/speechflow-node-xio-webrtc.js +2 -0
  84. package/speechflow-cli/dst/speechflow-node-xio-webrtc.js.map +1 -1
  85. package/speechflow-cli/dst/speechflow-node-xio-websocket.js +9 -9
  86. package/speechflow-cli/dst/speechflow-node-xio-websocket.js.map +1 -1
  87. package/speechflow-cli/dst/speechflow-util-audio.js +4 -0
  88. package/speechflow-cli/dst/speechflow-util-audio.js.map +1 -1
  89. package/speechflow-cli/dst/speechflow-util-llm.d.ts +0 -1
  90. package/speechflow-cli/dst/speechflow-util-llm.js +4 -8
  91. package/speechflow-cli/dst/speechflow-util-llm.js.map +1 -1
  92. package/speechflow-cli/dst/speechflow-util-queue.js +2 -1
  93. package/speechflow-cli/dst/speechflow-util-queue.js.map +1 -1
  94. package/speechflow-cli/dst/speechflow-util.js +1 -0
  95. package/speechflow-cli/dst/speechflow-util.js.map +1 -1
  96. package/speechflow-cli/dst/test.d.ts +1 -0
  97. package/speechflow-cli/dst/test.js +18 -0
  98. package/speechflow-cli/dst/test.js.map +1 -0
  99. package/speechflow-cli/etc/oxlint.jsonc +3 -1
  100. package/speechflow-cli/package.json +16 -16
  101. package/speechflow-cli/src/speechflow-main-api.ts +16 -16
  102. package/speechflow-cli/src/speechflow-main-cli.ts +1 -0
  103. package/speechflow-cli/src/speechflow-main-graph.ts +7 -9
  104. package/speechflow-cli/src/speechflow-main-nodes.ts +1 -0
  105. package/speechflow-cli/src/speechflow-node-a2a-compressor-wt.ts +1 -0
  106. package/speechflow-cli/src/speechflow-node-a2a-compressor.ts +8 -10
  107. package/speechflow-cli/src/speechflow-node-a2a-expander-wt.ts +1 -0
  108. package/speechflow-cli/src/speechflow-node-a2a-expander.ts +9 -10
  109. package/speechflow-cli/src/speechflow-node-a2a-filler.ts +2 -0
  110. package/speechflow-cli/src/speechflow-node-a2a-gender.ts +3 -3
  111. package/speechflow-cli/src/speechflow-node-a2a-meter.ts +2 -2
  112. package/speechflow-cli/src/speechflow-node-a2a-pitch.ts +11 -9
  113. package/speechflow-cli/src/speechflow-node-a2a-rnnoise-wt.ts +1 -0
  114. package/speechflow-cli/src/speechflow-node-a2a-rnnoise.ts +1 -1
  115. package/speechflow-cli/src/speechflow-node-a2a-speex.ts +5 -3
  116. package/speechflow-cli/src/speechflow-node-a2a-vad.ts +20 -23
  117. package/speechflow-cli/src/speechflow-node-a2a-wav.ts +7 -0
  118. package/speechflow-cli/src/speechflow-node-a2t-amazon.ts +6 -18
  119. package/speechflow-cli/src/speechflow-node-a2t-google.ts +4 -11
  120. package/speechflow-cli/src/speechflow-node-a2t-openai.ts +12 -7
  121. package/speechflow-cli/src/speechflow-node-t2a-amazon.ts +32 -10
  122. package/speechflow-cli/src/speechflow-node-t2a-elevenlabs.ts +6 -4
  123. package/speechflow-cli/src/speechflow-node-t2a-google.ts +1 -4
  124. package/speechflow-cli/src/speechflow-node-t2a-kokoro.ts +33 -10
  125. package/speechflow-cli/src/speechflow-node-t2a-openai.ts +1 -4
  126. package/speechflow-cli/src/speechflow-node-t2a-supertonic.ts +106 -571
  127. package/speechflow-cli/src/speechflow-node-t2t-amazon.ts +1 -3
  128. package/speechflow-cli/src/speechflow-node-t2t-deepl.ts +2 -2
  129. package/speechflow-cli/src/speechflow-node-t2t-google.ts +1 -1
  130. package/speechflow-cli/src/speechflow-node-t2t-opus.ts +19 -18
  131. package/speechflow-cli/src/speechflow-node-t2t-punctuation.ts +2 -3
  132. package/speechflow-cli/src/speechflow-node-t2t-spellcheck.ts +2 -3
  133. package/speechflow-cli/src/speechflow-node-t2t-subtitle.ts +5 -2
  134. package/speechflow-cli/src/speechflow-node-t2t-summary.ts +2 -3
  135. package/speechflow-cli/src/speechflow-node-t2t-translate.ts +1 -2
  136. package/speechflow-cli/src/speechflow-node-x2x-filter.ts +2 -0
  137. package/speechflow-cli/src/speechflow-node-xio-exec.ts +1 -0
  138. package/speechflow-cli/src/speechflow-node-xio-file.ts +3 -5
  139. package/speechflow-cli/src/speechflow-node-xio-mqtt.ts +2 -2
  140. package/speechflow-cli/src/speechflow-node-xio-vban.ts +5 -5
  141. package/speechflow-cli/src/speechflow-node-xio-webrtc.ts +2 -0
  142. package/speechflow-cli/src/speechflow-node-xio-websocket.ts +9 -9
  143. package/speechflow-cli/src/speechflow-util-audio.ts +5 -0
  144. package/speechflow-cli/src/speechflow-util-llm.ts +4 -9
  145. package/speechflow-cli/src/speechflow-util-queue.ts +4 -4
  146. package/speechflow-cli/src/speechflow-util.ts +1 -0
  147. package/speechflow-ui-db/dst/index.js +14 -14
  148. package/speechflow-ui-db/package.json +6 -6
  149. package/speechflow-ui-st/dst/index.js +32 -32
  150. package/speechflow-ui-st/package.json +6 -6
@@ -5,7 +5,7 @@
5
5
  */
6
6
 
7
7
  /* standard dependencies */
8
- import Stream from "node:stream"
8
+ import Stream from "node:stream"
9
9
 
10
10
  /* external dependencies */
11
11
  import { TranslateClient, TranslateTextCommand } from "@aws-sdk/client-translate"
@@ -65,8 +65,6 @@ export default class SpeechFlowNodeT2TAmazon extends SpeechFlowNode {
65
65
  secretAccessKey: this.params.secKey
66
66
  }
67
67
  })
68
- if (this.client === null)
69
- throw new Error("failed to establish Amazon Translate client")
70
68
 
71
69
  /* provide text-to-text translation */
72
70
  const maxRetries = 10
@@ -5,10 +5,10 @@
5
5
  */
6
6
 
7
7
  /* standard dependencies */
8
- import Stream from "node:stream"
8
+ import Stream from "node:stream"
9
9
 
10
10
  /* external dependencies */
11
- import * as DeepL from "deepl-node"
11
+ import * as DeepL from "deepl-node"
12
12
 
13
13
  /* internal dependencies */
14
14
  import SpeechFlowNode, { SpeechFlowChunk } from "./speechflow-node"
@@ -5,7 +5,7 @@
5
5
  */
6
6
 
7
7
  /* standard dependencies */
8
- import Stream from "node:stream"
8
+ import Stream from "node:stream"
9
9
 
10
10
  /* external dependencies */
11
11
  import { TranslationServiceClient } from "@google-cloud/translate"
@@ -68,18 +68,19 @@ export default class SpeechFlowNodeT2TOPUS extends SpeechFlowNode {
68
68
  }, 1000)
69
69
 
70
70
  /* instantiate Transformers engine and model */
71
- const pipeline = Transformers.pipeline("translation", model, {
72
- cache_dir: path.join(this.config.cacheDir, "transformers"),
73
- dtype: "q4",
74
- device: "auto",
75
- progress_callback: progressCallback
76
- })
77
- this.translator = await pipeline
78
- if (this.translator === null)
79
- throw new Error("failed to instantiate translator pipeline")
80
-
81
- /* clear progress interval again */
82
- clearInterval(interval)
71
+ try {
72
+ const pipeline = Transformers.pipeline("translation", model, {
73
+ cache_dir: path.join(this.config.cacheDir, "transformers"),
74
+ dtype: "q4",
75
+ device: "auto",
76
+ progress_callback: progressCallback
77
+ })
78
+ this.translator = await pipeline
79
+ }
80
+ finally {
81
+ /* clear progress interval again */
82
+ clearInterval(interval)
83
+ }
83
84
 
84
85
  /* provide text-to-text translation */
85
86
  const translate = async (text: string) => {
@@ -120,17 +121,17 @@ export default class SpeechFlowNodeT2TOPUS extends SpeechFlowNode {
120
121
 
121
122
  /* close node */
122
123
  async close () {
123
- /* shutdown stream */
124
- if (this.stream !== null) {
125
- await util.destroyStream(this.stream)
126
- this.stream = null
127
- }
128
-
129
124
  /* shutdown Transformers */
130
125
  if (this.translator !== null) {
131
126
  this.translator.dispose()
132
127
  this.translator = null
133
128
  }
129
+
130
+ /* shutdown stream */
131
+ if (this.stream !== null) {
132
+ await util.destroyStream(this.stream)
133
+ this.stream = null
134
+ }
134
135
  }
135
136
  }
136
137
 
@@ -74,7 +74,7 @@ export default class SpeechFlowNodeT2TPunctuation extends SpeechFlowNode {
74
74
  "Gib KEINE Erklärungen.\n" +
75
75
  "Gib KEINE Einleitung.\n" +
76
76
  "Gib KEINE Kommentare.\n" +
77
- "Gib KEINE Preamble.\n" +
77
+ "Gib KEINE Präambel.\n" +
78
78
  "Gib KEINEN Prolog.\n" +
79
79
  "Gib KEINEN Epilog.\n" +
80
80
  "Ändere NICHT die Wörter.\n" +
@@ -133,8 +133,7 @@ export default class SpeechFlowNodeT2TPunctuation extends SpeechFlowNode {
133
133
  api: this.params.api,
134
134
  model: this.params.model,
135
135
  key: this.params.key,
136
- temperature: 0.7,
137
- topP: 0.5
136
+ temperature: 0.7
138
137
  })
139
138
  this.llm.on("log", (level: string, message: string) => {
140
139
  this.log(level as "info" | "warning" | "error", message)
@@ -66,7 +66,7 @@ export default class SpeechFlowNodeT2TSpellcheck extends SpeechFlowNode {
66
66
  "Gib KEINE Erklärungen.\n" +
67
67
  "Gib KEINE Einleitung.\n" +
68
68
  "Gib KEINE Kommentare.\n" +
69
- "Gib KEINE Preamble.\n" +
69
+ "Gib KEINE Präambel.\n" +
70
70
  "Gib KEINEN Prolog.\n" +
71
71
  "Gib KEINEN Epilog.\n" +
72
72
  "Ändere NICHT die Grammatik.\n" +
@@ -120,8 +120,7 @@ export default class SpeechFlowNodeT2TSpellcheck extends SpeechFlowNode {
120
120
  api: this.params.api,
121
121
  model: this.params.model,
122
122
  key: this.params.key,
123
- temperature: 0.7,
124
- topP: 0.5
123
+ temperature: 0.7
125
124
  })
126
125
  this.llm.on("log", (level: string, message: string) => {
127
126
  this.log(level as "info" | "warning" | "error", message)
@@ -191,7 +191,7 @@ export default class SpeechFlowNodeT2TSubtitle extends SpeechFlowNode {
191
191
  for (const block of blocks) {
192
192
  const lines = block.trim().split(/\r?\n/)
193
193
  if (lines.length < 2) {
194
- this.log("warning", "SRT block contains less than 2 lines")
194
+ this.log("warning", "SRT block contains fewer than 2 lines")
195
195
  continue
196
196
  }
197
197
 
@@ -231,7 +231,7 @@ export default class SpeechFlowNodeT2TSubtitle extends SpeechFlowNode {
231
231
  for (const block of blocks) {
232
232
  const lines = block.trim().split(/\r?\n/)
233
233
  if (lines.length < 1) {
234
- this.log("warning", "VTT block contains less than 1 line")
234
+ this.log("warning", "VTT block contains fewer than 1 line")
235
235
  continue
236
236
  }
237
237
 
@@ -394,15 +394,18 @@ export default class SpeechFlowNodeT2TSubtitle extends SpeechFlowNode {
394
394
  h.response({}).code(204)
395
395
  })
396
396
 
397
+ /* start HAPI server */
397
398
  await this.hapi.start()
398
399
  this.log("info", `HAPI: started REST/WebSocket network service: http://${this.params.addr}:${this.params.port}`)
399
400
 
401
+ /* helper to emit chunks to WebSocket peers */
400
402
  const emit = (chunk: SpeechFlowChunk) => {
401
403
  const data = JSON.stringify(chunk)
402
404
  for (const info of wsPeers.values())
403
405
  info.ws.send(data)
404
406
  }
405
407
 
408
+ /* establish writable stream */
406
409
  this.stream = new Stream.Writable({
407
410
  objectMode: true,
408
411
  decodeStrings: false,
@@ -60,7 +60,7 @@ export default class SpeechFlowNodeT2TSummary extends SpeechFlowNode {
60
60
  "Gib KEINE Erklärungen.\n" +
61
61
  "Gib KEINE Einleitung.\n" +
62
62
  "Gib KEINE Kommentare.\n" +
63
- "Gib KEINE Prämbel.\n" +
63
+ "Gib KEINE Präambel.\n" +
64
64
  "Gib KEINEN Prolog.\n" +
65
65
  "Gib KEINEN Epilog.\n" +
66
66
  "Komme auf den Punkt.\n" +
@@ -119,8 +119,7 @@ export default class SpeechFlowNodeT2TSummary extends SpeechFlowNode {
119
119
  api: this.params.api,
120
120
  model: this.params.model,
121
121
  key: this.params.key,
122
- temperature: 0.7,
123
- topP: 0.5
122
+ temperature: 0.7
124
123
  })
125
124
  this.llm.on("log", (level: string, message: string) => {
126
125
  this.log(level as "info" | "warning" | "error", message)
@@ -112,8 +112,7 @@ export default class SpeechFlowNodeT2TTranslate extends SpeechFlowNode {
112
112
  api: this.params.api,
113
113
  model: this.params.model,
114
114
  key: this.params.key,
115
- temperature: 0.7,
116
- topP: 0.5
115
+ temperature: 0.7
117
116
  })
118
117
  this.llm.on("log", (level: string, message: string) => {
119
118
  this.log(level as "info" | "warning" | "error", message)
@@ -120,6 +120,8 @@ export default class SpeechFlowNodeX2XFilter extends SpeechFlowNode {
120
120
  val1 = chunk.timestampStart.toMillis()
121
121
  else if (self.params.var === "time:end")
122
122
  val1 = chunk.timestampEnd.toMillis()
123
+ else
124
+ val1 = undefined
123
125
  if (comparison(val1, self.params.op, val2)) {
124
126
  self.log("info", `[${self.params.name}]: passing through ${chunk.type} chunk`)
125
127
  this.push(chunk)
@@ -198,6 +198,7 @@ export default class SpeechFlowNodeXIOExec extends SpeechFlowNode {
198
198
  this.subprocess.removeAllListeners("error")
199
199
  this.subprocess.removeAllListeners("exit")
200
200
 
201
+ /* clear subprocess reference */
201
202
  this.subprocess = null
202
203
  }
203
204
 
@@ -54,7 +54,7 @@ export default class SpeechFlowNodeXIOFile extends SpeechFlowNode {
54
54
  /* open node */
55
55
  async open () {
56
56
  /* determine how many bytes we need per chunk when
57
- the chunk should be of the required duration/size */
57
+ the chunk should be of the required duration/size */
58
58
  const highWaterMarkAudio = (
59
59
  this.config.audioSampleRate *
60
60
  (this.config.audioBitDepth / 8)
@@ -139,11 +139,10 @@ export default class SpeechFlowNodeXIOFile extends SpeechFlowNode {
139
139
  const payload = Buffer.isBuffer(chunk.payload) ?
140
140
  chunk.payload : Buffer.from(chunk.payload)
141
141
  const seekPosition = chunk.meta.get("chunk:seek") as number | undefined
142
- if (seekPosition !== undefined) {
142
+ if (seekPosition !== undefined)
143
143
  /* seek to specified position and write (overload) */
144
144
  fs.write(self.fd!, payload, 0, payload.byteLength, seekPosition, callback)
145
- }
146
- else {
145
+ else
147
146
  /* append at current position */
148
147
  fs.write(self.fd!, payload, 0, payload.byteLength, writePosition, (err) => {
149
148
  if (err)
@@ -153,7 +152,6 @@ export default class SpeechFlowNodeXIOFile extends SpeechFlowNode {
153
152
  callback()
154
153
  }
155
154
  })
156
- }
157
155
  },
158
156
  final (callback) {
159
157
  callback()
@@ -21,8 +21,8 @@ export default class SpeechFlowNodeXIOMQTT extends SpeechFlowNode {
21
21
  public static name = "xio-mqtt"
22
22
 
23
23
  /* internal state */
24
- private broker: MQTT.MqttClient | null = null
25
- private clientId: string = (new UUID(1)).format()
24
+ private broker: MQTT.MqttClient | null = null
25
+ private clientId: string = (new UUID(1)).format()
26
26
  private chunkQueue: util.SingleQueue<SpeechFlowChunk> | null = null
27
27
 
28
28
  /* construct node */
@@ -29,11 +29,11 @@ export default class SpeechFlowNodeXIOVBAN extends SpeechFlowNode {
29
29
  public static name = "xio-vban"
30
30
 
31
31
  /* internal state */
32
- private server: VBANServer | null = null
33
- private chunkQueue: util.SingleQueue<SpeechFlowChunk> | null = null
34
- private frameCounter = 0
35
- private targetAddress = ""
36
- private targetPort = 0
32
+ private server: VBANServer | null = null
33
+ private chunkQueue: util.SingleQueue<SpeechFlowChunk> | null = null
34
+ private frameCounter = 0
35
+ private targetAddress = ""
36
+ private targetPort = 0
37
37
 
38
38
  /* construct node */
39
39
  constructor (id: string, cfg: { [ id: string ]: any }, opts: { [ id: string ]: any }, args: any[]) {
@@ -154,6 +154,7 @@ export default class SpeechFlowNodeXIOWebRTC extends SpeechFlowNode {
154
154
  this.pcmBuffer = this.pcmBuffer.subarray(this.pcmBuffer.length - maxBufferSize)
155
155
  }
156
156
 
157
+ /* process full Opus frames from buffer */
157
158
  while (this.pcmBuffer.length >= this.OPUS_FRAME_BYTES) {
158
159
  const frame = this.pcmBuffer.subarray(0, this.OPUS_FRAME_BYTES)
159
160
  this.pcmBuffer = this.pcmBuffer.subarray(this.OPUS_FRAME_BYTES)
@@ -418,6 +419,7 @@ export default class SpeechFlowNodeXIOWebRTC extends SpeechFlowNode {
418
419
  const isPublisher = hasSendonly || hasSendrecv
419
420
  const isViewer = hasRecvonly
420
421
 
422
+ /* handle protocol based on mode */
421
423
  if (self.params.mode === "r" && isPublisher)
422
424
  /* in read mode, accept WHIP publishers */
423
425
  await self.handleWHIP(res, body)
@@ -15,7 +15,7 @@ import ReconnWebSocket, { ErrorEvent } from "@opensumi/reconnecting-websocket"
15
15
  import SpeechFlowNode, { SpeechFlowChunk } from "./speechflow-node"
16
16
  import * as util from "./speechflow-util"
17
17
 
18
- /* SpeechFlow node for Websocket networking */
18
+ /* SpeechFlow node for WebSocket networking */
19
19
  export default class SpeechFlowNodeXIOWebSocket extends SpeechFlowNode {
20
20
  /* declare official node name */
21
21
  public static name = "xio-websocket"
@@ -38,9 +38,9 @@ export default class SpeechFlowNodeXIOWebSocket extends SpeechFlowNode {
38
38
 
39
39
  /* sanity check parameters */
40
40
  if (this.params.listen !== "" && this.params.connect !== "")
41
- throw new Error("Websocket node cannot listen and connect at the same time")
41
+ throw new Error("WebSocket node cannot listen and connect at the same time")
42
42
  else if (this.params.listen === "" && this.params.connect === "")
43
- throw new Error("Websocket node requires either listen or connect mode")
43
+ throw new Error("WebSocket node requires either listen or connect mode")
44
44
 
45
45
  /* declare node input/output format */
46
46
  if (this.params.mode === "rw") {
@@ -121,7 +121,7 @@ export default class SpeechFlowNodeXIOWebSocket extends SpeechFlowNode {
121
121
  else if (chunk.type !== self.params.type)
122
122
  callback(new Error(`written chunk is not of ${self.params.type} type`))
123
123
  else if (websockets.size === 0)
124
- callback(new Error("still no Websocket connections available"))
124
+ callback(new Error("still no WebSocket connections available"))
125
125
  else {
126
126
  const data = util.streamChunkEncode(chunk)
127
127
  const results: Promise<void>[] = []
@@ -168,10 +168,10 @@ export default class SpeechFlowNodeXIOWebSocket extends SpeechFlowNode {
168
168
  connectionTimeout: 4000,
169
169
  minUptime: 5000
170
170
  })
171
- this.client.addEventListener("open", (ev) => {
171
+ this.client.addEventListener("open", (_ev) => {
172
172
  this.log("info", `connection opened to URL ${this.params.connect}`)
173
173
  })
174
- this.client.addEventListener("close", (ev) => {
174
+ this.client.addEventListener("close", (_ev) => {
175
175
  this.log("info", `connection closed to URL ${this.params.connect}`)
176
176
  })
177
177
  this.client.addEventListener("error", (ev: ErrorEvent) => {
@@ -208,7 +208,7 @@ export default class SpeechFlowNodeXIOWebSocket extends SpeechFlowNode {
208
208
  else if (chunk.type !== self.params.type)
209
209
  callback(new Error(`written chunk is not of ${self.params.type} type`))
210
210
  else if (!self.client!.OPEN)
211
- callback(new Error("still no Websocket connection available"))
211
+ callback(new Error("still no WebSocket connection available"))
212
212
  else {
213
213
  const data = util.streamChunkEncode(chunk)
214
214
  self.client!.send(data)
@@ -234,7 +234,7 @@ export default class SpeechFlowNodeXIOWebSocket extends SpeechFlowNode {
234
234
 
235
235
  /* close node */
236
236
  async close () {
237
- /* close Websocket server */
237
+ /* close WebSocket server */
238
238
  if (this.server !== null) {
239
239
  await new Promise<void>((resolve, reject) => {
240
240
  this.server!.close((error) => {
@@ -245,7 +245,7 @@ export default class SpeechFlowNodeXIOWebSocket extends SpeechFlowNode {
245
245
  this.server = null
246
246
  }
247
247
 
248
- /* close Websocket client */
248
+ /* close WebSocket client */
249
249
  if (this.client !== null) {
250
250
  this.client.close()
251
251
  this.client = null
@@ -162,6 +162,9 @@ export function updateEnvelopeForChannel (
162
162
  else
163
163
  currentEnv = alphaR * currentEnv + (1 - alphaR) * det
164
164
  }
165
+
166
+ /* store updated envelope value back */
167
+ env[chan] = currentEnv
165
168
  return Math.sqrt(Math.max(currentEnv, 1e-12))
166
169
  }
167
170
 
@@ -173,6 +176,7 @@ export function dB2lin (db: number): number {
173
176
  return Math.pow(10, db / 20)
174
177
  }
175
178
 
179
+ /* Web Audio API wrapper class */
176
180
  export class WebAudio {
177
181
  /* internal state */
178
182
  public audioContext: AudioContext
@@ -281,6 +285,7 @@ export class WebAudio {
281
285
  })
282
286
  }
283
287
 
288
+ /* destroy object */
284
289
  public async destroy (): Promise<void> {
285
290
  /* reject all pending promises */
286
291
  shield(() => {
@@ -27,7 +27,6 @@ export type LLMConfig = {
27
27
  timeout?: number
28
28
  temperature?: number
29
29
  maxTokens?: number
30
- topP?: number
31
30
  cacheDir?: string
32
31
  }
33
32
  export type LLMCompleteOptions = {
@@ -61,7 +60,6 @@ export class LLM extends EventEmitter {
61
60
  timeout: 30 * 1000,
62
61
  temperature: 0.7,
63
62
  maxTokens: 1024,
64
- topP: 0.5,
65
63
  cacheDir: "",
66
64
  ...config
67
65
  } as Required<LLMConfig>
@@ -102,7 +100,9 @@ export class LLM extends EventEmitter {
102
100
  /* instantiate Anthropic API */
103
101
  this.anthropic = new Anthropic({
104
102
  ...(this.config.api !== "" ? { baseURL: this.config.api } : {}),
105
- apiKey: this.config.key,
103
+ ...(this.config.key.match(/^sk-ant-oat/) ?
104
+ { authToken: this.config.key } :
105
+ { apiKey: this.config.key } ),
106
106
  timeout: this.config.timeout
107
107
  })
108
108
  }
@@ -229,7 +229,6 @@ export class LLM extends EventEmitter {
229
229
  model: this.config.model,
230
230
  max_tokens: this.config.maxTokens,
231
231
  temperature: this.config.temperature,
232
- top_p: this.config.topP,
233
232
  messages: messages as OpenAI.ChatCompletionMessageParam[]
234
233
  }).catch((err) => {
235
234
  throw new Error(`failed to perform OpenAI chat completion: ${err}`, { cause: err })
@@ -252,7 +251,6 @@ export class LLM extends EventEmitter {
252
251
  model: this.config.model,
253
252
  max_tokens: this.config.maxTokens,
254
253
  temperature: this.config.temperature,
255
- top_p: this.config.topP,
256
254
  system: systemMessage?.content,
257
255
  messages: chatMessages as Anthropic.MessageParam[]
258
256
  }).catch((err) => {
@@ -283,7 +281,6 @@ export class LLM extends EventEmitter {
283
281
  config: {
284
282
  maxOutputTokens: this.config.maxTokens,
285
283
  temperature: this.config.temperature,
286
- topP: this.config.topP,
287
284
  ...(systemInstruction ? { systemInstruction } : {})
288
285
  }
289
286
  }).catch((err) => {
@@ -305,8 +302,7 @@ export class LLM extends EventEmitter {
305
302
  keep_alive: "10m",
306
303
  options: {
307
304
  num_predict: this.config.maxTokens,
308
- temperature: this.config.temperature,
309
- top_p: this.config.topP
305
+ temperature: this.config.temperature
310
306
  }
311
307
  }).catch((err) => {
312
308
  throw new Error(`failed to perform Ollama chat completion: ${err}`, { cause: err })
@@ -324,7 +320,6 @@ export class LLM extends EventEmitter {
324
320
  const result = await this.transformer(messages, {
325
321
  max_new_tokens: this.config.maxTokens,
326
322
  temperature: this.config.temperature,
327
- top_p: this.config.topP,
328
323
  do_sample: true
329
324
  }).catch((err) => {
330
325
  throw new Error(`failed to perform HuggingFace Transformers text generation: ${err}`, { cause: err })
@@ -6,17 +6,17 @@
6
6
 
7
7
  /* standard dependencies */
8
8
  import { EventEmitter } from "node:events"
9
- import { type, type Type } from "arktype"
10
9
 
11
10
  /* external dependencies */
12
- import { Duration } from "luxon"
11
+ import { type, type Type } from "arktype"
12
+ import { Duration } from "luxon"
13
13
  import * as IntervalTree from "node-interval-tree"
14
14
 
15
15
  /* internal dependencies */
16
16
  import * as util from "./speechflow-util"
17
17
 
18
18
  /* import an object with parsing and strict error handling */
19
- export function importObject<T>(name: string, arg: object | string, validator: Type<T, {}>): T {
19
+ export function importObject<T> (name: string, arg: object | string, validator: Type<T, {}>): T {
20
20
  const obj: object = typeof arg === "string" ?
21
21
  util.run(`${name}: parsing JSON`, () => JSON.parse(arg)) :
22
22
  arg
@@ -289,7 +289,7 @@ export class AsyncQueue<T> {
289
289
  if (this.queue.length > 0)
290
290
  return this.queue.shift()!
291
291
  else
292
- return new Promise<T>((resolve, reject) => this.resolvers.push({ resolve, reject }))
292
+ return new Promise<T>((resolve, reject) => { this.resolvers.push({ resolve, reject }) })
293
293
  }
294
294
  empty () {
295
295
  return this.queue.length === 0
@@ -4,6 +4,7 @@
4
4
  ** Licensed under GPL 3.0 <https://spdx.org/licenses/GPL-3.0-only>
5
5
  */
6
6
 
7
+ /* re-export utility modules */
7
8
  export * from "./speechflow-util-audio"
8
9
  export * from "./speechflow-util-error"
9
10
  export * from "./speechflow-util-stream"