omnius 1.0.18 → 1.0.19
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 +199 -34
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -84452,7 +84452,7 @@ var require_mime_types = __commonJS({
|
|
|
84452
84452
|
"../node_modules/mime-types/index.js"(exports) {
|
|
84453
84453
|
"use strict";
|
|
84454
84454
|
var db = require_mime_db();
|
|
84455
|
-
var
|
|
84455
|
+
var extname16 = __require("path").extname;
|
|
84456
84456
|
var EXTRACT_TYPE_REGEXP = /^\s*([^;\s]*)(?:;|\s|$)/;
|
|
84457
84457
|
var TEXT_TYPE_REGEXP = /^text\//i;
|
|
84458
84458
|
exports.charset = charset;
|
|
@@ -84506,7 +84506,7 @@ var require_mime_types = __commonJS({
|
|
|
84506
84506
|
if (!path11 || typeof path11 !== "string") {
|
|
84507
84507
|
return false;
|
|
84508
84508
|
}
|
|
84509
|
-
var extension4 =
|
|
84509
|
+
var extension4 = extname16("x." + path11).toLowerCase().substr(1);
|
|
84510
84510
|
if (!extension4) {
|
|
84511
84511
|
return false;
|
|
84512
84512
|
}
|
|
@@ -477005,7 +477005,7 @@ var require_path_browserify = __commonJS({
|
|
|
477005
477005
|
return path11.slice(start2, end);
|
|
477006
477006
|
}
|
|
477007
477007
|
},
|
|
477008
|
-
extname: function
|
|
477008
|
+
extname: function extname16(path11) {
|
|
477009
477009
|
assertPath(path11);
|
|
477010
477010
|
var startDot = -1;
|
|
477011
477011
|
var startPart = 0;
|
|
@@ -507302,12 +507302,23 @@ function ensureGeneratedVoiceDir() {
|
|
|
507302
507302
|
mkdirSync16(generatedVoiceDir(), { recursive: true });
|
|
507303
507303
|
}
|
|
507304
507304
|
function ttsOutputPath(args, backend) {
|
|
507305
|
-
const
|
|
507306
|
-
|
|
507307
|
-
|
|
507305
|
+
for (const key of ["output", "output_path", "path", "file_path", "file"]) {
|
|
507306
|
+
const output = args[key];
|
|
507307
|
+
if (typeof output === "string" && output.trim()) {
|
|
507308
|
+
return resolvePath(output.trim());
|
|
507309
|
+
}
|
|
507310
|
+
}
|
|
507308
507311
|
ensureGeneratedVoiceDir();
|
|
507309
507312
|
return join58(generatedVoiceDir(), `tts-${backend}-${Date.now()}-${Math.random().toString(36).slice(2, 7)}.wav`);
|
|
507310
507313
|
}
|
|
507314
|
+
function ttsTextArg(args) {
|
|
507315
|
+
for (const key of ["text", "input", "prompt", "content", "message"]) {
|
|
507316
|
+
const value2 = args[key];
|
|
507317
|
+
if (typeof value2 === "string" && value2.trim())
|
|
507318
|
+
return value2.trim();
|
|
507319
|
+
}
|
|
507320
|
+
return "";
|
|
507321
|
+
}
|
|
507311
507322
|
function listCloneRefs() {
|
|
507312
507323
|
try {
|
|
507313
507324
|
return readdirSync14(cloneRefsDir()).filter((file) => /\.(wav|mp3|flac|ogg|m4a)$/i.test(file) && existsSync40(join58(cloneRefsDir(), file))).sort((a2, b) => a2.localeCompare(b));
|
|
@@ -507348,6 +507359,12 @@ function supertonicInferScript() {
|
|
|
507348
507359
|
function mlxVenvPy() {
|
|
507349
507360
|
return process.platform === "win32" ? join58(voiceDir(), "mlx-venv", "Scripts", "python.exe") : join58(voiceDir(), "mlx-venv", "bin", "python3");
|
|
507350
507361
|
}
|
|
507362
|
+
function piperVenvDir() {
|
|
507363
|
+
return join58(voiceDir(), "piper-venv");
|
|
507364
|
+
}
|
|
507365
|
+
function piperVenvBin() {
|
|
507366
|
+
return process.platform === "win32" ? join58(piperVenvDir(), "Scripts", "piper.exe") : join58(piperVenvDir(), "bin", "piper");
|
|
507367
|
+
}
|
|
507351
507368
|
function ensureSupertonicInstalled() {
|
|
507352
507369
|
const venvPy = supertonicVenvPy();
|
|
507353
507370
|
if (!existsSync40(venvPy)) {
|
|
@@ -507385,6 +507402,25 @@ function ensureMlxInstalled() {
|
|
|
507385
507402
|
}
|
|
507386
507403
|
return venvPy;
|
|
507387
507404
|
}
|
|
507405
|
+
function ensurePiperInstalled() {
|
|
507406
|
+
if (hasCommand3("piper"))
|
|
507407
|
+
return "piper";
|
|
507408
|
+
const bin = piperVenvBin();
|
|
507409
|
+
if (!existsSync40(bin)) {
|
|
507410
|
+
const py = findPython32();
|
|
507411
|
+
if (!py)
|
|
507412
|
+
throw new Error("python3 is required to set up Piper TTS.");
|
|
507413
|
+
mkdirSync16(voiceDir(), { recursive: true });
|
|
507414
|
+
execFileSync2(py, ["-m", "venv", piperVenvDir()], { stdio: "pipe", timeout: 18e4 });
|
|
507415
|
+
const venvPy = process.platform === "win32" ? join58(piperVenvDir(), "Scripts", "python.exe") : join58(piperVenvDir(), "bin", "python3");
|
|
507416
|
+
execFileSync2(venvPy, ["-m", "pip", "install", "--quiet", "--upgrade", "pip"], { stdio: "pipe", timeout: 12e4 });
|
|
507417
|
+
execFileSync2(venvPy, ["-m", "pip", "install", "--quiet", "piper-tts"], { stdio: "pipe", timeout: 6e5 });
|
|
507418
|
+
}
|
|
507419
|
+
if (!existsSync40(bin)) {
|
|
507420
|
+
throw new Error("Piper TTS installed but the piper executable was not found in the managed venv.");
|
|
507421
|
+
}
|
|
507422
|
+
return bin;
|
|
507423
|
+
}
|
|
507388
507424
|
function saveCloneRefFromSample(sample, cloneName) {
|
|
507389
507425
|
const source = resolvePath(sample);
|
|
507390
507426
|
if (!existsSync40(source))
|
|
@@ -507552,7 +507588,7 @@ except Exception as exc:
|
|
|
507552
507588
|
`;
|
|
507553
507589
|
AudioPlaybackTool = class {
|
|
507554
507590
|
name = "audio_playback";
|
|
507555
|
-
description = "Play audio through speakers, synthesize text-to-speech, and manage TTS clone voices. Actions: 'play' to play an audio file (WAV/MP3/OGG — including recordings from memory episodes), 'speak' to synthesize and play text, 'synthesize' to save TTS to a WAV file, 'clone' to register a voice-clone sample, 'list_voices' to inspect available clone refs/backends, 'volume' to get or set system volume, 'list' to enumerate audio output devices. TTS backends are explicit: auto, luxtts, supertonic, mlx, onnx/piper, or espeak. Use generate_tts when the task is specifically to create a TTS file.";
|
|
507591
|
+
description = "Play audio through speakers, synthesize text-to-speech, and manage TTS clone voices. Actions: 'play' to play an audio file (WAV/MP3/OGG — including recordings from memory episodes), 'speak' to synthesize and play text, 'synthesize' to save TTS to a WAV file, 'clone' to register a voice-clone sample, 'list_voices' to inspect available clone refs/backends, 'volume' to get or set system volume, 'list' to enumerate audio output devices. TTS backends are explicit: auto, luxtts, supertonic, mlx, onnx/piper, or espeak. Neural TTS backends self-provision into ~/.omnius/voice on first use where supported. Use generate_tts when the task is specifically to create a TTS file; do not use shell speech commands or generate_audio for spoken TTS.";
|
|
507556
507592
|
parameters = {
|
|
507557
507593
|
type: "object",
|
|
507558
507594
|
properties: {
|
|
@@ -507569,6 +507605,14 @@ except Exception as exc:
|
|
|
507569
507605
|
type: "string",
|
|
507570
507606
|
description: "Text to speak or synthesize"
|
|
507571
507607
|
},
|
|
507608
|
+
input: {
|
|
507609
|
+
type: "string",
|
|
507610
|
+
description: "Alias for text."
|
|
507611
|
+
},
|
|
507612
|
+
prompt: {
|
|
507613
|
+
type: "string",
|
|
507614
|
+
description: "Alias for text."
|
|
507615
|
+
},
|
|
507572
507616
|
backend: {
|
|
507573
507617
|
type: "string",
|
|
507574
507618
|
enum: ["auto", "luxtts", "supertonic", "mlx", "onnx", "piper", "espeak"],
|
|
@@ -507598,6 +507642,10 @@ except Exception as exc:
|
|
|
507598
507642
|
type: "string",
|
|
507599
507643
|
description: "Backend model id or raw ONNX/Piper model path. MLX default is mlx-community/Kokoro-82M-bf16."
|
|
507600
507644
|
},
|
|
507645
|
+
strict_backend: {
|
|
507646
|
+
type: "boolean",
|
|
507647
|
+
description: "When true, fail instead of falling back if the requested TTS backend is unavailable. Defaults false."
|
|
507648
|
+
},
|
|
507601
507649
|
volume: {
|
|
507602
507650
|
type: "number",
|
|
507603
507651
|
description: "Volume level 0-100 (for 'volume' action to SET volume)"
|
|
@@ -507693,7 +507741,7 @@ except Exception as exc:
|
|
|
507693
507741
|
` luxtts: ${existsSync40(join58(voiceDir(), "luxtts-venv", "bin", "python3")) ? "installed" : "not installed"}; clone refs: ${refs.length}`,
|
|
507694
507742
|
` supertonic: ${existsSync40(supertonicVenvPy()) ? "installed" : "not installed"}; voices include M1, M2, M3, M4 when package assets are available`,
|
|
507695
507743
|
` mlx: ${existsSync40(mlxVenvPy()) ? "installed" : "not installed"}; Apple Silicon only; default model mlx-community/Kokoro-82M-bf16`,
|
|
507696
|
-
` piper/onnx: ${hasCommand3("piper") ? "available" : "not
|
|
507744
|
+
` piper/onnx: ${hasCommand3("piper") || existsSync40(piperVenvBin()) ? "available" : "not installed"}; first use installs piper-tts into ${piperVenvDir()}; pass model=<path.onnx> for raw ONNX voices`,
|
|
507697
507745
|
` espeak: ${hasCommand3("espeak-ng") ? "available" : "not found"}`,
|
|
507698
507746
|
"",
|
|
507699
507747
|
"Registered clone refs:",
|
|
@@ -507702,16 +507750,18 @@ except Exception as exc:
|
|
|
507702
507750
|
return { success: true, output: lines.join("\n"), durationMs: performance.now() - start2 };
|
|
507703
507751
|
}
|
|
507704
507752
|
async synthesizeText(args, start2, speakDefault) {
|
|
507705
|
-
const text =
|
|
507753
|
+
const text = ttsTextArg(args);
|
|
507706
507754
|
if (!text) {
|
|
507707
507755
|
return { success: false, output: "", error: "Missing 'text' parameter. Provide text to synthesize.", durationMs: performance.now() - start2 };
|
|
507708
507756
|
}
|
|
507709
507757
|
const requestedBackend = normalizeTtsBackend(args["backend"]);
|
|
507758
|
+
const strictBackend = boolArg(args["strict_backend"] ?? args["strictBackend"], false);
|
|
507710
507759
|
const playback = playbackArg(args, speakDefault);
|
|
507711
507760
|
const outputPath2 = ttsOutputPath(args, requestedBackend);
|
|
507712
507761
|
const device = typeof args["device"] === "string" ? args["device"] : "default";
|
|
507713
507762
|
const tried = [];
|
|
507714
|
-
const
|
|
507763
|
+
const autoCandidates = ["luxtts", "supertonic", ...process.platform === "darwin" && process.arch === "arm64" ? ["mlx"] : [], "piper", "espeak"];
|
|
507764
|
+
const candidates = requestedBackend === "auto" ? autoCandidates : strictBackend ? [requestedBackend] : [requestedBackend, ...autoCandidates.filter((backend) => backend !== requestedBackend)];
|
|
507715
507765
|
let usedBackend = "";
|
|
507716
507766
|
let voiceSummary = "";
|
|
507717
507767
|
for (const backend of candidates) {
|
|
@@ -507734,7 +507784,7 @@ except Exception as exc:
|
|
|
507734
507784
|
} catch (err) {
|
|
507735
507785
|
const message2 = err instanceof Error ? err.message : String(err);
|
|
507736
507786
|
tried.push(`${backend}: ${message2.slice(0, 300)}`);
|
|
507737
|
-
if (requestedBackend !== "auto") {
|
|
507787
|
+
if (requestedBackend !== "auto" && strictBackend) {
|
|
507738
507788
|
return { success: false, output: "", error: `${backend} TTS failed: ${message2}`, durationMs: performance.now() - start2 };
|
|
507739
507789
|
}
|
|
507740
507790
|
}
|
|
@@ -507754,11 +507804,13 @@ ${tried.map((line) => `- ${line}`).join("\n")}`,
|
|
|
507754
507804
|
})() : " Playback: disabled";
|
|
507755
507805
|
const size = Math.round(statSync18(outputPath2).size / 1024);
|
|
507756
507806
|
const preview = text.length > 140 ? `${text.slice(0, 137)}...` : text;
|
|
507807
|
+
const fallbackLine = requestedBackend !== "auto" && usedBackend !== requestedBackend ? ` Fallback: requested ${requestedBackend}; ${tried[0] ?? "requested backend unavailable"}` : "";
|
|
507757
507808
|
return {
|
|
507758
507809
|
success: true,
|
|
507759
507810
|
output: [
|
|
507760
507811
|
`TTS generated: ${outputPath2}`,
|
|
507761
507812
|
` Backend: ${usedBackend}`,
|
|
507813
|
+
fallbackLine,
|
|
507762
507814
|
voiceSummary ? ` Voice: ${voiceSummary}` : "",
|
|
507763
507815
|
` Size: ${size}KB`,
|
|
507764
507816
|
playbackLine,
|
|
@@ -507783,8 +507835,9 @@ ${tried.map((line) => `- ${line}`).join("\n")}`,
|
|
|
507783
507835
|
}
|
|
507784
507836
|
const venvPy = join58(voiceDir(), "luxtts-venv", "bin", "python3");
|
|
507785
507837
|
const repoDir = join58(voiceDir(), "LuxTTS");
|
|
507786
|
-
if (!existsSync40(venvPy) || !existsSync40(repoDir))
|
|
507787
|
-
throw new Error("LuxTTS is not installed
|
|
507838
|
+
if (!existsSync40(venvPy) || !existsSync40(repoDir)) {
|
|
507839
|
+
throw new Error("LuxTTS is not installed in the managed voice environment yet.");
|
|
507840
|
+
}
|
|
507788
507841
|
const pyScript = [
|
|
507789
507842
|
"import json, sys, wave",
|
|
507790
507843
|
"import numpy as np, torch",
|
|
@@ -507842,8 +507895,7 @@ ${tried.map((line) => `- ${line}`).join("\n")}`,
|
|
|
507842
507895
|
return `${voice} (${model})`;
|
|
507843
507896
|
}
|
|
507844
507897
|
synthesizePiper(text, outputPath2, args, requireModel) {
|
|
507845
|
-
|
|
507846
|
-
throw new Error("piper command not found. Install Piper for ONNX TTS.");
|
|
507898
|
+
const piper = ensurePiperInstalled();
|
|
507847
507899
|
const rawModel = typeof args["model"] === "string" ? args["model"] : typeof args["voice"] === "string" && /\.(onnx|onnx\.json)$/i.test(args["voice"]) ? args["voice"] : "";
|
|
507848
507900
|
const argv = ["--output_file", outputPath2];
|
|
507849
507901
|
let summary = "default piper voice";
|
|
@@ -507853,10 +507905,10 @@ ${tried.map((line) => `- ${line}`).join("\n")}`,
|
|
|
507853
507905
|
throw new Error(`Piper/ONNX model file not found: ${rawModel}`);
|
|
507854
507906
|
argv.unshift("--model", modelPath);
|
|
507855
507907
|
summary = basename12(modelPath);
|
|
507856
|
-
} else
|
|
507857
|
-
throw new Error("Raw ONNX TTS requires model=<path.onnx> or voice=<path.onnx
|
|
507908
|
+
} else {
|
|
507909
|
+
throw new Error(`${requireModel ? "Raw ONNX" : "Piper"} TTS requires model=<path.onnx> or voice=<path.onnx>.`);
|
|
507858
507910
|
}
|
|
507859
|
-
execFileSync2(
|
|
507911
|
+
execFileSync2(piper, argv, { input: text, stdio: ["pipe", "pipe", "pipe"], timeout: 12e4 });
|
|
507860
507912
|
return summary;
|
|
507861
507913
|
}
|
|
507862
507914
|
synthesizeEspeak(text, outputPath2, args) {
|
|
@@ -507943,14 +507995,18 @@ ${devices.join("\n")}`,
|
|
|
507943
507995
|
};
|
|
507944
507996
|
TtsGenerateTool = class {
|
|
507945
507997
|
name = "generate_tts";
|
|
507946
|
-
description = "Generate text-to-speech audio as a WAV file, optionally playing it after synthesis. Supports explicit backends: auto, luxtts voice cloning, supertonic, mlx, onnx/piper, and espeak. Use clone_ref to select a registered LuxTTS voice, sample+clone_name to register a clone sample via audio_playback action=clone, and playback=false for silent file generation.";
|
|
507998
|
+
description = "Generate text-to-speech audio as a WAV file, optionally playing it after synthesis. Supports explicit backends: auto, luxtts voice cloning, supertonic, mlx, onnx/piper, and espeak. Neural TTS backends self-provision into ~/.omnius/voice on first use where supported. Use clone_ref to select a registered LuxTTS voice, sample+clone_name to register a clone sample via audio_playback action=clone, and playback=false for silent file generation. Use this tool for speech/TTS requests; do not use shell commands or generate_audio as a TTS fallback.";
|
|
507947
507999
|
parameters = {
|
|
507948
508000
|
type: "object",
|
|
507949
508001
|
properties: {
|
|
507950
508002
|
text: { type: "string", description: "Text to synthesize" },
|
|
508003
|
+
input: { type: "string", description: "Alias for text." },
|
|
508004
|
+
prompt: { type: "string", description: "Alias for text." },
|
|
507951
508005
|
backend: { type: "string", enum: ["auto", "luxtts", "supertonic", "mlx", "onnx", "piper", "espeak"] },
|
|
507952
508006
|
output: { type: "string", description: "Output WAV path. Defaults to ~/.omnius/voice/generated/tts-*.wav." },
|
|
508007
|
+
path: { type: "string", description: "Alias for output." },
|
|
507953
508008
|
playback: { type: "boolean", description: "Whether to play after generating. Defaults false for generate_tts." },
|
|
508009
|
+
strict_backend: { type: "boolean", description: "When true, fail instead of falling back if the requested backend is unavailable. Defaults false." },
|
|
507954
508010
|
voice: { type: "string", description: "Voice id/name, or raw Piper/ONNX path when backend=onnx/piper." },
|
|
507955
508011
|
clone_ref: { type: "string", description: "LuxTTS clone reference path, filename, or registered clone name." },
|
|
507956
508012
|
model: { type: "string", description: "Backend model id or raw ONNX/Piper model path." },
|
|
@@ -507958,7 +508014,7 @@ ${devices.join("\n")}`,
|
|
|
507958
508014
|
speed: { type: "number", description: "Speech speed multiplier or backend-specific rate." },
|
|
507959
508015
|
device: { type: "string", description: "Playback output device when playback=true." }
|
|
507960
508016
|
},
|
|
507961
|
-
required: [
|
|
508017
|
+
required: []
|
|
507962
508018
|
};
|
|
507963
508019
|
async execute(args) {
|
|
507964
508020
|
const tool = new AudioPlaybackTool();
|
|
@@ -534492,7 +534548,7 @@ Respond with your assessment, then take action.`;
|
|
|
534492
534548
|
} catch {
|
|
534493
534549
|
}
|
|
534494
534550
|
}
|
|
534495
|
-
if (!this.options.disablePersistentMemory && !this.options.disableCodebaseMap && process.env["OMNIUS_DISABLE_CODEBASE_MAP"] !== "1" && this._episodeStore && this._workingDirectory) {
|
|
534551
|
+
if (!this.options.disablePersistentMemory && !this.options.disableCodebaseMap && !this.options.subAgent && !this.options.stateDir && process.env["OMNIUS_DISABLE_CODEBASE_MAP"] !== "1" && this._episodeStore && this._workingDirectory) {
|
|
534496
534552
|
try {
|
|
534497
534553
|
const memMod = await Promise.resolve().then(() => (init_dist7(), dist_exports2));
|
|
534498
534554
|
let commitSha = "no-commit";
|
|
@@ -596290,6 +596346,8 @@ var init_tool_policy = __esm({
|
|
|
596290
596346
|
"glob_find",
|
|
596291
596347
|
"list_directory",
|
|
596292
596348
|
"code_sandbox",
|
|
596349
|
+
"full_sub_agent",
|
|
596350
|
+
"telegram_sandbox_handoff",
|
|
596293
596351
|
"codebase_map",
|
|
596294
596352
|
"diagnostic",
|
|
596295
596353
|
"git_info",
|
|
@@ -596324,7 +596382,6 @@ var init_tool_policy = __esm({
|
|
|
596324
596382
|
"generate_tts",
|
|
596325
596383
|
"create_audio_file",
|
|
596326
596384
|
"telegram_send_file",
|
|
596327
|
-
"telegram_sandbox_handoff",
|
|
596328
596385
|
"task_complete"
|
|
596329
596386
|
]);
|
|
596330
596387
|
SAFE_GROUP_ADMIN_TOOLS = /* @__PURE__ */ new Set([
|
|
@@ -596341,7 +596398,6 @@ var init_tool_policy = __esm({
|
|
|
596341
596398
|
"generate_tts",
|
|
596342
596399
|
"create_audio_file",
|
|
596343
596400
|
"telegram_send_file",
|
|
596344
|
-
"telegram_sandbox_handoff",
|
|
596345
596401
|
"task_complete"
|
|
596346
596402
|
]);
|
|
596347
596403
|
}
|
|
@@ -596359,6 +596415,7 @@ import { mkdir as mkdir17 } from "node:fs/promises";
|
|
|
596359
596415
|
import {
|
|
596360
596416
|
basename as basename22,
|
|
596361
596417
|
dirname as dirname33,
|
|
596418
|
+
extname as extname14,
|
|
596362
596419
|
isAbsolute as isAbsolute6,
|
|
596363
596420
|
join as join119,
|
|
596364
596421
|
relative as relative12,
|
|
@@ -596377,11 +596434,26 @@ function formatTelegramCreativeWorkspacePrompt(root) {
|
|
|
596377
596434
|
"Public/group creative workspace is enabled.",
|
|
596378
596435
|
`Workspace root: ${root}`,
|
|
596379
596436
|
"Creative file tools are scoped to that folder only.",
|
|
596380
|
-
"Allowed: create
|
|
596381
|
-
"Forbidden: delete files, access paths outside this workspace, mutate the project tree, run shell commands, or touch system state.",
|
|
596437
|
+
"Allowed: create and send non-executable creative artifacts in this workspace.",
|
|
596438
|
+
"Forbidden: delete files, create scripts/executables, access paths outside this workspace, mutate the project tree, run shell/Python/code commands, or touch system state.",
|
|
596382
596439
|
"When a user asks for an artifact to be sent, create it here and then call telegram_send_file. The bridge also auto-attaches recorded artifacts as a fallback. Refer to the attachment naturally; do not expose filesystem paths unless the admin explicitly asks."
|
|
596383
596440
|
].join("\n");
|
|
596384
596441
|
}
|
|
596442
|
+
function publicCreativeArtifactPolicyError(path11) {
|
|
596443
|
+
const ext = extname14(path11).toLowerCase();
|
|
596444
|
+
if (PUBLIC_EXECUTABLE_ARTIFACT_EXTENSIONS.has(ext)) {
|
|
596445
|
+
return `Public Telegram creative work cannot create or send executable/script/code artifacts (${ext || "no extension"}). Use a non-executable artifact such as .md, .txt, .json, image, audio, or PDF.`;
|
|
596446
|
+
}
|
|
596447
|
+
return null;
|
|
596448
|
+
}
|
|
596449
|
+
function publicCreativeContentPolicyError(args) {
|
|
596450
|
+
const content = args["content"] ?? args["text"] ?? args["data"];
|
|
596451
|
+
if (typeof content !== "string") return null;
|
|
596452
|
+
if (/^\s*#!/.test(content)) {
|
|
596453
|
+
return "Public Telegram creative work cannot create executable scripts or shebang files.";
|
|
596454
|
+
}
|
|
596455
|
+
return null;
|
|
596456
|
+
}
|
|
596385
596457
|
function collectGeneratedArtifactPathsFromText(text, root) {
|
|
596386
596458
|
const rootAbs = resolve38(root);
|
|
596387
596459
|
const paths = /* @__PURE__ */ new Set();
|
|
@@ -596461,6 +596533,10 @@ function scopedTool(base3, root, mode) {
|
|
|
596461
596533
|
if (pathKey) {
|
|
596462
596534
|
const guarded = guardPath(rootAbs, String(next[pathKey]));
|
|
596463
596535
|
if (!guarded.ok) return denied(guarded.error);
|
|
596536
|
+
const pathPolicyError = publicCreativeArtifactPolicyError(guarded.path.abs);
|
|
596537
|
+
if (pathPolicyError) return denied(pathPolicyError);
|
|
596538
|
+
const contentPolicyError = mode === "create" || mode === "edit" ? publicCreativeContentPolicyError(next) : null;
|
|
596539
|
+
if (contentPolicyError) return denied(contentPolicyError);
|
|
596464
596540
|
if (mode === "edit" && !manifestHas(rootAbs, guarded.path.rel)) {
|
|
596465
596541
|
return denied(`Public Telegram creative tools can only edit files created in this chat workspace: ${guarded.path.rel}`);
|
|
596466
596542
|
}
|
|
@@ -596573,7 +596649,7 @@ function denied(error) {
|
|
|
596573
596649
|
mutatedFiles: []
|
|
596574
596650
|
};
|
|
596575
596651
|
}
|
|
596576
|
-
var MANIFEST_FILE, PATH_KEYS, MEDIA_PATH_RE, CreativeAudioFileTool;
|
|
596652
|
+
var MANIFEST_FILE, PATH_KEYS, MEDIA_PATH_RE, PUBLIC_EXECUTABLE_ARTIFACT_EXTENSIONS, CreativeAudioFileTool;
|
|
596577
596653
|
var init_telegram_creative_tools = __esm({
|
|
596578
596654
|
"packages/cli/src/tui/telegram-creative-tools.ts"() {
|
|
596579
596655
|
"use strict";
|
|
@@ -596582,6 +596658,65 @@ var init_telegram_creative_tools = __esm({
|
|
|
596582
596658
|
MANIFEST_FILE = ".omnius-creative-manifest.json";
|
|
596583
596659
|
PATH_KEYS = ["path", "file", "file_path", "filename", "filepath", "filePath"];
|
|
596584
596660
|
MEDIA_PATH_RE = /(?:^|[\s([])(\/[^\s<>"')\]]+\.[A-Za-z0-9]{1,12})(?:$|[\s),.\]])/g;
|
|
596661
|
+
PUBLIC_EXECUTABLE_ARTIFACT_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
596662
|
+
".sh",
|
|
596663
|
+
".bash",
|
|
596664
|
+
".zsh",
|
|
596665
|
+
".fish",
|
|
596666
|
+
".ksh",
|
|
596667
|
+
".csh",
|
|
596668
|
+
".py",
|
|
596669
|
+
".pyw",
|
|
596670
|
+
".pyc",
|
|
596671
|
+
".pyo",
|
|
596672
|
+
".ipynb",
|
|
596673
|
+
".js",
|
|
596674
|
+
".mjs",
|
|
596675
|
+
".cjs",
|
|
596676
|
+
".ts",
|
|
596677
|
+
".tsx",
|
|
596678
|
+
".jsx",
|
|
596679
|
+
".rb",
|
|
596680
|
+
".pl",
|
|
596681
|
+
".pm",
|
|
596682
|
+
".php",
|
|
596683
|
+
".lua",
|
|
596684
|
+
".r",
|
|
596685
|
+
".jl",
|
|
596686
|
+
".ps1",
|
|
596687
|
+
".psm1",
|
|
596688
|
+
".bat",
|
|
596689
|
+
".cmd",
|
|
596690
|
+
".com",
|
|
596691
|
+
".exe",
|
|
596692
|
+
".msi",
|
|
596693
|
+
".jar",
|
|
596694
|
+
".class",
|
|
596695
|
+
".war",
|
|
596696
|
+
".ear",
|
|
596697
|
+
".go",
|
|
596698
|
+
".rs",
|
|
596699
|
+
".c",
|
|
596700
|
+
".cc",
|
|
596701
|
+
".cpp",
|
|
596702
|
+
".cxx",
|
|
596703
|
+
".h",
|
|
596704
|
+
".hpp",
|
|
596705
|
+
".java",
|
|
596706
|
+
".kt",
|
|
596707
|
+
".kts",
|
|
596708
|
+
".scala",
|
|
596709
|
+
".swift",
|
|
596710
|
+
".cs",
|
|
596711
|
+
".vb",
|
|
596712
|
+
".fs",
|
|
596713
|
+
".so",
|
|
596714
|
+
".dylib",
|
|
596715
|
+
".dll",
|
|
596716
|
+
".app",
|
|
596717
|
+
".appimage",
|
|
596718
|
+
".desktop"
|
|
596719
|
+
]);
|
|
596585
596720
|
CreativeAudioFileTool = class {
|
|
596586
596721
|
constructor(root) {
|
|
596587
596722
|
this.root = root;
|
|
@@ -596593,6 +596728,8 @@ var init_telegram_creative_tools = __esm({
|
|
|
596593
596728
|
type: "object",
|
|
596594
596729
|
properties: {
|
|
596595
596730
|
text: { type: "string", description: "Text to synthesize into speech" },
|
|
596731
|
+
input: { type: "string", description: "Alias for text" },
|
|
596732
|
+
prompt: { type: "string", description: "Alias for text" },
|
|
596596
596733
|
path: { type: "string", description: "Output .wav path inside the creative workspace" },
|
|
596597
596734
|
backend: { type: "string", enum: ["auto", "luxtts", "supertonic", "mlx", "onnx", "piper", "espeak"], description: "TTS backend. Defaults to auto." },
|
|
596598
596735
|
voice: { type: "string", description: "Voice id/name for the selected TTS backend" },
|
|
@@ -596600,11 +596737,11 @@ var init_telegram_creative_tools = __esm({
|
|
|
596600
596737
|
model: { type: "string", description: "Optional backend model id or raw Piper/ONNX path" },
|
|
596601
596738
|
speed: { type: "number", description: "Speech speed multiplier or backend-specific rate" }
|
|
596602
596739
|
},
|
|
596603
|
-
required: [
|
|
596740
|
+
required: []
|
|
596604
596741
|
};
|
|
596605
596742
|
async execute(args) {
|
|
596606
596743
|
const start2 = performance.now();
|
|
596607
|
-
const text = typeof args["text"] === "string" ? args["text"].trim() : "";
|
|
596744
|
+
const text = typeof args["text"] === "string" && args["text"].trim() ? args["text"].trim() : typeof args["input"] === "string" && args["input"].trim() ? args["input"].trim() : typeof args["prompt"] === "string" && args["prompt"].trim() ? args["prompt"].trim() : "";
|
|
596608
596745
|
if (!text) return { success: false, output: "", error: "text is required", durationMs: performance.now() - start2 };
|
|
596609
596746
|
const rawPath = typeof args["path"] === "string" && args["path"].trim() ? String(args["path"]) : `speech-${Date.now()}.wav`;
|
|
596610
596747
|
const guarded = guardPath(this.root, rawPath);
|
|
@@ -597122,7 +597259,8 @@ function telegramSyntheticHelpSignatures() {
|
|
|
597122
597259
|
return [
|
|
597123
597260
|
{ signature: "/help", description: "Show Telegram command help" },
|
|
597124
597261
|
{ signature: "/start", description: "Show Telegram bridge status and authentication instructions" },
|
|
597125
|
-
{ signature: "/auth <code>", description: "Authenticate this Telegram user as bot admin using the TUI code" }
|
|
597262
|
+
{ signature: "/auth <code>", description: "Authenticate this Telegram user as bot admin using the TUI code" },
|
|
597263
|
+
{ signature: "/call", description: "Get the active voice call link when a call session is running" }
|
|
597126
597264
|
];
|
|
597127
597265
|
}
|
|
597128
597266
|
function telegramHelpCommandAllowed(cmd, scope) {
|
|
@@ -597626,7 +597764,8 @@ path and target. Do not search for Telegram bot tokens, environment secrets, or
|
|
|
597626
597764
|
credentials; upload authorization is encapsulated by telegram_send_file.
|
|
597627
597765
|
|
|
597628
597766
|
When asked to generate speech, narration, or TTS, use generate_tts or audio_playback.
|
|
597629
|
-
|
|
597767
|
+
Those tools handle first-use backend setup where supported. Do not fall back to shell
|
|
597768
|
+
commands or generic audio generation for speech synthesis while those tools are available.
|
|
597630
597769
|
|
|
597631
597770
|
Keep responses concise for Telegram but don't withhold information from the admin.
|
|
597632
597771
|
`.trim();
|
|
@@ -599550,6 +599689,9 @@ ${mediaContext}` : ""}`
|
|
|
599550
599689
|
runner.onEvent((event) => {
|
|
599551
599690
|
if (subAgent.aborted) return;
|
|
599552
599691
|
let suppressExternalEvent = false;
|
|
599692
|
+
if (!isAdminDM && event.type === "status") {
|
|
599693
|
+
suppressExternalEvent = true;
|
|
599694
|
+
}
|
|
599553
599695
|
if (event.type === "tool_call" && event.toolName) {
|
|
599554
599696
|
if (event.toolName === "task_complete") {
|
|
599555
599697
|
subAgent.completionBoundarySeen = true;
|
|
@@ -599585,7 +599727,9 @@ ${mediaContext}` : ""}`
|
|
|
599585
599727
|
}
|
|
599586
599728
|
}
|
|
599587
599729
|
} else if (event.type === "status" && event.content) {
|
|
599588
|
-
|
|
599730
|
+
if (isAdminDM) {
|
|
599731
|
+
this.subAgentViewCallbacks?.onWrite(subAgent.viewId, `status: ${event.content}`);
|
|
599732
|
+
}
|
|
599589
599733
|
} else if (event.type === "assistant_text" && event.content && event.source !== "task_complete_summary") {
|
|
599590
599734
|
subAgent.assistantText = event.content;
|
|
599591
599735
|
} else if (event.type === "stream_start") {
|
|
@@ -600056,10 +600200,27 @@ Scoped workspace: ${scopedRoot}`,
|
|
|
600056
600200
|
).map((tool) => adaptTool5(tool, todoSessionId));
|
|
600057
600201
|
adaptedTools.push(...creativeTools);
|
|
600058
600202
|
adaptedTools.push(adaptTool5(this.buildTelegramSendFileTool(context2, repoRoot, chatId, msg), todoSessionId));
|
|
600059
|
-
adaptedTools
|
|
600203
|
+
adaptedTools = this.filterNonAdminTelegramTools(adaptedTools);
|
|
600060
600204
|
}
|
|
600061
600205
|
return [...adaptedTools, taskComplete];
|
|
600062
600206
|
}
|
|
600207
|
+
filterNonAdminTelegramTools(tools) {
|
|
600208
|
+
const blocked = /* @__PURE__ */ new Set([
|
|
600209
|
+
"shell",
|
|
600210
|
+
"code_sandbox",
|
|
600211
|
+
"background_run",
|
|
600212
|
+
"task_output",
|
|
600213
|
+
"task_status",
|
|
600214
|
+
"task_stop",
|
|
600215
|
+
"full_sub_agent",
|
|
600216
|
+
"telegram_sandbox_handoff",
|
|
600217
|
+
"create_tool",
|
|
600218
|
+
"manage_tools",
|
|
600219
|
+
"aiwg_setup",
|
|
600220
|
+
"aiwg_workflow"
|
|
600221
|
+
]);
|
|
600222
|
+
return tools.filter((tool) => !blocked.has(tool.name));
|
|
600223
|
+
}
|
|
600063
600224
|
imageGenerationDefaultsForRepo(repoRoot) {
|
|
600064
600225
|
const settings = resolveSettings(repoRoot);
|
|
600065
600226
|
return {
|
|
@@ -600221,6 +600382,10 @@ ${knownList}` : "Private-user telegram_send_file target must be this DM or a kno
|
|
|
600221
600382
|
if (scopedRoot && !isPathInside(base3, abs)) {
|
|
600222
600383
|
return { ok: false, error: `Public/group telegram_send_file can only send files inside ${base3}.` };
|
|
600223
600384
|
}
|
|
600385
|
+
if (scopedRoot) {
|
|
600386
|
+
const policyError = publicCreativeArtifactPolicyError(abs);
|
|
600387
|
+
if (policyError) return { ok: false, error: policyError };
|
|
600388
|
+
}
|
|
600224
600389
|
if (!existsSync106(abs)) return { ok: false, error: `File does not exist: ${trimmed}` };
|
|
600225
600390
|
if (!statSync36(abs).isFile()) return { ok: false, error: `Path is not a file: ${trimmed}` };
|
|
600226
600391
|
return { ok: true, path: abs };
|
|
@@ -625026,7 +625191,7 @@ var init_clipboard_media = __esm({
|
|
|
625026
625191
|
|
|
625027
625192
|
// packages/cli/src/tui/interactive.ts
|
|
625028
625193
|
import { cwd } from "node:process";
|
|
625029
|
-
import { resolve as resolve44, join as join137, dirname as dirname38, extname as
|
|
625194
|
+
import { resolve as resolve44, join as join137, dirname as dirname38, extname as extname15, relative as relative14 } from "node:path";
|
|
625030
625195
|
import { createRequire as createRequire8 } from "node:module";
|
|
625031
625196
|
import { fileURLToPath as fileURLToPath18 } from "node:url";
|
|
625032
625197
|
import {
|
|
@@ -632328,7 +632493,7 @@ Execute this skill now. Follow the behavioral guidance above.`;
|
|
|
632328
632493
|
const imgPath = resolve44(repoRoot, cleanPath);
|
|
632329
632494
|
const imgBuffer = readFileSync100(imgPath);
|
|
632330
632495
|
const base642 = imgBuffer.toString("base64");
|
|
632331
|
-
const ext =
|
|
632496
|
+
const ext = extname15(cleanPath).toLowerCase();
|
|
632332
632497
|
const mime = ext === ".png" ? "image/png" : ext === ".gif" ? "image/gif" : ext === ".webp" ? "image/webp" : "image/jpeg";
|
|
632333
632498
|
const asciiContext = await renderAsciiPreviewForImage(
|
|
632334
632499
|
imgPath,
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "omnius",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.19",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "omnius",
|
|
9
|
-
"version": "1.0.
|
|
9
|
+
"version": "1.0.19",
|
|
10
10
|
"bundleDependencies": [
|
|
11
11
|
"image-to-ascii"
|
|
12
12
|
],
|
package/package.json
CHANGED