omnius 1.0.186 → 1.0.187
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/dist/index.js +683 -101
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -25161,11 +25161,154 @@ ${content}`
|
|
|
25161
25161
|
}
|
|
25162
25162
|
});
|
|
25163
25163
|
|
|
25164
|
+
// packages/execution/dist/tools/cuda-device-filter.js
|
|
25165
|
+
import { execFileSync as execFileSync3 } from "node:child_process";
|
|
25166
|
+
function cleanEnvValue(value2) {
|
|
25167
|
+
const trimmed = value2?.trim();
|
|
25168
|
+
return trimmed ? trimmed : void 0;
|
|
25169
|
+
}
|
|
25170
|
+
function envFlagEnabled(value2) {
|
|
25171
|
+
return /^(1|true|yes|on)$/i.test(value2?.trim() ?? "");
|
|
25172
|
+
}
|
|
25173
|
+
function parseCudaComputeCapability(value2) {
|
|
25174
|
+
const match = value2?.match(/(\d+(?:\.\d+)?)/);
|
|
25175
|
+
if (!match)
|
|
25176
|
+
return null;
|
|
25177
|
+
const parsed = Number(match[1]);
|
|
25178
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
25179
|
+
}
|
|
25180
|
+
function modalityEnvPrefix(modality) {
|
|
25181
|
+
return `OMNIUS_${modality.toUpperCase()}`;
|
|
25182
|
+
}
|
|
25183
|
+
function parseMinCudaComputeCapability(modality, env2) {
|
|
25184
|
+
const prefix = modalityEnvPrefix(modality);
|
|
25185
|
+
const parsed = parseCudaComputeCapability(env2[`${prefix}_MIN_CUDA_CC`]) ?? parseCudaComputeCapability(env2["OMNIUS_MEDIA_MIN_CUDA_CC"]);
|
|
25186
|
+
return parsed && parsed > 0 ? parsed : DEFAULT_MEDIA_MIN_CUDA_COMPUTE_CAPABILITY;
|
|
25187
|
+
}
|
|
25188
|
+
function splitCudaVisibleDevices(value2) {
|
|
25189
|
+
return (value2 ?? "").split(",").map((part) => part.trim()).filter(Boolean);
|
|
25190
|
+
}
|
|
25191
|
+
function parseCudaDeviceInfo(text) {
|
|
25192
|
+
const devices = [];
|
|
25193
|
+
for (const line of text.split(/\r?\n/)) {
|
|
25194
|
+
const trimmed = line.trim();
|
|
25195
|
+
if (!trimmed)
|
|
25196
|
+
continue;
|
|
25197
|
+
const parts = trimmed.split(",").map((part) => part.trim());
|
|
25198
|
+
if (parts.length < 4)
|
|
25199
|
+
continue;
|
|
25200
|
+
const index = Number.parseInt(parts.shift() ?? "", 10);
|
|
25201
|
+
const capability = parseCudaComputeCapability(parts.pop());
|
|
25202
|
+
const uuid = cleanEnvValue(parts.shift());
|
|
25203
|
+
const name10 = cleanEnvValue(parts.join(", "));
|
|
25204
|
+
if (!Number.isFinite(index) || index < 0)
|
|
25205
|
+
continue;
|
|
25206
|
+
devices.push({ index, uuid, name: name10, computeCapability: capability });
|
|
25207
|
+
}
|
|
25208
|
+
return devices;
|
|
25209
|
+
}
|
|
25210
|
+
function detectCudaDevices() {
|
|
25211
|
+
try {
|
|
25212
|
+
const out = execFileSync3("nvidia-smi", ["--query-gpu=index,uuid,name,compute_cap", "--format=csv,noheader,nounits"], {
|
|
25213
|
+
encoding: "utf8",
|
|
25214
|
+
timeout: 5e3,
|
|
25215
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
25216
|
+
});
|
|
25217
|
+
return parseCudaDeviceInfo(out);
|
|
25218
|
+
} catch {
|
|
25219
|
+
return [];
|
|
25220
|
+
}
|
|
25221
|
+
}
|
|
25222
|
+
function resolveMediaCudaVisibleDevicesForEnv(args) {
|
|
25223
|
+
const env2 = args.env ?? process.env;
|
|
25224
|
+
const prefix = modalityEnvPrefix(args.modality);
|
|
25225
|
+
const explicit = cleanEnvValue(env2[`${prefix}_CUDA_VISIBLE_DEVICES`]) ?? cleanEnvValue(env2["OMNIUS_MEDIA_CUDA_VISIBLE_DEVICES"]) ?? (args.modality === "audio" ? cleanEnvValue(env2["OMNIUS_AUDIO_GPU"]) : void 0);
|
|
25226
|
+
if (explicit)
|
|
25227
|
+
return explicit;
|
|
25228
|
+
const current = cleanEnvValue(env2["CUDA_VISIBLE_DEVICES"]);
|
|
25229
|
+
if (envFlagEnabled(env2[`${prefix}_DISABLE_CUDA_FILTER`]) || envFlagEnabled(env2["OMNIUS_MEDIA_DISABLE_CUDA_FILTER"])) {
|
|
25230
|
+
return current;
|
|
25231
|
+
}
|
|
25232
|
+
const devices = args.devices ?? detectCudaDevices();
|
|
25233
|
+
const minComputeCapability = args.minComputeCapability ?? parseMinCudaComputeCapability(args.modality, env2);
|
|
25234
|
+
const compatible = devices.filter((device) => device.computeCapability !== null && device.computeCapability >= minComputeCapability);
|
|
25235
|
+
if (compatible.length === 0)
|
|
25236
|
+
return current;
|
|
25237
|
+
const compatibleTokens = /* @__PURE__ */ new Set();
|
|
25238
|
+
for (const device of compatible) {
|
|
25239
|
+
compatibleTokens.add(String(device.index));
|
|
25240
|
+
if (device.uuid)
|
|
25241
|
+
compatibleTokens.add(device.uuid);
|
|
25242
|
+
}
|
|
25243
|
+
if (current) {
|
|
25244
|
+
const requested = splitCudaVisibleDevices(current);
|
|
25245
|
+
const canFilter = requested.length > 0 && requested.every((token) => /^\d+$/.test(token) || token.startsWith("GPU-"));
|
|
25246
|
+
if (!canFilter)
|
|
25247
|
+
return current;
|
|
25248
|
+
const kept = requested.filter((token) => compatibleTokens.has(token));
|
|
25249
|
+
return (kept.length > 0 ? kept : compatible.map((device) => String(device.index))).join(",");
|
|
25250
|
+
}
|
|
25251
|
+
return compatible.map((device) => String(device.index)).join(",");
|
|
25252
|
+
}
|
|
25253
|
+
function mediaBrokerGpuIndexIsCompatible(gpuIndex, modality, env2 = process.env, devices = detectCudaDevices()) {
|
|
25254
|
+
const prefix = modalityEnvPrefix(modality);
|
|
25255
|
+
if (envFlagEnabled(env2[`${prefix}_DISABLE_CUDA_FILTER`]) || envFlagEnabled(env2["OMNIUS_MEDIA_DISABLE_CUDA_FILTER"])) {
|
|
25256
|
+
return true;
|
|
25257
|
+
}
|
|
25258
|
+
if (devices.length === 0)
|
|
25259
|
+
return true;
|
|
25260
|
+
const minComputeCapability = parseMinCudaComputeCapability(modality, env2);
|
|
25261
|
+
const device = devices.find((candidate) => candidate.index === gpuIndex);
|
|
25262
|
+
if (!device || device.computeCapability === null)
|
|
25263
|
+
return true;
|
|
25264
|
+
return device.computeCapability >= minComputeCapability;
|
|
25265
|
+
}
|
|
25266
|
+
function applyMediaCudaDeviceFilterToEnv(env2, modality) {
|
|
25267
|
+
const cudaVisibleDevices = resolveMediaCudaVisibleDevicesForEnv({ modality, env: env2 });
|
|
25268
|
+
if (cudaVisibleDevices) {
|
|
25269
|
+
env2["CUDA_VISIBLE_DEVICES"] = cudaVisibleDevices;
|
|
25270
|
+
env2["PYTORCH_NVML_BASED_CUDA_CHECK"] = process.env["PYTORCH_NVML_BASED_CUDA_CHECK"] ?? "1";
|
|
25271
|
+
}
|
|
25272
|
+
return env2;
|
|
25273
|
+
}
|
|
25274
|
+
var DEFAULT_MEDIA_MIN_CUDA_COMPUTE_CAPABILITY;
|
|
25275
|
+
var init_cuda_device_filter = __esm({
|
|
25276
|
+
"packages/execution/dist/tools/cuda-device-filter.js"() {
|
|
25277
|
+
"use strict";
|
|
25278
|
+
DEFAULT_MEDIA_MIN_CUDA_COMPUTE_CAPABILITY = 7.5;
|
|
25279
|
+
}
|
|
25280
|
+
});
|
|
25281
|
+
|
|
25164
25282
|
// packages/execution/dist/tools/transcribe-tool.js
|
|
25165
25283
|
import { existsSync as existsSync29, mkdirSync as mkdirSync13, writeFileSync as writeFileSync14, readFileSync as readFileSync22, unlinkSync as unlinkSync3, readdirSync as readdirSync13 } from "node:fs";
|
|
25166
25284
|
import { join as join32, basename as basename6, extname as extname3, resolve as resolve17 } from "node:path";
|
|
25167
25285
|
import { homedir as homedir10 } from "node:os";
|
|
25168
|
-
import { execFileSync as
|
|
25286
|
+
import { execFileSync as execFileSync4, execSync as execSync15 } from "node:child_process";
|
|
25287
|
+
function transcriptionPythonEnv(extra = {}) {
|
|
25288
|
+
const env2 = { ...process.env, ...extra };
|
|
25289
|
+
applyMediaCudaDeviceFilterToEnv(env2, "asr");
|
|
25290
|
+
return env2;
|
|
25291
|
+
}
|
|
25292
|
+
async function withProcessEnv(env2, fn) {
|
|
25293
|
+
const previous = /* @__PURE__ */ new Map();
|
|
25294
|
+
for (const [key, value2] of Object.entries(env2)) {
|
|
25295
|
+
previous.set(key, process.env[key]);
|
|
25296
|
+
if (value2 === void 0)
|
|
25297
|
+
delete process.env[key];
|
|
25298
|
+
else
|
|
25299
|
+
process.env[key] = value2;
|
|
25300
|
+
}
|
|
25301
|
+
try {
|
|
25302
|
+
return await fn();
|
|
25303
|
+
} finally {
|
|
25304
|
+
for (const [key, value2] of previous) {
|
|
25305
|
+
if (value2 === void 0)
|
|
25306
|
+
delete process.env[key];
|
|
25307
|
+
else
|
|
25308
|
+
process.env[key] = value2;
|
|
25309
|
+
}
|
|
25310
|
+
}
|
|
25311
|
+
}
|
|
25169
25312
|
function whisperRamEstimate(model) {
|
|
25170
25313
|
const m2 = model.toLowerCase();
|
|
25171
25314
|
if (m2.includes("large"))
|
|
@@ -25251,6 +25394,7 @@ var init_transcribe_tool = __esm({
|
|
|
25251
25394
|
"use strict";
|
|
25252
25395
|
init_model_broker();
|
|
25253
25396
|
init_network_egress_policy();
|
|
25397
|
+
init_cuda_device_filter();
|
|
25254
25398
|
AUDIO_EXTS = /* @__PURE__ */ new Set([
|
|
25255
25399
|
".mp3",
|
|
25256
25400
|
".wav",
|
|
@@ -25353,13 +25497,13 @@ var init_transcribe_tool = __esm({
|
|
|
25353
25497
|
return this.execViaCli(filePath, model, diarize, start2);
|
|
25354
25498
|
}
|
|
25355
25499
|
try {
|
|
25356
|
-
const result = await tc.transcribe(filePath, {
|
|
25500
|
+
const result = await withProcessEnv(transcriptionPythonEnv(), () => tc.transcribe(filePath, {
|
|
25357
25501
|
model,
|
|
25358
25502
|
format: "json",
|
|
25359
25503
|
diarize,
|
|
25360
25504
|
wordTimestamps: true
|
|
25361
25505
|
// Always get timestamps for structured output
|
|
25362
|
-
});
|
|
25506
|
+
}));
|
|
25363
25507
|
const transcriptDir = join32(this.workingDir, ".omnius", "transcripts");
|
|
25364
25508
|
mkdirSync13(transcriptDir, { recursive: true });
|
|
25365
25509
|
const fileBase = basename6(filePath).replace(/\.[^.]+$/, "");
|
|
@@ -25453,7 +25597,8 @@ var init_transcribe_tool = __esm({
|
|
|
25453
25597
|
timeout: 3e5,
|
|
25454
25598
|
// 5 min max
|
|
25455
25599
|
cwd: this.workingDir,
|
|
25456
|
-
stdio: ["pipe", "pipe", "pipe"]
|
|
25600
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
25601
|
+
env: transcriptionPythonEnv()
|
|
25457
25602
|
});
|
|
25458
25603
|
return {
|
|
25459
25604
|
success: true,
|
|
@@ -25522,7 +25667,7 @@ var init_transcribe_tool = __esm({
|
|
|
25522
25667
|
}
|
|
25523
25668
|
tmpFile = `${tmpBase}.mp3`;
|
|
25524
25669
|
try {
|
|
25525
|
-
|
|
25670
|
+
execFileSync4("yt-dlp", ["-x", "--audio-format", "mp3", "--audio-quality", "5", "-o", `${tmpBase}.%(ext)s`, url], { timeout: 3e5, stdio: ["pipe", "pipe", "pipe"] });
|
|
25526
25671
|
if (!existsSync29(tmpFile)) {
|
|
25527
25672
|
const files = readdirSync13(tmpDir).filter((f2) => f2.startsWith(`download-`) && f2 !== ".gitkeep");
|
|
25528
25673
|
const match = files.find((f2) => f2.includes(basename6(tmpBase)));
|
|
@@ -25647,13 +25792,13 @@ ${result.output}`,
|
|
|
25647
25792
|
try {
|
|
25648
25793
|
let title = "download";
|
|
25649
25794
|
try {
|
|
25650
|
-
title =
|
|
25795
|
+
title = execFileSync4("yt-dlp", ["--get-title", url], { timeout: 15e3, stdio: "pipe" }).toString().trim().replace(/[<>:"/\\|?*]/g, "_").slice(0, 100);
|
|
25651
25796
|
} catch {
|
|
25652
25797
|
}
|
|
25653
25798
|
if (format3 === "mp4") {
|
|
25654
25799
|
const outPath = join32(outputDir, `${title}.mp4`);
|
|
25655
25800
|
const outTemplate = join32(outputDir, `${title}.%(ext)s`);
|
|
25656
|
-
|
|
25801
|
+
execFileSync4("yt-dlp", [
|
|
25657
25802
|
"-f",
|
|
25658
25803
|
"bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/best",
|
|
25659
25804
|
"--merge-output-format",
|
|
@@ -25673,7 +25818,7 @@ Format: mp4`,
|
|
|
25673
25818
|
} else {
|
|
25674
25819
|
const outPath = join32(outputDir, `${title}.mp3`);
|
|
25675
25820
|
const outTemplate = join32(outputDir, `${title}.%(ext)s`);
|
|
25676
|
-
|
|
25821
|
+
execFileSync4("yt-dlp", ["-x", "--audio-format", "mp3", "--audio-quality", "0", "-o", outTemplate, url], { timeout: 6e5, stdio: "pipe", cwd: outputDir });
|
|
25677
25822
|
const actualPath = existsSync29(outPath) ? outPath : outTemplate.replace("%(ext)s", "mp3");
|
|
25678
25823
|
return {
|
|
25679
25824
|
success: true,
|
|
@@ -259246,7 +259391,9 @@ function formatDiffusersFailure(stderrOrStdout) {
|
|
|
259246
259391
|
Note: ${note}`)].filter(Boolean).join("");
|
|
259247
259392
|
}
|
|
259248
259393
|
function imageGenerationPythonEnv(_repoRoot) {
|
|
259249
|
-
|
|
259394
|
+
const env2 = unifiedPythonEnv();
|
|
259395
|
+
applyMediaCudaDeviceFilterToEnv(env2, "image");
|
|
259396
|
+
return env2;
|
|
259250
259397
|
}
|
|
259251
259398
|
function approxImageDownloadBytes(preset) {
|
|
259252
259399
|
if (preset?.approxDownloadGB)
|
|
@@ -259389,6 +259536,7 @@ var init_image_generate = __esm({
|
|
|
259389
259536
|
init_venv_paths();
|
|
259390
259537
|
init_model_store();
|
|
259391
259538
|
init_hf_media_models();
|
|
259539
|
+
init_cuda_device_filter();
|
|
259392
259540
|
DEFAULT_DIFFUSERS_IMAGE_MODEL = "Efficient-Large-Model/SANA1.5_1.6B_1024px_diffusers";
|
|
259393
259541
|
DEFAULT_OLLAMA_IMAGE_MODEL = "x/flux2-klein";
|
|
259394
259542
|
LEGACY_SDXL_TURBO_MODEL = "stabilityai/sdxl-turbo";
|
|
@@ -260746,7 +260894,14 @@ ${errText.slice(0, 800)}`,
|
|
|
260746
260894
|
this.emitProgress({ stage: "load", message: `Starting image generation with ${args.model}` });
|
|
260747
260895
|
const runnerEnv = { ...python.env };
|
|
260748
260896
|
if (this._brokerGpuIndex !== null) {
|
|
260749
|
-
|
|
260897
|
+
if (mediaBrokerGpuIndexIsCompatible(this._brokerGpuIndex, "image", runnerEnv)) {
|
|
260898
|
+
runnerEnv["OMNIUS_GPU_INDEX"] = String(this._brokerGpuIndex);
|
|
260899
|
+
} else {
|
|
260900
|
+
this.emitProgress({
|
|
260901
|
+
stage: "setup",
|
|
260902
|
+
message: `Broker selected CUDA GPU ${this._brokerGpuIndex}, but image CUDA filtering excluded it; using CUDA_VISIBLE_DEVICES=${runnerEnv["CUDA_VISIBLE_DEVICES"] ?? "default"}`
|
|
260903
|
+
});
|
|
260904
|
+
}
|
|
260750
260905
|
}
|
|
260751
260906
|
const result = await runProcess2(python.command, argv, {
|
|
260752
260907
|
cwd: this.cwd,
|
|
@@ -260948,6 +261103,7 @@ __export(audio_generate_exports, {
|
|
|
260948
261103
|
AudioGenerateTool: () => AudioGenerateTool,
|
|
260949
261104
|
DEFAULT_MUSIC_MODEL: () => DEFAULT_MUSIC_MODEL,
|
|
260950
261105
|
DEFAULT_SOUND_MODEL: () => DEFAULT_SOUND_MODEL,
|
|
261106
|
+
audioBrokerGpuIndexIsCompatible: () => audioBrokerGpuIndexIsCompatible,
|
|
260951
261107
|
audioGenerationDir: () => audioGenerationDir,
|
|
260952
261108
|
audioGenerationFallbackCandidates: () => audioGenerationFallbackCandidates,
|
|
260953
261109
|
audioGenerationModelPresets: () => audioGenerationModelPresets,
|
|
@@ -260958,9 +261114,11 @@ __export(audio_generate_exports, {
|
|
|
260958
261114
|
findNonGatedAudioFallback: () => findNonGatedAudioFallback,
|
|
260959
261115
|
getAudioGenerationPreset: () => getAudioGenerationPreset,
|
|
260960
261116
|
inferAudioGenerationBackend: () => inferAudioGenerationBackend,
|
|
260961
|
-
isAudioPresetGated: () => isAudioPresetGated
|
|
261117
|
+
isAudioPresetGated: () => isAudioPresetGated,
|
|
261118
|
+
parseAudioCudaDeviceInfo: () => parseAudioCudaDeviceInfo,
|
|
261119
|
+
resolveAudioCudaVisibleDevicesForEnv: () => resolveAudioCudaVisibleDevicesForEnv
|
|
260962
261120
|
});
|
|
260963
|
-
import {
|
|
261121
|
+
import { spawn as spawn8 } from "node:child_process";
|
|
260964
261122
|
import { existsSync as existsSync32, readdirSync as readdirSync14, statSync as statSync13 } from "node:fs";
|
|
260965
261123
|
import { chmod as chmod4, mkdir as mkdir13, writeFile as writeFile18 } from "node:fs/promises";
|
|
260966
261124
|
import { join as join42 } from "node:path";
|
|
@@ -261025,25 +261183,36 @@ function backendPackages(backend) {
|
|
|
261025
261183
|
return TANGOFLUX_PACKAGES;
|
|
261026
261184
|
return DIFFUSERS_AUDIO_PACKAGES;
|
|
261027
261185
|
}
|
|
261186
|
+
function splitCudaVisibleDevices2(value2) {
|
|
261187
|
+
return (value2 ?? "").split(",").map((part) => part.trim()).filter(Boolean);
|
|
261188
|
+
}
|
|
261189
|
+
function parseAudioCudaDeviceInfo(text) {
|
|
261190
|
+
return parseCudaDeviceInfo(text);
|
|
261191
|
+
}
|
|
261192
|
+
function detectAudioCudaDevices() {
|
|
261193
|
+
return detectCudaDevices();
|
|
261194
|
+
}
|
|
261195
|
+
function resolveAudioCudaVisibleDevicesForEnv(args = {}) {
|
|
261196
|
+
return resolveMediaCudaVisibleDevicesForEnv({
|
|
261197
|
+
modality: "audio",
|
|
261198
|
+
env: args.env,
|
|
261199
|
+
devices: args.devices,
|
|
261200
|
+
minComputeCapability: args.minComputeCapability
|
|
261201
|
+
});
|
|
261202
|
+
}
|
|
261203
|
+
function audioBrokerGpuIndexIsCompatible(gpuIndex, env2 = process.env, devices = detectAudioCudaDevices()) {
|
|
261204
|
+
return mediaBrokerGpuIndexIsCompatible(gpuIndex, "audio", env2, devices);
|
|
261205
|
+
}
|
|
261028
261206
|
function detectLegacyCudaComputeCapability() {
|
|
261029
|
-
|
|
261030
|
-
|
|
261031
|
-
|
|
261032
|
-
|
|
261033
|
-
|
|
261034
|
-
}).trim();
|
|
261035
|
-
const first2 = out.split(/\r?\n/).map((line) => line.trim()).find(Boolean);
|
|
261036
|
-
const match = first2?.match(/^(\d+)\.(\d+)\s*,?\s*(.*)$/);
|
|
261037
|
-
if (!match)
|
|
261038
|
-
return null;
|
|
261039
|
-
const major = Number(match[1]);
|
|
261040
|
-
const minor = Number(match[2]);
|
|
261041
|
-
if (!Number.isFinite(major) || !Number.isFinite(minor))
|
|
261042
|
-
return null;
|
|
261043
|
-
return { major, minor, name: match[3]?.trim() || void 0 };
|
|
261044
|
-
} catch {
|
|
261207
|
+
const devices = detectAudioCudaDevices();
|
|
261208
|
+
const visible = new Set(splitCudaVisibleDevices2(resolveAudioCudaVisibleDevicesForEnv({ devices })));
|
|
261209
|
+
const candidates = visible.size > 0 ? devices.filter((device) => visible.has(String(device.index)) || device.uuid && visible.has(device.uuid)) : devices;
|
|
261210
|
+
const legacy = candidates.find((device) => device.computeCapability !== null && isLegacyCudaCapability(Math.floor(device.computeCapability), Math.round(device.computeCapability % 1 * 10)));
|
|
261211
|
+
if (!legacy || legacy.computeCapability === null)
|
|
261045
261212
|
return null;
|
|
261046
|
-
|
|
261213
|
+
const major = Math.floor(legacy.computeCapability);
|
|
261214
|
+
const minor = Math.round(legacy.computeCapability % 1 * 10);
|
|
261215
|
+
return { major, minor, name: legacy.name };
|
|
261047
261216
|
}
|
|
261048
261217
|
function isLegacyCudaCapability(major, minor) {
|
|
261049
261218
|
return major < 7 || major === 7 && minor < 5;
|
|
@@ -261087,7 +261256,9 @@ function backendImportCheck(backend) {
|
|
|
261087
261256
|
return "import torch, diffusers, scipy\nfrom diffusers import AudioLDMPipeline\n";
|
|
261088
261257
|
}
|
|
261089
261258
|
function audioGenerationPythonEnv(_repoRoot) {
|
|
261090
|
-
|
|
261259
|
+
const env2 = unifiedPythonEnv();
|
|
261260
|
+
applyMediaCudaDeviceFilterToEnv(env2, "audio");
|
|
261261
|
+
return env2;
|
|
261091
261262
|
}
|
|
261092
261263
|
function approxAudioDownloadBytes(preset) {
|
|
261093
261264
|
if (preset?.approxDownloadGB)
|
|
@@ -261341,8 +261512,8 @@ function formatAudioSetupFailure(backend, text) {
|
|
|
261341
261512
|
if (lowered.includes("cuda") && lowered.includes("not available")) {
|
|
261342
261513
|
notes2.push("CUDA was not available to the selected Python environment; install a Torch build matching this machine's CUDA runtime or use CPU-compatible settings.");
|
|
261343
261514
|
}
|
|
261344
|
-
if (lowered.includes("cudnn
|
|
261345
|
-
notes2.push(
|
|
261515
|
+
if (lowered.includes("cudnn") && lowered.includes("incompatible") || lowered.includes("sm < 7.5") || lowered.includes("not compatible") && (lowered.includes("sm_") || lowered.includes("compute capability"))) {
|
|
261516
|
+
notes2.push(`The installed PyTorch wheel is touching a legacy CUDA GPU. Audio generation auto-filters CUDA devices below SM 7.5; current resolved CUDA_VISIBLE_DEVICES=${resolveAudioCudaVisibleDevicesForEnv() ?? "unset"}. Override with OMNIUS_AUDIO_CUDA_VISIBLE_DEVICES or disable with OMNIUS_AUDIO_DISABLE_CUDA_FILTER=1.`);
|
|
261346
261517
|
}
|
|
261347
261518
|
return [body, ...notes2.map((note) => `
|
|
261348
261519
|
${note}`)].filter(Boolean).join("");
|
|
@@ -261733,6 +261904,7 @@ var init_audio_generate = __esm({
|
|
|
261733
261904
|
init_venv_paths();
|
|
261734
261905
|
init_model_store();
|
|
261735
261906
|
init_hf_media_models();
|
|
261907
|
+
init_cuda_device_filter();
|
|
261736
261908
|
DEFAULT_SOUND_MODEL = "cvssp/audioldm-s-full-v2";
|
|
261737
261909
|
DEFAULT_MUSIC_MODEL = "facebook/musicgen-small";
|
|
261738
261910
|
DIFFUSERS_AUDIO_PACKAGES = [
|
|
@@ -262094,9 +262266,9 @@ var init_audio_generate = __esm({
|
|
|
262094
262266
|
import argparse, json, os, sys, time
|
|
262095
262267
|
from pathlib import Path
|
|
262096
262268
|
|
|
262097
|
-
# Broker
|
|
262098
|
-
_omnius_gpu = os.environ.get("OMNIUS_GPU_INDEX", "").strip()
|
|
262099
|
-
if _omnius_gpu
|
|
262269
|
+
# Broker/audio GPU pinning — must run before importing torch.
|
|
262270
|
+
_omnius_gpu = os.environ.get("OMNIUS_GPU_INDEX", "").strip() or os.environ.get("OMNIUS_AUDIO_GPU", "").strip()
|
|
262271
|
+
if _omnius_gpu:
|
|
262100
262272
|
os.environ["CUDA_VISIBLE_DEVICES"] = _omnius_gpu
|
|
262101
262273
|
|
|
262102
262274
|
def _format_bytes(value):
|
|
@@ -262239,9 +262411,14 @@ if __name__ == "__main__":
|
|
|
262239
262411
|
main()
|
|
262240
262412
|
`;
|
|
262241
262413
|
AUDIOCRAFT_RUNNER = String.raw`#!/usr/bin/env python3
|
|
262242
|
-
import argparse, json, sys, time
|
|
262414
|
+
import argparse, json, os, sys, time
|
|
262243
262415
|
from pathlib import Path
|
|
262244
262416
|
|
|
262417
|
+
# Broker/audio GPU pinning — must run before importing torch/audiocraft.
|
|
262418
|
+
_omnius_gpu = os.environ.get("OMNIUS_GPU_INDEX", "").strip() or os.environ.get("OMNIUS_AUDIO_GPU", "").strip()
|
|
262419
|
+
if _omnius_gpu:
|
|
262420
|
+
os.environ["CUDA_VISIBLE_DEVICES"] = _omnius_gpu
|
|
262421
|
+
|
|
262245
262422
|
def _progress(stage, message, percent=None):
|
|
262246
262423
|
payload = {"omnius_progress": True, "stage": stage, "message": message}
|
|
262247
262424
|
if percent is not None:
|
|
@@ -262295,9 +262472,9 @@ if __name__ == "__main__":
|
|
|
262295
262472
|
import argparse, json, os, sys, time
|
|
262296
262473
|
from pathlib import Path
|
|
262297
262474
|
|
|
262298
|
-
# Broker
|
|
262299
|
-
_omnius_gpu = os.environ.get("OMNIUS_GPU_INDEX", "").strip()
|
|
262300
|
-
if _omnius_gpu
|
|
262475
|
+
# Broker/audio GPU pinning — must run before importing torch.
|
|
262476
|
+
_omnius_gpu = os.environ.get("OMNIUS_GPU_INDEX", "").strip() or os.environ.get("OMNIUS_AUDIO_GPU", "").strip()
|
|
262477
|
+
if _omnius_gpu:
|
|
262301
262478
|
os.environ["CUDA_VISIBLE_DEVICES"] = _omnius_gpu
|
|
262302
262479
|
|
|
262303
262480
|
def _format_bytes(value):
|
|
@@ -262411,9 +262588,14 @@ if __name__ == "__main__":
|
|
|
262411
262588
|
main()
|
|
262412
262589
|
`;
|
|
262413
262590
|
TANGOFLUX_RUNNER = String.raw`#!/usr/bin/env python3
|
|
262414
|
-
import argparse, json, sys, time
|
|
262591
|
+
import argparse, json, os, sys, time
|
|
262415
262592
|
from pathlib import Path
|
|
262416
262593
|
|
|
262594
|
+
# Broker/audio GPU pinning — must run before importing torch/tangoflux.
|
|
262595
|
+
_omnius_gpu = os.environ.get("OMNIUS_GPU_INDEX", "").strip() or os.environ.get("OMNIUS_AUDIO_GPU", "").strip()
|
|
262596
|
+
if _omnius_gpu:
|
|
262597
|
+
os.environ["CUDA_VISIBLE_DEVICES"] = _omnius_gpu
|
|
262598
|
+
|
|
262417
262599
|
def _format_bytes(value):
|
|
262418
262600
|
try:
|
|
262419
262601
|
n = float(value)
|
|
@@ -262885,7 +263067,14 @@ if __name__ == "__main__":
|
|
|
262885
263067
|
this.emitProgress({ stage: "load", message: `Starting ${args.kind} generation with ${args.model}` });
|
|
262886
263068
|
const runnerEnv = { ...python.env };
|
|
262887
263069
|
if (this._brokerGpuIndex !== null) {
|
|
262888
|
-
|
|
263070
|
+
if (audioBrokerGpuIndexIsCompatible(this._brokerGpuIndex, runnerEnv)) {
|
|
263071
|
+
runnerEnv["OMNIUS_GPU_INDEX"] = String(this._brokerGpuIndex);
|
|
263072
|
+
} else {
|
|
263073
|
+
this.emitProgress({
|
|
263074
|
+
stage: "setup",
|
|
263075
|
+
message: `Broker selected CUDA GPU ${this._brokerGpuIndex}, but audio CUDA filtering excluded it; using CUDA_VISIBLE_DEVICES=${runnerEnv["CUDA_VISIBLE_DEVICES"] ?? "default"}`
|
|
263076
|
+
});
|
|
263077
|
+
}
|
|
262889
263078
|
}
|
|
262890
263079
|
const result = await runProcess3(python.command, argv, {
|
|
262891
263080
|
cwd: this.cwd,
|
|
@@ -263359,6 +263548,7 @@ function resolveHfToken() {
|
|
|
263359
263548
|
}
|
|
263360
263549
|
function videoGenerationPythonEnv(_repoRoot) {
|
|
263361
263550
|
const env2 = unifiedPythonEnv();
|
|
263551
|
+
applyMediaCudaDeviceFilterToEnv(env2, "video");
|
|
263362
263552
|
const token = resolveHfToken();
|
|
263363
263553
|
if (token) {
|
|
263364
263554
|
env2["HF_TOKEN"] = token;
|
|
@@ -263717,6 +263907,7 @@ var init_video_generate = __esm({
|
|
|
263717
263907
|
init_venv_paths();
|
|
263718
263908
|
init_model_store();
|
|
263719
263909
|
init_hf_media_models();
|
|
263910
|
+
init_cuda_device_filter();
|
|
263720
263911
|
DEFAULT_DIFFUSERS_VIDEO_MODEL = "Efficient-Large-Model/SANA-Video_2B_480p";
|
|
263721
263912
|
SANA_VIDEO_480P_MODEL = "Efficient-Large-Model/SANA-Video_2B_480p";
|
|
263722
263913
|
SANA_VIDEO_720P_MODEL = "Efficient-Large-Model/SANA-Video_2B_720p";
|
|
@@ -265555,7 +265746,14 @@ ${llmAnnotation}` : result.llmContent;
|
|
|
265555
265746
|
runnerEnv["HUGGING_FACE_HUB_TOKEN"] = effectiveToken;
|
|
265556
265747
|
}
|
|
265557
265748
|
if (this._brokerGpuIndex !== null) {
|
|
265558
|
-
|
|
265749
|
+
if (mediaBrokerGpuIndexIsCompatible(this._brokerGpuIndex, "video", runnerEnv)) {
|
|
265750
|
+
runnerEnv["OMNIUS_GPU_INDEX"] = String(this._brokerGpuIndex);
|
|
265751
|
+
} else {
|
|
265752
|
+
this.emitProgress({
|
|
265753
|
+
stage: "setup",
|
|
265754
|
+
message: `Broker selected CUDA GPU ${this._brokerGpuIndex}, but video CUDA filtering excluded it; using CUDA_VISIBLE_DEVICES=${runnerEnv["CUDA_VISIBLE_DEVICES"] ?? "default"}`
|
|
265755
|
+
});
|
|
265756
|
+
}
|
|
265559
265757
|
}
|
|
265560
265758
|
const argv = [
|
|
265561
265759
|
runner,
|
|
@@ -266682,6 +266880,11 @@ import { readFileSync as readFileSync24, existsSync as existsSync34, statSync as
|
|
|
266682
266880
|
import { execSync as execSync16, spawn as spawn10, spawnSync as spawnSync4 } from "node:child_process";
|
|
266683
266881
|
import { resolve as resolve23, extname as extname6, basename as basename8, dirname as dirname9, join as join44 } from "node:path";
|
|
266684
266882
|
import { fileURLToPath as fileURLToPath4 } from "node:url";
|
|
266883
|
+
function visionPythonEnv(extra = {}) {
|
|
266884
|
+
const env2 = { ...process.env, ...extra };
|
|
266885
|
+
applyMediaCudaDeviceFilterToEnv(env2, "vision");
|
|
266886
|
+
return env2;
|
|
266887
|
+
}
|
|
266685
266888
|
async function probeStation(endpoint) {
|
|
266686
266889
|
try {
|
|
266687
266890
|
const healthUrl = endpoint.replace(/\/v1\/?$/, "/health");
|
|
@@ -266752,7 +266955,8 @@ async function autoLaunchStation(port = 2020) {
|
|
|
266752
266955
|
return false;
|
|
266753
266956
|
return new Promise((resolvePromise) => {
|
|
266754
266957
|
const child = spawn10(pythonBin, [launcherScript, "--port", String(port)], {
|
|
266755
|
-
stdio: ["ignore", "pipe", "pipe"]
|
|
266958
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
266959
|
+
env: visionPythonEnv()
|
|
266756
266960
|
});
|
|
266757
266961
|
stationProcess = child;
|
|
266758
266962
|
const cleanupStation = () => {
|
|
@@ -267067,7 +267271,11 @@ function tryHuggingFacePointBackend(options2) {
|
|
|
267067
267271
|
hfPointUnavailable = "Python not found";
|
|
267068
267272
|
return null;
|
|
267069
267273
|
}
|
|
267070
|
-
const deps = spawnSync4(python, ["-c", "import torch, transformers, PIL"], {
|
|
267274
|
+
const deps = spawnSync4(python, ["-c", "import torch, transformers, PIL"], {
|
|
267275
|
+
stdio: "pipe",
|
|
267276
|
+
timeout: 1e4,
|
|
267277
|
+
env: visionPythonEnv()
|
|
267278
|
+
});
|
|
267071
267279
|
if (deps.status !== 0) {
|
|
267072
267280
|
hfPointUnavailable = bufferishToString3(deps.stderr) || "Python dependencies torch, transformers, and pillow are not importable";
|
|
267073
267281
|
return null;
|
|
@@ -267114,7 +267322,7 @@ print(json.dumps(last_result))
|
|
|
267114
267322
|
encoding: "utf8",
|
|
267115
267323
|
stdio: ["pipe", "pipe", "pipe"],
|
|
267116
267324
|
timeout: Math.max(options2.timeoutMs ?? 6e4, 3e5),
|
|
267117
|
-
env:
|
|
267325
|
+
env: visionPythonEnv()
|
|
267118
267326
|
});
|
|
267119
267327
|
if (run2.status !== 0) {
|
|
267120
267328
|
hfPointUnavailable = run2.stderr || run2.stdout || "Hugging Face Moondream point backend failed";
|
|
@@ -267167,6 +267375,7 @@ var init_vision = __esm({
|
|
|
267167
267375
|
"packages/execution/dist/tools/vision.js"() {
|
|
267168
267376
|
"use strict";
|
|
267169
267377
|
init_model_broker();
|
|
267378
|
+
init_cuda_device_filter();
|
|
267170
267379
|
moondreamClient = null;
|
|
267171
267380
|
moondreamError = null;
|
|
267172
267381
|
stationProcess = null;
|
|
@@ -520577,6 +520786,11 @@ import { execFileSync as execFileSync5, execSync as execSync30, spawn as spawn15
|
|
|
520577
520786
|
import { copyFileSync as copyFileSync3, existsSync as existsSync47, statSync as statSync23, writeFileSync as writeFileSync19, mkdirSync as mkdirSync20, readdirSync as readdirSync18, writeSync } from "node:fs";
|
|
520578
520787
|
import { basename as basename15, extname as extname10, isAbsolute as isAbsolute2, join as join63 } from "node:path";
|
|
520579
520788
|
import { homedir as homedir16, tmpdir as tmpdir11 } from "node:os";
|
|
520789
|
+
function ttsPythonEnv(extra = {}) {
|
|
520790
|
+
const env2 = { ...process.env, ...extra };
|
|
520791
|
+
applyMediaCudaDeviceFilterToEnv(env2, "tts");
|
|
520792
|
+
return env2;
|
|
520793
|
+
}
|
|
520580
520794
|
function hasCommand3(command) {
|
|
520581
520795
|
try {
|
|
520582
520796
|
if (process.platform === "win32") {
|
|
@@ -521144,7 +521358,7 @@ function ensureLuxttsDaemon() {
|
|
|
521144
521358
|
const daemon = spawn15(venvPy, [inferScript], {
|
|
521145
521359
|
stdio: ["pipe", "pipe", "pipe"],
|
|
521146
521360
|
cwd: tmpdir11(),
|
|
521147
|
-
env: {
|
|
521361
|
+
env: ttsPythonEnv({ LUXTTS_REPO_PATH: repoDir })
|
|
521148
521362
|
});
|
|
521149
521363
|
_luxttsDaemon = daemon;
|
|
521150
521364
|
_luxttsBuffer = "";
|
|
@@ -521224,6 +521438,7 @@ var init_audio_playback = __esm({
|
|
|
521224
521438
|
"packages/execution/dist/tools/audio-playback.js"() {
|
|
521225
521439
|
"use strict";
|
|
521226
521440
|
init_hf_media_models();
|
|
521441
|
+
init_cuda_device_filter();
|
|
521227
521442
|
_luxttsDaemon = null;
|
|
521228
521443
|
_luxttsReady = false;
|
|
521229
521444
|
_luxttsRequestId = 0;
|
|
@@ -521605,7 +521820,7 @@ ${tried.map((line) => `- ${line}`).join("\n")}`,
|
|
|
521605
521820
|
execFileSync5(venvPy, ["-c", pyScript, JSON.stringify({ text, output: outputPath3, clone_ref: cloneRef, repo: repoDir, speed })], {
|
|
521606
521821
|
stdio: "pipe",
|
|
521607
521822
|
timeout: 12e4,
|
|
521608
|
-
env: {
|
|
521823
|
+
env: ttsPythonEnv({ LUXTTS_REPO_PATH: repoDir })
|
|
521609
521824
|
});
|
|
521610
521825
|
return `${basename15(cloneRef)} (LuxTTS standalone)`;
|
|
521611
521826
|
}
|
|
@@ -521619,7 +521834,8 @@ ${tried.map((line) => `- ${line}`).join("\n")}`,
|
|
|
521619
521834
|
input: JSON.stringify({ text, output_path: outputPath3, voice_name: voice, lang, speed, total_step: totalStep }),
|
|
521620
521835
|
encoding: "utf8",
|
|
521621
521836
|
stdio: ["pipe", "pipe", "pipe"],
|
|
521622
|
-
timeout: 18e4
|
|
521837
|
+
timeout: 18e4,
|
|
521838
|
+
env: ttsPythonEnv()
|
|
521623
521839
|
});
|
|
521624
521840
|
const line = stdout.trim().split(/\r?\n/).pop() || "";
|
|
521625
521841
|
const parsed = JSON.parse(line);
|
|
@@ -523041,10 +523257,16 @@ import { execSync as execSync36 } from "node:child_process";
|
|
|
523041
523257
|
import { existsSync as existsSync50, mkdirSync as mkdirSync22, writeFileSync as writeFileSync20, readFileSync as readFileSync35 } from "node:fs";
|
|
523042
523258
|
import { join as join65 } from "node:path";
|
|
523043
523259
|
import { homedir as homedir17, tmpdir as tmpdir13 } from "node:os";
|
|
523260
|
+
function audioAnalysisPythonEnv(extra = {}) {
|
|
523261
|
+
const env2 = { ...process.env, ...extra };
|
|
523262
|
+
applyMediaCudaDeviceFilterToEnv(env2, "asr");
|
|
523263
|
+
return env2;
|
|
523264
|
+
}
|
|
523044
523265
|
var VENV_DIR, VENV_PIP, VENV_PYTHON, AudioAnalyzeTool;
|
|
523045
523266
|
var init_audio_analyze = __esm({
|
|
523046
523267
|
"packages/execution/dist/tools/audio-analyze.js"() {
|
|
523047
523268
|
"use strict";
|
|
523269
|
+
init_cuda_device_filter();
|
|
523048
523270
|
VENV_DIR = join65(homedir17(), ".omnius", "audio-ml-venv");
|
|
523049
523271
|
VENV_PIP = join65(VENV_DIR, "bin", "pip");
|
|
523050
523272
|
VENV_PYTHON = join65(VENV_DIR, "bin", "python3");
|
|
@@ -523334,15 +523556,15 @@ Context saved to: ${contextFile}`,
|
|
|
523334
523556
|
/** Ensure Python venv with required packages */
|
|
523335
523557
|
async ensureVenv(packages) {
|
|
523336
523558
|
if (!existsSync50(VENV_PYTHON)) {
|
|
523337
|
-
execSync36(`python3 -m venv ${VENV_DIR}`, { timeout: 3e4, stdio: "pipe" });
|
|
523559
|
+
execSync36(`python3 -m venv ${VENV_DIR}`, { timeout: 3e4, stdio: "pipe", env: audioAnalysisPythonEnv() });
|
|
523338
523560
|
}
|
|
523339
523561
|
for (const pkg of packages) {
|
|
523340
523562
|
const importName = pkg.replace(/[<>=!].*/g, "").replace(/-/g, "_");
|
|
523341
523563
|
try {
|
|
523342
|
-
execSync36(`${VENV_PYTHON} -c "import ${importName}"`, { timeout: 1e4, stdio: "pipe" });
|
|
523564
|
+
execSync36(`${VENV_PYTHON} -c "import ${importName}"`, { timeout: 1e4, stdio: "pipe", env: audioAnalysisPythonEnv() });
|
|
523343
523565
|
} catch {
|
|
523344
523566
|
try {
|
|
523345
|
-
execSync36(`${VENV_PIP} install "${pkg}"`, { timeout: 3e5, stdio: "pipe" });
|
|
523567
|
+
execSync36(`${VENV_PIP} install "${pkg}"`, { timeout: 3e5, stdio: "pipe", env: audioAnalysisPythonEnv() });
|
|
523346
523568
|
} catch {
|
|
523347
523569
|
}
|
|
523348
523570
|
}
|
|
@@ -523356,7 +523578,7 @@ Context saved to: ${contextFile}`,
|
|
|
523356
523578
|
const output = execSync36(`${VENV_PYTHON} ${scriptFile}`, {
|
|
523357
523579
|
encoding: "utf8",
|
|
523358
523580
|
timeout: 3e5,
|
|
523359
|
-
env: {
|
|
523581
|
+
env: audioAnalysisPythonEnv({ TF_CPP_MIN_LOG_LEVEL: "3", TF_ENABLE_ONEDNN_OPTS: "0", PYTHONUNBUFFERED: "1" })
|
|
523360
523582
|
});
|
|
523361
523583
|
try {
|
|
523362
523584
|
const result = JSON.parse(output.trim().split("\n").pop());
|
|
@@ -524192,10 +524414,16 @@ import { execSync as execSync38 } from "node:child_process";
|
|
|
524192
524414
|
import { existsSync as existsSync52, mkdirSync as mkdirSync24, writeFileSync as writeFileSync22, readFileSync as readFileSync37 } from "node:fs";
|
|
524193
524415
|
import { join as join67 } from "node:path";
|
|
524194
524416
|
import { homedir as homedir19, tmpdir as tmpdir15 } from "node:os";
|
|
524417
|
+
function visualMemoryPythonEnv(extra = {}) {
|
|
524418
|
+
const env2 = { ...process.env, ...extra };
|
|
524419
|
+
applyMediaCudaDeviceFilterToEnv(env2, "vision");
|
|
524420
|
+
return env2;
|
|
524421
|
+
}
|
|
524195
524422
|
var VMEM_DIR, VENV_DIR2, VENV_PY, VENV_PIP2, VisualMemoryTool;
|
|
524196
524423
|
var init_visual_memory = __esm({
|
|
524197
524424
|
"packages/execution/dist/tools/visual-memory.js"() {
|
|
524198
524425
|
"use strict";
|
|
524426
|
+
init_cuda_device_filter();
|
|
524199
524427
|
VMEM_DIR = join67(homedir19(), ".omnius", "visual-memory");
|
|
524200
524428
|
VENV_DIR2 = join67(homedir19(), ".omnius", "vision-ml-venv");
|
|
524201
524429
|
VENV_PY = join67(VENV_DIR2, "bin", "python3");
|
|
@@ -524723,19 +524951,23 @@ ${objects.join("\n") || " (none taught)"}`,
|
|
|
524723
524951
|
async ensureVenv() {
|
|
524724
524952
|
if (existsSync52(VENV_PY)) {
|
|
524725
524953
|
try {
|
|
524726
|
-
execSync38(`${VENV_PY} -c "import insightface, transformers, torch"`, {
|
|
524954
|
+
execSync38(`${VENV_PY} -c "import insightface, transformers, torch"`, {
|
|
524955
|
+
timeout: 15e3,
|
|
524956
|
+
stdio: "pipe",
|
|
524957
|
+
env: visualMemoryPythonEnv()
|
|
524958
|
+
});
|
|
524727
524959
|
return true;
|
|
524728
524960
|
} catch {
|
|
524729
524961
|
}
|
|
524730
524962
|
}
|
|
524731
524963
|
try {
|
|
524732
524964
|
if (!existsSync52(VENV_PY)) {
|
|
524733
|
-
execSync38(`python3 -m venv ${VENV_DIR2}`, { timeout: 3e4, stdio: "pipe" });
|
|
524965
|
+
execSync38(`python3 -m venv ${VENV_DIR2}`, { timeout: 3e4, stdio: "pipe", env: visualMemoryPythonEnv() });
|
|
524734
524966
|
}
|
|
524735
|
-
execSync38(`${VENV_PIP2} install "setuptools<81" wheel`, { timeout: 6e4, stdio: "pipe" });
|
|
524736
|
-
execSync38(`${VENV_PIP2} install torch torchvision`, { timeout: 6e5, stdio: "pipe" });
|
|
524737
|
-
execSync38(`${VENV_PIP2} install insightface onnxruntime opencv-python-headless`, { timeout: 3e5, stdio: "pipe" });
|
|
524738
|
-
execSync38(`${VENV_PIP2} install transformers pillow`, { timeout: 3e5, stdio: "pipe" });
|
|
524967
|
+
execSync38(`${VENV_PIP2} install "setuptools<81" wheel`, { timeout: 6e4, stdio: "pipe", env: visualMemoryPythonEnv() });
|
|
524968
|
+
execSync38(`${VENV_PIP2} install torch torchvision`, { timeout: 6e5, stdio: "pipe", env: visualMemoryPythonEnv() });
|
|
524969
|
+
execSync38(`${VENV_PIP2} install insightface onnxruntime opencv-python-headless`, { timeout: 3e5, stdio: "pipe", env: visualMemoryPythonEnv() });
|
|
524970
|
+
execSync38(`${VENV_PIP2} install transformers pillow`, { timeout: 3e5, stdio: "pipe", env: visualMemoryPythonEnv() });
|
|
524739
524971
|
return true;
|
|
524740
524972
|
} catch {
|
|
524741
524973
|
return false;
|
|
@@ -524748,7 +524980,7 @@ ${objects.join("\n") || " (none taught)"}`,
|
|
|
524748
524980
|
const output = execSync38(`${VENV_PY} ${scriptFile}`, {
|
|
524749
524981
|
encoding: "utf8",
|
|
524750
524982
|
timeout: timeoutMs,
|
|
524751
|
-
env: {
|
|
524983
|
+
env: visualMemoryPythonEnv({ PYTHONUNBUFFERED: "1" })
|
|
524752
524984
|
});
|
|
524753
524985
|
const lastLine = output.trim().split("\n").pop() || "{}";
|
|
524754
524986
|
return JSON.parse(lastLine);
|
|
@@ -525364,6 +525596,11 @@ import { existsSync as existsSync54, mkdirSync as mkdirSync26, writeFileSync as
|
|
|
525364
525596
|
import { dirname as dirname15, join as join69, resolve as resolve35 } from "node:path";
|
|
525365
525597
|
import { tmpdir as tmpdir17, homedir as homedir21 } from "node:os";
|
|
525366
525598
|
import { fileURLToPath as fileURLToPath8 } from "node:url";
|
|
525599
|
+
function asrPythonEnv(extra = {}) {
|
|
525600
|
+
const env2 = { ...process.env, ...extra };
|
|
525601
|
+
applyMediaCudaDeviceFilterToEnv(env2, "asr");
|
|
525602
|
+
return env2;
|
|
525603
|
+
}
|
|
525367
525604
|
function _findNemotronScript() {
|
|
525368
525605
|
const candidates = [];
|
|
525369
525606
|
try {
|
|
@@ -525399,6 +525636,7 @@ var init_asr_listen = __esm({
|
|
|
525399
525636
|
"packages/execution/dist/tools/asr-listen.js"() {
|
|
525400
525637
|
"use strict";
|
|
525401
525638
|
init_hf_media_models();
|
|
525639
|
+
init_cuda_device_filter();
|
|
525402
525640
|
AsrListenTool = class {
|
|
525403
525641
|
name = "asr_listen";
|
|
525404
525642
|
description = "Record from microphone and transcribe speech to text. Backends: 'whisper' (default, battle-tested openai-whisper / faster-whisper), 'nemotron' (nvidia/nemotron-speech-streaming-en-0.6b — faster streaming), or 'parallel' (runs BOTH engines on the same audio and returns a side-by-side comparison with per-engine latency and character counts). Actions: 'listen' to record + transcribe in one step, 'transcribe' to run on an existing file. Use this when you need to HEAR what a human is saying — ask a question via audio_playback speak, then use asr_listen to capture and transcribe their response.";
|
|
@@ -525633,7 +525871,7 @@ print(json.dumps({"ok": False, "error": "No whisper backend available"}))
|
|
|
525633
525871
|
const output = execSync40(`"${pyPath}" "${scriptFile}"`, {
|
|
525634
525872
|
encoding: "utf8",
|
|
525635
525873
|
timeout: 12e4,
|
|
525636
|
-
env: {
|
|
525874
|
+
env: asrPythonEnv({ PYTHONUNBUFFERED: "1" })
|
|
525637
525875
|
}).trim();
|
|
525638
525876
|
const lines = output.split("\n");
|
|
525639
525877
|
for (let i2 = lines.length - 1; i2 >= 0; i2--) {
|
|
@@ -525682,7 +525920,8 @@ print(json.dumps({"ok": False, "error": "No whisper backend available"}))
|
|
|
525682
525920
|
const result = spawnSync7("python3", [script, "--file", audioFile], {
|
|
525683
525921
|
encoding: "utf8",
|
|
525684
525922
|
timeout: 6e5,
|
|
525685
|
-
stdio: ["ignore", "pipe", "pipe"]
|
|
525923
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
525924
|
+
env: asrPythonEnv()
|
|
525686
525925
|
});
|
|
525687
525926
|
if (result.error) {
|
|
525688
525927
|
return {
|
|
@@ -530791,6 +531030,7 @@ __export(dist_exports, {
|
|
|
530791
531030
|
CustomTool: () => CustomTool,
|
|
530792
531031
|
DEFAULT_DIFFUSERS_IMAGE_MODEL: () => DEFAULT_DIFFUSERS_IMAGE_MODEL,
|
|
530793
531032
|
DEFAULT_DIFFUSERS_VIDEO_MODEL: () => DEFAULT_DIFFUSERS_VIDEO_MODEL,
|
|
531033
|
+
DEFAULT_MEDIA_MIN_CUDA_COMPUTE_CAPABILITY: () => DEFAULT_MEDIA_MIN_CUDA_COMPUTE_CAPABILITY,
|
|
530794
531034
|
DEFAULT_MUSIC_MODEL: () => DEFAULT_MUSIC_MODEL,
|
|
530795
531035
|
DEFAULT_OLLAMA_IMAGE_MODEL: () => DEFAULT_OLLAMA_IMAGE_MODEL,
|
|
530796
531036
|
DEFAULT_SOUND_MODEL: () => DEFAULT_SOUND_MODEL,
|
|
@@ -530905,6 +531145,7 @@ __export(dist_exports, {
|
|
|
530905
531145
|
addProjectConstraint: () => addProjectConstraint,
|
|
530906
531146
|
addSessionConstraint: () => addSessionConstraint,
|
|
530907
531147
|
aliasTool: () => aliasTool,
|
|
531148
|
+
applyMediaCudaDeviceFilterToEnv: () => applyMediaCudaDeviceFilterToEnv,
|
|
530908
531149
|
applyPatch: () => applyPatch,
|
|
530909
531150
|
applyToolResultTriage: () => applyToolResultTriage,
|
|
530910
531151
|
artifactManifestFromBytes: () => artifactManifestFromBytes,
|
|
@@ -530945,6 +531186,7 @@ __export(dist_exports, {
|
|
|
530945
531186
|
defaultExtensionForMime: () => defaultExtensionForMime,
|
|
530946
531187
|
deleteMediaModelAdapter: () => deleteMediaModelAdapter,
|
|
530947
531188
|
deleteTodos: () => deleteTodos,
|
|
531189
|
+
detectCudaDevices: () => detectCudaDevices,
|
|
530948
531190
|
detectElevationMethod: () => detectElevationMethod,
|
|
530949
531191
|
detectLegacyCaches: () => detectLegacyCaches,
|
|
530950
531192
|
detectSearchProvider: () => detectSearchProvider,
|
|
@@ -531046,6 +531288,7 @@ __export(dist_exports, {
|
|
|
531046
531288
|
markSessionValidated: () => markSessionValidated,
|
|
531047
531289
|
measureRepoCacheBytes: () => measureRepoCacheBytes,
|
|
531048
531290
|
mediaBackendCompatibleWithModality: () => mediaBackendCompatibleWithModality,
|
|
531291
|
+
mediaBrokerGpuIndexIsCompatible: () => mediaBrokerGpuIndexIsCompatible,
|
|
531049
531292
|
mediaMimeFromPath: () => mediaMimeFromPath,
|
|
531050
531293
|
mediaModelCatalogDir: () => mediaModelCatalogDir,
|
|
531051
531294
|
mediaModelSlug: () => mediaModelSlug,
|
|
@@ -531056,6 +531299,8 @@ __export(dist_exports, {
|
|
|
531056
531299
|
normalizeSponsorMediaConfig: () => normalizeSponsorMediaConfig,
|
|
531057
531300
|
omniusHomeDir: () => omniusHomeDir,
|
|
531058
531301
|
packetPath: () => packetPath,
|
|
531302
|
+
parseCudaComputeCapability: () => parseCudaComputeCapability,
|
|
531303
|
+
parseCudaDeviceInfo: () => parseCudaDeviceInfo,
|
|
531059
531304
|
parseMcpMarkdown: () => parseMcpMarkdown,
|
|
531060
531305
|
parseMcpToolName: () => parseMcpToolName,
|
|
531061
531306
|
parseSponsorMediaCapability: () => parseSponsorMediaCapability,
|
|
@@ -531078,6 +531323,7 @@ __export(dist_exports, {
|
|
|
531078
531323
|
renderCustomToolDocs: () => renderCustomToolDocs,
|
|
531079
531324
|
resetDepCache: () => resetDepCache,
|
|
531080
531325
|
resetMoondreamClient: () => resetMoondreamClient,
|
|
531326
|
+
resolveMediaCudaVisibleDevicesForEnv: () => resolveMediaCudaVisibleDevicesForEnv,
|
|
531081
531327
|
resolveMediaModel: () => resolveMediaModel,
|
|
531082
531328
|
resolveSecret: () => resolveSecret,
|
|
531083
531329
|
revokeSecret: () => revokeSecret,
|
|
@@ -531199,6 +531445,7 @@ var init_dist5 = __esm({
|
|
|
531199
531445
|
init_embedding_store();
|
|
531200
531446
|
init_image_generate();
|
|
531201
531447
|
init_audio_generate();
|
|
531448
|
+
init_cuda_device_filter();
|
|
531202
531449
|
init_model_store();
|
|
531203
531450
|
init_video_generate();
|
|
531204
531451
|
init_sponsor_media();
|
|
@@ -589502,6 +589749,7 @@ ${CONTENT_BG_SEQ}`);
|
|
|
589502
589749
|
});
|
|
589503
589750
|
|
|
589504
589751
|
// packages/cli/src/tui/tui-select.ts
|
|
589752
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
589505
589753
|
function ansi3(code8, text) {
|
|
589506
589754
|
return isTTY2 ? `\x1B[${code8}m${text}\x1B[0m` : text;
|
|
589507
589755
|
}
|
|
@@ -589511,6 +589759,48 @@ function fg2563(code8, text) {
|
|
|
589511
589759
|
function stripAnsi3(s2) {
|
|
589512
589760
|
return s2.replace(/\x1B\[[0-9;]*m/g, "");
|
|
589513
589761
|
}
|
|
589762
|
+
function stripTerminalControl(s2) {
|
|
589763
|
+
return s2.replace(/\x1B(?:\[[\d;?]*[ -/]*[@-~]|\][^\x07\x1B]*(?:\x07|\x1B\\)?|[@-Z\\-_])/g, "");
|
|
589764
|
+
}
|
|
589765
|
+
function isNonInteractiveSelectSurface() {
|
|
589766
|
+
return Boolean(nonInteractiveSelectSurface.getStore());
|
|
589767
|
+
}
|
|
589768
|
+
function runWithNonInteractiveSelectSurface(fn, opts = {}) {
|
|
589769
|
+
return nonInteractiveSelectSurface.run(opts, fn);
|
|
589770
|
+
}
|
|
589771
|
+
function renderNonInteractiveSelect(opts, currentTitle, skipSet) {
|
|
589772
|
+
const surface = nonInteractiveSelectSurface.getStore();
|
|
589773
|
+
const maxItems = Math.max(1, surface?.maxItems ?? 30);
|
|
589774
|
+
const lines = [];
|
|
589775
|
+
if (currentTitle) lines.push(stripTerminalControl(stripAnsi3(currentTitle)));
|
|
589776
|
+
if (lines.length) lines.push("");
|
|
589777
|
+
let idx = 1;
|
|
589778
|
+
let shown = 0;
|
|
589779
|
+
let omitted = 0;
|
|
589780
|
+
for (const item of opts.items) {
|
|
589781
|
+
const isSkip = skipSet.has(item.key);
|
|
589782
|
+
const labelPlain = stripTerminalControl(stripAnsi3(item.label)).trim();
|
|
589783
|
+
const detailPlain = item.detail ? stripTerminalControl(stripAnsi3(item.detail)).trim() : "";
|
|
589784
|
+
if (isSkip) {
|
|
589785
|
+
if (labelPlain) lines.push(labelPlain);
|
|
589786
|
+
continue;
|
|
589787
|
+
}
|
|
589788
|
+
if (shown >= maxItems) {
|
|
589789
|
+
omitted++;
|
|
589790
|
+
idx++;
|
|
589791
|
+
continue;
|
|
589792
|
+
}
|
|
589793
|
+
const num = String(idx).padStart(2, " ");
|
|
589794
|
+
const detail = detailPlain ? ` - ${detailPlain}` : "";
|
|
589795
|
+
lines.push(` ${num}. ${labelPlain}${detail}`);
|
|
589796
|
+
shown++;
|
|
589797
|
+
idx++;
|
|
589798
|
+
}
|
|
589799
|
+
if (omitted > 0) lines.push(` ... ${omitted} more`);
|
|
589800
|
+
if (opts.customKeyHint) lines.push("", stripTerminalControl(stripAnsi3(opts.customKeyHint)));
|
|
589801
|
+
lines.push("", surface?.hint ?? "(non-interactive: menu shown as text; open the TUI for selection)");
|
|
589802
|
+
process.stdout.write(lines.join("\n").trimEnd() + "\n");
|
|
589803
|
+
}
|
|
589514
589804
|
function defaultRenderRow(item, focused, isActive) {
|
|
589515
589805
|
const marker = isActive ? selectColors.green("●") : focused ? selectColors.blue("●") : selectColors.dim("○");
|
|
589516
589806
|
const label = focused ? selectColors.blue(selectColors.bold(item.label)) : isActive ? selectColors.green(item.label) : item.label;
|
|
@@ -589535,27 +589825,8 @@ function tuiSelect(opts) {
|
|
|
589535
589825
|
if (items.length === 0) {
|
|
589536
589826
|
return Promise.resolve({ confirmed: false, key: null, index: -1 });
|
|
589537
589827
|
}
|
|
589538
|
-
if (!process.stdin.isTTY && process.env["OMNIUS_TUI_FORCE_INTERACTIVE"] !== "1") {
|
|
589539
|
-
|
|
589540
|
-
if (currentTitle) lines.push(currentTitle);
|
|
589541
|
-
if (lines.length) lines.push("");
|
|
589542
|
-
let idx = 1;
|
|
589543
|
-
for (const item of items) {
|
|
589544
|
-
const isSkip = skipSet.has(item.key);
|
|
589545
|
-
const labelPlain = stripAnsi3(item.label);
|
|
589546
|
-
const detailPlain = item.detail ? stripAnsi3(item.detail) : "";
|
|
589547
|
-
if (isSkip) {
|
|
589548
|
-
lines.push(labelPlain);
|
|
589549
|
-
} else {
|
|
589550
|
-
const num = String(idx).padStart(2, " ");
|
|
589551
|
-
const detail = detailPlain ? ` — ${detailPlain}` : "";
|
|
589552
|
-
lines.push(` ${num}. ${labelPlain}${detail}`);
|
|
589553
|
-
idx++;
|
|
589554
|
-
}
|
|
589555
|
-
}
|
|
589556
|
-
if (opts.customKeyHint) lines.push("", opts.customKeyHint);
|
|
589557
|
-
lines.push("", "(non-interactive: list shown above; pick options by re-running this command from the TUI)");
|
|
589558
|
-
process.stdout.write(lines.join("\n") + "\n");
|
|
589828
|
+
if (isNonInteractiveSelectSurface() || !process.stdin.isTTY && process.env["OMNIUS_TUI_FORCE_INTERACTIVE"] !== "1") {
|
|
589829
|
+
renderNonInteractiveSelect(opts, currentTitle, skipSet);
|
|
589559
589830
|
return Promise.resolve({ confirmed: false, key: null, index: -1 });
|
|
589560
589831
|
}
|
|
589561
589832
|
const isSkippable = (idx) => skipSet.has(items[idx].key);
|
|
@@ -590136,7 +590407,7 @@ ${tuiBgSeq()}`);
|
|
|
590136
590407
|
}
|
|
590137
590408
|
});
|
|
590138
590409
|
}
|
|
590139
|
-
var isTTY2, MENU_ACTIVE_GREEN_256, selectColors;
|
|
590410
|
+
var isTTY2, MENU_ACTIVE_GREEN_256, selectColors, nonInteractiveSelectSurface;
|
|
590140
590411
|
var init_tui_select = __esm({
|
|
590141
590412
|
"packages/cli/src/tui/tui-select.ts"() {
|
|
590142
590413
|
"use strict";
|
|
@@ -590156,6 +590427,7 @@ var init_tui_select = __esm({
|
|
|
590156
590427
|
/** Readable grey for non-matching items */
|
|
590157
590428
|
matchDark: (t2) => fg2563(tuiTextDim(), t2)
|
|
590158
590429
|
};
|
|
590430
|
+
nonInteractiveSelectSurface = new AsyncLocalStorage();
|
|
590159
590431
|
}
|
|
590160
590432
|
});
|
|
590161
590433
|
|
|
@@ -590182,12 +590454,17 @@ import { join as join114, dirname as dirname32 } from "node:path";
|
|
|
590182
590454
|
import { homedir as homedir36 } from "node:os";
|
|
590183
590455
|
import { execSync as execSync50, spawn as spawn26 } from "node:child_process";
|
|
590184
590456
|
import { fileURLToPath as fileURLToPath15 } from "node:url";
|
|
590457
|
+
function personaplexPythonEnv(extra = {}) {
|
|
590458
|
+
const env2 = { ...process.env, ...extra };
|
|
590459
|
+
applyMediaCudaDeviceFilterToEnv(env2, "voice");
|
|
590460
|
+
return env2;
|
|
590461
|
+
}
|
|
590185
590462
|
function execAsync(cmd, opts = {}) {
|
|
590186
590463
|
return new Promise((resolve59, reject) => {
|
|
590187
590464
|
const child = spawn26("bash", ["-c", cmd], {
|
|
590188
590465
|
stdio: ["ignore", "pipe", "pipe"],
|
|
590189
590466
|
timeout: opts.timeout ?? 3e5,
|
|
590190
|
-
env: opts.env ??
|
|
590467
|
+
env: personaplexPythonEnv(opts.env ?? {})
|
|
590191
590468
|
});
|
|
590192
590469
|
let stdout = "";
|
|
590193
590470
|
let stderr = "";
|
|
@@ -590261,7 +590538,8 @@ function detectPersonaPlexCapability() {
|
|
|
590261
590538
|
try {
|
|
590262
590539
|
execSync50('python3 -c "import torch; assert torch.cuda.is_available()"', {
|
|
590263
590540
|
timeout: 1e4,
|
|
590264
|
-
stdio: "pipe"
|
|
590541
|
+
stdio: "pipe",
|
|
590542
|
+
env: personaplexPythonEnv()
|
|
590265
590543
|
});
|
|
590266
590544
|
} catch {
|
|
590267
590545
|
const tier2 = selectWeightTier(vramGB);
|
|
@@ -590438,7 +590716,8 @@ async function installPersonaPlex(onInfo, weightTier) {
|
|
|
590438
590716
|
const sitePackages = execSync50(`"${python}" -c "import moshi, os; print(os.path.dirname(moshi.__file__))"`, {
|
|
590439
590717
|
encoding: "utf8",
|
|
590440
590718
|
timeout: 5e3,
|
|
590441
|
-
stdio: "pipe"
|
|
590719
|
+
stdio: "pipe",
|
|
590720
|
+
env: personaplexPythonEnv()
|
|
590442
590721
|
}).trim();
|
|
590443
590722
|
const serverFile = join114(sitePackages, "server.py");
|
|
590444
590723
|
if (existsSync99(serverFile)) {
|
|
@@ -590455,7 +590734,8 @@ async function installPersonaPlex(onInfo, weightTier) {
|
|
|
590455
590734
|
const sitePackages = execSync50(`"${python}" -c "import moshi, os; print(os.path.dirname(moshi.__file__))"`, {
|
|
590456
590735
|
encoding: "utf8",
|
|
590457
590736
|
timeout: 5e3,
|
|
590458
|
-
stdio: "pipe"
|
|
590737
|
+
stdio: "pipe",
|
|
590738
|
+
env: personaplexPythonEnv()
|
|
590459
590739
|
}).trim();
|
|
590460
590740
|
const loadersFile = join114(sitePackages, "models", "loaders.py");
|
|
590461
590741
|
if (existsSync99(loadersFile)) {
|
|
@@ -590559,7 +590839,8 @@ $2if filename.endswith(".safetensors"):`
|
|
|
590559
590839
|
const sitePackages2 = execSync50(`"${python}" -c "import moshi, os; print(os.path.dirname(moshi.__file__))"`, {
|
|
590560
590840
|
encoding: "utf8",
|
|
590561
590841
|
timeout: 5e3,
|
|
590562
|
-
stdio: "pipe"
|
|
590842
|
+
stdio: "pipe",
|
|
590843
|
+
env: personaplexPythonEnv()
|
|
590563
590844
|
}).trim();
|
|
590564
590845
|
const hybridDest = join114(sitePackages2, "hybrid_agent.py");
|
|
590565
590846
|
const serverDest = join114(sitePackages2, "server.py");
|
|
@@ -590693,7 +590974,7 @@ async function startPersonaPlexDaemon(onInfo) {
|
|
|
590693
590974
|
try {
|
|
590694
590975
|
const weightPath = execSync50(
|
|
590695
590976
|
`"${venvPython2}" -c "from huggingface_hub import hf_hub_download; print(hf_hub_download('${repoInfo.repo}', '${repoInfo.file}', token=False))"`,
|
|
590696
|
-
{ encoding: "utf8", timeout: 6e4, stdio: "pipe" }
|
|
590977
|
+
{ encoding: "utf8", timeout: 6e4, stdio: "pipe", env: personaplexPythonEnv() }
|
|
590697
590978
|
).trim();
|
|
590698
590979
|
if (existsSync99(weightPath)) {
|
|
590699
590980
|
if (!existsSync99(cachedBf16)) {
|
|
@@ -590706,7 +590987,7 @@ state = {k: v.to(torch.bfloat16) if v.is_floating_point() else v for k, v in sta
|
|
|
590706
590987
|
save_file(state, '${cachedBf16}')
|
|
590707
590988
|
print('Converted')
|
|
590708
590989
|
"`,
|
|
590709
|
-
{ timeout: 18e4, stdio: "pipe" }
|
|
590990
|
+
{ timeout: 18e4, stdio: "pipe", env: personaplexPythonEnv() }
|
|
590710
590991
|
);
|
|
590711
590992
|
}
|
|
590712
590993
|
if (existsSync99(cachedBf16)) {
|
|
@@ -590732,13 +591013,13 @@ print('Converted')
|
|
|
590732
591013
|
try {
|
|
590733
591014
|
const weightPath = execSync50(
|
|
590734
591015
|
`"${venvPython2}" -c "from huggingface_hub import hf_hub_download; print(hf_hub_download('${repoInfo.repo}', '${repoInfo.file}'${repoInfo.needsToken ? "" : ", token=False"}))"`,
|
|
590735
|
-
{ encoding: "utf8", timeout: 3e4, stdio: "pipe" }
|
|
591016
|
+
{ encoding: "utf8", timeout: 3e4, stdio: "pipe", env: personaplexPythonEnv() }
|
|
590736
591017
|
).trim();
|
|
590737
591018
|
if (existsSync99(dequantScript) && existsSync99(weightPath)) {
|
|
590738
591019
|
try {
|
|
590739
591020
|
execSync50(
|
|
590740
591021
|
`"${venvPython2}" "${dequantScript}" --input "${weightPath}" --output "${cachedBf16}"`,
|
|
590741
|
-
{ timeout: 3e5, stdio: "pipe" }
|
|
591022
|
+
{ timeout: 3e5, stdio: "pipe", env: personaplexPythonEnv() }
|
|
590742
591023
|
);
|
|
590743
591024
|
if (existsSync99(cachedBf16)) {
|
|
590744
591025
|
extraArgs.push("--moshi-weight", cachedBf16);
|
|
@@ -590751,7 +591032,7 @@ print('Converted')
|
|
|
590751
591032
|
try {
|
|
590752
591033
|
const mimiPath = execSync50(
|
|
590753
591034
|
`"${venvPython2}" -c "from huggingface_hub import hf_hub_download; print(hf_hub_download('${repoInfo.repo}', 'tokenizer-e351c8d8-checkpoint125.safetensors', token=False))"`,
|
|
590754
|
-
{ encoding: "utf8", timeout: 3e4, stdio: "pipe" }
|
|
591035
|
+
{ encoding: "utf8", timeout: 3e4, stdio: "pipe", env: personaplexPythonEnv() }
|
|
590755
591036
|
).trim();
|
|
590756
591037
|
if (existsSync99(mimiPath)) extraArgs.push("--mimi-weight", mimiPath);
|
|
590757
591038
|
} catch {
|
|
@@ -590759,7 +591040,7 @@ print('Converted')
|
|
|
590759
591040
|
try {
|
|
590760
591041
|
const tokPath = execSync50(
|
|
590761
591042
|
`"${venvPython2}" -c "from huggingface_hub import hf_hub_download; print(hf_hub_download('${repoInfo.repo}', 'tokenizer_spm_32k_3.model', token=False))"`,
|
|
590762
|
-
{ encoding: "utf8", timeout: 3e4, stdio: "pipe" }
|
|
591043
|
+
{ encoding: "utf8", timeout: 3e4, stdio: "pipe", env: personaplexPythonEnv() }
|
|
590763
591044
|
).trim();
|
|
590764
591045
|
if (existsSync99(tokPath)) extraArgs.push("--tokenizer", tokPath);
|
|
590765
591046
|
} catch {
|
|
@@ -590814,7 +591095,7 @@ print('Converted')
|
|
|
590814
591095
|
];
|
|
590815
591096
|
if (hybridEnabled) serverArgs.push("--hybrid");
|
|
590816
591097
|
if (needsOffload) serverArgs.push("--cpu-offload");
|
|
590817
|
-
const serverEnv =
|
|
591098
|
+
const serverEnv = personaplexPythonEnv();
|
|
590818
591099
|
if (hybridEnabled) {
|
|
590819
591100
|
serverEnv["HYBRID_ENABLED"] = "1";
|
|
590820
591101
|
serverEnv["HYBRID_LLM_MODEL"] = ollamaModel;
|
|
@@ -590959,7 +591240,7 @@ async function clonePersonaPlexVoice(inputWav, voiceName, onInfo) {
|
|
|
590959
591240
|
"cuda"
|
|
590960
591241
|
], {
|
|
590961
591242
|
stdio: ["ignore", "pipe", "pipe"],
|
|
590962
|
-
env:
|
|
591243
|
+
env: personaplexPythonEnv(),
|
|
590963
591244
|
cwd: PERSONAPLEX_DIR
|
|
590964
591245
|
});
|
|
590965
591246
|
let output = "";
|
|
@@ -591135,6 +591416,7 @@ var init_personaplex = __esm({
|
|
|
591135
591416
|
init_render();
|
|
591136
591417
|
init_daemon_registry();
|
|
591137
591418
|
init_typed_node_events();
|
|
591419
|
+
init_dist5();
|
|
591138
591420
|
WEIGHT_REPOS = {
|
|
591139
591421
|
original: { repo: "nvidia/personaplex-7b-v1", file: "model.safetensors", sizeGB: 15.6, needsToken: true },
|
|
591140
591422
|
nf4: { repo: "cudabenchmarktest/personaplex-7b-nf4", file: "model-nf4.safetensors", sizeGB: 4.1, needsToken: false },
|
|
@@ -599715,6 +599997,11 @@ import {
|
|
|
599715
599997
|
spawn as nodeSpawn
|
|
599716
599998
|
} from "node:child_process";
|
|
599717
599999
|
import { createRequire as createRequire6 } from "node:module";
|
|
600000
|
+
function voicePythonEnv(extra = {}) {
|
|
600001
|
+
const env2 = { ...process.env, ...extra };
|
|
600002
|
+
applyMediaCudaDeviceFilterToEnv(env2, "tts");
|
|
600003
|
+
return env2;
|
|
600004
|
+
}
|
|
599718
600005
|
function sanitizeForTTS(text) {
|
|
599719
600006
|
return text.replace(/^#{1,6}\s+/gm, "").replace(/\*{1,3}([^*]+)\*{1,3}/g, "$1").replace(/_{1,3}([^_]+)_{1,3}/g, "$1").replace(/~~([^~]+)~~/g, "$1").replace(/`([^`]+)`/g, "$1").replace(/```[\s\S]*?```/g, "").replace(/\[([^\]]+)\]\([^)]+\)/g, "$1").replace(/!\[([^\]]*)\]\([^)]+\)/g, "$1").replace(/^[\s]*[-*+]\s+/gm, "").replace(/^[\s]*\d+\.\s+/gm, "").replace(/^>\s+/gm, "").replace(/^[-*_]{3,}$/gm, "").replace(/\[[ xX]\]\s*/g, "").replace(/[\u{1F600}-\u{1F64F}]/gu, "").replace(/[\u{1F300}-\u{1F5FF}]/gu, "").replace(/[\u{1F680}-\u{1F6FF}]/gu, "").replace(/[\u{1F1E0}-\u{1F1FF}]/gu, "").replace(/[\u{2600}-\u{26FF}]/gu, "").replace(/[\u{2700}-\u{27BF}]/gu, "").replace(/[\u{FE00}-\u{FE0F}]/gu, "").replace(/[\u{1F900}-\u{1F9FF}]/gu, "").replace(/[\u{1FA00}-\u{1FA6F}]/gu, "").replace(/[\u{1FA70}-\u{1FAFF}]/gu, "").replace(/[\u{200D}]/gu, "").replace(/[\u{20E3}]/gu, "").replace(/[✓✔✗✘✕✖⚠️⏸⏹⏵●○◆◇■□▪▫►▼▲◀⬆⬇⬅➡↑↓←→⇐⇒⇑⇓]/g, "").replace(/[─━│┃┌┐└┘├┤┬┴┼╔╗╚╝╠╣╦╩╬⎿⎾▕▏⏐░▒▓█⠀-⣿]/g, "").replace(/\s{2,}/g, " ").trim();
|
|
599720
600007
|
}
|
|
@@ -600620,6 +600907,7 @@ var init_voice = __esm({
|
|
|
600620
600907
|
init_typed_node_events();
|
|
600621
600908
|
init_render();
|
|
600622
600909
|
init_daemon_registry();
|
|
600910
|
+
init_dist5();
|
|
600623
600911
|
VOICE_MODELS = {
|
|
600624
600912
|
glados: {
|
|
600625
600913
|
id: "glados",
|
|
@@ -602134,7 +602422,8 @@ except Exception as exc:
|
|
|
602134
602422
|
return new Promise((resolve59, reject) => {
|
|
602135
602423
|
const proc = nodeSpawn("sh", ["-c", command], {
|
|
602136
602424
|
stdio: ["ignore", "pipe", "pipe"],
|
|
602137
|
-
cwd: tmpdir20()
|
|
602425
|
+
cwd: tmpdir20(),
|
|
602426
|
+
env: voicePythonEnv()
|
|
602138
602427
|
});
|
|
602139
602428
|
let stdout = "";
|
|
602140
602429
|
let stderr = "";
|
|
@@ -602909,7 +603198,7 @@ if __name__ == '__main__':
|
|
|
602909
603198
|
const venvPy = luxttsVenvPy2();
|
|
602910
603199
|
if (!existsSync109(venvPy)) return false;
|
|
602911
603200
|
return new Promise((resolve59) => {
|
|
602912
|
-
const env2 = {
|
|
603201
|
+
const env2 = voicePythonEnv({ LUXTTS_REPO_PATH: luxttsRepoDir2() });
|
|
602913
603202
|
const daemon = nodeSpawn(venvPy, [luxttsInferScript2()], {
|
|
602914
603203
|
stdio: ["pipe", "pipe", "pipe"],
|
|
602915
603204
|
cwd: tmpdir20(),
|
|
@@ -625604,6 +625893,146 @@ var init_telegram_stats_menu = __esm({
|
|
|
625604
625893
|
}
|
|
625605
625894
|
});
|
|
625606
625895
|
|
|
625896
|
+
// packages/cli/src/tui/telegram-command-menu.ts
|
|
625897
|
+
function isBareTelegramGenerativeCommand(input) {
|
|
625898
|
+
const trimmed = input.trim();
|
|
625899
|
+
if (!trimmed.startsWith("/")) return false;
|
|
625900
|
+
const parts = trimmed.split(/\s+/);
|
|
625901
|
+
const name10 = (parts[0] ?? "").slice(1).split("@")[0]?.toLowerCase() ?? "";
|
|
625902
|
+
return parts.length === 1 && GENERATIVE_COMMANDS.has(name10);
|
|
625903
|
+
}
|
|
625904
|
+
function buildTelegramCommandMenuItems(scope) {
|
|
625905
|
+
const commands = listCommandRegistry({ includePlanned: false }).filter((cmd) => cmd.implementationStatus === "implemented").filter((cmd) => scope === "admin" || ["help", "start"].includes(cmd.name));
|
|
625906
|
+
const seen = /* @__PURE__ */ new Set();
|
|
625907
|
+
const items = [];
|
|
625908
|
+
for (const cmd of commands) {
|
|
625909
|
+
const signature = cmd.signatures[0]?.signature;
|
|
625910
|
+
if (!signature || seen.has(cmd.name)) continue;
|
|
625911
|
+
seen.add(cmd.name);
|
|
625912
|
+
items.push({
|
|
625913
|
+
label: `/${cmd.name}`,
|
|
625914
|
+
command: `/${cmd.name}`,
|
|
625915
|
+
description: cmd.signatures[0]?.description ?? signature,
|
|
625916
|
+
adminOnly: scope === "admin"
|
|
625917
|
+
});
|
|
625918
|
+
}
|
|
625919
|
+
return items.sort((a2, b) => a2.label.localeCompare(b.label));
|
|
625920
|
+
}
|
|
625921
|
+
function buildTelegramGenerativeMenuItems(commandName) {
|
|
625922
|
+
const name10 = commandName.replace(/^\//, "").toLowerCase();
|
|
625923
|
+
if (!GENERATIVE_COMMANDS.has(name10)) return [];
|
|
625924
|
+
const title = name10[0].toUpperCase() + name10.slice(1);
|
|
625925
|
+
return [
|
|
625926
|
+
{ label: `${title} models`, command: `/${name10} list`, description: `List available ${name10} models and hardware fit.` },
|
|
625927
|
+
{ label: `${title} setup`, command: `/${name10} setup`, description: `Show setup commands for the ${name10} backend.` }
|
|
625928
|
+
];
|
|
625929
|
+
}
|
|
625930
|
+
function encodeTelegramCommandMenuCallback(action, value2) {
|
|
625931
|
+
const data = `${CALLBACK_PREFIX2}:${action[0]}:${value2}`;
|
|
625932
|
+
return Buffer.byteLength(data, "utf8") <= MAX_CALLBACK_DATA_BYTES ? data : data.slice(0, MAX_CALLBACK_DATA_BYTES);
|
|
625933
|
+
}
|
|
625934
|
+
function decodeTelegramCommandMenuCallback(data) {
|
|
625935
|
+
const parts = data.split(":");
|
|
625936
|
+
if (parts.length !== 3 || parts[0] !== CALLBACK_PREFIX2) return null;
|
|
625937
|
+
const action = parts[1] === "p" ? "page" : parts[1] === "r" ? "run" : parts[1] === "c" ? "close" : null;
|
|
625938
|
+
if (!action) return null;
|
|
625939
|
+
return { action, value: parts[2] ?? "" };
|
|
625940
|
+
}
|
|
625941
|
+
function renderTelegramCommandMenu(state) {
|
|
625942
|
+
const totalPages = Math.max(1, Math.ceil(state.items.length / PAGE_SIZE2));
|
|
625943
|
+
const page2 = Math.max(0, Math.min(state.page, totalPages - 1));
|
|
625944
|
+
const start2 = page2 * PAGE_SIZE2;
|
|
625945
|
+
const visible = state.items.slice(start2, start2 + PAGE_SIZE2);
|
|
625946
|
+
const title = state.kind === "generative" ? "Generative command" : "Commands";
|
|
625947
|
+
const scope = state.scope === "admin" ? "admin" : "public";
|
|
625948
|
+
const lines = [
|
|
625949
|
+
`<b>${escapeHTML3(title)}</b>`,
|
|
625950
|
+
`<i>${escapeHTML3(scope)} scope - page ${page2 + 1}/${totalPages}</i>`,
|
|
625951
|
+
"",
|
|
625952
|
+
...visible.flatMap((item) => [
|
|
625953
|
+
`<code>${escapeHTML3(item.command)}</code>`,
|
|
625954
|
+
escapeHTML3(item.description)
|
|
625955
|
+
])
|
|
625956
|
+
];
|
|
625957
|
+
const keyboard = visible.map((item, offset) => [{
|
|
625958
|
+
text: item.label.slice(0, 32),
|
|
625959
|
+
callback_data: encodeTelegramCommandMenuCallback("run", start2 + offset)
|
|
625960
|
+
}]);
|
|
625961
|
+
const nav = [];
|
|
625962
|
+
nav.push({ text: "Close", callback_data: encodeTelegramCommandMenuCallback("close", 0) });
|
|
625963
|
+
if (page2 > 0) nav.push({ text: "Prev", callback_data: encodeTelegramCommandMenuCallback("page", page2 - 1) });
|
|
625964
|
+
nav.push({ text: `${page2 + 1}/${totalPages}`, callback_data: encodeTelegramCommandMenuCallback("page", page2) });
|
|
625965
|
+
if (page2 < totalPages - 1) nav.push({ text: "Next", callback_data: encodeTelegramCommandMenuCallback("page", page2 + 1) });
|
|
625966
|
+
keyboard.push(nav);
|
|
625967
|
+
return { text: lines.join("\n"), reply_markup: { inline_keyboard: keyboard } };
|
|
625968
|
+
}
|
|
625969
|
+
function handleTelegramCommandMenuCallback(data, state, now = Date.now()) {
|
|
625970
|
+
const decoded = decodeTelegramCommandMenuCallback(data);
|
|
625971
|
+
if (!decoded) return null;
|
|
625972
|
+
if (state.expiresAt <= now) return null;
|
|
625973
|
+
if (decoded.action === "close") return { close: true };
|
|
625974
|
+
if (decoded.action === "page") {
|
|
625975
|
+
const totalPages = Math.max(1, Math.ceil(state.items.length / PAGE_SIZE2));
|
|
625976
|
+
const page2 = Math.max(0, Math.min(Number.parseInt(decoded.value, 10) || 0, totalPages - 1));
|
|
625977
|
+
const newState = { ...state, page: page2 };
|
|
625978
|
+
return { newState, render: renderTelegramCommandMenu(newState) };
|
|
625979
|
+
}
|
|
625980
|
+
const index = Number.parseInt(decoded.value, 10);
|
|
625981
|
+
const item = Number.isFinite(index) ? state.items[index] : void 0;
|
|
625982
|
+
return item ? { command: item.command } : null;
|
|
625983
|
+
}
|
|
625984
|
+
function escapeHTML3(text) {
|
|
625985
|
+
return text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
625986
|
+
}
|
|
625987
|
+
var CALLBACK_PREFIX2, PAGE_SIZE2, TTL_MS, MAX_CALLBACK_DATA_BYTES, GENERATIVE_COMMANDS, TelegramCommandMenuStateStore;
|
|
625988
|
+
var init_telegram_command_menu = __esm({
|
|
625989
|
+
"packages/cli/src/tui/telegram-command-menu.ts"() {
|
|
625990
|
+
"use strict";
|
|
625991
|
+
init_command_registry();
|
|
625992
|
+
CALLBACK_PREFIX2 = "ocm";
|
|
625993
|
+
PAGE_SIZE2 = 8;
|
|
625994
|
+
TTL_MS = 10 * 60 * 1e3;
|
|
625995
|
+
MAX_CALLBACK_DATA_BYTES = 64;
|
|
625996
|
+
GENERATIVE_COMMANDS = /* @__PURE__ */ new Set(["image", "video", "sound", "music"]);
|
|
625997
|
+
TelegramCommandMenuStateStore = class {
|
|
625998
|
+
states = /* @__PURE__ */ new Map();
|
|
625999
|
+
key(chatId, messageId) {
|
|
626000
|
+
return `${chatId}:${messageId}`;
|
|
626001
|
+
}
|
|
626002
|
+
create(input, now = Date.now()) {
|
|
626003
|
+
return {
|
|
626004
|
+
...input,
|
|
626005
|
+
createdAt: now,
|
|
626006
|
+
expiresAt: now + TTL_MS
|
|
626007
|
+
};
|
|
626008
|
+
}
|
|
626009
|
+
set(state) {
|
|
626010
|
+
this.states.set(this.key(state.chatId, state.messageId), state);
|
|
626011
|
+
}
|
|
626012
|
+
get(chatId, messageId, now = Date.now()) {
|
|
626013
|
+
const state = this.states.get(this.key(chatId, messageId));
|
|
626014
|
+
if (!state) return void 0;
|
|
626015
|
+
if (state.expiresAt <= now) {
|
|
626016
|
+
this.delete(chatId, messageId);
|
|
626017
|
+
return void 0;
|
|
626018
|
+
}
|
|
626019
|
+
return state;
|
|
626020
|
+
}
|
|
626021
|
+
delete(chatId, messageId) {
|
|
626022
|
+
this.states.delete(this.key(chatId, messageId));
|
|
626023
|
+
}
|
|
626024
|
+
prune(now = Date.now()) {
|
|
626025
|
+
for (const [key, state] of this.states) {
|
|
626026
|
+
if (state.expiresAt <= now) this.states.delete(key);
|
|
626027
|
+
}
|
|
626028
|
+
}
|
|
626029
|
+
clear() {
|
|
626030
|
+
this.states.clear();
|
|
626031
|
+
}
|
|
626032
|
+
};
|
|
626033
|
+
}
|
|
626034
|
+
});
|
|
626035
|
+
|
|
625607
626036
|
// packages/cli/src/tui/telegram-creative-tools.ts
|
|
625608
626037
|
import { createCipheriv as createCipheriv4, createDecipheriv as createDecipheriv4, randomBytes as randomBytes23 } from "node:crypto";
|
|
625609
626038
|
import {
|
|
@@ -630996,6 +631425,7 @@ var init_telegram_bridge = __esm({
|
|
|
630996
631425
|
init_command_registry();
|
|
630997
631426
|
init_telegram_help_menu();
|
|
630998
631427
|
init_telegram_stats_menu();
|
|
631428
|
+
init_telegram_command_menu();
|
|
630999
631429
|
init_scoped_personality();
|
|
631000
631430
|
init_voice_soul();
|
|
631001
631431
|
init_telegram_creative_tools();
|
|
@@ -631606,6 +632036,8 @@ Telegram link integrity contract:
|
|
|
631606
632036
|
statsMenuTimers = null;
|
|
631607
632037
|
/** Prune expired stats menu states every 5 minutes */
|
|
631608
632038
|
statsMenuPruneTimer = null;
|
|
632039
|
+
/** Telegram-native command and generative command menus */
|
|
632040
|
+
telegramCommandMenuStates = new TelegramCommandMenuStateStore();
|
|
631609
632041
|
/** Command handler for admin DM slash commands (wired from interactive.ts) */
|
|
631610
632042
|
commandHandler = null;
|
|
631611
632043
|
/** Callback fired after a Telegram user completes the TUI-only admin auth challenge */
|
|
@@ -631938,6 +632370,10 @@ Telegram link integrity contract:
|
|
|
631938
632370
|
const name10 = this.telegramSlashName(input);
|
|
631939
632371
|
return name10 === "help" || name10 === "h" || name10 === "commands" || name10 === "cmds";
|
|
631940
632372
|
}
|
|
632373
|
+
isTelegramCommandsMenuCommand(input) {
|
|
632374
|
+
const name10 = this.telegramSlashName(input);
|
|
632375
|
+
return name10 === "commands" || name10 === "cmds";
|
|
632376
|
+
}
|
|
631941
632377
|
isTelegramStatsCommand(input) {
|
|
631942
632378
|
const name10 = this.telegramSlashName(input);
|
|
631943
632379
|
return name10 === "stats" || name10 === "metrics";
|
|
@@ -632531,6 +632967,49 @@ ${message2}`)
|
|
|
632531
632967
|
this.helpMenuTimers.startTimer(state);
|
|
632532
632968
|
}
|
|
632533
632969
|
}
|
|
632970
|
+
async replyWithTelegramCommandMenu(msg, isAdmin, kind, commandName) {
|
|
632971
|
+
const scope = isAdmin ? "admin" : "public";
|
|
632972
|
+
const items = kind === "generative" ? buildTelegramGenerativeMenuItems(commandName ?? "") : buildTelegramCommandMenuItems(scope);
|
|
632973
|
+
if (items.length === 0) {
|
|
632974
|
+
await this.replyToTelegramMessage(msg, "No Telegram command menu entries are available.");
|
|
632975
|
+
return;
|
|
632976
|
+
}
|
|
632977
|
+
if (msg.guestQueryId || !isAdmin) {
|
|
632978
|
+
const lines = items.slice(0, 24).map((item) => `${item.command} - ${item.description}`);
|
|
632979
|
+
const text = ["Available commands:", "", ...lines].join("\n");
|
|
632980
|
+
if (msg.guestQueryId) {
|
|
632981
|
+
await this.answerGuestQuery(msg.guestQueryId, text);
|
|
632982
|
+
} else {
|
|
632983
|
+
await this.replyToTelegramMessage(msg, text);
|
|
632984
|
+
}
|
|
632985
|
+
return;
|
|
632986
|
+
}
|
|
632987
|
+
const previewState = this.telegramCommandMenuStates.create({
|
|
632988
|
+
chatId: msg.chatId,
|
|
632989
|
+
messageId: 0,
|
|
632990
|
+
invokerMessageId: msg.messageId,
|
|
632991
|
+
fromUserId: msg.fromUserId ?? 0,
|
|
632992
|
+
scope,
|
|
632993
|
+
kind,
|
|
632994
|
+
page: 0,
|
|
632995
|
+
items
|
|
632996
|
+
});
|
|
632997
|
+
const menu = renderTelegramCommandMenu(previewState);
|
|
632998
|
+
const sent = await this.apiCall("sendMessage", {
|
|
632999
|
+
chat_id: msg.chatId,
|
|
633000
|
+
text: menu.text,
|
|
633001
|
+
parse_mode: "HTML",
|
|
633002
|
+
reply_markup: JSON.stringify(menu.reply_markup),
|
|
633003
|
+
...msg.chatType !== "private" ? { reply_to_message_id: msg.messageId } : {}
|
|
633004
|
+
});
|
|
633005
|
+
if (sent.ok && sent.result?.message_id) {
|
|
633006
|
+
this.telegramCommandMenuStates.prune();
|
|
633007
|
+
this.telegramCommandMenuStates.set({
|
|
633008
|
+
...previewState,
|
|
633009
|
+
messageId: sent.result.message_id
|
|
633010
|
+
});
|
|
633011
|
+
}
|
|
633012
|
+
}
|
|
632534
633013
|
collectSessionMetricsSnapshot() {
|
|
632535
633014
|
if (this._metricsProvider) {
|
|
632536
633015
|
try {
|
|
@@ -637339,6 +637818,7 @@ ${TELEGRAM_PUBLIC_ORCHESTRATOR_CONTRACT}`);
|
|
|
637339
637818
|
this.telegramActiveWorkGenerations.clear();
|
|
637340
637819
|
this.telegramActiveWorkStartedAtMs.clear();
|
|
637341
637820
|
this.telegramAdminLivePanels.clear();
|
|
637821
|
+
this.telegramCommandMenuStates.clear();
|
|
637342
637822
|
this.flushTelegramViewWrites();
|
|
637343
637823
|
this.flushTelegramTuiWrites();
|
|
637344
637824
|
this.telegramActiveInferences.clear();
|
|
@@ -637717,6 +638197,10 @@ ${summary}` : ""
|
|
|
637717
638197
|
return;
|
|
637718
638198
|
}
|
|
637719
638199
|
const isAdmin = this.isAdminUser(msg);
|
|
638200
|
+
if (msg.text.trim().startsWith("/") && this.isTelegramCommandsMenuCommand(normalizedCommandText)) {
|
|
638201
|
+
await this.replyWithTelegramCommandMenu(msg, isAdmin, "commands");
|
|
638202
|
+
return;
|
|
638203
|
+
}
|
|
637720
638204
|
if (msg.text.trim().startsWith("/") && this.isTelegramHelpCommand(normalizedCommandText)) {
|
|
637721
638205
|
await this.replyWithTelegramHelp(msg, isAdmin);
|
|
637722
638206
|
return;
|
|
@@ -637751,6 +638235,10 @@ ${summary}` : ""
|
|
|
637751
638235
|
const toolContext = this.resolveToolContext(msg, isAdmin);
|
|
637752
638236
|
const isAdminDM = toolContext === "telegram-admin-dm";
|
|
637753
638237
|
const sessionKey = this.sessionKeyForMessage(msg);
|
|
638238
|
+
if (isAdminDM && isBareTelegramGenerativeCommand(normalizedCommandText)) {
|
|
638239
|
+
await this.replyWithTelegramCommandMenu(msg, isAdmin, "generative", telegramSlash);
|
|
638240
|
+
return;
|
|
638241
|
+
}
|
|
637754
638242
|
if (msg.text.trim().startsWith("/") && TELEGRAM_REMINDER_SLASH_COMMANDS.has(telegramSlash)) {
|
|
637755
638243
|
await this.handleTelegramReminderSlash(msg, normalizedCommandText, toolContext);
|
|
637756
638244
|
return;
|
|
@@ -640485,6 +640973,90 @@ Scoped workspace: ${scopedRoot}`,
|
|
|
640485
640973
|
return Boolean(result.ok);
|
|
640486
640974
|
}
|
|
640487
640975
|
async handleTelegramCallbackQuery(callback) {
|
|
640976
|
+
const commandMenuDecoded = decodeTelegramCommandMenuCallback(callback.data);
|
|
640977
|
+
if (commandMenuDecoded) {
|
|
640978
|
+
let answerText2 = "";
|
|
640979
|
+
let alert2 = false;
|
|
640980
|
+
let answered = false;
|
|
640981
|
+
try {
|
|
640982
|
+
const chatId = callback.chatId;
|
|
640983
|
+
const messageId = callback.messageId;
|
|
640984
|
+
if (!chatId || !messageId) {
|
|
640985
|
+
answerText2 = "Cannot identify menu message.";
|
|
640986
|
+
alert2 = true;
|
|
640987
|
+
return;
|
|
640988
|
+
}
|
|
640989
|
+
const menuState = this.telegramCommandMenuStates.get(chatId, messageId);
|
|
640990
|
+
if (!menuState) {
|
|
640991
|
+
answerText2 = "This command menu expired. Send /commands for a fresh one.";
|
|
640992
|
+
alert2 = true;
|
|
640993
|
+
return;
|
|
640994
|
+
}
|
|
640995
|
+
const isAdmin = this.isAdminActor(callback.fromUserId, callback.username);
|
|
640996
|
+
if (callback.fromUserId !== menuState.fromUserId && !isAdmin) {
|
|
640997
|
+
answerText2 = "Only the user who opened this menu can use it.";
|
|
640998
|
+
alert2 = true;
|
|
640999
|
+
return;
|
|
641000
|
+
}
|
|
641001
|
+
if (!isAdmin) {
|
|
641002
|
+
answerText2 = "That command requires Telegram admin authentication.";
|
|
641003
|
+
alert2 = true;
|
|
641004
|
+
return;
|
|
641005
|
+
}
|
|
641006
|
+
const result = handleTelegramCommandMenuCallback(callback.data, menuState);
|
|
641007
|
+
if (!result) {
|
|
641008
|
+
answerText2 = "Unknown or expired command menu action.";
|
|
641009
|
+
alert2 = true;
|
|
641010
|
+
return;
|
|
641011
|
+
}
|
|
641012
|
+
if (result.close) {
|
|
641013
|
+
this.telegramCommandMenuStates.delete(chatId, messageId);
|
|
641014
|
+
await this.apiCall("deleteMessage", { chat_id: chatId, message_id: messageId }).catch(() => {
|
|
641015
|
+
});
|
|
641016
|
+
if (menuState.invokerMessageId) {
|
|
641017
|
+
await this.apiCall("deleteMessage", { chat_id: chatId, message_id: menuState.invokerMessageId }).catch(() => {
|
|
641018
|
+
});
|
|
641019
|
+
}
|
|
641020
|
+
answered = await this.answerCallbackQuery(callback.id).catch(() => false);
|
|
641021
|
+
return;
|
|
641022
|
+
}
|
|
641023
|
+
if (result.render && result.newState) {
|
|
641024
|
+
this.telegramCommandMenuStates.set(result.newState);
|
|
641025
|
+
await this.apiCall("editMessageText", {
|
|
641026
|
+
chat_id: chatId,
|
|
641027
|
+
message_id: messageId,
|
|
641028
|
+
text: result.render.text,
|
|
641029
|
+
parse_mode: "HTML",
|
|
641030
|
+
reply_markup: JSON.stringify(result.render.reply_markup)
|
|
641031
|
+
});
|
|
641032
|
+
return;
|
|
641033
|
+
}
|
|
641034
|
+
if (result.command) {
|
|
641035
|
+
if (!this.commandHandler) {
|
|
641036
|
+
answerText2 = "No command handler is available.";
|
|
641037
|
+
alert2 = true;
|
|
641038
|
+
return;
|
|
641039
|
+
}
|
|
641040
|
+
answered = await this.answerCallbackQuery(callback.id, `Running ${result.command}...`).catch(() => false);
|
|
641041
|
+
const output = await this.commandHandler(result.command);
|
|
641042
|
+
if (output) {
|
|
641043
|
+
await this.sendMessageHTML(chatId, convertMarkdownToTelegramHTML(output));
|
|
641044
|
+
}
|
|
641045
|
+
return;
|
|
641046
|
+
}
|
|
641047
|
+
} catch (err) {
|
|
641048
|
+
answerText2 = err instanceof Error ? err.message : String(err);
|
|
641049
|
+
alert2 = true;
|
|
641050
|
+
} finally {
|
|
641051
|
+
if (answered) {
|
|
641052
|
+
} else if (answerText2) {
|
|
641053
|
+
await this.answerCallbackQuery(callback.id, answerText2.slice(0, 180), alert2).catch(() => false);
|
|
641054
|
+
} else {
|
|
641055
|
+
await this.answerCallbackQuery(callback.id).catch(() => false);
|
|
641056
|
+
}
|
|
641057
|
+
}
|
|
641058
|
+
return;
|
|
641059
|
+
}
|
|
640488
641060
|
const helpDecoded = decodeHelpCallback(callback.data);
|
|
640489
641061
|
if (helpDecoded) {
|
|
640490
641062
|
let answerText2 = "";
|
|
@@ -673904,14 +674476,24 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
673904
674476
|
telegramBridge.setCommandHandler(async (input) => {
|
|
673905
674477
|
const captured = [];
|
|
673906
674478
|
const origWrite = process.stdout.write;
|
|
673907
|
-
process.stdout.write = function(chunk, ...
|
|
674479
|
+
process.stdout.write = function(chunk, ...args) {
|
|
673908
674480
|
if (typeof chunk === "string") {
|
|
673909
674481
|
captured.push(chunk);
|
|
674482
|
+
} else if (Buffer.isBuffer(chunk)) {
|
|
674483
|
+
captured.push(chunk.toString("utf8"));
|
|
673910
674484
|
}
|
|
674485
|
+
const cb = args.find((arg) => typeof arg === "function");
|
|
674486
|
+
if (cb) cb();
|
|
673911
674487
|
return true;
|
|
673912
674488
|
};
|
|
673913
674489
|
try {
|
|
673914
|
-
const result = await
|
|
674490
|
+
const result = await runWithNonInteractiveSelectSurface(
|
|
674491
|
+
() => handleSlashCommand(input, commandCtx),
|
|
674492
|
+
{
|
|
674493
|
+
maxItems: 24,
|
|
674494
|
+
hint: "(Telegram: interactive menu shown as text; use concrete slash arguments or open the TUI to select)"
|
|
674495
|
+
}
|
|
674496
|
+
);
|
|
673915
674497
|
process.stdout.write = origWrite;
|
|
673916
674498
|
if (statusBar.isActive) statusBar.handleResize();
|
|
673917
674499
|
if (result === "exit") {
|
|
@@ -673925,7 +674507,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
673925
674507
|
return `Skill invoked: ${result.name}`;
|
|
673926
674508
|
}
|
|
673927
674509
|
const raw = captured.join("");
|
|
673928
|
-
const clean5 = raw.replace(/\x1B
|
|
674510
|
+
const clean5 = raw.replace(/\x1B(?:\[[\d;?]*[ -/]*[@-~]|\][^\x07\x1B]*(?:\x07|\x1B\\)?|[@-Z\\-_])/g, "").replace(/\x1B/g, "").replace(/[─━│┃┌┐└┘├┤┬┴┼╔╗╚╝╠╣╦╩╬⎿⎾▕▏⏐]/g, "").replace(/\n{3,}/g, "\n\n").trim();
|
|
673929
674511
|
if (!clean5) return null;
|
|
673930
674512
|
return clean5.length > 3900 ? clean5.slice(0, 3900) + "\n..." : clean5;
|
|
673931
674513
|
} catch (err) {
|