speechflow 1.7.1 → 2.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.
Files changed (99) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/README.md +387 -119
  3. package/etc/claude.md +5 -5
  4. package/etc/speechflow.yaml +2 -2
  5. package/package.json +3 -3
  6. package/speechflow-cli/dst/speechflow-main-graph.d.ts +1 -0
  7. package/speechflow-cli/dst/speechflow-main-graph.js +28 -5
  8. package/speechflow-cli/dst/speechflow-main-graph.js.map +1 -1
  9. package/speechflow-cli/dst/speechflow-node-a2a-wav.js +24 -4
  10. package/speechflow-cli/dst/speechflow-node-a2a-wav.js.map +1 -1
  11. package/speechflow-cli/dst/speechflow-node-a2t-google.d.ts +17 -0
  12. package/speechflow-cli/dst/speechflow-node-a2t-google.js +320 -0
  13. package/speechflow-cli/dst/speechflow-node-a2t-google.js.map +1 -0
  14. package/speechflow-cli/dst/speechflow-node-t2a-google.d.ts +15 -0
  15. package/speechflow-cli/dst/speechflow-node-t2a-google.js +218 -0
  16. package/speechflow-cli/dst/speechflow-node-t2a-google.js.map +1 -0
  17. package/speechflow-cli/dst/speechflow-node-t2a-openai.d.ts +15 -0
  18. package/speechflow-cli/dst/speechflow-node-t2a-openai.js +195 -0
  19. package/speechflow-cli/dst/speechflow-node-t2a-openai.js.map +1 -0
  20. package/speechflow-cli/dst/speechflow-node-t2a-supertonic.d.ts +17 -0
  21. package/speechflow-cli/dst/speechflow-node-t2a-supertonic.js +608 -0
  22. package/speechflow-cli/dst/speechflow-node-t2a-supertonic.js.map +1 -0
  23. package/speechflow-cli/dst/speechflow-node-t2t-amazon.js.map +1 -1
  24. package/speechflow-cli/dst/{speechflow-node-t2t-transformers.d.ts → speechflow-node-t2t-opus.d.ts} +1 -3
  25. package/speechflow-cli/dst/speechflow-node-t2t-opus.js +159 -0
  26. package/speechflow-cli/dst/speechflow-node-t2t-opus.js.map +1 -0
  27. package/speechflow-cli/dst/speechflow-node-t2t-profanity.d.ts +11 -0
  28. package/speechflow-cli/dst/speechflow-node-t2t-profanity.js +118 -0
  29. package/speechflow-cli/dst/speechflow-node-t2t-profanity.js.map +1 -0
  30. package/speechflow-cli/dst/speechflow-node-t2t-punctuation.d.ts +13 -0
  31. package/speechflow-cli/dst/speechflow-node-t2t-punctuation.js +220 -0
  32. package/speechflow-cli/dst/speechflow-node-t2t-punctuation.js.map +1 -0
  33. package/speechflow-cli/dst/{speechflow-node-t2t-openai.d.ts → speechflow-node-t2t-spellcheck.d.ts} +2 -2
  34. package/speechflow-cli/dst/{speechflow-node-t2t-openai.js → speechflow-node-t2t-spellcheck.js} +47 -99
  35. package/speechflow-cli/dst/speechflow-node-t2t-spellcheck.js.map +1 -0
  36. package/speechflow-cli/dst/speechflow-node-t2t-subtitle.js +3 -6
  37. package/speechflow-cli/dst/speechflow-node-t2t-subtitle.js.map +1 -1
  38. package/speechflow-cli/dst/speechflow-node-t2t-summary.d.ts +16 -0
  39. package/speechflow-cli/dst/speechflow-node-t2t-summary.js +241 -0
  40. package/speechflow-cli/dst/speechflow-node-t2t-summary.js.map +1 -0
  41. package/speechflow-cli/dst/{speechflow-node-t2t-ollama.d.ts → speechflow-node-t2t-translate.d.ts} +2 -2
  42. package/speechflow-cli/dst/{speechflow-node-t2t-transformers.js → speechflow-node-t2t-translate.js} +53 -115
  43. package/speechflow-cli/dst/speechflow-node-t2t-translate.js.map +1 -0
  44. package/speechflow-cli/dst/speechflow-node-xio-exec.d.ts +12 -0
  45. package/speechflow-cli/dst/speechflow-node-xio-exec.js +223 -0
  46. package/speechflow-cli/dst/speechflow-node-xio-exec.js.map +1 -0
  47. package/speechflow-cli/dst/speechflow-node-xio-file.d.ts +1 -0
  48. package/speechflow-cli/dst/speechflow-node-xio-file.js +79 -66
  49. package/speechflow-cli/dst/speechflow-node-xio-file.js.map +1 -1
  50. package/speechflow-cli/dst/speechflow-node-xio-vban.d.ts +17 -0
  51. package/speechflow-cli/dst/speechflow-node-xio-vban.js +330 -0
  52. package/speechflow-cli/dst/speechflow-node-xio-vban.js.map +1 -0
  53. package/speechflow-cli/dst/speechflow-node-xio-webrtc.d.ts +39 -0
  54. package/speechflow-cli/dst/speechflow-node-xio-webrtc.js +500 -0
  55. package/speechflow-cli/dst/speechflow-node-xio-webrtc.js.map +1 -0
  56. package/speechflow-cli/dst/speechflow-util-audio.js +4 -5
  57. package/speechflow-cli/dst/speechflow-util-audio.js.map +1 -1
  58. package/speechflow-cli/dst/speechflow-util-error.d.ts +1 -0
  59. package/speechflow-cli/dst/speechflow-util-error.js +5 -0
  60. package/speechflow-cli/dst/speechflow-util-error.js.map +1 -1
  61. package/speechflow-cli/dst/speechflow-util-llm.d.ts +35 -0
  62. package/speechflow-cli/dst/speechflow-util-llm.js +363 -0
  63. package/speechflow-cli/dst/speechflow-util-llm.js.map +1 -0
  64. package/speechflow-cli/dst/speechflow-util.d.ts +1 -0
  65. package/speechflow-cli/dst/speechflow-util.js +1 -0
  66. package/speechflow-cli/dst/speechflow-util.js.map +1 -1
  67. package/speechflow-cli/etc/oxlint.jsonc +2 -1
  68. package/speechflow-cli/package.json +34 -17
  69. package/speechflow-cli/src/lib.d.ts +5 -0
  70. package/speechflow-cli/src/speechflow-main-graph.ts +31 -5
  71. package/speechflow-cli/src/speechflow-node-a2a-wav.ts +24 -4
  72. package/speechflow-cli/src/speechflow-node-a2t-google.ts +322 -0
  73. package/speechflow-cli/src/speechflow-node-t2a-google.ts +206 -0
  74. package/speechflow-cli/src/speechflow-node-t2a-openai.ts +179 -0
  75. package/speechflow-cli/src/speechflow-node-t2a-supertonic.ts +701 -0
  76. package/speechflow-cli/src/speechflow-node-t2t-amazon.ts +2 -1
  77. package/speechflow-cli/src/speechflow-node-t2t-opus.ts +136 -0
  78. package/speechflow-cli/src/speechflow-node-t2t-profanity.ts +93 -0
  79. package/speechflow-cli/src/speechflow-node-t2t-punctuation.ts +201 -0
  80. package/speechflow-cli/src/{speechflow-node-t2t-openai.ts → speechflow-node-t2t-spellcheck.ts} +48 -107
  81. package/speechflow-cli/src/speechflow-node-t2t-subtitle.ts +3 -6
  82. package/speechflow-cli/src/speechflow-node-t2t-summary.ts +229 -0
  83. package/speechflow-cli/src/speechflow-node-t2t-translate.ts +181 -0
  84. package/speechflow-cli/src/speechflow-node-xio-exec.ts +210 -0
  85. package/speechflow-cli/src/speechflow-node-xio-file.ts +92 -79
  86. package/speechflow-cli/src/speechflow-node-xio-vban.ts +325 -0
  87. package/speechflow-cli/src/speechflow-node-xio-webrtc.ts +533 -0
  88. package/speechflow-cli/src/speechflow-util-audio.ts +5 -5
  89. package/speechflow-cli/src/speechflow-util-error.ts +9 -0
  90. package/speechflow-cli/src/speechflow-util-llm.ts +367 -0
  91. package/speechflow-cli/src/speechflow-util.ts +1 -0
  92. package/speechflow-ui-db/package.json +9 -9
  93. package/speechflow-ui-st/package.json +9 -9
  94. package/speechflow-cli/dst/speechflow-node-t2t-ollama.js +0 -293
  95. package/speechflow-cli/dst/speechflow-node-t2t-ollama.js.map +0 -1
  96. package/speechflow-cli/dst/speechflow-node-t2t-openai.js.map +0 -1
  97. package/speechflow-cli/dst/speechflow-node-t2t-transformers.js.map +0 -1
  98. package/speechflow-cli/src/speechflow-node-t2t-ollama.ts +0 -281
  99. package/speechflow-cli/src/speechflow-node-t2t-transformers.ts +0 -247
@@ -42,26 +42,22 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
42
42
  };
43
43
  Object.defineProperty(exports, "__esModule", { value: true });
44
44
  /* standard dependencies */
45
- const node_path_1 = __importDefault(require("node:path"));
46
45
  const node_stream_1 = __importDefault(require("node:stream"));
47
- /* external dependencies */
48
- const Transformers = __importStar(require("@huggingface/transformers"));
49
46
  /* internal dependencies */
50
47
  const speechflow_node_1 = __importDefault(require("./speechflow-node"));
51
48
  const util = __importStar(require("./speechflow-util"));
52
- /* SpeechFlow node for Transformers text-to-text translation */
53
- class SpeechFlowNodeT2TTransformers extends speechflow_node_1.default {
49
+ const speechflow_util_llm_1 = require("./speechflow-util-llm");
50
+ /* SpeechFlow node for LLM-based text-to-text translation */
51
+ class SpeechFlowNodeT2TTranslate extends speechflow_node_1.default {
54
52
  /* declare official node name */
55
- static name = "t2t-transformers";
53
+ static name = "t2t-translate";
56
54
  /* internal state */
57
- translator = null;
58
- generator = null;
55
+ llm = null;
59
56
  /* internal LLM setup */
60
57
  setup = {
61
- /* SmolLM3: English (EN) to German (DE) translation */
62
- "SmolLM3:en-de": {
63
- systemPrompt: "/no_think\n" +
64
- "You are a translator.\n" +
58
+ /* English (EN) to German (DE) translation */
59
+ "en-de": {
60
+ systemPrompt: "You are a translator.\n" +
65
61
  "Output only the requested text.\n" +
66
62
  "Do not use markdown.\n" +
67
63
  "Do not chat.\n" +
@@ -82,10 +78,9 @@ class SpeechFlowNodeT2TTransformers extends speechflow_node_1.default {
82
78
  { role: "assistant", content: "Das Leben ist einfach großartig." }
83
79
  ]
84
80
  },
85
- /* SmolLM3: German (DE) to English (EN) translation */
86
- "SmolLM3:de-en": {
87
- systemPrompt: "/no_think\n" +
88
- "You are a translator.\n" +
81
+ /* German (DE) to English (EN) translation */
82
+ "de-en": {
83
+ systemPrompt: "You are a translator.\n" +
89
84
  "Output only the requested text.\n" +
90
85
  "Do not use markdown.\n" +
91
86
  "Do not chat.\n" +
@@ -114,102 +109,50 @@ class SpeechFlowNodeT2TTransformers extends speechflow_node_1.default {
114
109
  this.configure({
115
110
  src: { type: "string", pos: 0, val: "de", match: /^(?:de|en)$/ },
116
111
  dst: { type: "string", pos: 1, val: "en", match: /^(?:de|en)$/ },
117
- model: { type: "string", val: "OPUS", match: /^(?:OPUS|SmolLM3)$/ }
112
+ provider: { type: "string", val: "ollama", match: /^(?:openai|anthropic|google|ollama|transformers)$/ },
113
+ api: { type: "string", val: "http://127.0.0.1:11434", match: /^https?:\/\/.+?(:\d+)?$/ },
114
+ model: { type: "string", val: "gemma3:4b-it-q4_K_M", match: /^.+$/ },
115
+ key: { type: "string", val: "", match: /^.*$/ }
118
116
  });
119
- /* sanity check parameters */
117
+ /* validate translation direction */
120
118
  if (this.params.src === this.params.dst)
121
- throw new Error("source and destination languages cannot be the same");
119
+ throw new Error("source and destination language must be different for translation");
120
+ /* tell effective mode */
121
+ this.log("info", `translating from language "${this.params.src}" to language "${this.params.dst}" ` +
122
+ `via ${this.params.provider} LLM (model: ${this.params.model})`);
122
123
  /* declare node input/output format */
123
124
  this.input = "text";
124
125
  this.output = "text";
125
126
  }
126
127
  /* open node */
127
128
  async open() {
128
- let model = "";
129
- /* track download progress when instantiating Transformers engine and model */
130
- const progressState = new Map();
131
- const progressCallback = (progress) => {
132
- let artifact = model;
133
- if (typeof progress.file === "string")
134
- artifact += `:${progress.file}`;
135
- let percent = 0;
136
- if (typeof progress.loaded === "number" && typeof progress.total === "number")
137
- percent = (progress.loaded / progress.total) * 100;
138
- else if (typeof progress.progress === "number")
139
- percent = progress.progress;
140
- if (percent > 0)
141
- progressState.set(artifact, percent);
142
- };
143
- const interval = setInterval(() => {
144
- for (const [artifact, percent] of progressState) {
145
- this.log("info", `downloaded ${percent.toFixed(2)}% of artifact "${artifact}"`);
146
- if (percent >= 100.0)
147
- progressState.delete(artifact);
148
- }
149
- }, 1000);
150
- /* instantiate Transformers engine and model */
151
- if (this.params.model === "OPUS") {
152
- model = `onnx-community/opus-mt-${this.params.src}-${this.params.dst}`;
153
- const pipeline = Transformers.pipeline("translation", model, {
154
- cache_dir: node_path_1.default.join(this.config.cacheDir, "transformers"),
155
- dtype: "q4",
156
- device: "auto",
157
- progress_callback: progressCallback
158
- });
159
- this.translator = await pipeline;
160
- if (this.translator === null)
161
- throw new Error("failed to instantiate translator pipeline");
162
- }
163
- else if (this.params.model === "SmolLM3") {
164
- model = "HuggingFaceTB/SmolLM3-3B-ONNX";
165
- const pipeline = Transformers.pipeline("text-generation", model, {
166
- cache_dir: node_path_1.default.join(this.config.cacheDir, "transformers"),
167
- dtype: "q4",
168
- device: "auto",
169
- progress_callback: progressCallback
170
- });
171
- this.generator = await pipeline;
172
- if (this.generator === null)
173
- throw new Error("failed to instantiate generator pipeline");
174
- }
175
- else
176
- throw new Error("invalid model");
177
- /* clear progress interval again */
178
- clearInterval(interval);
129
+ /* instantiate LLM */
130
+ this.llm = new speechflow_util_llm_1.LLM({
131
+ provider: this.params.provider,
132
+ api: this.params.api,
133
+ model: this.params.model,
134
+ key: this.params.key,
135
+ temperature: 0.7,
136
+ topP: 0.5
137
+ });
138
+ this.llm.on("log", (level, message) => {
139
+ this.log(level, message);
140
+ });
141
+ await this.llm.open();
179
142
  /* provide text-to-text translation */
143
+ const llm = this.llm;
180
144
  const translate = async (text) => {
181
- if (this.params.model === "OPUS") {
182
- const result = await this.translator(text);
183
- const single = Array.isArray(result) ? result[0] : result;
184
- return single.translation_text;
185
- }
186
- else if (this.params.model === "SmolLM3") {
187
- const key = `SmolLM3:${this.params.src}-${this.params.dst}`;
188
- const cfg = this.setup[key];
189
- const messages = [
190
- { role: "system", content: cfg.systemPrompt },
191
- ...cfg.chat,
192
- { role: "user", content: text }
193
- ];
194
- const result = await this.generator(messages, {
195
- max_new_tokens: 100,
196
- temperature: 0.6,
197
- top_p: 0.95,
198
- streamer: new Transformers.TextStreamer(this.generator.tokenizer, {
199
- skip_prompt: true,
200
- skip_special_tokens: true
201
- })
202
- });
203
- const single = Array.isArray(result) ? result[0] : result;
204
- const generatedText = single.generated_text;
205
- return typeof generatedText === "string" ?
206
- generatedText :
207
- generatedText.at(-1).content;
208
- }
209
- else
210
- throw new Error("invalid model");
145
+ const key = `${this.params.src}-${this.params.dst}`;
146
+ const cfg = this.setup[key];
147
+ if (!cfg)
148
+ throw new Error(`unsupported language pair: ${key}`);
149
+ return llm.complete({
150
+ system: cfg.systemPrompt,
151
+ messages: cfg.chat,
152
+ prompt: text
153
+ });
211
154
  };
212
- /* establish a duplex stream and connect it to Transformers */
155
+ /* establish a transform stream and connect it to LLM */
213
156
  this.stream = new node_stream_1.default.Transform({
214
157
  readableObjectMode: true,
215
158
  writableObjectMode: true,
@@ -224,9 +167,9 @@ class SpeechFlowNodeT2TTransformers extends speechflow_node_1.default {
224
167
  }
225
168
  else {
226
169
  translate(chunk.payload).then((payload) => {
227
- chunk = chunk.clone();
228
- chunk.payload = payload;
229
- this.push(chunk);
170
+ const chunkNew = chunk.clone();
171
+ chunkNew.payload = payload;
172
+ this.push(chunkNew);
230
173
  callback();
231
174
  }).catch((error) => {
232
175
  callback(util.ensureError(error));
@@ -234,7 +177,6 @@ class SpeechFlowNodeT2TTransformers extends speechflow_node_1.default {
234
177
  }
235
178
  },
236
179
  final(callback) {
237
- this.push(null);
238
180
  callback();
239
181
  }
240
182
  });
@@ -246,16 +188,12 @@ class SpeechFlowNodeT2TTransformers extends speechflow_node_1.default {
246
188
  await util.destroyStream(this.stream);
247
189
  this.stream = null;
248
190
  }
249
- /* shutdown Transformers */
250
- if (this.translator !== null) {
251
- this.translator.dispose();
252
- this.translator = null;
253
- }
254
- if (this.generator !== null) {
255
- this.generator.dispose();
256
- this.generator = null;
191
+ /* shutdown LLM */
192
+ if (this.llm !== null) {
193
+ await this.llm.close();
194
+ this.llm = null;
257
195
  }
258
196
  }
259
197
  }
260
- exports.default = SpeechFlowNodeT2TTransformers;
261
- //# sourceMappingURL=speechflow-node-t2t-transformers.js.map
198
+ exports.default = SpeechFlowNodeT2TTranslate;
199
+ //# sourceMappingURL=speechflow-node-t2t-translate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"speechflow-node-t2t-translate.js","sourceRoot":"","sources":["../src/speechflow-node-t2t-translate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import SpeechFlowNode from "./speechflow-node";
2
+ export default class SpeechFlowNodeXIOExec extends SpeechFlowNode {
3
+ static name: string;
4
+ private subprocess;
5
+ constructor(id: string, cfg: {
6
+ [id: string]: any;
7
+ }, opts: {
8
+ [id: string]: any;
9
+ }, args: any[]);
10
+ open(): Promise<void>;
11
+ close(): Promise<void>;
12
+ }
@@ -0,0 +1,223 @@
1
+ "use strict";
2
+ /*
3
+ ** SpeechFlow - Speech Processing Flow Graph
4
+ ** Copyright (c) 2024-2025 Dr. Ralf S. Engelschall <rse@engelschall.com>
5
+ ** Licensed under GPL 3.0 <https://spdx.org/licenses/GPL-3.0-only>
6
+ */
7
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
8
+ if (k2 === undefined) k2 = k;
9
+ var desc = Object.getOwnPropertyDescriptor(m, k);
10
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
11
+ desc = { enumerable: true, get: function() { return m[k]; } };
12
+ }
13
+ Object.defineProperty(o, k2, desc);
14
+ }) : (function(o, m, k, k2) {
15
+ if (k2 === undefined) k2 = k;
16
+ o[k2] = m[k];
17
+ }));
18
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
19
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
20
+ }) : function(o, v) {
21
+ o["default"] = v;
22
+ });
23
+ var __importStar = (this && this.__importStar) || (function () {
24
+ var ownKeys = function(o) {
25
+ ownKeys = Object.getOwnPropertyNames || function (o) {
26
+ var ar = [];
27
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
28
+ return ar;
29
+ };
30
+ return ownKeys(o);
31
+ };
32
+ return function (mod) {
33
+ if (mod && mod.__esModule) return mod;
34
+ var result = {};
35
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
36
+ __setModuleDefault(result, mod);
37
+ return result;
38
+ };
39
+ })();
40
+ var __importDefault = (this && this.__importDefault) || function (mod) {
41
+ return (mod && mod.__esModule) ? mod : { "default": mod };
42
+ };
43
+ Object.defineProperty(exports, "__esModule", { value: true });
44
+ /* standard dependencies */
45
+ const node_stream_1 = __importDefault(require("node:stream"));
46
+ /* external dependencies */
47
+ const execa_1 = require("execa");
48
+ const shell_parser_1 = __importDefault(require("shell-parser"));
49
+ /* internal dependencies */
50
+ const speechflow_node_1 = __importDefault(require("./speechflow-node"));
51
+ const util = __importStar(require("./speechflow-util"));
52
+ /* SpeechFlow node for external command execution */
53
+ class SpeechFlowNodeXIOExec extends speechflow_node_1.default {
54
+ /* declare official node name */
55
+ static name = "xio-exec";
56
+ /* internal state */
57
+ subprocess = null;
58
+ /* construct node */
59
+ constructor(id, cfg, opts, args) {
60
+ super(id, cfg, opts, args);
61
+ /* declare node configuration parameters */
62
+ this.configure({
63
+ command: { type: "string", pos: 0, val: "" },
64
+ mode: { type: "string", pos: 1, val: "r", match: /^(?:r|w|rw)$/ },
65
+ type: { type: "string", pos: 2, val: "audio", match: /^(?:audio|text)$/ },
66
+ chunkAudio: { type: "number", val: 200, match: (n) => n >= 10 && n <= 1000 },
67
+ chunkText: { type: "number", val: 65536, match: (n) => n >= 1024 && n <= 131072 }
68
+ });
69
+ /* sanity check parameters */
70
+ if (this.params.command === "")
71
+ throw new Error("required parameter \"command\" has to be given");
72
+ /* declare node input/output format */
73
+ if (this.params.mode === "rw") {
74
+ this.input = this.params.type;
75
+ this.output = this.params.type;
76
+ }
77
+ else if (this.params.mode === "r") {
78
+ this.input = "none";
79
+ this.output = this.params.type;
80
+ }
81
+ else if (this.params.mode === "w") {
82
+ this.input = this.params.type;
83
+ this.output = "none";
84
+ }
85
+ }
86
+ /* open node */
87
+ async open() {
88
+ /* determine how many bytes we need per chunk when
89
+ the chunk should be of the required duration/size */
90
+ const highWaterMarkAudio = (this.config.audioSampleRate *
91
+ (this.config.audioBitDepth / 8)) / (1000 / this.params.chunkAudio);
92
+ const highWaterMarkText = this.params.chunkText;
93
+ /* parse command into executable and arguments
94
+ (SECURITY: caller must ensure command parameter is properly validated
95
+ and does not contain untrusted user input to prevent command injection) */
96
+ const cmdParts = (0, shell_parser_1.default)(this.params.command);
97
+ if (cmdParts.length === 0)
98
+ throw new Error("failed to parse command: no executable found");
99
+ /* warn about potentially dangerous shell metacharacters */
100
+ if (/[;&|`$()<>]/.test(this.params.command))
101
+ this.log("warning", "command contains shell metacharacters -- ensure input is trusted");
102
+ const executable = cmdParts[0];
103
+ const args = cmdParts.slice(1);
104
+ /* determine subprocess options */
105
+ const encoding = (this.params.type === "text" ?
106
+ this.config.textEncoding : "buffer");
107
+ /* spawn subprocess */
108
+ this.log("info", `executing command: ${this.params.command}`);
109
+ this.subprocess = (0, execa_1.execa)(executable, args, {
110
+ buffer: false,
111
+ encoding,
112
+ ...(this.params.mode === "rw" ? { stdin: "pipe", stdout: "pipe" } : {}),
113
+ ...(this.params.mode === "r" ? { stdin: "ignore", stdout: "pipe" } : {}),
114
+ ...(this.params.mode === "w" ? { stdin: "pipe", stdout: "ignore" } : {})
115
+ });
116
+ /* handle subprocess errors */
117
+ this.subprocess.on("error", (err) => {
118
+ this.log("error", `subprocess error: ${err.message}`);
119
+ this.emit("error", err);
120
+ if (this.stream !== null)
121
+ this.stream.emit("error", err);
122
+ });
123
+ /* handle subprocess exit */
124
+ this.subprocess.on("exit", (code, signal) => {
125
+ if (code !== 0 && code !== null)
126
+ this.log("warning", `subprocess exited with code ${code}`);
127
+ else if (signal)
128
+ this.log("warning", `subprocess terminated by signal ${signal}`);
129
+ else
130
+ this.log("info", "subprocess terminated gracefully");
131
+ });
132
+ /* determine high water mark based on type */
133
+ const highWaterMark = this.params.type === "audio" ? highWaterMarkAudio : highWaterMarkText;
134
+ /* configure stream encoding */
135
+ if (this.subprocess.stdout && this.params.type === "text")
136
+ this.subprocess.stdout.setEncoding(this.config.textEncoding);
137
+ if (this.subprocess.stdin)
138
+ this.subprocess.stdin.setDefaultEncoding(this.params.type === "text" ?
139
+ this.config.textEncoding : "binary");
140
+ /* dispatch according to mode */
141
+ if (this.params.mode === "rw") {
142
+ /* bidirectional mode: both stdin and stdout */
143
+ this.stream = node_stream_1.default.Duplex.from({
144
+ readable: this.subprocess.stdout,
145
+ writable: this.subprocess.stdin
146
+ });
147
+ const wrapper1 = util.createTransformStreamForWritableSide(this.params.type, highWaterMark);
148
+ const wrapper2 = util.createTransformStreamForReadableSide(this.params.type, () => this.timeZero, highWaterMark);
149
+ this.stream = node_stream_1.default.compose(wrapper1, this.stream, wrapper2);
150
+ }
151
+ else if (this.params.mode === "r") {
152
+ /* read-only mode: stdout only */
153
+ const wrapper = util.createTransformStreamForReadableSide(this.params.type, () => this.timeZero, highWaterMark);
154
+ this.stream = node_stream_1.default.compose(this.subprocess.stdout, wrapper);
155
+ }
156
+ else if (this.params.mode === "w") {
157
+ /* write-only mode: stdin only */
158
+ const wrapper = util.createTransformStreamForWritableSide(this.params.type, highWaterMark);
159
+ this.stream = node_stream_1.default.compose(wrapper, this.subprocess.stdin);
160
+ }
161
+ }
162
+ /* close node */
163
+ async close() {
164
+ /* terminate subprocess */
165
+ if (this.subprocess !== null) {
166
+ /* gracefully end stdin if in write or read/write mode */
167
+ if ((this.params.mode === "w" || this.params.mode === "rw") && this.subprocess.stdin &&
168
+ !this.subprocess.stdin.destroyed && !this.subprocess.stdin.writableEnded) {
169
+ await Promise.race([
170
+ new Promise((resolve, reject) => {
171
+ this.subprocess.stdin.end((err) => {
172
+ if (err)
173
+ reject(err);
174
+ else
175
+ resolve();
176
+ });
177
+ }),
178
+ util.timeout(2000)
179
+ ]).catch((err) => {
180
+ const error = util.ensureError(err);
181
+ this.log("warning", `failed to gracefully close stdin: ${error.message}`);
182
+ });
183
+ }
184
+ /* wait for subprocess to exit gracefully */
185
+ await Promise.race([
186
+ this.subprocess,
187
+ util.timeout(5000, "subprocess exit timeout")
188
+ ]).catch(async (err) => {
189
+ /* force kill with SIGTERM */
190
+ const error = util.ensureError(err);
191
+ if (error.message.includes("timeout")) {
192
+ this.log("warning", "subprocess did not exit gracefully, forcing termination");
193
+ this.subprocess.kill("SIGTERM");
194
+ return Promise.race([
195
+ this.subprocess,
196
+ util.timeout(2000)
197
+ ]);
198
+ }
199
+ }).catch(async () => {
200
+ /* force kill with SIGKILL */
201
+ this.log("warning", "subprocess did not respond to SIGTERM, forcing SIGKILL");
202
+ this.subprocess.kill("SIGKILL");
203
+ return Promise.race([
204
+ this.subprocess,
205
+ util.timeout(1000)
206
+ ]);
207
+ }).catch(() => {
208
+ this.log("error", "subprocess did not terminate even after SIGKILL");
209
+ });
210
+ /* remove event listeners to prevent memory leaks */
211
+ this.subprocess.removeAllListeners("error");
212
+ this.subprocess.removeAllListeners("exit");
213
+ this.subprocess = null;
214
+ }
215
+ /* shutdown stream */
216
+ if (this.stream !== null) {
217
+ await util.destroyStream(this.stream);
218
+ this.stream = null;
219
+ }
220
+ }
221
+ }
222
+ exports.default = SpeechFlowNodeXIOExec;
223
+ //# sourceMappingURL=speechflow-node-xio-exec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"speechflow-node-xio-exec.js","sourceRoot":"","sources":["../src/speechflow-node-xio-exec.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,7 @@
1
1
  import SpeechFlowNode from "./speechflow-node";
2
2
  export default class SpeechFlowNodeXIOFile extends SpeechFlowNode {
3
3
  static name: string;
4
+ private fd;
4
5
  constructor(id: string, cfg: {
5
6
  [id: string]: any;
6
7
  }, opts: {