omnius 1.0.17 → 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 +478 -129
- 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();
|
|
@@ -512308,7 +512364,7 @@ var init_agent_tool = __esm({
|
|
|
512308
512364
|
})();
|
|
512309
512365
|
if (isolation === "worktree") {
|
|
512310
512366
|
this.callbacks.onViewRegister?.(agentId, label);
|
|
512311
|
-
const
|
|
512367
|
+
const spawn31 = this.callbacks.spawnSubprocess({
|
|
512312
512368
|
id: agentId,
|
|
512313
512369
|
task: composedPrompt,
|
|
512314
512370
|
model,
|
|
@@ -512318,7 +512374,7 @@ var init_agent_tool = __esm({
|
|
|
512318
512374
|
success: true,
|
|
512319
512375
|
output: `Agent spawned (subprocess, worktree): ${agentId}
|
|
512320
512376
|
Type: ${subagentType}
|
|
512321
|
-
PID: ${
|
|
512377
|
+
PID: ${spawn31.pid}
|
|
512322
512378
|
Task: ${prompt.slice(0, 100)}
|
|
512323
512379
|
Use task_status("${agentId}") to check progress.`,
|
|
512324
512380
|
durationMs: performance.now() - start2
|
|
@@ -530830,7 +530886,7 @@ RECOVERY: cd to the directory containing '${file}', run a plain install with no
|
|
|
530830
530886
|
import { existsSync as _fsExistsSync, readFileSync as _fsReadFileSync, writeFileSync as _fsWriteFileSync, unlinkSync as _fsUnlinkSync, mkdirSync as _fsMkdirSync } from "node:fs";
|
|
530831
530887
|
import { execFile as _execFile } from "node:child_process";
|
|
530832
530888
|
import { createHash as _createHash } from "node:crypto";
|
|
530833
|
-
import { join as _pathJoin } from "node:path";
|
|
530889
|
+
import { join as _pathJoin, resolve as _pathResolve } from "node:path";
|
|
530834
530890
|
import { tmpdir as _osTmpdir } from "node:os";
|
|
530835
530891
|
import { homedir as _osHomedir } from "node:os";
|
|
530836
530892
|
import { z as z15 } from "zod";
|
|
@@ -531578,6 +531634,9 @@ var init_agenticRunner = __esm({
|
|
|
531578
531634
|
compactionThreshold: options2?.compactionThreshold ?? 4e4,
|
|
531579
531635
|
deepContext: options2?.deepContext ?? false,
|
|
531580
531636
|
dynamicContext: options2?.dynamicContext ?? "",
|
|
531637
|
+
stateDir: options2?.stateDir ?? "",
|
|
531638
|
+
disablePersistentMemory: options2?.disablePersistentMemory ?? false,
|
|
531639
|
+
disableCodebaseMap: options2?.disableCodebaseMap ?? false,
|
|
531581
531640
|
sessionId: options2?.sessionId ?? "",
|
|
531582
531641
|
streamEnabled: options2?.streamEnabled ?? false,
|
|
531583
531642
|
thinking: options2?.thinking ?? true,
|
|
@@ -531604,6 +531663,11 @@ var init_agenticRunner = __esm({
|
|
|
531604
531663
|
setWorkingDirectory(dir) {
|
|
531605
531664
|
this._workingDirectory = dir;
|
|
531606
531665
|
}
|
|
531666
|
+
/** State root for runner-owned memory/artifacts. Defaults to cwd/.omnius. */
|
|
531667
|
+
omniusStateDir() {
|
|
531668
|
+
const configured = (this.options.stateDir || "").trim();
|
|
531669
|
+
return configured ? _pathResolve(configured) : _pathJoin(process.cwd(), ".omnius");
|
|
531670
|
+
}
|
|
531607
531671
|
/** Get current task state (for external inspection) */
|
|
531608
531672
|
get taskState() {
|
|
531609
531673
|
return this._taskState;
|
|
@@ -534298,10 +534362,10 @@ Respond with your assessment, then take action.`;
|
|
|
534298
534362
|
this._toolLastUsedTurn.clear();
|
|
534299
534363
|
this._contextTree = null;
|
|
534300
534364
|
this._lastSurfacedAnchorIds.clear();
|
|
534301
|
-
if (!this._memoryInitialized) {
|
|
534365
|
+
if (!this.options.disablePersistentMemory && !this._memoryInitialized) {
|
|
534302
534366
|
try {
|
|
534303
534367
|
const path11 = await import("node:path");
|
|
534304
|
-
const omniusDir =
|
|
534368
|
+
const omniusDir = this.omniusStateDir();
|
|
534305
534369
|
const rawEpisodeStore = new EpisodeStore(path11.join(omniusDir, "episodes.db"));
|
|
534306
534370
|
const crlConfig = getCRLConfigStore(process.cwd());
|
|
534307
534371
|
if (crlConfig.get().mode !== "json") {
|
|
@@ -534334,8 +534398,9 @@ Respond with your assessment, then take action.`;
|
|
|
534334
534398
|
const path11 = await import("node:path");
|
|
534335
534399
|
const os8 = await import("node:os");
|
|
534336
534400
|
const globalFile = path11.join(os8.homedir(), ".omnius", "error-patterns.json");
|
|
534337
|
-
const localFile = path11.join(process.cwd(), ".omnius", "error-patterns.json");
|
|
534338
|
-
|
|
534401
|
+
const localFile = this.options.stateDir ? path11.join(this.omniusStateDir(), "error-patterns.json") : path11.join(process.cwd(), ".omnius", "error-patterns.json");
|
|
534402
|
+
const patternFiles = this.options.stateDir ? [localFile] : [globalFile, localFile];
|
|
534403
|
+
for (const patternsFile of patternFiles) {
|
|
534339
534404
|
try {
|
|
534340
534405
|
if (fs10.existsSync(patternsFile)) {
|
|
534341
534406
|
const saved = JSON.parse(fs10.readFileSync(patternsFile, "utf8"));
|
|
@@ -534426,7 +534491,7 @@ Respond with your assessment, then take action.`;
|
|
|
534426
534491
|
} catch {
|
|
534427
534492
|
}
|
|
534428
534493
|
}
|
|
534429
|
-
if (process.env["OMNIUS_DISABLE_STAGE_CONTEXT"] !== "1") {
|
|
534494
|
+
if (!this.options.disablePersistentMemory && process.env["OMNIUS_DISABLE_STAGE_CONTEXT"] !== "1") {
|
|
534430
534495
|
try {
|
|
534431
534496
|
const memMod = await Promise.resolve().then(() => (init_dist7(), dist_exports2));
|
|
534432
534497
|
if (!this._stageContext) {
|
|
@@ -534459,7 +534524,7 @@ Respond with your assessment, then take action.`;
|
|
|
534459
534524
|
} catch {
|
|
534460
534525
|
}
|
|
534461
534526
|
}
|
|
534462
|
-
if (process.env["OMNIUS_DISABLE_EMBEDDING_DRIFT_CHECK"] !== "1" && this._episodeStore) {
|
|
534527
|
+
if (!this.options.disablePersistentMemory && process.env["OMNIUS_DISABLE_EMBEDDING_DRIFT_CHECK"] !== "1" && this._episodeStore) {
|
|
534463
534528
|
try {
|
|
534464
534529
|
const memMod = await Promise.resolve().then(() => (init_dist7(), dist_exports2));
|
|
534465
534530
|
const currentModel = process.env["OMNIUS_EMBEDDING_MODEL"] || "default";
|
|
@@ -534483,7 +534548,7 @@ Respond with your assessment, then take action.`;
|
|
|
534483
534548
|
} catch {
|
|
534484
534549
|
}
|
|
534485
534550
|
}
|
|
534486
|
-
if (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) {
|
|
534487
534552
|
try {
|
|
534488
534553
|
const memMod = await Promise.resolve().then(() => (init_dist7(), dist_exports2));
|
|
534489
534554
|
let commitSha = "no-commit";
|
|
@@ -534604,7 +534669,7 @@ TASK: ${task}` : task;
|
|
|
534604
534669
|
}
|
|
534605
534670
|
try {
|
|
534606
534671
|
if (!this._reflectionBuffer) {
|
|
534607
|
-
const omniusDir = this._workingDirectory ? _pathJoin(this._workingDirectory, ".omnius", "memory") : null;
|
|
534672
|
+
const omniusDir = this.options.stateDir ? _pathJoin(this.omniusStateDir(), "memory") : this._workingDirectory ? _pathJoin(this._workingDirectory, ".omnius", "memory") : null;
|
|
534608
534673
|
if (omniusDir) {
|
|
534609
534674
|
this._reflectionBuffer = new TaskReflectionBuffer(_pathJoin(omniusDir, "reflections.json"));
|
|
534610
534675
|
}
|
|
@@ -536572,7 +536637,7 @@ ${memoryLines.join("\n")}`
|
|
|
536572
536637
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
536573
536638
|
});
|
|
536574
536639
|
try {
|
|
536575
|
-
const archDir = __require("node:path").join(
|
|
536640
|
+
const archDir = __require("node:path").join(this.omniusStateDir(), "phases");
|
|
536576
536641
|
__require("node:fs").mkdirSync(archDir, { recursive: true });
|
|
536577
536642
|
for (const phaseName of contracted) {
|
|
536578
536643
|
const node = this._contextTree.getSnapshot().phases[phaseName];
|
|
@@ -539190,8 +539255,9 @@ Full content available via: repl_exec(code="data = retrieve('${handleId}')") or
|
|
|
539190
539255
|
const path11 = await import("node:path");
|
|
539191
539256
|
const os8 = await import("node:os");
|
|
539192
539257
|
const globalFile = path11.join(os8.homedir(), ".omnius", "error-patterns.json");
|
|
539193
|
-
const localFile = path11.join(process.cwd(), ".omnius", "error-patterns.json");
|
|
539194
|
-
|
|
539258
|
+
const localFile = path11.join(this.options.stateDir ? this.omniusStateDir() : path11.join(process.cwd(), ".omnius"), "error-patterns.json");
|
|
539259
|
+
const targetFiles = this.options.stateDir ? [localFile] : [globalFile, localFile];
|
|
539260
|
+
for (const targetFile of targetFiles) {
|
|
539195
539261
|
try {
|
|
539196
539262
|
const dir = path11.dirname(targetFile);
|
|
539197
539263
|
fs10.mkdirSync(dir, { recursive: true });
|
|
@@ -539243,10 +539309,11 @@ Full content available via: repl_exec(code="data = retrieve('${handleId}')") or
|
|
|
539243
539309
|
};
|
|
539244
539310
|
const fs10 = await import("node:fs");
|
|
539245
539311
|
const path11 = await import("node:path");
|
|
539246
|
-
const
|
|
539312
|
+
const stateDir = this.omniusStateDir();
|
|
539313
|
+
const consolidDir = path11.join(stateDir, "consolidations");
|
|
539247
539314
|
fs10.mkdirSync(consolidDir, { recursive: true });
|
|
539248
539315
|
fs10.writeFileSync(path11.join(consolidDir, `${this._sessionId}.json`), JSON.stringify(consolidation, null, 2));
|
|
539249
|
-
const provenanceDir = path11.join(
|
|
539316
|
+
const provenanceDir = path11.join(stateDir, "provenance");
|
|
539250
539317
|
fs10.mkdirSync(provenanceDir, { recursive: true });
|
|
539251
539318
|
const provenanceGraph = {
|
|
539252
539319
|
sessionId: this._sessionId,
|
|
@@ -539746,7 +539813,7 @@ Full content available via: repl_exec(code="data = retrieve('${handleId}')") or
|
|
|
539746
539813
|
try {
|
|
539747
539814
|
const fs10 = await import("node:fs");
|
|
539748
539815
|
const path11 = await import("node:path");
|
|
539749
|
-
const trajDir = path11.join(
|
|
539816
|
+
const trajDir = path11.join(this.omniusStateDir(), "trajectories");
|
|
539750
539817
|
fs10.mkdirSync(trajDir, { recursive: true });
|
|
539751
539818
|
const trajectory = {
|
|
539752
539819
|
id: this._sessionId,
|
|
@@ -539918,7 +539985,7 @@ ${errOutput}`;
|
|
|
539918
539985
|
try {
|
|
539919
539986
|
const { mkdirSync: mkdirSync76, writeFileSync: writeFileSync71 } = __require("node:fs");
|
|
539920
539987
|
const { join: join142 } = __require("node:path");
|
|
539921
|
-
const resultsDir = join142(
|
|
539988
|
+
const resultsDir = join142(this.omniusStateDir(), "tool-results");
|
|
539922
539989
|
mkdirSync76(resultsDir, { recursive: true });
|
|
539923
539990
|
writeFileSync71(join142(resultsDir, `${handleId}.txt`), `# Tool: ${toolName}
|
|
539924
539991
|
# Turn: ${turn}
|
|
@@ -539929,7 +539996,7 @@ ${result.output}`, "utf-8");
|
|
|
539929
539996
|
} catch {
|
|
539930
539997
|
}
|
|
539931
539998
|
const { join: _pj } = __require("node:path");
|
|
539932
|
-
const savedPath = _pj(
|
|
539999
|
+
const savedPath = _pj(this.omniusStateDir(), "tool-results", `${handleId}.txt`);
|
|
539933
540000
|
const folded = this.foldOutput(modelContent, maxLen);
|
|
539934
540001
|
return `[Tool output truncated — ${result.output.length} chars, ${lineCount} lines]
|
|
539935
540002
|
Full output saved to: ${savedPath}
|
|
@@ -540283,7 +540350,7 @@ Actions: (1) list_directory on the parent directory to see what's there, (2) Che
|
|
|
540283
540350
|
try {
|
|
540284
540351
|
const { mkdirSync: mkdirSync76, writeFileSync: writeFileSync71 } = __require("node:fs");
|
|
540285
540352
|
const { join: join142 } = __require("node:path");
|
|
540286
|
-
const sessionDir = join142(this._workingDirectory, ".omnius", "session", this._sessionId);
|
|
540353
|
+
const sessionDir = this.options.stateDir ? join142(this.omniusStateDir(), "session", this._sessionId) : join142(this._workingDirectory, ".omnius", "session", this._sessionId);
|
|
540287
540354
|
mkdirSync76(sessionDir, { recursive: true });
|
|
540288
540355
|
const checkpoint = {
|
|
540289
540356
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -579164,13 +579231,13 @@ async function runSudoScript(ctx3, script) {
|
|
|
579164
579231
|
} catch {
|
|
579165
579232
|
}
|
|
579166
579233
|
try {
|
|
579167
|
-
const { spawn:
|
|
579234
|
+
const { spawn: spawn31 } = await import("node:child_process");
|
|
579168
579235
|
const full = `set -e; ${script}`;
|
|
579169
579236
|
await new Promise((resolve48) => {
|
|
579170
579237
|
const usePkexec = process.platform === "linux";
|
|
579171
579238
|
const cmd = usePkexec ? "pkexec" : "sudo";
|
|
579172
579239
|
const args = usePkexec ? ["bash", "-lc", full] : ["-n", "bash", "-lc", full];
|
|
579173
|
-
const child =
|
|
579240
|
+
const child = spawn31(cmd, args, { stdio: ["ignore", "pipe", "pipe"] });
|
|
579174
579241
|
let stdout = "";
|
|
579175
579242
|
let stderr = "";
|
|
579176
579243
|
child.stdout?.on("data", (data) => {
|
|
@@ -581357,8 +581424,8 @@ async function handleSlashCommand(input, ctx3) {
|
|
|
581357
581424
|
writeFileSync50(jwtFile, JSON.stringify(jwtPayload, null, 2));
|
|
581358
581425
|
renderInfo(`Launching fortemi-react from ${fDir}...`);
|
|
581359
581426
|
try {
|
|
581360
|
-
const { spawn:
|
|
581361
|
-
const child =
|
|
581427
|
+
const { spawn: spawn31 } = __require("node:child_process");
|
|
581428
|
+
const child = spawn31(
|
|
581362
581429
|
"npx",
|
|
581363
581430
|
["vite", "dev", "--host", "0.0.0.0", "--port", "3000"],
|
|
581364
581431
|
{
|
|
@@ -582293,9 +582360,9 @@ systemctl --user daemon-reload || true
|
|
|
582293
582360
|
systemctl --user enable --now omnius-daemon.service || true
|
|
582294
582361
|
sleep 1
|
|
582295
582362
|
`;
|
|
582296
|
-
const { spawn:
|
|
582363
|
+
const { spawn: spawn31 } = await import("node:child_process");
|
|
582297
582364
|
await new Promise((resolve48) => {
|
|
582298
|
-
const child =
|
|
582365
|
+
const child = spawn31("bash", ["-lc", takeover], {
|
|
582299
582366
|
stdio: "inherit"
|
|
582300
582367
|
});
|
|
582301
582368
|
onChildExit(child, () => resolve48());
|
|
@@ -588307,8 +588374,8 @@ ${escapedContent}EOF'`, {
|
|
|
588307
588374
|
}
|
|
588308
588375
|
await new Promise((r2) => setTimeout(r2, 1e3));
|
|
588309
588376
|
process.env.OLLAMA_NUM_PARALLEL = String(n2);
|
|
588310
|
-
const { spawn:
|
|
588311
|
-
const child =
|
|
588377
|
+
const { spawn: spawn31 } = await import("node:child_process");
|
|
588378
|
+
const child = spawn31("ollama", ["serve"], {
|
|
588312
588379
|
stdio: "ignore",
|
|
588313
588380
|
detached: true,
|
|
588314
588381
|
env: { ...process.env, OLLAMA_NUM_PARALLEL: String(n2) }
|
|
@@ -596226,9 +596293,9 @@ function getDefaultPolicy(context2) {
|
|
|
596226
596293
|
case "telegram-admin-dm":
|
|
596227
596294
|
return { blocked: /* @__PURE__ */ new Set(), allowed: /* @__PURE__ */ new Set() };
|
|
596228
596295
|
case "telegram-admin-group":
|
|
596229
|
-
return { blocked:
|
|
596296
|
+
return { blocked: new Set(SYSTEM_TOOLS), allowed: SAFE_GROUP_ADMIN_TOOLS };
|
|
596230
596297
|
case "telegram-public":
|
|
596231
|
-
return { blocked:
|
|
596298
|
+
return { blocked: new Set(SYSTEM_TOOLS), allowed: SAFE_PUBLIC_TOOLS };
|
|
596232
596299
|
case "api":
|
|
596233
596300
|
return { blocked: /* @__PURE__ */ new Set(), allowed: /* @__PURE__ */ new Set() };
|
|
596234
596301
|
default:
|
|
@@ -596263,10 +596330,45 @@ function applyToolPolicy(tools, context2, userConfig) {
|
|
|
596263
596330
|
return policy.allowed.has(tool.name);
|
|
596264
596331
|
});
|
|
596265
596332
|
}
|
|
596266
|
-
var SAFE_PUBLIC_TOOLS, SAFE_GROUP_ADMIN_TOOLS;
|
|
596333
|
+
var SYSTEM_TOOLS, SAFE_PUBLIC_TOOLS, SAFE_GROUP_ADMIN_TOOLS;
|
|
596267
596334
|
var init_tool_policy = __esm({
|
|
596268
596335
|
"packages/cli/src/tui/tool-policy.ts"() {
|
|
596269
596336
|
"use strict";
|
|
596337
|
+
SYSTEM_TOOLS = /* @__PURE__ */ new Set([
|
|
596338
|
+
"shell",
|
|
596339
|
+
"file_write",
|
|
596340
|
+
"file_edit",
|
|
596341
|
+
"file_read",
|
|
596342
|
+
"file_patch",
|
|
596343
|
+
"batch_edit",
|
|
596344
|
+
"structured_file",
|
|
596345
|
+
"grep_search",
|
|
596346
|
+
"glob_find",
|
|
596347
|
+
"list_directory",
|
|
596348
|
+
"code_sandbox",
|
|
596349
|
+
"full_sub_agent",
|
|
596350
|
+
"telegram_sandbox_handoff",
|
|
596351
|
+
"codebase_map",
|
|
596352
|
+
"diagnostic",
|
|
596353
|
+
"git_info",
|
|
596354
|
+
"structured_read",
|
|
596355
|
+
"screenshot",
|
|
596356
|
+
"desktop_click",
|
|
596357
|
+
"desktop_describe",
|
|
596358
|
+
"background_run",
|
|
596359
|
+
"task_status",
|
|
596360
|
+
"task_output",
|
|
596361
|
+
"task_stop",
|
|
596362
|
+
"create_tool",
|
|
596363
|
+
"manage_tools",
|
|
596364
|
+
"aiwg_setup",
|
|
596365
|
+
"aiwg_health",
|
|
596366
|
+
"aiwg_workflow",
|
|
596367
|
+
"autoresearch",
|
|
596368
|
+
"scheduler",
|
|
596369
|
+
"reminder",
|
|
596370
|
+
"agenda"
|
|
596371
|
+
]);
|
|
596270
596372
|
SAFE_PUBLIC_TOOLS = /* @__PURE__ */ new Set([
|
|
596271
596373
|
"memory_read",
|
|
596272
596374
|
"memory_write",
|
|
@@ -596280,7 +596382,6 @@ var init_tool_policy = __esm({
|
|
|
596280
596382
|
"generate_tts",
|
|
596281
596383
|
"create_audio_file",
|
|
596282
596384
|
"telegram_send_file",
|
|
596283
|
-
"telegram_sandbox_handoff",
|
|
596284
596385
|
"task_complete"
|
|
596285
596386
|
]);
|
|
596286
596387
|
SAFE_GROUP_ADMIN_TOOLS = /* @__PURE__ */ new Set([
|
|
@@ -596297,14 +596398,12 @@ var init_tool_policy = __esm({
|
|
|
596297
596398
|
"generate_tts",
|
|
596298
596399
|
"create_audio_file",
|
|
596299
596400
|
"telegram_send_file",
|
|
596300
|
-
"telegram_sandbox_handoff",
|
|
596301
596401
|
"task_complete"
|
|
596302
596402
|
]);
|
|
596303
596403
|
}
|
|
596304
596404
|
});
|
|
596305
596405
|
|
|
596306
596406
|
// packages/cli/src/tui/telegram-creative-tools.ts
|
|
596307
|
-
import { spawn as spawn27 } from "node:child_process";
|
|
596308
596407
|
import {
|
|
596309
596408
|
existsSync as existsSync104,
|
|
596310
596409
|
mkdirSync as mkdirSync59,
|
|
@@ -596316,6 +596415,7 @@ import { mkdir as mkdir17 } from "node:fs/promises";
|
|
|
596316
596415
|
import {
|
|
596317
596416
|
basename as basename22,
|
|
596318
596417
|
dirname as dirname33,
|
|
596418
|
+
extname as extname14,
|
|
596319
596419
|
isAbsolute as isAbsolute6,
|
|
596320
596420
|
join as join119,
|
|
596321
596421
|
relative as relative12,
|
|
@@ -596334,11 +596434,26 @@ function formatTelegramCreativeWorkspacePrompt(root) {
|
|
|
596334
596434
|
"Public/group creative workspace is enabled.",
|
|
596335
596435
|
`Workspace root: ${root}`,
|
|
596336
596436
|
"Creative file tools are scoped to that folder only.",
|
|
596337
|
-
"Allowed: create
|
|
596338
|
-
"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.",
|
|
596339
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."
|
|
596340
596440
|
].join("\n");
|
|
596341
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
|
+
}
|
|
596342
596457
|
function collectGeneratedArtifactPathsFromText(text, root) {
|
|
596343
596458
|
const rootAbs = resolve38(root);
|
|
596344
596459
|
const paths = /* @__PURE__ */ new Set();
|
|
@@ -596418,6 +596533,10 @@ function scopedTool(base3, root, mode) {
|
|
|
596418
596533
|
if (pathKey) {
|
|
596419
596534
|
const guarded = guardPath(rootAbs, String(next[pathKey]));
|
|
596420
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);
|
|
596421
596540
|
if (mode === "edit" && !manifestHas(rootAbs, guarded.path.rel)) {
|
|
596422
596541
|
return denied(`Public Telegram creative tools can only edit files created in this chat workspace: ${guarded.path.rel}`);
|
|
596423
596542
|
}
|
|
@@ -596530,33 +596649,7 @@ function denied(error) {
|
|
|
596530
596649
|
mutatedFiles: []
|
|
596531
596650
|
};
|
|
596532
596651
|
}
|
|
596533
|
-
|
|
596534
|
-
return new Promise((resolveProcess) => {
|
|
596535
|
-
const child = spawn27(command, args, {
|
|
596536
|
-
cwd: cwd4,
|
|
596537
|
-
stdio: ["ignore", "pipe", "pipe"]
|
|
596538
|
-
});
|
|
596539
|
-
let stdout = "";
|
|
596540
|
-
let stderr = "";
|
|
596541
|
-
const timer = setTimeout(() => child.kill("SIGTERM"), timeoutMs);
|
|
596542
|
-
timer.unref();
|
|
596543
|
-
child.stdout?.on("data", (chunk) => {
|
|
596544
|
-
stdout += chunk.toString();
|
|
596545
|
-
});
|
|
596546
|
-
child.stderr?.on("data", (chunk) => {
|
|
596547
|
-
stderr += chunk.toString();
|
|
596548
|
-
});
|
|
596549
|
-
onChildError(child, (err) => {
|
|
596550
|
-
clearTimeout(timer);
|
|
596551
|
-
resolveProcess({ code: 127, stdout, stderr: stderr + String(err.message || err) });
|
|
596552
|
-
});
|
|
596553
|
-
onChildClose(child, (code8) => {
|
|
596554
|
-
clearTimeout(timer);
|
|
596555
|
-
resolveProcess({ code: code8, stdout, stderr });
|
|
596556
|
-
});
|
|
596557
|
-
});
|
|
596558
|
-
}
|
|
596559
|
-
var MANIFEST_FILE, PATH_KEYS, MEDIA_PATH_RE, CreativeAudioFileTool;
|
|
596652
|
+
var MANIFEST_FILE, PATH_KEYS, MEDIA_PATH_RE, PUBLIC_EXECUTABLE_ARTIFACT_EXTENSIONS, CreativeAudioFileTool;
|
|
596560
596653
|
var init_telegram_creative_tools = __esm({
|
|
596561
596654
|
"packages/cli/src/tui/telegram-creative-tools.ts"() {
|
|
596562
596655
|
"use strict";
|
|
@@ -596565,6 +596658,65 @@ var init_telegram_creative_tools = __esm({
|
|
|
596565
596658
|
MANIFEST_FILE = ".omnius-creative-manifest.json";
|
|
596566
596659
|
PATH_KEYS = ["path", "file", "file_path", "filename", "filepath", "filePath"];
|
|
596567
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
|
+
]);
|
|
596568
596720
|
CreativeAudioFileTool = class {
|
|
596569
596721
|
constructor(root) {
|
|
596570
596722
|
this.root = root;
|
|
@@ -596576,15 +596728,20 @@ var init_telegram_creative_tools = __esm({
|
|
|
596576
596728
|
type: "object",
|
|
596577
596729
|
properties: {
|
|
596578
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" },
|
|
596579
596733
|
path: { type: "string", description: "Output .wav path inside the creative workspace" },
|
|
596580
|
-
|
|
596581
|
-
|
|
596734
|
+
backend: { type: "string", enum: ["auto", "luxtts", "supertonic", "mlx", "onnx", "piper", "espeak"], description: "TTS backend. Defaults to auto." },
|
|
596735
|
+
voice: { type: "string", description: "Voice id/name for the selected TTS backend" },
|
|
596736
|
+
clone_ref: { type: "string", description: "Optional LuxTTS clone reference" },
|
|
596737
|
+
model: { type: "string", description: "Optional backend model id or raw Piper/ONNX path" },
|
|
596738
|
+
speed: { type: "number", description: "Speech speed multiplier or backend-specific rate" }
|
|
596582
596739
|
},
|
|
596583
|
-
required: [
|
|
596740
|
+
required: []
|
|
596584
596741
|
};
|
|
596585
596742
|
async execute(args) {
|
|
596586
596743
|
const start2 = performance.now();
|
|
596587
|
-
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() : "";
|
|
596588
596745
|
if (!text) return { success: false, output: "", error: "text is required", durationMs: performance.now() - start2 };
|
|
596589
596746
|
const rawPath = typeof args["path"] === "string" && args["path"].trim() ? String(args["path"]) : `speech-${Date.now()}.wav`;
|
|
596590
596747
|
const guarded = guardPath(this.root, rawPath);
|
|
@@ -596596,15 +596753,23 @@ var init_telegram_creative_tools = __esm({
|
|
|
596596
596753
|
return denied("create_audio_file currently writes WAV files; use a .wav output path.");
|
|
596597
596754
|
}
|
|
596598
596755
|
await mkdir17(dirname33(guarded.path.abs), { recursive: true });
|
|
596599
|
-
const
|
|
596600
|
-
const
|
|
596601
|
-
|
|
596602
|
-
|
|
596756
|
+
const tts = new TtsGenerateTool();
|
|
596757
|
+
const result = await tts.execute({
|
|
596758
|
+
text,
|
|
596759
|
+
output: guarded.path.abs,
|
|
596760
|
+
playback: false,
|
|
596761
|
+
backend: args["backend"],
|
|
596762
|
+
voice: args["voice"],
|
|
596763
|
+
clone_ref: args["clone_ref"],
|
|
596764
|
+
model: args["model"],
|
|
596765
|
+
speed: args["speed"]
|
|
596766
|
+
});
|
|
596767
|
+
if (!result.success || !existsSync104(guarded.path.abs)) {
|
|
596603
596768
|
return {
|
|
596604
596769
|
success: false,
|
|
596605
596770
|
output: "",
|
|
596606
|
-
error: `Audio synthesis failed
|
|
596607
|
-
${(result.
|
|
596771
|
+
error: `Audio synthesis failed through generate_tts.
|
|
596772
|
+
${(result.error || result.output || "").slice(0, 1200)}`,
|
|
596608
596773
|
durationMs: performance.now() - start2
|
|
596609
596774
|
};
|
|
596610
596775
|
}
|
|
@@ -596612,7 +596777,8 @@ ${(result.stderr || result.stdout).slice(0, 800)}`,
|
|
|
596612
596777
|
const sizeKB = Math.round(statSync35(guarded.path.abs).size / 1024);
|
|
596613
596778
|
return {
|
|
596614
596779
|
success: true,
|
|
596615
|
-
output: `Created audio file: ${guarded.path.abs} (${sizeKB}KB WAV)
|
|
596780
|
+
output: `Created audio file: ${guarded.path.abs} (${sizeKB}KB WAV)
|
|
596781
|
+
${result.output}`,
|
|
596616
596782
|
llmContent: `Created audio file at ${guarded.path.abs}.`,
|
|
596617
596783
|
durationMs: performance.now() - start2,
|
|
596618
596784
|
mutated: true,
|
|
@@ -596777,7 +596943,7 @@ var init_vision_ingress = __esm({
|
|
|
596777
596943
|
});
|
|
596778
596944
|
|
|
596779
596945
|
// packages/cli/src/tui/telegram-bridge.ts
|
|
596780
|
-
import { mkdirSync as mkdirSync60, existsSync as existsSync106, unlinkSync as unlinkSync20, statSync as statSync36, readFileSync as readFileSync87, writeFileSync as writeFileSync57 } from "node:fs";
|
|
596946
|
+
import { mkdirSync as mkdirSync60, existsSync as existsSync106, unlinkSync as unlinkSync20, readdirSync as readdirSync36, statSync as statSync36, readFileSync as readFileSync87, writeFileSync as writeFileSync57 } from "node:fs";
|
|
596781
596947
|
import { join as join121, resolve as resolve39, basename as basename23, relative as relative13, isAbsolute as isAbsolute7 } from "node:path";
|
|
596782
596948
|
import { writeFile as writeFileAsync } from "node:fs/promises";
|
|
596783
596949
|
import { createHash as createHash19, randomInt } from "node:crypto";
|
|
@@ -597093,7 +597259,8 @@ function telegramSyntheticHelpSignatures() {
|
|
|
597093
597259
|
return [
|
|
597094
597260
|
{ signature: "/help", description: "Show Telegram command help" },
|
|
597095
597261
|
{ signature: "/start", description: "Show Telegram bridge status and authentication instructions" },
|
|
597096
|
-
{ 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" }
|
|
597097
597264
|
];
|
|
597098
597265
|
}
|
|
597099
597266
|
function telegramHelpCommandAllowed(cmd, scope) {
|
|
@@ -597592,6 +597759,14 @@ You are responding to an ADMIN user in a private Telegram DM. This user has full
|
|
|
597592
597759
|
and is the operator of this agent. You may use all available tools including memory read/write,
|
|
597593
597760
|
file access, and code analysis. Respond thoroughly and helpfully.
|
|
597594
597761
|
|
|
597762
|
+
When asked to send a generated or existing file to Telegram, call telegram_send_file with
|
|
597763
|
+
path and target. Do not search for Telegram bot tokens, environment secrets, or Bot API
|
|
597764
|
+
credentials; upload authorization is encapsulated by telegram_send_file.
|
|
597765
|
+
|
|
597766
|
+
When asked to generate speech, narration, or TTS, use generate_tts or audio_playback.
|
|
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.
|
|
597769
|
+
|
|
597595
597770
|
Keep responses concise for Telegram but don't withhold information from the admin.
|
|
597596
597771
|
`.trim();
|
|
597597
597772
|
ADMIN_GROUP_PROMPT = `
|
|
@@ -597821,6 +597996,8 @@ Telegram response contract:
|
|
|
597821
597996
|
telegramConversationDir;
|
|
597822
597997
|
/** Session keys loaded from persistent conversation memory */
|
|
597823
597998
|
loadedConversationState = /* @__PURE__ */ new Set();
|
|
597999
|
+
/** True once persisted Telegram conversation scopes have been bulk-loaded. */
|
|
598000
|
+
loadedAllConversationState = false;
|
|
597824
598001
|
/** Media metadata store per chat — chatId → metadata entries */
|
|
597825
598002
|
mediaMetadata = /* @__PURE__ */ new Map();
|
|
597826
598003
|
/** Cleanup timer for expired media cache entries */
|
|
@@ -598027,6 +598204,22 @@ Telegram response contract:
|
|
|
598027
598204
|
} catch {
|
|
598028
598205
|
}
|
|
598029
598206
|
}
|
|
598207
|
+
ensureAllTelegramConversationsLoaded() {
|
|
598208
|
+
if (this.loadedAllConversationState) return;
|
|
598209
|
+
this.loadedAllConversationState = true;
|
|
598210
|
+
if (!existsSync106(this.telegramConversationDir)) return;
|
|
598211
|
+
try {
|
|
598212
|
+
for (const file of readdirSync36(this.telegramConversationDir)) {
|
|
598213
|
+
if (!file.endsWith(".json")) continue;
|
|
598214
|
+
try {
|
|
598215
|
+
const parsed = JSON.parse(readFileSync87(join121(this.telegramConversationDir, file), "utf8"));
|
|
598216
|
+
if (parsed.sessionKey) this.ensureTelegramConversationLoaded(parsed.sessionKey);
|
|
598217
|
+
} catch {
|
|
598218
|
+
}
|
|
598219
|
+
}
|
|
598220
|
+
} catch {
|
|
598221
|
+
}
|
|
598222
|
+
}
|
|
598030
598223
|
saveTelegramConversationState(sessionKey) {
|
|
598031
598224
|
if (!this.repoRoot) return;
|
|
598032
598225
|
try {
|
|
@@ -598505,8 +598698,91 @@ ${lines.join("\n")}${suffix}`;
|
|
|
598505
598698
|
Checklist unavailable: ${reason}`;
|
|
598506
598699
|
}
|
|
598507
598700
|
}
|
|
598701
|
+
knownTelegramChatTargets() {
|
|
598702
|
+
this.ensureAllTelegramConversationsLoaded();
|
|
598703
|
+
const targets = /* @__PURE__ */ new Map();
|
|
598704
|
+
for (const [sessionKey, history] of this.chatHistory.entries()) {
|
|
598705
|
+
if (history.length === 0) continue;
|
|
598706
|
+
const latest = [...history].reverse().find((entry) => entry.chatId !== void 0);
|
|
598707
|
+
if (!latest || latest.chatId === void 0) continue;
|
|
598708
|
+
const key = String(latest.chatId);
|
|
598709
|
+
const participants = [...this.chatParticipants.get(sessionKey)?.values() ?? []];
|
|
598710
|
+
const existing = targets.get(key);
|
|
598711
|
+
const target = existing ?? {
|
|
598712
|
+
chatId: latest.chatId,
|
|
598713
|
+
chatType: latest.chatType ?? "private",
|
|
598714
|
+
title: latest.chatTitle,
|
|
598715
|
+
sessionKey,
|
|
598716
|
+
lastSeenTs: latest.ts ?? 0,
|
|
598717
|
+
participantUserIds: [],
|
|
598718
|
+
participantUsernames: []
|
|
598719
|
+
};
|
|
598720
|
+
target.chatType = latest.chatType ?? target.chatType;
|
|
598721
|
+
target.title = latest.chatTitle || target.title;
|
|
598722
|
+
target.lastSeenTs = Math.max(target.lastSeenTs, latest.ts ?? 0);
|
|
598723
|
+
for (const participant of participants) {
|
|
598724
|
+
if (participant.fromUserId && !target.participantUserIds.includes(participant.fromUserId)) {
|
|
598725
|
+
target.participantUserIds.push(participant.fromUserId);
|
|
598726
|
+
}
|
|
598727
|
+
const username = (participant.username || "").replace(/^@/, "").trim().toLowerCase();
|
|
598728
|
+
if (username && username !== "unknown" && !target.participantUsernames.includes(username)) {
|
|
598729
|
+
target.participantUsernames.push(username);
|
|
598730
|
+
}
|
|
598731
|
+
}
|
|
598732
|
+
targets.set(key, target);
|
|
598733
|
+
}
|
|
598734
|
+
return [...targets.values()].sort((a2, b) => b.lastSeenTs - a2.lastSeenTs);
|
|
598735
|
+
}
|
|
598736
|
+
telegramGroupTargetsForSender(msg) {
|
|
598737
|
+
const username = (msg.username || "").replace(/^@/, "").trim().toLowerCase();
|
|
598738
|
+
return this.knownTelegramChatTargets().filter((target) => {
|
|
598739
|
+
if (target.chatType !== "group" && target.chatType !== "supergroup") return false;
|
|
598740
|
+
if (msg.fromUserId && target.participantUserIds.includes(msg.fromUserId)) return true;
|
|
598741
|
+
return !!username && target.participantUsernames.includes(username);
|
|
598742
|
+
});
|
|
598743
|
+
}
|
|
598744
|
+
formatTelegramSendTargetList(targets, max = 14) {
|
|
598745
|
+
if (targets.length === 0) return "";
|
|
598746
|
+
const lines = targets.slice(0, max).map((target) => {
|
|
598747
|
+
const label = target.title ? ` "${target.title}"` : "";
|
|
598748
|
+
const participants = target.participantUsernames.length ? ` participants:@${target.participantUsernames.slice(0, 8).join(", @")}` : "";
|
|
598749
|
+
return `- chat_id ${String(target.chatId)} (${target.chatType}${label}; session ${target.sessionKey})${participants}`;
|
|
598750
|
+
});
|
|
598751
|
+
const suffix = targets.length > lines.length ? `
|
|
598752
|
+
- ... ${targets.length - lines.length} more known chat(s)` : "";
|
|
598753
|
+
return `${lines.join("\n")}${suffix}`;
|
|
598754
|
+
}
|
|
598755
|
+
buildTelegramSendTargetContext(msg, isAdminDM) {
|
|
598756
|
+
if (isAdminDM) {
|
|
598757
|
+
const targets = this.knownTelegramChatTargets();
|
|
598758
|
+
const list = this.formatTelegramSendTargetList(targets, 18);
|
|
598759
|
+
return [
|
|
598760
|
+
"## Telegram Send Targets",
|
|
598761
|
+
"telegram_send_file is the only supported way to send generated/existing files to Telegram. Never look for or reveal the bot token; the bridge already owns upload auth.",
|
|
598762
|
+
"Use target with one of these known chat ids when the admin asks to send a file to a group/private chat:",
|
|
598763
|
+
list || "- No known prior Telegram chats are loaded yet. Numeric chat_id or @username can still be used if the admin provides one."
|
|
598764
|
+
].join("\n");
|
|
598765
|
+
}
|
|
598766
|
+
if (msg.chatType === "private") {
|
|
598767
|
+
const targets = this.telegramGroupTargetsForSender(msg);
|
|
598768
|
+
const list = this.formatTelegramSendTargetList(targets, 10);
|
|
598769
|
+
return [
|
|
598770
|
+
"## Telegram Send Targets",
|
|
598771
|
+
"This private user may send generated files to this DM or to shared public groups where this sender has been observed by the bot. Public groups can never target private DMs.",
|
|
598772
|
+
list ? `Allowed shared group targets:
|
|
598773
|
+
${list}` : "No shared group target is currently known for this sender. Ask in the group once or provide a numeric group chat_id the bot already participates in."
|
|
598774
|
+
].join("\n");
|
|
598775
|
+
}
|
|
598776
|
+
return "";
|
|
598777
|
+
}
|
|
598778
|
+
telegramRunnerStateDir(sessionKey) {
|
|
598779
|
+
if (!this.repoRoot) return void 0;
|
|
598780
|
+
const safe = createHash19("sha1").update(sessionKey).digest("hex").slice(0, 20);
|
|
598781
|
+
return join121(this.repoRoot, ".omnius", "telegram-runner-state", safe);
|
|
598782
|
+
}
|
|
598508
598783
|
buildTelegramAdminOverviewContext(currentSessionKey) {
|
|
598509
598784
|
const sections = [];
|
|
598785
|
+
this.ensureAllTelegramConversationsLoaded();
|
|
598510
598786
|
const chatEntries = [...this.chatHistory.entries()].filter(([sessionKey, history]) => sessionKey !== currentSessionKey && history.length > 0).sort(([, a2], [, b]) => (b[b.length - 1]?.ts ?? 0) - (a2[a2.length - 1]?.ts ?? 0)).slice(0, 18);
|
|
598511
598787
|
for (const [sessionKey, history] of chatEntries) {
|
|
598512
598788
|
const latest = history[history.length - 1];
|
|
@@ -598519,7 +598795,7 @@ Checklist unavailable: ${reason}`;
|
|
|
598519
598795
|
).join("\n");
|
|
598520
598796
|
const cards = (this.chatMemoryCards.get(sessionKey) ?? []).slice(0, 4).map((card) => ` - ${card.title}: ${card.notes.slice(-1)[0] ?? ""}`).join("\n");
|
|
598521
598797
|
sections.push([
|
|
598522
|
-
`- ${sessionKey} (${latest.chatType || "chat"}${latest.chatTitle ? `: ${latest.chatTitle}` : ""})`,
|
|
598798
|
+
`- ${sessionKey} (chat_id ${String(latest.chatId ?? "unknown")}; ${latest.chatType || "chat"}${latest.chatTitle ? `: ${latest.chatTitle}` : ""})`,
|
|
598523
598799
|
participants ? ` Participants: ${participants}` : "",
|
|
598524
598800
|
` Latest: ${telegramHistorySpeaker(latest)}: ${truncateTelegramContextLine(latest.text, 180)}`,
|
|
598525
598801
|
recent ? ` Recent:
|
|
@@ -598560,6 +598836,8 @@ ${chatLabel}`,
|
|
|
598560
598836
|
TELEGRAM_ACTION_RESPONSE_CONTRACT
|
|
598561
598837
|
];
|
|
598562
598838
|
sections.push(conversationStream);
|
|
598839
|
+
const sendTargetContext = this.buildTelegramSendTargetContext(msg, isAdminDM);
|
|
598840
|
+
if (sendTargetContext) sections.push(sendTargetContext);
|
|
598563
598841
|
if (isAdminDM) {
|
|
598564
598842
|
sections.push(`## Admin Capability Contract
|
|
598565
598843
|
|
|
@@ -599374,6 +599652,7 @@ ${mediaContext}` : ""}`
|
|
|
599374
599652
|
const creativeWorkspace = subAgent.creativeWorkspaceRoot ? formatTelegramCreativeWorkspacePrompt(subAgent.creativeWorkspaceRoot) : "";
|
|
599375
599653
|
const sessionContext = this.buildTelegramSessionContext(msg, ctx3, profile, modelTier);
|
|
599376
599654
|
const contextWindowSize = this.contextWindowSize;
|
|
599655
|
+
const runnerStateDir = isAdminDM ? void 0 : this.telegramRunnerStateDir(sessionContext.sessionKey);
|
|
599377
599656
|
const backend = new OllamaAgenticBackend(
|
|
599378
599657
|
config.backendUrl,
|
|
599379
599658
|
config.model,
|
|
@@ -599390,7 +599669,11 @@ ${mediaContext}` : ""}`
|
|
|
599390
599669
|
modelTier,
|
|
599391
599670
|
streamEnabled: true,
|
|
599392
599671
|
dynamicContext: sessionContext.context,
|
|
599393
|
-
|
|
599672
|
+
stateDir: runnerStateDir,
|
|
599673
|
+
sessionId: sessionContext.sessionId,
|
|
599674
|
+
disablePersistentMemory: false,
|
|
599675
|
+
disableCodebaseMap: !isAdminDM,
|
|
599676
|
+
subAgent: !isAdminDM
|
|
599394
599677
|
});
|
|
599395
599678
|
runner.setWorkingDirectory(repoRoot);
|
|
599396
599679
|
subAgent.runner = runner;
|
|
@@ -599406,6 +599689,9 @@ ${mediaContext}` : ""}`
|
|
|
599406
599689
|
runner.onEvent((event) => {
|
|
599407
599690
|
if (subAgent.aborted) return;
|
|
599408
599691
|
let suppressExternalEvent = false;
|
|
599692
|
+
if (!isAdminDM && event.type === "status") {
|
|
599693
|
+
suppressExternalEvent = true;
|
|
599694
|
+
}
|
|
599409
599695
|
if (event.type === "tool_call" && event.toolName) {
|
|
599410
599696
|
if (event.toolName === "task_complete") {
|
|
599411
599697
|
subAgent.completionBoundarySeen = true;
|
|
@@ -599441,7 +599727,9 @@ ${mediaContext}` : ""}`
|
|
|
599441
599727
|
}
|
|
599442
599728
|
}
|
|
599443
599729
|
} else if (event.type === "status" && event.content) {
|
|
599444
|
-
|
|
599730
|
+
if (isAdminDM) {
|
|
599731
|
+
this.subAgentViewCallbacks?.onWrite(subAgent.viewId, `status: ${event.content}`);
|
|
599732
|
+
}
|
|
599445
599733
|
} else if (event.type === "assistant_text" && event.content && event.source !== "task_complete_summary") {
|
|
599446
599734
|
subAgent.assistantText = event.content;
|
|
599447
599735
|
} else if (event.type === "stream_start") {
|
|
@@ -599456,7 +599744,7 @@ ${mediaContext}` : ""}`
|
|
|
599456
599744
|
subAgent.accumulated += event.content;
|
|
599457
599745
|
}
|
|
599458
599746
|
const intermediateLine = formatTelegramProgressEvent(event);
|
|
599459
|
-
if (intermediateLine) {
|
|
599747
|
+
if (intermediateLine && (isAdminDM || event.type !== "status")) {
|
|
599460
599748
|
subAgent.intermediateLines.push(intermediateLine);
|
|
599461
599749
|
}
|
|
599462
599750
|
if (!msg.guestQueryId) {
|
|
@@ -599878,6 +600166,9 @@ Scoped workspace: ${scopedRoot}`,
|
|
|
599878
600166
|
new PlaywrightBrowserTool(),
|
|
599879
600167
|
new ImageGenerateTool(repoRoot, this.agentConfig?.backendUrl, imageDefaults),
|
|
599880
600168
|
new AudioGenerateTool(repoRoot, audioDefaults),
|
|
600169
|
+
new TtsGenerateTool(),
|
|
600170
|
+
new AudioPlaybackTool(),
|
|
600171
|
+
new SoundPlaybackTool(),
|
|
599881
600172
|
new NotebookEditTool(),
|
|
599882
600173
|
new RepoMapTool(repoRoot),
|
|
599883
600174
|
new ImportGraphTool(repoRoot),
|
|
@@ -599886,7 +600177,7 @@ Scoped workspace: ${scopedRoot}`,
|
|
|
599886
600177
|
new CodeNeighborsTool(repoRoot),
|
|
599887
600178
|
new ProcessHealthTool(),
|
|
599888
600179
|
fullSubAgentTool,
|
|
599889
|
-
this.buildTelegramSendFileTool(context2, repoRoot, chatId)
|
|
600180
|
+
this.buildTelegramSendFileTool(context2, repoRoot, chatId, msg)
|
|
599890
600181
|
];
|
|
599891
600182
|
const allTools = context2 === "telegram-admin-dm" ? adminTools : sharedReadMemoryWebTools;
|
|
599892
600183
|
if (this.contextWindowSize > 0) {
|
|
@@ -599908,11 +600199,28 @@ Scoped workspace: ${scopedRoot}`,
|
|
|
599908
600199
|
audioDefaults
|
|
599909
600200
|
).map((tool) => adaptTool5(tool, todoSessionId));
|
|
599910
600201
|
adaptedTools.push(...creativeTools);
|
|
599911
|
-
adaptedTools.push(adaptTool5(this.buildTelegramSendFileTool(context2, repoRoot, chatId), todoSessionId));
|
|
599912
|
-
adaptedTools
|
|
600202
|
+
adaptedTools.push(adaptTool5(this.buildTelegramSendFileTool(context2, repoRoot, chatId, msg), todoSessionId));
|
|
600203
|
+
adaptedTools = this.filterNonAdminTelegramTools(adaptedTools);
|
|
599913
600204
|
}
|
|
599914
600205
|
return [...adaptedTools, taskComplete];
|
|
599915
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
|
+
}
|
|
599916
600224
|
imageGenerationDefaultsForRepo(repoRoot) {
|
|
599917
600225
|
const settings = resolveSettings(repoRoot);
|
|
599918
600226
|
return {
|
|
@@ -599929,13 +600237,13 @@ Scoped workspace: ${scopedRoot}`,
|
|
|
599929
600237
|
musicBackend: settings.musicBackend
|
|
599930
600238
|
};
|
|
599931
600239
|
}
|
|
599932
|
-
buildTelegramSendFileTool(context2, repoRoot, currentChatId) {
|
|
600240
|
+
buildTelegramSendFileTool(context2, repoRoot, currentChatId, currentMsg) {
|
|
599933
600241
|
const bridge = this;
|
|
599934
600242
|
const adminDm = context2 === "telegram-admin-dm";
|
|
599935
600243
|
const scopedRoot = adminDm ? void 0 : telegramCreativeWorkspaceRoot(repoRoot, currentChatId);
|
|
599936
600244
|
return {
|
|
599937
600245
|
name: "telegram_send_file",
|
|
599938
|
-
description: adminDm ? "Upload an existing local file to a Telegram
|
|
600246
|
+
description: adminDm ? "Upload an existing local file to a Telegram target. Use target=<chat_id|user_id|@username> to send to a specific group/user the bot can message. This only sends the file; it does not create, edit, delete, or inspect bot tokens." : currentMsg?.chatType === "private" ? `Upload an existing file from this private chat's scoped creative workspace. target may be omitted for this DM or set to a known shared group chat_id for this sender. It cannot target other private users and cannot send files outside ${scopedRoot}.` : `Upload an existing file from this chat's scoped creative workspace to the current Telegram chat. Public/group scope cannot target private DMs or other chats and cannot send files outside ${scopedRoot}.`,
|
|
599939
600247
|
parameters: {
|
|
599940
600248
|
type: "object",
|
|
599941
600249
|
properties: {
|
|
@@ -599943,13 +600251,25 @@ Scoped workspace: ${scopedRoot}`,
|
|
|
599943
600251
|
type: "string",
|
|
599944
600252
|
description: adminDm ? "Local file path to send. Relative paths resolve from the repo root; absolute paths are allowed for admin DM." : "File path inside the scoped creative workspace."
|
|
599945
600253
|
},
|
|
600254
|
+
target: {
|
|
600255
|
+
type: "string",
|
|
600256
|
+
description: adminDm ? "Optional target chat/user. Use a known numeric group chat_id (for example -100...), a numeric user id, or @username. Defaults to the current private chat." : currentMsg?.chatType === "private" ? "Optional target. Omit for this DM, or use a known shared group chat_id/title/session key for this sender." : "Public/group scope ignores external targets and may only send to the current chat."
|
|
600257
|
+
},
|
|
599946
600258
|
chat_id: {
|
|
599947
600259
|
type: "string",
|
|
599948
|
-
description: "
|
|
600260
|
+
description: "Alias for target. Admin/private DM only."
|
|
600261
|
+
},
|
|
600262
|
+
target_chat_id: {
|
|
600263
|
+
type: "string",
|
|
600264
|
+
description: "Alias for target/chat_id. Admin/private DM only."
|
|
599949
600265
|
},
|
|
599950
600266
|
user_id: {
|
|
599951
600267
|
type: "string",
|
|
599952
|
-
description: "
|
|
600268
|
+
description: "Alias for target when sending to a numeric Telegram user id from admin/private DM."
|
|
600269
|
+
},
|
|
600270
|
+
username: {
|
|
600271
|
+
type: "string",
|
|
600272
|
+
description: "Alias for target when sending to @username from admin/private DM."
|
|
599953
600273
|
},
|
|
599954
600274
|
kind: {
|
|
599955
600275
|
type: "string",
|
|
@@ -599973,7 +600293,7 @@ Scoped workspace: ${scopedRoot}`,
|
|
|
599973
600293
|
if (!rawPath) {
|
|
599974
600294
|
return { success: false, output: "", error: "path is required", durationMs: performance.now() - start2 };
|
|
599975
600295
|
}
|
|
599976
|
-
const target = bridge.resolveTelegramFileTarget(args, currentChatId, adminDm);
|
|
600296
|
+
const target = bridge.resolveTelegramFileTarget(args, currentChatId, adminDm, currentMsg);
|
|
599977
600297
|
if (!target.ok) {
|
|
599978
600298
|
return { success: false, output: "", error: target.error, durationMs: performance.now() - start2 };
|
|
599979
600299
|
}
|
|
@@ -600009,9 +600329,34 @@ Scoped workspace: ${scopedRoot}`,
|
|
|
600009
600329
|
}
|
|
600010
600330
|
};
|
|
600011
600331
|
}
|
|
600012
|
-
resolveTelegramFileTarget(args, currentChatId, adminDm) {
|
|
600013
|
-
const rawTarget = args["chat_id"] ?? args["target_chat_id"] ?? args["user_id"] ?? args["username"];
|
|
600332
|
+
resolveTelegramFileTarget(args, currentChatId, adminDm, currentMsg) {
|
|
600333
|
+
const rawTarget = args["target"] ?? args["chat_id"] ?? args["target_chat_id"] ?? args["user_id"] ?? args["username"];
|
|
600014
600334
|
if (!adminDm) {
|
|
600335
|
+
if (currentMsg?.chatType === "private") {
|
|
600336
|
+
if (rawTarget === void 0 || !String(rawTarget).trim()) {
|
|
600337
|
+
if (currentChatId === void 0) return { ok: false, error: "Current Telegram chat id is unavailable." };
|
|
600338
|
+
return { ok: true, chatId: currentChatId };
|
|
600339
|
+
}
|
|
600340
|
+
const target2 = String(rawTarget).trim();
|
|
600341
|
+
if (currentChatId !== void 0 && target2 === String(currentChatId)) {
|
|
600342
|
+
return { ok: true, chatId: currentChatId };
|
|
600343
|
+
}
|
|
600344
|
+
const knownGroups = this.telegramGroupTargetsForSender(currentMsg);
|
|
600345
|
+
const normalized = target2.replace(/^@/, "").trim().toLowerCase();
|
|
600346
|
+
const match = knownGroups.find((candidate) => {
|
|
600347
|
+
if (String(candidate.chatId) === target2) return true;
|
|
600348
|
+
if (candidate.sessionKey === target2) return true;
|
|
600349
|
+
if (candidate.title && candidate.title.trim().toLowerCase() === normalized) return true;
|
|
600350
|
+
return false;
|
|
600351
|
+
});
|
|
600352
|
+
if (match) return { ok: true, chatId: match.chatId };
|
|
600353
|
+
const knownList = this.formatTelegramSendTargetList(knownGroups, 8);
|
|
600354
|
+
return {
|
|
600355
|
+
ok: false,
|
|
600356
|
+
error: knownList ? `Private-user telegram_send_file target must be this DM or a known shared group for this sender. Known shared groups:
|
|
600357
|
+
${knownList}` : "Private-user telegram_send_file target must be this DM or a known shared group for this sender. No shared group is currently known."
|
|
600358
|
+
};
|
|
600359
|
+
}
|
|
600015
600360
|
if (rawTarget !== void 0 && String(rawTarget).trim() && String(rawTarget).trim() !== String(currentChatId)) {
|
|
600016
600361
|
return { ok: false, error: "Public/group telegram_send_file cannot target another chat. It may only send to the current chat." };
|
|
600017
600362
|
}
|
|
@@ -600037,6 +600382,10 @@ Scoped workspace: ${scopedRoot}`,
|
|
|
600037
600382
|
if (scopedRoot && !isPathInside(base3, abs)) {
|
|
600038
600383
|
return { ok: false, error: `Public/group telegram_send_file can only send files inside ${base3}.` };
|
|
600039
600384
|
}
|
|
600385
|
+
if (scopedRoot) {
|
|
600386
|
+
const policyError = publicCreativeArtifactPolicyError(abs);
|
|
600387
|
+
if (policyError) return { ok: false, error: policyError };
|
|
600388
|
+
}
|
|
600040
600389
|
if (!existsSync106(abs)) return { ok: false, error: `File does not exist: ${trimmed}` };
|
|
600041
600390
|
if (!statSync36(abs).isFile()) return { ok: false, error: `Path is not a file: ${trimmed}` };
|
|
600042
600391
|
return { ok: true, path: abs };
|
|
@@ -604417,7 +604766,7 @@ __export(graphical_sudo_exports, {
|
|
|
604417
604766
|
detectSudoHelper: () => detectSudoHelper,
|
|
604418
604767
|
runGraphicalSudo: () => runGraphicalSudo
|
|
604419
604768
|
});
|
|
604420
|
-
import { spawn as
|
|
604769
|
+
import { spawn as spawn27 } from "node:child_process";
|
|
604421
604770
|
import { existsSync as existsSync115, mkdirSync as mkdirSync67, writeFileSync as writeFileSync62, chmodSync as chmodSync2 } from "node:fs";
|
|
604422
604771
|
import { join as join129 } from "node:path";
|
|
604423
604772
|
import { tmpdir as tmpdir21 } from "node:os";
|
|
@@ -604487,7 +604836,7 @@ async function runGraphicalSudo(opts) {
|
|
|
604487
604836
|
args = ["/bin/bash", opts.scriptPath, ...opts.args ?? []];
|
|
604488
604837
|
}
|
|
604489
604838
|
return new Promise((resolve48, reject) => {
|
|
604490
|
-
const child =
|
|
604839
|
+
const child = spawn27(cmd, args, {
|
|
604491
604840
|
env: { ...process.env, ...opts.env || {}, ...extraEnv },
|
|
604492
604841
|
stdio: ["ignore", "pipe", "pipe"]
|
|
604493
604842
|
});
|
|
@@ -616921,7 +617270,7 @@ var init_profiles = __esm({
|
|
|
616921
617270
|
});
|
|
616922
617271
|
|
|
616923
617272
|
// packages/cli/src/docker.ts
|
|
616924
|
-
import { execSync as execSync56, spawn as
|
|
617273
|
+
import { execSync as execSync56, spawn as spawn28 } from "node:child_process";
|
|
616925
617274
|
import { existsSync as existsSync119, mkdirSync as mkdirSync70, writeFileSync as writeFileSync65 } from "node:fs";
|
|
616926
617275
|
import { join as join133, resolve as resolve42, dirname as dirname36 } from "node:path";
|
|
616927
617276
|
import { homedir as homedir44 } from "node:os";
|
|
@@ -617202,7 +617551,7 @@ function runInContainer(opts) {
|
|
|
617202
617551
|
if (opts.maxTurns) omniusArgs.push("--max-turns", String(opts.maxTurns));
|
|
617203
617552
|
if (opts.timeoutS) omniusArgs.push("--timeout", String(opts.timeoutS));
|
|
617204
617553
|
args.push(...omniusArgs);
|
|
617205
|
-
return
|
|
617554
|
+
return spawn28("docker", args, {
|
|
617206
617555
|
stdio: ["ignore", "pipe", "pipe"]
|
|
617207
617556
|
});
|
|
617208
617557
|
}
|
|
@@ -617405,7 +617754,7 @@ import { createRequire as createRequire7 } from "node:module";
|
|
|
617405
617754
|
import { fileURLToPath as fileURLToPath17 } from "node:url";
|
|
617406
617755
|
import { dirname as dirname37, join as join135, resolve as resolve43 } from "node:path";
|
|
617407
617756
|
import { homedir as homedir45 } from "node:os";
|
|
617408
|
-
import { spawn as
|
|
617757
|
+
import { spawn as spawn29, execSync as execSync57 } from "node:child_process";
|
|
617409
617758
|
import { mkdirSync as mkdirSync71, writeFileSync as writeFileSync66, readFileSync as readFileSync98, readdirSync as readdirSync41, existsSync as existsSync120, watch as fsWatch3, renameSync as renameSync8, unlinkSync as unlinkSync24 } from "node:fs";
|
|
617410
617759
|
import { randomBytes as randomBytes23, randomUUID as randomUUID16 } from "node:crypto";
|
|
617411
617760
|
import { createHash as createHash23 } from "node:crypto";
|
|
@@ -619678,7 +620027,7 @@ ${task}` : task;
|
|
|
619678
620027
|
runEnv["OMNIUS_RUN_SCOPE"] = req2._authScope || "admin";
|
|
619679
620028
|
runEnv["OLLAMA_HOST"] = currentCfg.backendUrl || process.env["OLLAMA_HOST"] || "http://127.0.0.1:11434";
|
|
619680
620029
|
if (currentCfg.apiKey) runEnv["OMNIUS_API_KEY_INHERIT"] = currentCfg.apiKey;
|
|
619681
|
-
const child =
|
|
620030
|
+
const child = spawn29(process.execPath, [omniusBin, ...args], {
|
|
619682
620031
|
cwd: resolve43(process.cwd()),
|
|
619683
620032
|
env: runEnv,
|
|
619684
620033
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -620007,7 +620356,7 @@ async function handleV1Update(req2, res, requestId) {
|
|
|
620007
620356
|
cleanEnv.PATH = pathParts.join(":");
|
|
620008
620357
|
let child;
|
|
620009
620358
|
if (isWin2) {
|
|
620010
|
-
child =
|
|
620359
|
+
child = spawn29(npmBin, ["install", "-g", pkgSpec, "--no-audit", "--no-fund", "--no-progress"], {
|
|
620011
620360
|
detached: true,
|
|
620012
620361
|
stdio: ["ignore", logFd, logFd],
|
|
620013
620362
|
windowsHide: true,
|
|
@@ -620029,13 +620378,13 @@ async function handleV1Update(req2, res, requestId) {
|
|
|
620029
620378
|
}
|
|
620030
620379
|
}
|
|
620031
620380
|
if (npmCli) {
|
|
620032
|
-
child =
|
|
620381
|
+
child = spawn29(nodeBin, [npmCli, "install", "-g", pkgSpec, "--no-audit", "--no-fund", "--no-progress"], {
|
|
620033
620382
|
detached: true,
|
|
620034
620383
|
stdio: ["ignore", logFd, logFd],
|
|
620035
620384
|
env: cleanEnv
|
|
620036
620385
|
});
|
|
620037
620386
|
} else {
|
|
620038
|
-
child =
|
|
620387
|
+
child = spawn29(npmBin, ["install", "-g", pkgSpec, "--no-audit", "--no-fund", "--no-progress"], {
|
|
620039
620388
|
detached: true,
|
|
620040
620389
|
stdio: ["ignore", logFd, logFd],
|
|
620041
620390
|
env: cleanEnv
|
|
@@ -620046,7 +620395,7 @@ async function handleV1Update(req2, res, requestId) {
|
|
|
620046
620395
|
const installPid = child.pid ?? 0;
|
|
620047
620396
|
if (installPid > 0 && !isWin2) {
|
|
620048
620397
|
try {
|
|
620049
|
-
const follower =
|
|
620398
|
+
const follower = spawn29("bash", ["-c", `while kill -0 ${installPid} 2>/dev/null; do sleep 1; done; echo "__EXIT_CODE=0" >> "${logPath3}"`], {
|
|
620050
620399
|
detached: true,
|
|
620051
620400
|
stdio: "ignore"
|
|
620052
620401
|
});
|
|
@@ -620069,7 +620418,7 @@ async function handleV1Update(req2, res, requestId) {
|
|
|
620069
620418
|
hasSystemdUnit ? `systemctl --user restart omnius-daemon.service >/dev/null 2>&1 || true` : `${JSON.stringify(omniusAbs)} serve --quiet --daemon >/dev/null 2>&1 & disown`,
|
|
620070
620419
|
`kill -TERM ${process.pid} >/dev/null 2>&1 || true`
|
|
620071
620420
|
].join("; ");
|
|
620072
|
-
const relauncher =
|
|
620421
|
+
const relauncher = spawn29("bash", ["-c", relaunchScript], {
|
|
620073
620422
|
detached: true,
|
|
620074
620423
|
stdio: "ignore",
|
|
620075
620424
|
env: cleanEnv
|
|
@@ -620291,7 +620640,7 @@ async function handleV1Run(req2, res) {
|
|
|
620291
620640
|
});
|
|
620292
620641
|
job.sandbox = "container";
|
|
620293
620642
|
} else {
|
|
620294
|
-
child =
|
|
620643
|
+
child = spawn29(process.execPath, [omniusBin, ...args], {
|
|
620295
620644
|
cwd: cwd4,
|
|
620296
620645
|
env: runEnv,
|
|
620297
620646
|
stdio: ["ignore", "pipe", "pipe"],
|
|
@@ -622270,7 +622619,7 @@ ${historyLines}
|
|
|
622270
622619
|
}
|
|
622271
622620
|
runEnv["OLLAMA_HOST"] = currentCfg.backendUrl || process.env["OLLAMA_HOST"] || "http://127.0.0.1:11434";
|
|
622272
622621
|
if (currentCfg.apiKey) runEnv["OMNIUS_API_KEY_INHERIT"] = currentCfg.apiKey;
|
|
622273
|
-
const child =
|
|
622622
|
+
const child = spawn29(process.execPath, [omniusBin, ...args], {
|
|
622274
622623
|
cwd: cwdPath,
|
|
622275
622624
|
env: runEnv,
|
|
622276
622625
|
stdio: ["ignore", "pipe", "pipe"],
|
|
@@ -624842,7 +625191,7 @@ var init_clipboard_media = __esm({
|
|
|
624842
625191
|
|
|
624843
625192
|
// packages/cli/src/tui/interactive.ts
|
|
624844
625193
|
import { cwd } from "node:process";
|
|
624845
|
-
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";
|
|
624846
625195
|
import { createRequire as createRequire8 } from "node:module";
|
|
624847
625196
|
import { fileURLToPath as fileURLToPath18 } from "node:url";
|
|
624848
625197
|
import {
|
|
@@ -632144,7 +632493,7 @@ Execute this skill now. Follow the behavioral guidance above.`;
|
|
|
632144
632493
|
const imgPath = resolve44(repoRoot, cleanPath);
|
|
632145
632494
|
const imgBuffer = readFileSync100(imgPath);
|
|
632146
632495
|
const base642 = imgBuffer.toString("base64");
|
|
632147
|
-
const ext =
|
|
632496
|
+
const ext = extname15(cleanPath).toLowerCase();
|
|
632148
632497
|
const mime = ext === ".png" ? "image/png" : ext === ".gif" ? "image/gif" : ext === ".webp" ? "image/webp" : "image/jpeg";
|
|
632149
632498
|
const asciiContext = await renderAsciiPreviewForImage(
|
|
632150
632499
|
imgPath,
|
|
@@ -633325,7 +633674,7 @@ __export(run_exports, {
|
|
|
633325
633674
|
statusCommand: () => statusCommand
|
|
633326
633675
|
});
|
|
633327
633676
|
import { resolve as resolve45 } from "node:path";
|
|
633328
|
-
import { spawn as
|
|
633677
|
+
import { spawn as spawn30 } from "node:child_process";
|
|
633329
633678
|
import { mkdirSync as mkdirSync74, writeFileSync as writeFileSync69, readFileSync as readFileSync101, readdirSync as readdirSync43, existsSync as existsSync122 } from "node:fs";
|
|
633330
633679
|
import { randomBytes as randomBytes24 } from "node:crypto";
|
|
633331
633680
|
import { join as join138 } from "node:path";
|
|
@@ -633438,7 +633787,7 @@ async function runBackground(task, config, opts) {
|
|
|
633438
633787
|
const omniusBin = process.argv[1] || "omnius";
|
|
633439
633788
|
const args = [task, "--json"];
|
|
633440
633789
|
if (config.model) args.push("--model", config.model);
|
|
633441
|
-
const child =
|
|
633790
|
+
const child = spawn30(process.execPath, [omniusBin, ...args], {
|
|
633442
633791
|
cwd: repoRoot,
|
|
633443
633792
|
env: { ...process.env, OMNIUS_JOB_ID: id },
|
|
633444
633793
|
stdio: ["ignore", "pipe", "pipe"],
|
|
@@ -634626,9 +634975,9 @@ async function main() {
|
|
|
634626
634975
|
const mode = process.argv[process.argv.indexOf("--self-test") + 1] || "crossmodal";
|
|
634627
634976
|
if (mode === "crossmodal") {
|
|
634628
634977
|
process.stdout.write("Running crossmodal smoke tests...\n");
|
|
634629
|
-
const { spawn:
|
|
634978
|
+
const { spawn: spawn31 } = await import("node:child_process");
|
|
634630
634979
|
const run = (file) => new Promise((resolve48, reject) => {
|
|
634631
|
-
const p2 =
|
|
634980
|
+
const p2 = spawn31(process.execPath, [file], { stdio: ["ignore", "pipe", "pipe"] });
|
|
634632
634981
|
p2.stdout.on("data", (d2) => process.stdout.write(d2));
|
|
634633
634982
|
p2.stderr.on("data", (d2) => process.stdout.write(d2));
|
|
634634
634983
|
onChildExit(p2, (code8) => code8 === 0 ? resolve48() : reject(new Error(`${file} exited ${code8}`)));
|