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.
- package/CHANGELOG.md +18 -0
- package/README.md +387 -119
- package/etc/claude.md +5 -5
- package/etc/speechflow.yaml +2 -2
- package/package.json +3 -3
- package/speechflow-cli/dst/speechflow-main-graph.d.ts +1 -0
- package/speechflow-cli/dst/speechflow-main-graph.js +28 -5
- package/speechflow-cli/dst/speechflow-main-graph.js.map +1 -1
- package/speechflow-cli/dst/speechflow-node-a2a-wav.js +24 -4
- package/speechflow-cli/dst/speechflow-node-a2a-wav.js.map +1 -1
- package/speechflow-cli/dst/speechflow-node-a2t-google.d.ts +17 -0
- package/speechflow-cli/dst/speechflow-node-a2t-google.js +320 -0
- package/speechflow-cli/dst/speechflow-node-a2t-google.js.map +1 -0
- package/speechflow-cli/dst/speechflow-node-t2a-google.d.ts +15 -0
- package/speechflow-cli/dst/speechflow-node-t2a-google.js +218 -0
- package/speechflow-cli/dst/speechflow-node-t2a-google.js.map +1 -0
- package/speechflow-cli/dst/speechflow-node-t2a-openai.d.ts +15 -0
- package/speechflow-cli/dst/speechflow-node-t2a-openai.js +195 -0
- package/speechflow-cli/dst/speechflow-node-t2a-openai.js.map +1 -0
- package/speechflow-cli/dst/speechflow-node-t2a-supertonic.d.ts +17 -0
- package/speechflow-cli/dst/speechflow-node-t2a-supertonic.js +608 -0
- package/speechflow-cli/dst/speechflow-node-t2a-supertonic.js.map +1 -0
- package/speechflow-cli/dst/speechflow-node-t2t-amazon.js.map +1 -1
- package/speechflow-cli/dst/{speechflow-node-t2t-transformers.d.ts → speechflow-node-t2t-opus.d.ts} +1 -3
- package/speechflow-cli/dst/speechflow-node-t2t-opus.js +159 -0
- package/speechflow-cli/dst/speechflow-node-t2t-opus.js.map +1 -0
- package/speechflow-cli/dst/speechflow-node-t2t-profanity.d.ts +11 -0
- package/speechflow-cli/dst/speechflow-node-t2t-profanity.js +118 -0
- package/speechflow-cli/dst/speechflow-node-t2t-profanity.js.map +1 -0
- package/speechflow-cli/dst/speechflow-node-t2t-punctuation.d.ts +13 -0
- package/speechflow-cli/dst/speechflow-node-t2t-punctuation.js +220 -0
- package/speechflow-cli/dst/speechflow-node-t2t-punctuation.js.map +1 -0
- package/speechflow-cli/dst/{speechflow-node-t2t-openai.d.ts → speechflow-node-t2t-spellcheck.d.ts} +2 -2
- package/speechflow-cli/dst/{speechflow-node-t2t-openai.js → speechflow-node-t2t-spellcheck.js} +47 -99
- package/speechflow-cli/dst/speechflow-node-t2t-spellcheck.js.map +1 -0
- package/speechflow-cli/dst/speechflow-node-t2t-subtitle.js +3 -6
- package/speechflow-cli/dst/speechflow-node-t2t-subtitle.js.map +1 -1
- package/speechflow-cli/dst/speechflow-node-t2t-summary.d.ts +16 -0
- package/speechflow-cli/dst/speechflow-node-t2t-summary.js +241 -0
- package/speechflow-cli/dst/speechflow-node-t2t-summary.js.map +1 -0
- package/speechflow-cli/dst/{speechflow-node-t2t-ollama.d.ts → speechflow-node-t2t-translate.d.ts} +2 -2
- package/speechflow-cli/dst/{speechflow-node-t2t-transformers.js → speechflow-node-t2t-translate.js} +53 -115
- package/speechflow-cli/dst/speechflow-node-t2t-translate.js.map +1 -0
- package/speechflow-cli/dst/speechflow-node-xio-exec.d.ts +12 -0
- package/speechflow-cli/dst/speechflow-node-xio-exec.js +223 -0
- package/speechflow-cli/dst/speechflow-node-xio-exec.js.map +1 -0
- package/speechflow-cli/dst/speechflow-node-xio-file.d.ts +1 -0
- package/speechflow-cli/dst/speechflow-node-xio-file.js +79 -66
- package/speechflow-cli/dst/speechflow-node-xio-file.js.map +1 -1
- package/speechflow-cli/dst/speechflow-node-xio-vban.d.ts +17 -0
- package/speechflow-cli/dst/speechflow-node-xio-vban.js +330 -0
- package/speechflow-cli/dst/speechflow-node-xio-vban.js.map +1 -0
- package/speechflow-cli/dst/speechflow-node-xio-webrtc.d.ts +39 -0
- package/speechflow-cli/dst/speechflow-node-xio-webrtc.js +500 -0
- package/speechflow-cli/dst/speechflow-node-xio-webrtc.js.map +1 -0
- package/speechflow-cli/dst/speechflow-util-audio.js +4 -5
- package/speechflow-cli/dst/speechflow-util-audio.js.map +1 -1
- package/speechflow-cli/dst/speechflow-util-error.d.ts +1 -0
- package/speechflow-cli/dst/speechflow-util-error.js +5 -0
- package/speechflow-cli/dst/speechflow-util-error.js.map +1 -1
- package/speechflow-cli/dst/speechflow-util-llm.d.ts +35 -0
- package/speechflow-cli/dst/speechflow-util-llm.js +363 -0
- package/speechflow-cli/dst/speechflow-util-llm.js.map +1 -0
- package/speechflow-cli/dst/speechflow-util.d.ts +1 -0
- package/speechflow-cli/dst/speechflow-util.js +1 -0
- package/speechflow-cli/dst/speechflow-util.js.map +1 -1
- package/speechflow-cli/etc/oxlint.jsonc +2 -1
- package/speechflow-cli/package.json +34 -17
- package/speechflow-cli/src/lib.d.ts +5 -0
- package/speechflow-cli/src/speechflow-main-graph.ts +31 -5
- package/speechflow-cli/src/speechflow-node-a2a-wav.ts +24 -4
- package/speechflow-cli/src/speechflow-node-a2t-google.ts +322 -0
- package/speechflow-cli/src/speechflow-node-t2a-google.ts +206 -0
- package/speechflow-cli/src/speechflow-node-t2a-openai.ts +179 -0
- package/speechflow-cli/src/speechflow-node-t2a-supertonic.ts +701 -0
- package/speechflow-cli/src/speechflow-node-t2t-amazon.ts +2 -1
- package/speechflow-cli/src/speechflow-node-t2t-opus.ts +136 -0
- package/speechflow-cli/src/speechflow-node-t2t-profanity.ts +93 -0
- package/speechflow-cli/src/speechflow-node-t2t-punctuation.ts +201 -0
- package/speechflow-cli/src/{speechflow-node-t2t-openai.ts → speechflow-node-t2t-spellcheck.ts} +48 -107
- package/speechflow-cli/src/speechflow-node-t2t-subtitle.ts +3 -6
- package/speechflow-cli/src/speechflow-node-t2t-summary.ts +229 -0
- package/speechflow-cli/src/speechflow-node-t2t-translate.ts +181 -0
- package/speechflow-cli/src/speechflow-node-xio-exec.ts +210 -0
- package/speechflow-cli/src/speechflow-node-xio-file.ts +92 -79
- package/speechflow-cli/src/speechflow-node-xio-vban.ts +325 -0
- package/speechflow-cli/src/speechflow-node-xio-webrtc.ts +533 -0
- package/speechflow-cli/src/speechflow-util-audio.ts +5 -5
- package/speechflow-cli/src/speechflow-util-error.ts +9 -0
- package/speechflow-cli/src/speechflow-util-llm.ts +367 -0
- package/speechflow-cli/src/speechflow-util.ts +1 -0
- package/speechflow-ui-db/package.json +9 -9
- package/speechflow-ui-st/package.json +9 -9
- package/speechflow-cli/dst/speechflow-node-t2t-ollama.js +0 -293
- package/speechflow-cli/dst/speechflow-node-t2t-ollama.js.map +0 -1
- package/speechflow-cli/dst/speechflow-node-t2t-openai.js.map +0 -1
- package/speechflow-cli/dst/speechflow-node-t2t-transformers.js.map +0 -1
- package/speechflow-cli/src/speechflow-node-t2t-ollama.ts +0 -281
- package/speechflow-cli/src/speechflow-node-t2t-transformers.ts +0 -247
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import EventEmitter from "node:events";
|
|
2
|
+
export type LLMCompleteMessage = {
|
|
3
|
+
role: "system" | "user" | "assistant";
|
|
4
|
+
content: string;
|
|
5
|
+
};
|
|
6
|
+
export type LLMConfig = {
|
|
7
|
+
provider?: "openai" | "anthropic" | "google" | "ollama" | "transformers";
|
|
8
|
+
api?: string;
|
|
9
|
+
model?: string;
|
|
10
|
+
key?: string;
|
|
11
|
+
timeout?: number;
|
|
12
|
+
temperature?: number;
|
|
13
|
+
maxTokens?: number;
|
|
14
|
+
topP?: number;
|
|
15
|
+
cacheDir?: string;
|
|
16
|
+
};
|
|
17
|
+
export type LLMCompleteOptions = {
|
|
18
|
+
system?: string;
|
|
19
|
+
messages?: LLMCompleteMessage[];
|
|
20
|
+
prompt: string;
|
|
21
|
+
};
|
|
22
|
+
export declare class LLM extends EventEmitter {
|
|
23
|
+
private config;
|
|
24
|
+
private openai;
|
|
25
|
+
private anthropic;
|
|
26
|
+
private google;
|
|
27
|
+
private ollama;
|
|
28
|
+
private transformer;
|
|
29
|
+
private initialized;
|
|
30
|
+
constructor(config: LLMConfig);
|
|
31
|
+
private log;
|
|
32
|
+
open(): Promise<void>;
|
|
33
|
+
complete(options: LLMCompleteOptions): Promise<string>;
|
|
34
|
+
close(): Promise<void>;
|
|
35
|
+
}
|
|
@@ -0,0 +1,363 @@
|
|
|
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
|
+
exports.LLM = void 0;
|
|
45
|
+
/* standard dependencies */
|
|
46
|
+
const node_events_1 = __importDefault(require("node:events"));
|
|
47
|
+
/* external dependencies */
|
|
48
|
+
const openai_1 = __importDefault(require("openai"));
|
|
49
|
+
const sdk_1 = __importDefault(require("@anthropic-ai/sdk"));
|
|
50
|
+
const genai_1 = require("@google/genai");
|
|
51
|
+
const ollama_1 = require("ollama");
|
|
52
|
+
const Transformers = __importStar(require("@huggingface/transformers"));
|
|
53
|
+
/* LLM class for unified LLM access */
|
|
54
|
+
class LLM extends node_events_1.default {
|
|
55
|
+
/* internal state */
|
|
56
|
+
config;
|
|
57
|
+
openai = null;
|
|
58
|
+
anthropic = null;
|
|
59
|
+
google = null;
|
|
60
|
+
ollama = null;
|
|
61
|
+
transformer = null;
|
|
62
|
+
initialized = false;
|
|
63
|
+
/* construct LLM instance */
|
|
64
|
+
constructor(config) {
|
|
65
|
+
/* pass-through to EventEmitter */
|
|
66
|
+
super();
|
|
67
|
+
/* provide configuration defaults */
|
|
68
|
+
this.config = {
|
|
69
|
+
provider: "openai",
|
|
70
|
+
api: "",
|
|
71
|
+
model: "",
|
|
72
|
+
key: "",
|
|
73
|
+
timeout: 30 * 1000,
|
|
74
|
+
temperature: 0.7,
|
|
75
|
+
maxTokens: 1024,
|
|
76
|
+
topP: 0.5,
|
|
77
|
+
cacheDir: "",
|
|
78
|
+
...config
|
|
79
|
+
};
|
|
80
|
+
/* validate configuration options */
|
|
81
|
+
if (this.config.key === "") {
|
|
82
|
+
if (this.config.provider === "openai")
|
|
83
|
+
this.config.key = process.env.SPEECHFLOW_OPENAI_KEY ?? "";
|
|
84
|
+
else if (this.config.provider === "anthropic")
|
|
85
|
+
this.config.key = process.env.SPEECHFLOW_ANTHROPIC_KEY ?? "";
|
|
86
|
+
else if (this.config.provider === "google")
|
|
87
|
+
this.config.key = process.env.SPEECHFLOW_GOOGLE_KEY ?? "";
|
|
88
|
+
if (this.config.provider.match(/^(?:openai|anthropic|google)$/) && this.config.key === "")
|
|
89
|
+
throw new Error(`API key is required for provider "${this.config.provider}"`);
|
|
90
|
+
}
|
|
91
|
+
if (this.config.model === "")
|
|
92
|
+
throw new Error("model is required");
|
|
93
|
+
}
|
|
94
|
+
/* internal logging helper */
|
|
95
|
+
log(level, message) {
|
|
96
|
+
this.emit("log", level, message);
|
|
97
|
+
}
|
|
98
|
+
/* initialize the LLM client */
|
|
99
|
+
async open() {
|
|
100
|
+
if (this.initialized)
|
|
101
|
+
return;
|
|
102
|
+
if (this.config.provider === "openai") {
|
|
103
|
+
/* instantiate OpenAI API */
|
|
104
|
+
this.openai = new openai_1.default({
|
|
105
|
+
...(this.config.api !== "" ? { baseURL: this.config.api } : {}),
|
|
106
|
+
apiKey: this.config.key,
|
|
107
|
+
timeout: this.config.timeout
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
else if (this.config.provider === "anthropic") {
|
|
111
|
+
/* instantiate Anthropic API */
|
|
112
|
+
this.anthropic = new sdk_1.default({
|
|
113
|
+
...(this.config.api !== "" ? { baseURL: this.config.api } : {}),
|
|
114
|
+
apiKey: this.config.key,
|
|
115
|
+
timeout: this.config.timeout
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
else if (this.config.provider === "google") {
|
|
119
|
+
/* instantiate Google API */
|
|
120
|
+
this.google = new genai_1.GoogleGenAI({
|
|
121
|
+
apiKey: this.config.key,
|
|
122
|
+
httpOptions: {
|
|
123
|
+
timeout: this.config.timeout,
|
|
124
|
+
...(this.config.api !== "" ? { baseUrl: this.config.api } : {})
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
else if (this.config.provider === "ollama") {
|
|
129
|
+
/* instantiate Ollama API */
|
|
130
|
+
this.ollama = new ollama_1.Ollama({ host: this.config.api });
|
|
131
|
+
/* ensure the model is available */
|
|
132
|
+
let models;
|
|
133
|
+
try {
|
|
134
|
+
models = await this.ollama.list();
|
|
135
|
+
}
|
|
136
|
+
catch (err) {
|
|
137
|
+
throw new Error(`failed to connect to Ollama API at ${this.config.api}: ${err}`, { cause: err });
|
|
138
|
+
}
|
|
139
|
+
const exists = models.models.some((m) => m.name === this.config.model);
|
|
140
|
+
if (!exists) {
|
|
141
|
+
this.log("info", `LLM: model "${this.config.model}" still not present in Ollama -- ` +
|
|
142
|
+
"automatically downloading model");
|
|
143
|
+
let artifact = "";
|
|
144
|
+
let percent = 0;
|
|
145
|
+
let lastLoggedPercent = -1;
|
|
146
|
+
const interval = setInterval(() => {
|
|
147
|
+
if (percent !== lastLoggedPercent) {
|
|
148
|
+
this.log("info", `LLM: downloaded ${percent.toFixed(2)}% of artifact "${artifact}"`);
|
|
149
|
+
lastLoggedPercent = percent;
|
|
150
|
+
}
|
|
151
|
+
}, 1000);
|
|
152
|
+
try {
|
|
153
|
+
const progress = await this.ollama.pull({ model: this.config.model, stream: true });
|
|
154
|
+
for await (const event of progress) {
|
|
155
|
+
if (event.digest)
|
|
156
|
+
artifact = event.digest;
|
|
157
|
+
if (event.completed && event.total)
|
|
158
|
+
percent = (event.completed / event.total) * 100;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
finally {
|
|
162
|
+
clearInterval(interval);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
else if (this.config.provider === "transformers") {
|
|
167
|
+
/* track download progress when instantiating Transformers pipeline */
|
|
168
|
+
const progressState = new Map();
|
|
169
|
+
const progressCallback = (progress) => {
|
|
170
|
+
let artifact = this.config.model;
|
|
171
|
+
if (typeof progress.file === "string")
|
|
172
|
+
artifact += `:${progress.file}`;
|
|
173
|
+
let percent = 0;
|
|
174
|
+
if (typeof progress.loaded === "number" && typeof progress.total === "number")
|
|
175
|
+
percent = (progress.loaded / progress.total) * 100;
|
|
176
|
+
else if (typeof progress.progress === "number")
|
|
177
|
+
percent = progress.progress;
|
|
178
|
+
if (percent > 0)
|
|
179
|
+
progressState.set(artifact, percent);
|
|
180
|
+
};
|
|
181
|
+
const interval = setInterval(() => {
|
|
182
|
+
for (const [artifact, percent] of progressState) {
|
|
183
|
+
this.log("info", `LLM: downloaded ${percent.toFixed(2)}% of artifact "${artifact}"`);
|
|
184
|
+
if (percent >= 100.0)
|
|
185
|
+
progressState.delete(artifact);
|
|
186
|
+
}
|
|
187
|
+
}, 1000);
|
|
188
|
+
/* instantiate HuggingFace Transformers text generation pipeline */
|
|
189
|
+
try {
|
|
190
|
+
const pipelinePromise = Transformers.pipeline("text-generation", this.config.model, {
|
|
191
|
+
...(this.config.cacheDir !== "" ? { cache_dir: this.config.cacheDir } : {}),
|
|
192
|
+
dtype: "q4",
|
|
193
|
+
device: "auto",
|
|
194
|
+
progress_callback: progressCallback
|
|
195
|
+
});
|
|
196
|
+
this.transformer = await pipelinePromise;
|
|
197
|
+
}
|
|
198
|
+
catch (err) {
|
|
199
|
+
throw new Error(`failed to instantiate HuggingFace Transformers pipeline: ${err}`, { cause: err });
|
|
200
|
+
}
|
|
201
|
+
finally {
|
|
202
|
+
clearInterval(interval);
|
|
203
|
+
}
|
|
204
|
+
if (this.transformer === null)
|
|
205
|
+
throw new Error("failed to instantiate HuggingFace Transformers pipeline");
|
|
206
|
+
}
|
|
207
|
+
else {
|
|
208
|
+
const exhaustive = this.config.provider;
|
|
209
|
+
throw new Error(`unsupported LLM provider: ${exhaustive}`);
|
|
210
|
+
}
|
|
211
|
+
this.log("info", `LLM: initialized ${this.config.provider} client ` +
|
|
212
|
+
`(${this.config.api !== "" ? `api: ${this.config.api}, ` : ""}model: ${this.config.model})`);
|
|
213
|
+
this.initialized = true;
|
|
214
|
+
}
|
|
215
|
+
/* perform a completion */
|
|
216
|
+
async complete(options) {
|
|
217
|
+
if (!this.initialized)
|
|
218
|
+
throw new Error("LLM still not initialized");
|
|
219
|
+
/* build messages array */
|
|
220
|
+
const messages = [];
|
|
221
|
+
if (options.system)
|
|
222
|
+
messages.push({ role: "system", content: options.system });
|
|
223
|
+
if (options.messages)
|
|
224
|
+
messages.push(...options.messages);
|
|
225
|
+
messages.push({ role: "user", content: options.prompt });
|
|
226
|
+
/* perform LLM query */
|
|
227
|
+
if (this.config.provider === "openai") {
|
|
228
|
+
if (!this.openai)
|
|
229
|
+
throw new Error("OpenAI client not available");
|
|
230
|
+
/* perform OpenAI chat completion */
|
|
231
|
+
const completion = await this.openai.chat.completions.create({
|
|
232
|
+
model: this.config.model,
|
|
233
|
+
max_tokens: this.config.maxTokens,
|
|
234
|
+
temperature: this.config.temperature,
|
|
235
|
+
top_p: this.config.topP,
|
|
236
|
+
messages: messages
|
|
237
|
+
}).catch((err) => {
|
|
238
|
+
throw new Error(`failed to perform OpenAI chat completion: ${err}`, { cause: err });
|
|
239
|
+
});
|
|
240
|
+
const content = completion?.choices?.[0]?.message?.content;
|
|
241
|
+
if (!content)
|
|
242
|
+
throw new Error("OpenAI API returned empty content");
|
|
243
|
+
return content;
|
|
244
|
+
}
|
|
245
|
+
else if (this.config.provider === "anthropic") {
|
|
246
|
+
if (!this.anthropic)
|
|
247
|
+
throw new Error("Anthropic client not available");
|
|
248
|
+
/* separate system message from other messages for Anthropic API */
|
|
249
|
+
const systemMessage = messages.find((m) => m.role === "system");
|
|
250
|
+
const chatMessages = messages.filter((m) => m.role !== "system");
|
|
251
|
+
/* perform Anthropic chat completion */
|
|
252
|
+
const message = await this.anthropic.messages.create({
|
|
253
|
+
model: this.config.model,
|
|
254
|
+
max_tokens: this.config.maxTokens,
|
|
255
|
+
temperature: this.config.temperature,
|
|
256
|
+
top_p: this.config.topP,
|
|
257
|
+
system: systemMessage?.content,
|
|
258
|
+
messages: chatMessages
|
|
259
|
+
}).catch((err) => {
|
|
260
|
+
throw new Error(`failed to perform Anthropic chat completion: ${err}`, { cause: err });
|
|
261
|
+
});
|
|
262
|
+
const content = message?.content?.[0];
|
|
263
|
+
if (!content || content.type !== "text")
|
|
264
|
+
throw new Error("Anthropic API returned empty or non-text content");
|
|
265
|
+
return content.text;
|
|
266
|
+
}
|
|
267
|
+
else if (this.config.provider === "google") {
|
|
268
|
+
if (!this.google)
|
|
269
|
+
throw new Error("Google client not available");
|
|
270
|
+
/* convert messages for Google API */
|
|
271
|
+
const systemInstruction = messages.find((m) => m.role === "system")?.content;
|
|
272
|
+
const contents = messages.filter((m) => m.role !== "system").map((m) => ({
|
|
273
|
+
role: m.role === "assistant" ? "model" : "user",
|
|
274
|
+
parts: [{ text: m.content }]
|
|
275
|
+
}));
|
|
276
|
+
/* perform Google chat completion */
|
|
277
|
+
const response = await this.google.models.generateContent({
|
|
278
|
+
model: this.config.model,
|
|
279
|
+
contents,
|
|
280
|
+
config: {
|
|
281
|
+
maxOutputTokens: this.config.maxTokens,
|
|
282
|
+
temperature: this.config.temperature,
|
|
283
|
+
topP: this.config.topP,
|
|
284
|
+
...(systemInstruction ? { systemInstruction } : {})
|
|
285
|
+
}
|
|
286
|
+
}).catch((err) => {
|
|
287
|
+
throw new Error(`failed to perform Google chat completion: ${err}`, { cause: err });
|
|
288
|
+
});
|
|
289
|
+
const content = response?.text;
|
|
290
|
+
if (!content)
|
|
291
|
+
throw new Error("Google API returned empty content");
|
|
292
|
+
return content;
|
|
293
|
+
}
|
|
294
|
+
else if (this.config.provider === "ollama") {
|
|
295
|
+
if (!this.ollama)
|
|
296
|
+
throw new Error("Ollama client not available");
|
|
297
|
+
/* perform Ollama chat completion */
|
|
298
|
+
const response = await this.ollama.chat({
|
|
299
|
+
model: this.config.model,
|
|
300
|
+
messages,
|
|
301
|
+
keep_alive: "10m",
|
|
302
|
+
options: {
|
|
303
|
+
num_predict: this.config.maxTokens,
|
|
304
|
+
temperature: this.config.temperature,
|
|
305
|
+
top_p: this.config.topP
|
|
306
|
+
}
|
|
307
|
+
}).catch((err) => {
|
|
308
|
+
throw new Error(`failed to perform Ollama chat completion: ${err}`, { cause: err });
|
|
309
|
+
});
|
|
310
|
+
const content = response?.message?.content;
|
|
311
|
+
if (!content)
|
|
312
|
+
throw new Error("Ollama API returned empty content");
|
|
313
|
+
return content;
|
|
314
|
+
}
|
|
315
|
+
else if (this.config.provider === "transformers") {
|
|
316
|
+
if (!this.transformer)
|
|
317
|
+
throw new Error("HuggingFace Transformers pipeline not available");
|
|
318
|
+
/* perform HuggingFace Transformers text generation */
|
|
319
|
+
const result = await this.transformer(messages, {
|
|
320
|
+
max_new_tokens: this.config.maxTokens,
|
|
321
|
+
temperature: this.config.temperature,
|
|
322
|
+
top_p: this.config.topP,
|
|
323
|
+
do_sample: true
|
|
324
|
+
}).catch((err) => {
|
|
325
|
+
throw new Error(`failed to perform HuggingFace Transformers text generation: ${err}`, { cause: err });
|
|
326
|
+
});
|
|
327
|
+
const single = Array.isArray(result) ? result[0] : result;
|
|
328
|
+
const generatedText = single.generated_text;
|
|
329
|
+
const content = typeof generatedText === "string" ?
|
|
330
|
+
generatedText :
|
|
331
|
+
generatedText.at(-1)?.content;
|
|
332
|
+
if (!content)
|
|
333
|
+
throw new Error("HuggingFace Transformers API returned empty content");
|
|
334
|
+
return content;
|
|
335
|
+
}
|
|
336
|
+
else {
|
|
337
|
+
const exhaustive = this.config.provider;
|
|
338
|
+
throw new Error(`unsupported LLM provider: ${exhaustive}`);
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
/* close the LLM client */
|
|
342
|
+
async close() {
|
|
343
|
+
if (!this.initialized)
|
|
344
|
+
return;
|
|
345
|
+
if (this.config.provider === "openai")
|
|
346
|
+
this.openai = null;
|
|
347
|
+
else if (this.config.provider === "anthropic")
|
|
348
|
+
this.anthropic = null;
|
|
349
|
+
else if (this.config.provider === "google")
|
|
350
|
+
this.google = null;
|
|
351
|
+
else if (this.config.provider === "ollama") {
|
|
352
|
+
this.ollama?.abort();
|
|
353
|
+
this.ollama = null;
|
|
354
|
+
}
|
|
355
|
+
else if (this.config.provider === "transformers") {
|
|
356
|
+
this.transformer?.dispose();
|
|
357
|
+
this.transformer = null;
|
|
358
|
+
}
|
|
359
|
+
this.initialized = false;
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
exports.LLM = LLM;
|
|
363
|
+
//# sourceMappingURL=speechflow-util-llm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"speechflow-util-llm.js","sourceRoot":"","sources":["../src/speechflow-util-llm.ts"],"names":[],"mappings":"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"}
|
|
@@ -24,4 +24,5 @@ __exportStar(require("./speechflow-util-error"), exports);
|
|
|
24
24
|
__exportStar(require("./speechflow-util-stream"), exports);
|
|
25
25
|
__exportStar(require("./speechflow-util-queue"), exports);
|
|
26
26
|
__exportStar(require("./speechflow-util-misc"), exports);
|
|
27
|
+
__exportStar(require("./speechflow-util-llm"), exports);
|
|
27
28
|
//# sourceMappingURL=speechflow-util.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"speechflow-util.js","sourceRoot":"","sources":["../src/speechflow-util.ts"],"names":[],"mappings":";AAAA;;;;EAIE;;;;;;;;;;;;;;;;AAEF,0DAAuC;AACvC,0DAAuC;AACvC,2DAAwC;AACxC,0DAAuC;AACvC,yDAAsC"}
|
|
1
|
+
{"version":3,"file":"speechflow-util.js","sourceRoot":"","sources":["../src/speechflow-util.ts"],"names":[],"mappings":";AAAA;;;;EAIE;;;;;;;;;;;;;;;;AAEF,0DAAuC;AACvC,0DAAuC;AACvC,2DAAwC;AACxC,0DAAuC;AACvC,yDAAsC;AACtC,wDAAqC"}
|
|
@@ -20,18 +20,22 @@
|
|
|
20
20
|
"flowlink": "1.2.3",
|
|
21
21
|
"js-yaml": "4.1.1",
|
|
22
22
|
"@gpeng/naudiodon": "2.4.1",
|
|
23
|
+
"execa": "9.6.1",
|
|
24
|
+
"shell-parser": "1.0.0",
|
|
23
25
|
"@deepgram/sdk": "4.11.2",
|
|
24
|
-
"deepl-node": "1.
|
|
25
|
-
"@elevenlabs/elevenlabs-js": "2.
|
|
26
|
+
"deepl-node": "1.24.0",
|
|
27
|
+
"@elevenlabs/elevenlabs-js": "2.27.0",
|
|
26
28
|
"get-stream": "9.0.1",
|
|
27
|
-
"@dotenvx/dotenvx": "1.51.
|
|
29
|
+
"@dotenvx/dotenvx": "1.51.2",
|
|
28
30
|
"speex-resampler": "3.0.1",
|
|
29
31
|
"@sapphi-red/speex-preprocess-wasm": "0.4.0",
|
|
30
32
|
"@shiguredo/rnnoise-wasm": "2025.1.5",
|
|
31
|
-
"@aws-sdk/client-transcribe-streaming": "3.
|
|
32
|
-
"@aws-sdk/client-translate": "3.
|
|
33
|
-
"@aws-sdk/client-polly": "3.
|
|
33
|
+
"@aws-sdk/client-transcribe-streaming": "3.948.0",
|
|
34
|
+
"@aws-sdk/client-translate": "3.948.0",
|
|
35
|
+
"@aws-sdk/client-polly": "3.948.0",
|
|
34
36
|
"@google-cloud/translate": "9.3.0",
|
|
37
|
+
"@google-cloud/speech": "7.2.1",
|
|
38
|
+
"@google-cloud/text-to-speech": "6.4.0",
|
|
35
39
|
"node-web-audio-api": "1.0.7",
|
|
36
40
|
"object-path": "0.11.8",
|
|
37
41
|
"glob": "13.0.0",
|
|
@@ -46,40 +50,49 @@
|
|
|
46
50
|
"@opensumi/reconnecting-websocket": "4.4.0",
|
|
47
51
|
"ollama": "0.6.3",
|
|
48
52
|
"openai": "6.10.0",
|
|
53
|
+
"@anthropic-ai/sdk": "0.71.2",
|
|
54
|
+
"@google/genai": "1.33.0",
|
|
49
55
|
"@rse/ffmpeg": "1.4.2",
|
|
50
56
|
"ffmpeg-stream": "1.0.1",
|
|
51
57
|
"installed-packages": "1.0.13",
|
|
52
58
|
"syspath": "1.0.8",
|
|
53
59
|
"wav": "1.0.2",
|
|
54
60
|
"mqtt": "5.14.1",
|
|
61
|
+
"vban": "1.5.6",
|
|
55
62
|
"cbor2": "2.0.1",
|
|
56
|
-
"arktype": "2.1.
|
|
63
|
+
"arktype": "2.1.29",
|
|
57
64
|
"pure-uuid": "1.8.1",
|
|
58
65
|
"wavefile": "11.0.0",
|
|
59
66
|
"audio-inspect": "0.0.4",
|
|
60
67
|
"@huggingface/transformers": "3.8.1",
|
|
68
|
+
"@huggingface/hub": "2.7.1",
|
|
69
|
+
"onnxruntime-node": "1.20.1",
|
|
61
70
|
"kokoro-js": "1.2.1",
|
|
62
71
|
"@ericedouard/vad-node-realtime": "0.2.0",
|
|
63
72
|
"osc-js": "2.4.1",
|
|
64
73
|
"luxon": "3.7.2",
|
|
65
74
|
"node-interval-tree": "2.1.2",
|
|
66
75
|
"wrap-text": "1.0.10",
|
|
76
|
+
"bad-words-next": "3.2.0",
|
|
67
77
|
"cli-table3": "0.6.5",
|
|
78
|
+
"mkdirp": "3.0.1",
|
|
68
79
|
"@soundtouchjs/audio-worklet": "0.2.1",
|
|
80
|
+
"werift": "0.22.2",
|
|
81
|
+
"@discordjs/opus": "0.10.0",
|
|
69
82
|
"@rse/stx": "1.1.2"
|
|
70
83
|
},
|
|
71
84
|
"devDependencies": {
|
|
72
|
-
"eslint": "9.39.
|
|
73
|
-
"@eslint/js": "9.39.
|
|
85
|
+
"eslint": "9.39.2",
|
|
86
|
+
"@eslint/js": "9.39.2",
|
|
74
87
|
"neostandard": "0.12.2",
|
|
75
88
|
"eslint-plugin-promise": "7.2.1",
|
|
76
89
|
"eslint-plugin-import": "2.32.0",
|
|
77
90
|
"eslint-plugin-node": "11.1.0",
|
|
78
|
-
"typescript-eslint": "8.
|
|
79
|
-
"@typescript-eslint/eslint-plugin": "8.
|
|
80
|
-
"@typescript-eslint/parser": "8.
|
|
81
|
-
"oxlint": "1.
|
|
82
|
-
"eslint-plugin-oxlint": "1.
|
|
91
|
+
"typescript-eslint": "8.49.0",
|
|
92
|
+
"@typescript-eslint/eslint-plugin": "8.49.0",
|
|
93
|
+
"@typescript-eslint/parser": "8.49.0",
|
|
94
|
+
"oxlint": "1.32.0",
|
|
95
|
+
"eslint-plugin-oxlint": "1.32.0",
|
|
83
96
|
"@biomejs/biome": "2.0.6",
|
|
84
97
|
"eslint-config-biome": "2.1.3",
|
|
85
98
|
|
|
@@ -98,15 +111,19 @@
|
|
|
98
111
|
"stmux": "1.8.11",
|
|
99
112
|
"nodemon": "3.1.11",
|
|
100
113
|
"shx": "0.4.0",
|
|
101
|
-
"@yao-pkg/pkg": "6.
|
|
114
|
+
"@yao-pkg/pkg": "6.11.0",
|
|
102
115
|
"typescript": "5.9.3",
|
|
103
116
|
"delay-cli": "3.0.0",
|
|
104
117
|
"cross-env": "10.1.0"
|
|
105
118
|
},
|
|
106
119
|
"overrides": {
|
|
107
|
-
"@huggingface/transformers": { "onnxruntime-node": "1.23.
|
|
120
|
+
"@huggingface/transformers": { "onnxruntime-node": "1.23.2" }
|
|
108
121
|
},
|
|
109
|
-
"upd":
|
|
122
|
+
"upd": [
|
|
123
|
+
"!@biomejs/biome",
|
|
124
|
+
"!onnxruntime-node",
|
|
125
|
+
"!@types/node"
|
|
126
|
+
],
|
|
110
127
|
"engines": {
|
|
111
128
|
"node": ">=22.0.0"
|
|
112
129
|
},
|
|
@@ -35,3 +35,8 @@ declare function registerProcessor(
|
|
|
35
35
|
processorCtor: new (...args: any[]) => AudioWorkletProcessor
|
|
36
36
|
): void
|
|
37
37
|
|
|
38
|
+
/* type definition for "shell-parser" */
|
|
39
|
+
declare module "shell-parser" {
|
|
40
|
+
export default function shellParser (command: string): string[]
|
|
41
|
+
}
|
|
42
|
+
|
|
@@ -237,7 +237,32 @@ export class NodeGraph {
|
|
|
237
237
|
this.cli.log("info", "**** everything established -- stream processing in SpeechFlow graph starts ****")
|
|
238
238
|
}
|
|
239
239
|
|
|
240
|
-
/* graph destruction: PASS 1:
|
|
240
|
+
/* graph destruction: PASS 1: end node streams */
|
|
241
|
+
async endStreams(): Promise<void> {
|
|
242
|
+
/* end all writable streams and wait for them to drain */
|
|
243
|
+
const drainPromises: Promise<void>[] = []
|
|
244
|
+
for (const node of this.graphNodes) {
|
|
245
|
+
if (node.stream === null)
|
|
246
|
+
continue
|
|
247
|
+
const stream = node.stream
|
|
248
|
+
if ((stream instanceof Stream.Writable || stream instanceof Stream.Duplex) &&
|
|
249
|
+
(!stream.writableEnded && !stream.destroyed)) {
|
|
250
|
+
drainPromises.push(
|
|
251
|
+
Promise.race([
|
|
252
|
+
new Promise<void>((resolve) => {
|
|
253
|
+
stream.end(() => { resolve() })
|
|
254
|
+
}),
|
|
255
|
+
util.timeout(5000)
|
|
256
|
+
]).catch(() => {
|
|
257
|
+
/* ignore timeout -- stream will be destroyed later */
|
|
258
|
+
})
|
|
259
|
+
)
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
await Promise.all(drainPromises)
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/* graph destruction: PASS 2: disconnect node streams */
|
|
241
266
|
async disconnectStreams(): Promise<void> {
|
|
242
267
|
for (const node of this.graphNodes) {
|
|
243
268
|
if (node.stream === null) {
|
|
@@ -265,7 +290,7 @@ export class NodeGraph {
|
|
|
265
290
|
}
|
|
266
291
|
}
|
|
267
292
|
|
|
268
|
-
/* graph destruction: PASS
|
|
293
|
+
/* graph destruction: PASS 3: close nodes */
|
|
269
294
|
async closeNodes(): Promise<void> {
|
|
270
295
|
for (const node of this.graphNodes) {
|
|
271
296
|
this.cli.log("info", `close node <${node.id}>`)
|
|
@@ -278,7 +303,7 @@ export class NodeGraph {
|
|
|
278
303
|
}
|
|
279
304
|
}
|
|
280
305
|
|
|
281
|
-
/* graph destruction: PASS
|
|
306
|
+
/* graph destruction: PASS 4: disconnect nodes */
|
|
282
307
|
disconnectNodes(): void {
|
|
283
308
|
for (const node of this.graphNodes) {
|
|
284
309
|
this.cli.log("info", `disconnect node <${node.id}>`)
|
|
@@ -289,7 +314,7 @@ export class NodeGraph {
|
|
|
289
314
|
}
|
|
290
315
|
}
|
|
291
316
|
|
|
292
|
-
/* graph destruction: PASS
|
|
317
|
+
/* graph destruction: PASS 5: destroy nodes */
|
|
293
318
|
destroyNodes(): void {
|
|
294
319
|
for (const node of this.graphNodes) {
|
|
295
320
|
this.cli.log("info", `destroy node <${node.id}>`)
|
|
@@ -345,7 +370,8 @@ export class NodeGraph {
|
|
|
345
370
|
/* shutdown API service */
|
|
346
371
|
await api.stop(args)
|
|
347
372
|
|
|
348
|
-
/* disconnect, close and destroy nodes */
|
|
373
|
+
/* gracefully end, disconnect, close and destroy nodes */
|
|
374
|
+
await this.endStreams()
|
|
349
375
|
await this.disconnectStreams()
|
|
350
376
|
await this.closeNodes()
|
|
351
377
|
this.disconnectNodes()
|