@johpaz/hive-agents 0.0.30 → 0.0.32
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/README.md +16 -16
- package/dist/hive.js +583 -333
- package/package.json +1 -1
package/dist/hive.js
CHANGED
|
@@ -476741,18 +476741,320 @@ var init_models5 = __esm(() => {
|
|
|
476741
476741
|
];
|
|
476742
476742
|
});
|
|
476743
476743
|
|
|
476744
|
-
// packages/
|
|
476745
|
-
|
|
476744
|
+
// packages/tts/src/detect.ts
|
|
476745
|
+
function detectPlatform() {
|
|
476746
|
+
const os2 = process.platform;
|
|
476747
|
+
const arch = process.arch;
|
|
476748
|
+
if (os2 === "linux" && arch === "x64")
|
|
476749
|
+
return "linux-x64";
|
|
476750
|
+
if (os2 === "linux" && arch === "arm64")
|
|
476751
|
+
return "linux-arm64";
|
|
476752
|
+
if (os2 === "win32" && arch === "x64")
|
|
476753
|
+
return "windows-x64";
|
|
476754
|
+
if (os2 === "darwin" && arch === "x64")
|
|
476755
|
+
return "macos-x64";
|
|
476756
|
+
if (os2 === "darwin" && arch === "arm64")
|
|
476757
|
+
return "macos-arm64";
|
|
476758
|
+
throw new Error(`Plataforma no soportada: ${os2}/${arch}`);
|
|
476759
|
+
}
|
|
476760
|
+
function getPiperBinaryName(platform2) {
|
|
476761
|
+
return platform2.startsWith("windows") ? "piper.exe" : "piper";
|
|
476762
|
+
}
|
|
476763
|
+
var PIPER_VERSION = "2023.11.14-2", PIPER_BASE_URL, PIPER_URLS, DEFAULT_VOICE = "es_MX-claude-14947-epoch-high", VOICE_BASE_URL = "https://huggingface.co/spaces/HirCoir/Piper-TTS-Spanish", VOICE_URLS;
|
|
476764
|
+
var init_detect = __esm(() => {
|
|
476765
|
+
PIPER_BASE_URL = `https://github.com/rhasspy/piper/releases/download/${PIPER_VERSION}`;
|
|
476766
|
+
PIPER_URLS = {
|
|
476767
|
+
"linux-x64": `${PIPER_BASE_URL}/piper_linux_x86_64.tar.gz`,
|
|
476768
|
+
"linux-arm64": `${PIPER_BASE_URL}/piper_linux_aarch64.tar.gz`,
|
|
476769
|
+
"windows-x64": `${PIPER_BASE_URL}/piper_windows_amd64.zip`,
|
|
476770
|
+
"macos-x64": `${PIPER_BASE_URL}/piper_macos_x86_64.tar.gz`,
|
|
476771
|
+
"macos-arm64": `${PIPER_BASE_URL}/piper_macos_aarch64.tar.gz`
|
|
476772
|
+
};
|
|
476773
|
+
VOICE_URLS = {
|
|
476774
|
+
model: `${VOICE_BASE_URL}/resolve/main/es_MX-claude-14947-epoch-high.onnx`,
|
|
476775
|
+
config: `${VOICE_BASE_URL}/resolve/main/es_MX-claude-14947-epoch-high.onnx.json`
|
|
476776
|
+
};
|
|
476777
|
+
});
|
|
476778
|
+
|
|
476779
|
+
// packages/tts/src/install.ts
|
|
476780
|
+
import { existsSync as existsSync25, mkdirSync as mkdirSync15, readdirSync as readdirSync4, renameSync as renameSync2 } from "fs";
|
|
476746
476781
|
import { join as join18 } from "path";
|
|
476782
|
+
async function downloadFile2(url2, dest) {
|
|
476783
|
+
const filename = url2.split("/").pop();
|
|
476784
|
+
log76.info(`Descargando ${filename}...`);
|
|
476785
|
+
const res = await fetch(url2);
|
|
476786
|
+
if (!res.ok)
|
|
476787
|
+
throw new Error(`HTTP ${res.status} al descargar ${url2}`);
|
|
476788
|
+
const buf = await res.arrayBuffer();
|
|
476789
|
+
await Bun.write(dest, buf);
|
|
476790
|
+
log76.info(`${filename} \u2014 ${(buf.byteLength / 1024 / 1024).toFixed(1)} MB`);
|
|
476791
|
+
}
|
|
476792
|
+
async function extractTarGz(archivePath, destDir) {
|
|
476793
|
+
const code2 = await Bun.spawn(["tar", "-xzf", archivePath, "-C", destDir], {
|
|
476794
|
+
stdout: "inherit",
|
|
476795
|
+
stderr: "inherit"
|
|
476796
|
+
}).exited;
|
|
476797
|
+
if (code2 !== 0)
|
|
476798
|
+
throw new Error(`tar fall\xF3 con c\xF3digo ${code2}`);
|
|
476799
|
+
await Bun.spawn(["rm", "-f", archivePath]).exited;
|
|
476800
|
+
}
|
|
476801
|
+
async function extractZip(archivePath, destDir) {
|
|
476802
|
+
const code2 = await Bun.spawn(["unzip", "-q", archivePath, "-d", destDir], {
|
|
476803
|
+
stdout: "inherit",
|
|
476804
|
+
stderr: "inherit"
|
|
476805
|
+
}).exited;
|
|
476806
|
+
if (code2 !== 0)
|
|
476807
|
+
throw new Error(`unzip fall\xF3 con c\xF3digo ${code2}`);
|
|
476808
|
+
await Bun.spawn(["rm", "-f", archivePath]).exited;
|
|
476809
|
+
}
|
|
476810
|
+
async function runInstall(ttsRoot) {
|
|
476811
|
+
const BIN_DIR = join18(ttsRoot, "bin");
|
|
476812
|
+
const VOICES_DIR = join18(ttsRoot, "voices");
|
|
476813
|
+
mkdirSync15(BIN_DIR, { recursive: true });
|
|
476814
|
+
mkdirSync15(VOICES_DIR, { recursive: true });
|
|
476815
|
+
const platform2 = detectPlatform();
|
|
476816
|
+
const binaryName = getPiperBinaryName(platform2);
|
|
476817
|
+
const binaryPath = join18(BIN_DIR, binaryName);
|
|
476818
|
+
if (!existsSync25(binaryPath)) {
|
|
476819
|
+
const url2 = PIPER_URLS[platform2];
|
|
476820
|
+
const archiveExt = url2.endsWith(".zip") ? ".zip" : ".tar.gz";
|
|
476821
|
+
const archivePath = join18(BIN_DIR, `piper${archiveExt}`);
|
|
476822
|
+
log76.info(`Instalando Piper para ${platform2}...`);
|
|
476823
|
+
await downloadFile2(url2, archivePath);
|
|
476824
|
+
log76.info("Extrayendo...");
|
|
476825
|
+
if (archiveExt === ".zip") {
|
|
476826
|
+
await extractZip(archivePath, BIN_DIR);
|
|
476827
|
+
} else {
|
|
476828
|
+
await extractTarGz(archivePath, BIN_DIR);
|
|
476829
|
+
}
|
|
476830
|
+
const piperSubdir = join18(BIN_DIR, "piper");
|
|
476831
|
+
if (existsSync25(piperSubdir)) {
|
|
476832
|
+
const tempDir = join18(BIN_DIR, "_piper_tmp");
|
|
476833
|
+
renameSync2(piperSubdir, tempDir);
|
|
476834
|
+
for (const entry of readdirSync4(tempDir)) {
|
|
476835
|
+
renameSync2(join18(tempDir, entry), join18(BIN_DIR, entry));
|
|
476836
|
+
}
|
|
476837
|
+
await Bun.spawn(["rm", "-rf", tempDir]).exited;
|
|
476838
|
+
}
|
|
476839
|
+
if (!existsSync25(binaryPath)) {
|
|
476840
|
+
throw new Error(`Binario no encontrado tras extracci\xF3n: ${binaryPath}`);
|
|
476841
|
+
}
|
|
476842
|
+
if (!platform2.startsWith("windows")) {
|
|
476843
|
+
await Bun.spawn(["chmod", "+x", binaryPath]).exited;
|
|
476844
|
+
}
|
|
476845
|
+
log76.info(`Piper instalado en ${BIN_DIR}`);
|
|
476846
|
+
} else {
|
|
476847
|
+
log76.info("Piper ya instalado, omitiendo descarga.");
|
|
476848
|
+
}
|
|
476849
|
+
const modelPath = join18(VOICES_DIR, `${DEFAULT_VOICE}.onnx`);
|
|
476850
|
+
const configPath = join18(VOICES_DIR, `${DEFAULT_VOICE}.onnx.json`);
|
|
476851
|
+
if (!existsSync25(modelPath) || !existsSync25(configPath)) {
|
|
476852
|
+
log76.info(`Descargando modelo de voz ${DEFAULT_VOICE}...`);
|
|
476853
|
+
await downloadFile2(VOICE_URLS.model, modelPath);
|
|
476854
|
+
await downloadFile2(VOICE_URLS.config, configPath);
|
|
476855
|
+
log76.info(`Voz instalada en ${VOICES_DIR}`);
|
|
476856
|
+
} else {
|
|
476857
|
+
log76.info("Modelo de voz ya instalado, omitiendo descarga.");
|
|
476858
|
+
}
|
|
476859
|
+
log76.info("Hive TTS listo.");
|
|
476860
|
+
}
|
|
476861
|
+
var log76;
|
|
476862
|
+
var init_install = __esm(() => {
|
|
476863
|
+
init_detect();
|
|
476864
|
+
log76 = {
|
|
476865
|
+
info: (msg) => console.log(`[TTS] ${msg}`),
|
|
476866
|
+
warn: (msg) => console.warn(`[TTS] ${msg}`),
|
|
476867
|
+
error: (msg) => console.error(`[TTS] ${msg}`)
|
|
476868
|
+
};
|
|
476869
|
+
if (false) {}
|
|
476870
|
+
});
|
|
476871
|
+
|
|
476872
|
+
// packages/tts/src/server.ts
|
|
476873
|
+
import { existsSync as existsSync26, readdirSync as readdirSync5, readFileSync as readFileSync12 } from "fs";
|
|
476874
|
+
import { join as join19 } from "path";
|
|
476875
|
+
import { homedir as homedir3 } from "os";
|
|
476876
|
+
function getPiperPath() {
|
|
476877
|
+
const platform2 = detectPlatform();
|
|
476878
|
+
const binaryName = getPiperBinaryName(platform2);
|
|
476879
|
+
const binaryPath = join19(BIN_DIR, binaryName);
|
|
476880
|
+
if (!existsSync26(binaryPath)) {
|
|
476881
|
+
throw new Error("Piper no instalado. Ejecuta: bun run src/install.ts");
|
|
476882
|
+
}
|
|
476883
|
+
return binaryPath;
|
|
476884
|
+
}
|
|
476885
|
+
function listVoices() {
|
|
476886
|
+
if (!existsSync26(VOICES_DIR))
|
|
476887
|
+
return [];
|
|
476888
|
+
return readdirSync5(VOICES_DIR).filter((f2) => f2.endsWith(".onnx")).map((f2) => f2.replace(".onnx", ""));
|
|
476889
|
+
}
|
|
476890
|
+
async function synthesize(text2, voice) {
|
|
476891
|
+
const piperPath = getPiperPath();
|
|
476892
|
+
const modelPath = join19(VOICES_DIR, `${voice}.onnx`);
|
|
476893
|
+
const configPath = join19(VOICES_DIR, `${voice}.onnx.json`);
|
|
476894
|
+
if (!existsSync26(modelPath)) {
|
|
476895
|
+
throw new Error(`Voz no encontrada: ${voice}`);
|
|
476896
|
+
}
|
|
476897
|
+
let lengthScale = 0.95;
|
|
476898
|
+
let noiseScale = 0.6;
|
|
476899
|
+
let noiseW = 0.75;
|
|
476900
|
+
let sentenceSilence = 0.2;
|
|
476901
|
+
if (existsSync26(configPath)) {
|
|
476902
|
+
try {
|
|
476903
|
+
const config2 = JSON.parse(readFileSync12(configPath, "utf-8"));
|
|
476904
|
+
const inference = config2.inference || {};
|
|
476905
|
+
lengthScale = (inference.length_scale ?? 1) * 0.95;
|
|
476906
|
+
noiseScale = (inference.noise_scale ?? 0.667) * 0.9;
|
|
476907
|
+
noiseW = (inference.noise_w ?? 0.8) * 0.95;
|
|
476908
|
+
} catch (err) {
|
|
476909
|
+
log77.warn(`No se pudo leer configuraci\xF3n del modelo: ${err}`);
|
|
476910
|
+
}
|
|
476911
|
+
}
|
|
476912
|
+
lengthScale = Number(process.env.PIPER_LENGTH_SCALE ?? lengthScale);
|
|
476913
|
+
noiseScale = Number(process.env.PIPER_NOISE_SCALE ?? noiseScale);
|
|
476914
|
+
noiseW = Number(process.env.PIPER_NOISE_W ?? noiseW);
|
|
476915
|
+
sentenceSilence = Number(process.env.PIPER_SENTENCE_SILENCE ?? sentenceSilence);
|
|
476916
|
+
const args = [
|
|
476917
|
+
piperPath,
|
|
476918
|
+
"--model",
|
|
476919
|
+
modelPath,
|
|
476920
|
+
"--output-raw",
|
|
476921
|
+
"--length_scale",
|
|
476922
|
+
String(lengthScale),
|
|
476923
|
+
"--noise_scale",
|
|
476924
|
+
String(noiseScale),
|
|
476925
|
+
"--noise_w",
|
|
476926
|
+
String(noiseW),
|
|
476927
|
+
"--sentence_silence",
|
|
476928
|
+
String(sentenceSilence)
|
|
476929
|
+
];
|
|
476930
|
+
const proc = Bun.spawn(args, {
|
|
476931
|
+
stdin: "pipe",
|
|
476932
|
+
stdout: "pipe",
|
|
476933
|
+
stderr: "pipe"
|
|
476934
|
+
});
|
|
476935
|
+
proc.stdin.write(new TextEncoder().encode(text2));
|
|
476936
|
+
proc.stdin.end();
|
|
476937
|
+
const [audioBuffer, exitCode] = await Promise.all([
|
|
476938
|
+
new Response(proc.stdout).arrayBuffer(),
|
|
476939
|
+
proc.exited
|
|
476940
|
+
]);
|
|
476941
|
+
if (exitCode !== 0) {
|
|
476942
|
+
const errText = await new Response(proc.stderr).text();
|
|
476943
|
+
throw new Error(`Piper error (exit ${exitCode}): ${errText}`);
|
|
476944
|
+
}
|
|
476945
|
+
return wrapInWav(audioBuffer, 22050, 1, 16);
|
|
476946
|
+
}
|
|
476947
|
+
function wrapInWav(pcm, sampleRate, channels, bitsPerSample) {
|
|
476948
|
+
const dataSize = pcm.byteLength;
|
|
476949
|
+
const header = new ArrayBuffer(44);
|
|
476950
|
+
const view = new DataView(header);
|
|
476951
|
+
const writeStr = (offset, str2) => {
|
|
476952
|
+
for (let i3 = 0;i3 < str2.length; i3++)
|
|
476953
|
+
view.setUint8(offset + i3, str2.charCodeAt(i3));
|
|
476954
|
+
};
|
|
476955
|
+
writeStr(0, "RIFF");
|
|
476956
|
+
view.setUint32(4, 36 + dataSize, true);
|
|
476957
|
+
writeStr(8, "WAVE");
|
|
476958
|
+
writeStr(12, "fmt ");
|
|
476959
|
+
view.setUint32(16, 16, true);
|
|
476960
|
+
view.setUint16(20, 1, true);
|
|
476961
|
+
view.setUint16(22, channels, true);
|
|
476962
|
+
view.setUint32(24, sampleRate, true);
|
|
476963
|
+
view.setUint32(28, sampleRate * channels * bitsPerSample / 8, true);
|
|
476964
|
+
view.setUint16(32, channels * bitsPerSample / 8, true);
|
|
476965
|
+
view.setUint16(34, bitsPerSample, true);
|
|
476966
|
+
writeStr(36, "data");
|
|
476967
|
+
view.setUint32(40, dataSize, true);
|
|
476968
|
+
const wav = new Uint8Array(44 + dataSize);
|
|
476969
|
+
wav.set(new Uint8Array(header), 0);
|
|
476970
|
+
wav.set(new Uint8Array(pcm), 44);
|
|
476971
|
+
return wav.buffer;
|
|
476972
|
+
}
|
|
476973
|
+
function startTTSServer(opts) {
|
|
476974
|
+
const listenPort = opts?.port ?? PORT;
|
|
476975
|
+
const server = Bun.serve({
|
|
476976
|
+
port: listenPort,
|
|
476977
|
+
async fetch(req) {
|
|
476978
|
+
const url2 = new URL(req.url);
|
|
476979
|
+
if (req.method === "OPTIONS") {
|
|
476980
|
+
return new Response(null, { status: 204, headers: CORS });
|
|
476981
|
+
}
|
|
476982
|
+
if (req.method === "GET" && url2.pathname === "/health") {
|
|
476983
|
+
return Response.json({ ok: true, voice: DEFAULT_VOICE_ENV, voices: listVoices() }, { headers: CORS });
|
|
476984
|
+
}
|
|
476985
|
+
if (req.method === "GET" && url2.pathname === "/voices") {
|
|
476986
|
+
return Response.json({ voices: listVoices() }, { headers: CORS });
|
|
476987
|
+
}
|
|
476988
|
+
if (req.method === "POST" && url2.pathname === "/tts") {
|
|
476989
|
+
let body;
|
|
476990
|
+
try {
|
|
476991
|
+
body = await req.json();
|
|
476992
|
+
} catch {
|
|
476993
|
+
return Response.json({ error: "Body JSON inv\xE1lido" }, { status: 400, headers: CORS });
|
|
476994
|
+
}
|
|
476995
|
+
const { text: text2, voice = DEFAULT_VOICE_ENV } = body;
|
|
476996
|
+
if (!text2 || typeof text2 !== "string" || text2.trim().length === 0) {
|
|
476997
|
+
return Response.json({ error: "Campo 'text' requerido" }, { status: 400, headers: CORS });
|
|
476998
|
+
}
|
|
476999
|
+
if (text2.length > 2000) {
|
|
477000
|
+
return Response.json({ error: "Texto demasiado largo (m\xE1x 2000 chars)" }, { status: 400, headers: CORS });
|
|
477001
|
+
}
|
|
477002
|
+
try {
|
|
477003
|
+
const audio = await synthesize(text2.trim(), voice);
|
|
477004
|
+
return new Response(audio, {
|
|
477005
|
+
headers: {
|
|
477006
|
+
...CORS,
|
|
477007
|
+
"Content-Type": "audio/wav",
|
|
477008
|
+
"Content-Length": String(audio.byteLength)
|
|
477009
|
+
}
|
|
477010
|
+
});
|
|
477011
|
+
} catch (err) {
|
|
477012
|
+
const message = err instanceof Error ? err.message : "Error interno";
|
|
477013
|
+
return Response.json({ error: message }, { status: 500, headers: CORS });
|
|
477014
|
+
}
|
|
477015
|
+
}
|
|
477016
|
+
return Response.json({ error: "Not found" }, { status: 404, headers: CORS });
|
|
477017
|
+
}
|
|
477018
|
+
});
|
|
477019
|
+
log77.info(`Hive TTS Server escuchando en http://localhost:${listenPort}`);
|
|
477020
|
+
log77.info(`Voz por defecto: ${DEFAULT_VOICE_ENV}`);
|
|
477021
|
+
log77.info(`Voces disponibles: ${listVoices().join(", ") || "ninguna (ejecuta install.ts primero)"}`);
|
|
477022
|
+
return server;
|
|
477023
|
+
}
|
|
477024
|
+
var log77, TTS_ROOT, BIN_DIR, VOICES_DIR, PORT, DEFAULT_VOICE_ENV, CORS;
|
|
477025
|
+
var init_server = __esm(() => {
|
|
477026
|
+
init_detect();
|
|
477027
|
+
log77 = {
|
|
477028
|
+
info: (msg) => console.log(`[TTS] ${msg}`),
|
|
477029
|
+
warn: (msg) => console.warn(`[TTS] ${msg}`),
|
|
477030
|
+
error: (msg) => console.error(`[TTS] ${msg}`)
|
|
477031
|
+
};
|
|
477032
|
+
TTS_ROOT = process.env.HIVE_TTS_ROOT ?? join19(process.env.HIVE_HOME ?? join19(homedir3(), ".hive"), "tts");
|
|
477033
|
+
BIN_DIR = join19(TTS_ROOT, "bin");
|
|
477034
|
+
VOICES_DIR = join19(TTS_ROOT, "voices");
|
|
477035
|
+
PORT = Number(process.env.TTS_PORT ?? 5500);
|
|
477036
|
+
DEFAULT_VOICE_ENV = process.env.TTS_VOICE ?? DEFAULT_VOICE;
|
|
477037
|
+
CORS = {
|
|
477038
|
+
"Access-Control-Allow-Origin": "*",
|
|
477039
|
+
"Access-Control-Allow-Methods": "GET, POST, OPTIONS",
|
|
477040
|
+
"Access-Control-Allow-Headers": "Content-Type"
|
|
477041
|
+
};
|
|
477042
|
+
if (false) {}
|
|
477043
|
+
});
|
|
477044
|
+
|
|
477045
|
+
// packages/core/src/gateway/routes/tts-local.ts
|
|
477046
|
+
import { existsSync as existsSync27, readdirSync as readdirSync6, readFileSync as readFileSync13 } from "fs";
|
|
477047
|
+
import { join as join20 } from "path";
|
|
477048
|
+
import { homedir as homedir4 } from "os";
|
|
476747
477049
|
function isInstalled() {
|
|
476748
|
-
const piperExists =
|
|
477050
|
+
const piperExists = existsSync27(BIN_PATH);
|
|
476749
477051
|
const voiceExists = getInstalledVoices().length > 0;
|
|
476750
477052
|
return { piperExists, voiceExists, installed: piperExists && voiceExists };
|
|
476751
477053
|
}
|
|
476752
477054
|
function getInstalledVoices() {
|
|
476753
|
-
if (!
|
|
477055
|
+
if (!existsSync27(VOICES_DIR2))
|
|
476754
477056
|
return [];
|
|
476755
|
-
const files =
|
|
477057
|
+
const files = readdirSync6(VOICES_DIR2);
|
|
476756
477058
|
return files.filter((f2) => f2.endsWith(".onnx")).map((f2) => f2.replace(".onnx", ""));
|
|
476757
477059
|
}
|
|
476758
477060
|
async function isRunning() {
|
|
@@ -476780,7 +477082,7 @@ async function handleGetLocalTTSStatus(req, addCors) {
|
|
|
476780
477082
|
}), req);
|
|
476781
477083
|
}
|
|
476782
477084
|
async function handleGetLocalTTSLogs(req, addCors) {
|
|
476783
|
-
return addCors(Response.json({ logs: installLogs.slice(-100), ttsRoot:
|
|
477085
|
+
return addCors(Response.json({ logs: installLogs.slice(-100), ttsRoot: TTS_ROOT2, bunPath: process.execPath }), req);
|
|
476784
477086
|
}
|
|
476785
477087
|
async function handleInstallLocalTTS(req, addCors) {
|
|
476786
477088
|
if (installing) {
|
|
@@ -476789,57 +477091,28 @@ async function handleInstallLocalTTS(req, addCors) {
|
|
|
476789
477091
|
if (isInstalled().installed) {
|
|
476790
477092
|
return addCors(Response.json({ started: false, reason: "Piper ya est\xE1 instalado" }), req);
|
|
476791
477093
|
}
|
|
476792
|
-
const installScript = join18(TTS_ROOT, "src", "install.ts");
|
|
476793
|
-
if (!existsSync25(installScript)) {
|
|
476794
|
-
return addCors(Response.json({
|
|
476795
|
-
started: false,
|
|
476796
|
-
reason: `Script no encontrado: ${installScript}. Verifica que packages/tts existe.`
|
|
476797
|
-
}, { status: 500 }), req);
|
|
476798
|
-
}
|
|
476799
477094
|
installing = true;
|
|
476800
477095
|
installLogs = [`[${new Date().toISOString()}] Iniciando instalaci\xF3n de Piper...`];
|
|
476801
|
-
installLogs.push(` TTS_ROOT: ${
|
|
476802
|
-
|
|
476803
|
-
|
|
476804
|
-
|
|
476805
|
-
|
|
476806
|
-
|
|
476807
|
-
|
|
476808
|
-
|
|
476809
|
-
|
|
476810
|
-
|
|
476811
|
-
|
|
476812
|
-
|
|
476813
|
-
|
|
476814
|
-
if (done)
|
|
476815
|
-
break;
|
|
476816
|
-
const line = decoder.decode(value).trim();
|
|
476817
|
-
if (line)
|
|
476818
|
-
installLogs.push(line);
|
|
476819
|
-
}
|
|
476820
|
-
})();
|
|
476821
|
-
(async () => {
|
|
476822
|
-
const reader = proc.stderr.getReader();
|
|
476823
|
-
const decoder = new TextDecoder;
|
|
476824
|
-
while (true) {
|
|
476825
|
-
const { done, value } = await reader.read();
|
|
476826
|
-
if (done)
|
|
476827
|
-
break;
|
|
476828
|
-
const line = decoder.decode(value).trim();
|
|
476829
|
-
if (line) {
|
|
476830
|
-
installLogs.push(`[stderr] ${line}`);
|
|
476831
|
-
console.error(`[hive-tts install] ${line}`);
|
|
476832
|
-
}
|
|
476833
|
-
}
|
|
476834
|
-
})();
|
|
476835
|
-
proc.exited.then((code2) => {
|
|
476836
|
-
installing = false;
|
|
476837
|
-
installLogs.push(`[${new Date().toISOString()}] Proceso finalizado con c\xF3digo ${code2}`);
|
|
476838
|
-
if (code2 !== 0)
|
|
476839
|
-
console.error(`[hive-tts install] Fall\xF3 con c\xF3digo ${code2}`);
|
|
477096
|
+
installLogs.push(` TTS_ROOT: ${TTS_ROOT2}`);
|
|
477097
|
+
const origLog = console.log;
|
|
477098
|
+
const origWarn = console.warn;
|
|
477099
|
+
console.log = (...args) => {
|
|
477100
|
+
installLogs.push(args.join(" "));
|
|
477101
|
+
origLog(...args);
|
|
477102
|
+
};
|
|
477103
|
+
console.warn = (...args) => {
|
|
477104
|
+
installLogs.push(`[warn] ${args.join(" ")}`);
|
|
477105
|
+
origWarn(...args);
|
|
477106
|
+
};
|
|
477107
|
+
runInstall(TTS_ROOT2).then(() => {
|
|
477108
|
+
installLogs.push(`[${new Date().toISOString()}] Instalaci\xF3n completada`);
|
|
476840
477109
|
}).catch((err) => {
|
|
477110
|
+
installLogs.push(`[error] ${err instanceof Error ? err.message : String(err)}`);
|
|
477111
|
+
console.error(`[hive-tts install] Fall\xF3: ${err}`);
|
|
477112
|
+
}).finally(() => {
|
|
476841
477113
|
installing = false;
|
|
476842
|
-
|
|
477114
|
+
console.log = origLog;
|
|
477115
|
+
console.warn = origWarn;
|
|
476843
477116
|
});
|
|
476844
477117
|
return addCors(Response.json({ started: true }), req);
|
|
476845
477118
|
}
|
|
@@ -476850,48 +477123,27 @@ async function handleStartLocalTTS(req, addCors) {
|
|
|
476850
477123
|
if (!isInstalled().installed) {
|
|
476851
477124
|
return addCors(Response.json({ started: false, reason: "Piper no est\xE1 instalado. Inst\xE1lalo primero." }, { status: 400 }), req);
|
|
476852
477125
|
}
|
|
476853
|
-
|
|
476854
|
-
|
|
476855
|
-
|
|
476856
|
-
|
|
476857
|
-
|
|
476858
|
-
|
|
476859
|
-
|
|
476860
|
-
|
|
476861
|
-
|
|
476862
|
-
const decoder = new TextDecoder;
|
|
476863
|
-
while (true) {
|
|
476864
|
-
const { done, value } = await reader.read();
|
|
476865
|
-
if (done)
|
|
476866
|
-
break;
|
|
476867
|
-
const line = decoder.decode(value).trim();
|
|
476868
|
-
if (line) {
|
|
476869
|
-
installLogs.push(`[tts-server] ${line}`);
|
|
476870
|
-
console.error(`[tts-server] ${line}`);
|
|
476871
|
-
}
|
|
476872
|
-
}
|
|
476873
|
-
})();
|
|
477126
|
+
try {
|
|
477127
|
+
ttsServer = startTTSServer({ port: TTS_PORT });
|
|
477128
|
+
installLogs.push(`[tts-server] Servidor TTS iniciado en puerto ${TTS_PORT}`);
|
|
477129
|
+
} catch (err) {
|
|
477130
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
477131
|
+
console.error(`[tts-server] Fall\xF3 al iniciar: ${msg}`);
|
|
477132
|
+
installLogs.push(`[error] Servidor TTS fall\xF3 al iniciar: ${msg}`);
|
|
477133
|
+
return addCors(Response.json({ started: false, reason: msg }), req);
|
|
477134
|
+
}
|
|
476874
477135
|
for (let i3 = 0;i3 < 6; i3++) {
|
|
476875
477136
|
await Bun.sleep(500);
|
|
476876
477137
|
if (await isRunning())
|
|
476877
477138
|
break;
|
|
476878
477139
|
}
|
|
476879
477140
|
const running = await isRunning();
|
|
476880
|
-
if (!running) {
|
|
476881
|
-
const exitCode = await ttsProcess.exited;
|
|
476882
|
-
console.error(`[tts-server] Fall\xF3 al iniciar, exit code: ${exitCode}`);
|
|
476883
|
-
installLogs.push(`[error] Servidor TTS fall\xF3 al iniciar (c\xF3digo ${exitCode})`);
|
|
476884
|
-
}
|
|
476885
477141
|
return addCors(Response.json({ started: running }), req);
|
|
476886
477142
|
}
|
|
476887
477143
|
async function handleStopLocalTTS(req, addCors) {
|
|
476888
|
-
if (
|
|
476889
|
-
|
|
476890
|
-
|
|
476891
|
-
} else {
|
|
476892
|
-
try {
|
|
476893
|
-
Bun.spawn(["pkill", "-f", "tts/src/server.ts"]);
|
|
476894
|
-
} catch {}
|
|
477144
|
+
if (ttsServer) {
|
|
477145
|
+
ttsServer.stop(true);
|
|
477146
|
+
ttsServer = null;
|
|
476895
477147
|
}
|
|
476896
477148
|
return addCors(Response.json({ stopped: true }), req);
|
|
476897
477149
|
}
|
|
@@ -476900,15 +477152,11 @@ async function ensureTTSRunning() {
|
|
|
476900
477152
|
return true;
|
|
476901
477153
|
if (!isInstalled().installed)
|
|
476902
477154
|
return false;
|
|
476903
|
-
|
|
476904
|
-
|
|
477155
|
+
try {
|
|
477156
|
+
ttsServer = startTTSServer({ port: TTS_PORT });
|
|
477157
|
+
} catch {
|
|
476905
477158
|
return false;
|
|
476906
|
-
|
|
476907
|
-
stdout: "pipe",
|
|
476908
|
-
stderr: "pipe",
|
|
476909
|
-
env: { ...process.env, TTS_PORT: String(TTS_PORT) },
|
|
476910
|
-
cwd: TTS_ROOT
|
|
476911
|
-
});
|
|
477159
|
+
}
|
|
476912
477160
|
for (let i3 = 0;i3 < 10; i3++) {
|
|
476913
477161
|
await Bun.sleep(500);
|
|
476914
477162
|
if (await isRunning())
|
|
@@ -476965,10 +477213,10 @@ async function handleGetInstalledVoices(req, addCors) {
|
|
|
476965
477213
|
const voices = getInstalledVoices().map((id) => {
|
|
476966
477214
|
const model = getModelById(id);
|
|
476967
477215
|
let inferenceConfig = { length_scale: 1, noise_scale: 0.667, noise_w: 0.8 };
|
|
476968
|
-
const configPath =
|
|
476969
|
-
if (
|
|
477216
|
+
const configPath = join20(VOICES_DIR2, `${id}.onnx.json`);
|
|
477217
|
+
if (existsSync27(configPath)) {
|
|
476970
477218
|
try {
|
|
476971
|
-
const config2 = JSON.parse(
|
|
477219
|
+
const config2 = JSON.parse(readFileSync13(configPath, "utf-8"));
|
|
476972
477220
|
inferenceConfig = { ...inferenceConfig, ...config2.inference };
|
|
476973
477221
|
} catch {}
|
|
476974
477222
|
}
|
|
@@ -477010,8 +477258,8 @@ async function handleDownloadModel(req, addCors) {
|
|
|
477010
477258
|
downloadLogs = [`[${new Date().toISOString()}] Iniciando descarga de ${model.name}...`];
|
|
477011
477259
|
(async () => {
|
|
477012
477260
|
try {
|
|
477013
|
-
const modelDest =
|
|
477014
|
-
const configDest =
|
|
477261
|
+
const modelDest = join20(VOICES_DIR2, `${modelId}.onnx`);
|
|
477262
|
+
const configDest = join20(VOICES_DIR2, `${modelId}.onnx.json`);
|
|
477015
477263
|
downloadLogs.push(` Descargando modelo: ${model.size}`);
|
|
477016
477264
|
downloadLogs.push(` URL: ${model.modelUrl}`);
|
|
477017
477265
|
const modelRes = await fetch(model.modelUrl);
|
|
@@ -477046,12 +477294,14 @@ async function handleGetDownloadLogs(req, addCors) {
|
|
|
477046
477294
|
currentModelId: downloadingModelId
|
|
477047
477295
|
}), req);
|
|
477048
477296
|
}
|
|
477049
|
-
var
|
|
477297
|
+
var TTS_ROOT2, BIN_PATH, VOICES_DIR2, TTS_PORT, ttsServer = null, installing = false, installLogs, downloadingModelId = null, downloadLogs;
|
|
477050
477298
|
var init_tts_local = __esm(() => {
|
|
477051
477299
|
init_models5();
|
|
477052
|
-
|
|
477053
|
-
|
|
477054
|
-
|
|
477300
|
+
init_install();
|
|
477301
|
+
init_server();
|
|
477302
|
+
TTS_ROOT2 = process.env.HIVE_TTS_ROOT ?? join20(process.env.HIVE_HOME ?? join20(homedir4(), ".hive"), "tts");
|
|
477303
|
+
BIN_PATH = join20(TTS_ROOT2, "bin", process.platform === "win32" ? "piper.exe" : "piper");
|
|
477304
|
+
VOICES_DIR2 = join20(TTS_ROOT2, "voices");
|
|
477055
477305
|
TTS_PORT = Number(process.env.TTS_PORT ?? 5500);
|
|
477056
477306
|
installLogs = [];
|
|
477057
477307
|
downloadLogs = [];
|
|
@@ -477067,10 +477317,10 @@ async function handleCreateMeeting(req, addCorsHeaders) {
|
|
|
477067
477317
|
const result = db.query(`INSERT INTO meeting_sessions (title, stt_model)
|
|
477068
477318
|
VALUES (?, ?)
|
|
477069
477319
|
RETURNING id, title, status, stt_model, started_at`).get(title, sttModel);
|
|
477070
|
-
|
|
477320
|
+
log78.info(`Meeting session created: ${result.id}`);
|
|
477071
477321
|
return addCorsHeaders(Response.json({ ok: true, session: result }), req);
|
|
477072
477322
|
} catch (error54) {
|
|
477073
|
-
|
|
477323
|
+
log78.error(`handleCreateMeeting: ${error54.message}`);
|
|
477074
477324
|
return addCorsHeaders(Response.json({ ok: false, error: error54.message }, { status: 500 }), req);
|
|
477075
477325
|
}
|
|
477076
477326
|
}
|
|
@@ -477085,7 +477335,7 @@ async function handleListMeetings(req, addCorsHeaders) {
|
|
|
477085
477335
|
LIMIT 50`).all();
|
|
477086
477336
|
return addCorsHeaders(Response.json({ ok: true, sessions }), req);
|
|
477087
477337
|
} catch (error54) {
|
|
477088
|
-
|
|
477338
|
+
log78.error(`handleListMeetings: ${error54.message}`);
|
|
477089
477339
|
return addCorsHeaders(Response.json({ ok: false, error: error54.message }, { status: 500 }), req);
|
|
477090
477340
|
}
|
|
477091
477341
|
}
|
|
@@ -477100,7 +477350,7 @@ async function handleGetMeeting(req, addCorsHeaders, sessionId) {
|
|
|
477100
477350
|
WHERE session_id = ? ORDER BY seq ASC`).all(sessionId);
|
|
477101
477351
|
return addCorsHeaders(Response.json({ ok: true, session, segments }), req);
|
|
477102
477352
|
} catch (error54) {
|
|
477103
|
-
|
|
477353
|
+
log78.error(`handleGetMeeting: ${error54.message}`);
|
|
477104
477354
|
return addCorsHeaders(Response.json({ ok: false, error: error54.message }, { status: 500 }), req);
|
|
477105
477355
|
}
|
|
477106
477356
|
}
|
|
@@ -477128,7 +477378,7 @@ async function handleAddMeetingSegment(req, addCorsHeaders, sessionId) {
|
|
|
477128
477378
|
db.query(`INSERT INTO meeting_segments (session_id, seq, speaker, text) VALUES (?, ?, ?, ?)`).run(sessionId, seq, speaker, transcription);
|
|
477129
477379
|
return addCorsHeaders(Response.json({ ok: true, seq, speaker, text: transcription }), req);
|
|
477130
477380
|
} catch (error54) {
|
|
477131
|
-
|
|
477381
|
+
log78.error(`handleAddMeetingSegment: ${error54.message}`);
|
|
477132
477382
|
return addCorsHeaders(Response.json({ ok: false, error: error54.message }, { status: 500 }), req);
|
|
477133
477383
|
}
|
|
477134
477384
|
}
|
|
@@ -477145,7 +477395,7 @@ async function handleStopMeeting(req, addCorsHeaders, sessionId) {
|
|
|
477145
477395
|
}
|
|
477146
477396
|
db.query(`UPDATE meeting_sessions SET status = 'stopped', stopped_at = unixepoch() WHERE id = ?`).run(sessionId);
|
|
477147
477397
|
const countResult = db.query(`SELECT COUNT(*) as count FROM meeting_segments WHERE session_id = ?`).get(sessionId);
|
|
477148
|
-
|
|
477398
|
+
log78.info(`Meeting stopped: ${sessionId} \u2014 ${countResult.count} segments`);
|
|
477149
477399
|
return addCorsHeaders(Response.json({
|
|
477150
477400
|
ok: true,
|
|
477151
477401
|
session_id: sessionId,
|
|
@@ -477153,16 +477403,16 @@ async function handleStopMeeting(req, addCorsHeaders, sessionId) {
|
|
|
477153
477403
|
segment_count: countResult.count
|
|
477154
477404
|
}), req);
|
|
477155
477405
|
} catch (error54) {
|
|
477156
|
-
|
|
477406
|
+
log78.error(`handleStopMeeting: ${error54.message}`);
|
|
477157
477407
|
return addCorsHeaders(Response.json({ ok: false, error: error54.message }, { status: 500 }), req);
|
|
477158
477408
|
}
|
|
477159
477409
|
}
|
|
477160
|
-
var
|
|
477410
|
+
var log78;
|
|
477161
477411
|
var init_meeting2 = __esm(() => {
|
|
477162
477412
|
init_sqlite();
|
|
477163
477413
|
init_voice();
|
|
477164
477414
|
init_logger();
|
|
477165
|
-
|
|
477415
|
+
log78 = logger.child("meeting-routes");
|
|
477166
477416
|
});
|
|
477167
477417
|
|
|
477168
477418
|
// package.json
|
|
@@ -477170,7 +477420,7 @@ var package_default;
|
|
|
477170
477420
|
var init_package = __esm(() => {
|
|
477171
477421
|
package_default = {
|
|
477172
477422
|
name: "@johpaz/hive-agents",
|
|
477173
|
-
version: "0.0.
|
|
477423
|
+
version: "0.0.32",
|
|
477174
477424
|
description: "Tu colmena de agentes IA. Local-first. Multi-canal. Open source. Construido desde Colombia para el mundo.",
|
|
477175
477425
|
private: false,
|
|
477176
477426
|
bin: {
|
|
@@ -477667,7 +477917,7 @@ async function handleChat(req, addCorsHeaders) {
|
|
|
477667
477917
|
const finalUserId = userId || resolveUserId({ channel }) || "default";
|
|
477668
477918
|
const finalAgentId = agentId || resolveAgentId(null) || "main";
|
|
477669
477919
|
const threadId = thread_id || `${finalUserId}-${Date.now()}`;
|
|
477670
|
-
|
|
477920
|
+
log79.info(`[chat] Processing message from user=${finalUserId} agent=${finalAgentId} thread=${threadId}`);
|
|
477671
477921
|
const userRow = db.query("SELECT timezone FROM users WHERE id = ?").get(finalUserId);
|
|
477672
477922
|
const userTimezone = userRow?.timezone || "UTC";
|
|
477673
477923
|
const now = new Date;
|
|
@@ -477700,7 +477950,7 @@ ${message}`;
|
|
|
477700
477950
|
if (signal2.aborted)
|
|
477701
477951
|
return;
|
|
477702
477952
|
try {
|
|
477703
|
-
|
|
477953
|
+
log79.info(`[chat] Generating response for thread ${threadId}...`);
|
|
477704
477954
|
const response = await runner.generate({
|
|
477705
477955
|
provider,
|
|
477706
477956
|
messages: messages2,
|
|
@@ -477712,17 +477962,17 @@ ${message}`;
|
|
|
477712
477962
|
channel,
|
|
477713
477963
|
onStep: async (step) => {
|
|
477714
477964
|
if (step.type === "text" && step.message) {
|
|
477715
|
-
|
|
477965
|
+
log79.debug(`[chat] Step: ${step.message.substring(0, 100)}`);
|
|
477716
477966
|
}
|
|
477717
477967
|
if (step.type === "tool_result" && step.message) {
|
|
477718
|
-
|
|
477968
|
+
log79.debug(`[chat] Tool result: ${step.message.substring(0, 100)}`);
|
|
477719
477969
|
}
|
|
477720
477970
|
}
|
|
477721
477971
|
});
|
|
477722
477972
|
responseContent = response.content?.trim() || "Task completed.";
|
|
477723
|
-
|
|
477973
|
+
log79.info(`[chat] Response generated: ${responseContent.substring(0, 100)}...`);
|
|
477724
477974
|
} catch (error54) {
|
|
477725
|
-
|
|
477975
|
+
log79.error(`[chat] Error for thread ${threadId}: ${error54.message}`);
|
|
477726
477976
|
responseError = error54.message;
|
|
477727
477977
|
}
|
|
477728
477978
|
});
|
|
@@ -477751,7 +478001,7 @@ ${message}`;
|
|
|
477751
478001
|
content: responseContent
|
|
477752
478002
|
}), req);
|
|
477753
478003
|
} catch (error54) {
|
|
477754
|
-
|
|
478004
|
+
log79.error(`[chat] Handler error: ${error54.message}`);
|
|
477755
478005
|
return addCorsHeaders(Response.json({
|
|
477756
478006
|
success: false,
|
|
477757
478007
|
error: error54.message,
|
|
@@ -477780,7 +478030,7 @@ async function handleGetNotes(req, addCorsHeaders) {
|
|
|
477780
478030
|
`).all();
|
|
477781
478031
|
return addCorsHeaders(Response.json({ notes }), req);
|
|
477782
478032
|
}
|
|
477783
|
-
var
|
|
478033
|
+
var log79;
|
|
477784
478034
|
var init_chat3 = __esm(() => {
|
|
477785
478035
|
init_sqlite();
|
|
477786
478036
|
init_onboarding();
|
|
@@ -477788,7 +478038,7 @@ var init_chat3 = __esm(() => {
|
|
|
477788
478038
|
init_conversation_store();
|
|
477789
478039
|
init_providers3();
|
|
477790
478040
|
init_logger();
|
|
477791
|
-
|
|
478041
|
+
log79 = logger.child("api:chat");
|
|
477792
478042
|
});
|
|
477793
478043
|
|
|
477794
478044
|
// packages/core/src/gateway/helpers/redact.ts
|
|
@@ -477844,7 +478094,7 @@ async function handleGetConfig(req, addCorsHeaders, config2) {
|
|
|
477844
478094
|
var init_config = () => {};
|
|
477845
478095
|
|
|
477846
478096
|
// packages/core/src/gateway/routes/workspace.ts
|
|
477847
|
-
import { mkdirSync as
|
|
478097
|
+
import { mkdirSync as mkdirSync16, existsSync as existsSync28, accessSync, constants as constants2 } from "fs";
|
|
477848
478098
|
import * as path28 from "path";
|
|
477849
478099
|
import { exec as exec2 } from "child_process";
|
|
477850
478100
|
import { promisify as promisify4 } from "util";
|
|
@@ -477870,7 +478120,7 @@ async function handleValidateWorkspace(req, addCorsHeaders) {
|
|
|
477870
478120
|
isAbsolute: false
|
|
477871
478121
|
}), req);
|
|
477872
478122
|
}
|
|
477873
|
-
const exists =
|
|
478123
|
+
const exists = existsSync28(workspacePath);
|
|
477874
478124
|
if (!exists) {
|
|
477875
478125
|
return addCorsHeaders(Response.json({
|
|
477876
478126
|
ok: true,
|
|
@@ -477923,7 +478173,7 @@ async function handleCreateWorkspace(req, addCorsHeaders) {
|
|
|
477923
478173
|
error: "El path debe ser absoluto"
|
|
477924
478174
|
}), req);
|
|
477925
478175
|
}
|
|
477926
|
-
|
|
478176
|
+
mkdirSync16(workspacePath, { recursive: true });
|
|
477927
478177
|
return addCorsHeaders(Response.json({
|
|
477928
478178
|
ok: true,
|
|
477929
478179
|
path: workspacePath,
|
|
@@ -477952,7 +478202,7 @@ async function handleOpenWorkspace(req, addCorsHeaders) {
|
|
|
477952
478202
|
error: "El path debe ser absoluto"
|
|
477953
478203
|
}), req);
|
|
477954
478204
|
}
|
|
477955
|
-
if (!
|
|
478205
|
+
if (!existsSync28(workspacePath)) {
|
|
477956
478206
|
return addCorsHeaders(Response.json({
|
|
477957
478207
|
ok: false,
|
|
477958
478208
|
error: "El directorio no existe"
|
|
@@ -477999,7 +478249,7 @@ Define ethical guidelines here.`
|
|
|
477999
478249
|
async function handleUpdateWorkspace(req, addCorsHeaders, workspacePath, wsType, reloadFn) {
|
|
478000
478250
|
const content = await req.text();
|
|
478001
478251
|
const filePath = path28.join(workspacePath, `${wsType.toUpperCase()}.md`);
|
|
478002
|
-
|
|
478252
|
+
mkdirSync16(workspacePath, { recursive: true });
|
|
478003
478253
|
await Bun.write(filePath, content);
|
|
478004
478254
|
if (reloadFn) {
|
|
478005
478255
|
await reloadFn(wsType);
|
|
@@ -478111,7 +478361,7 @@ var init_helpers = __esm(() => {
|
|
|
478111
478361
|
});
|
|
478112
478362
|
|
|
478113
478363
|
// packages/core/src/gateway/server.ts
|
|
478114
|
-
import { mkdirSync as
|
|
478364
|
+
import { mkdirSync as mkdirSync17, unlinkSync as unlinkSync4, existsSync as existsSync29, writeFileSync as writeFileSync11, readFileSync as readFileSync14 } from "fs";
|
|
478115
478365
|
import * as path30 from "path";
|
|
478116
478366
|
import { cpus as osCpus } from "os";
|
|
478117
478367
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
@@ -478123,23 +478373,23 @@ async function startGateway(config2) {
|
|
|
478123
478373
|
const numCores = osCpus().length || 1;
|
|
478124
478374
|
let lastCpuSample = process.cpuUsage();
|
|
478125
478375
|
let lastCpuSampleTime = Date.now();
|
|
478126
|
-
const
|
|
478127
|
-
|
|
478376
|
+
const log80 = logger.child("gateway");
|
|
478377
|
+
log80.info(`Starting gateway on ${host}:${port}`);
|
|
478128
478378
|
const tokenFile = path30.join(getHiveDir(), ".auth_token");
|
|
478129
478379
|
if (!process.env.HIVE_AUTH_TOKEN) {
|
|
478130
|
-
if (
|
|
478131
|
-
process.env.HIVE_AUTH_TOKEN =
|
|
478132
|
-
|
|
478380
|
+
if (existsSync29(tokenFile)) {
|
|
478381
|
+
process.env.HIVE_AUTH_TOKEN = readFileSync14(tokenFile, "utf-8").trim();
|
|
478382
|
+
log80.info("\uD83D\uDD11 Auth token loaded from persistent storage");
|
|
478133
478383
|
} else {
|
|
478134
478384
|
const generated = randomUUID2().replace(/-/g, "");
|
|
478135
478385
|
process.env.HIVE_AUTH_TOKEN = generated;
|
|
478136
|
-
|
|
478386
|
+
mkdirSync17(path30.dirname(tokenFile), { recursive: true });
|
|
478137
478387
|
writeFileSync11(tokenFile, generated, { mode: 384 });
|
|
478138
|
-
|
|
478388
|
+
log80.info("\uD83D\uDD11 Auth token auto-generated and persisted");
|
|
478139
478389
|
}
|
|
478140
478390
|
} else {
|
|
478141
478391
|
writeFileSync11(tokenFile, process.env.HIVE_AUTH_TOKEN, { mode: 384 });
|
|
478142
|
-
|
|
478392
|
+
log80.info("\uD83D\uDD11 Auth token loaded from environment variable");
|
|
478143
478393
|
}
|
|
478144
478394
|
let agent;
|
|
478145
478395
|
let runner;
|
|
@@ -478169,7 +478419,7 @@ async function startGateway(config2) {
|
|
|
478169
478419
|
},
|
|
478170
478420
|
websocket: { open() {}, message() {}, close() {} }
|
|
478171
478421
|
});
|
|
478172
|
-
|
|
478422
|
+
log80.info(`Port ${port} bound (initializing gateway...)`);
|
|
478173
478423
|
try {
|
|
478174
478424
|
const db = initializeDatabase();
|
|
478175
478425
|
seedAllData();
|
|
@@ -478192,9 +478442,9 @@ async function startGateway(config2) {
|
|
|
478192
478442
|
await channelManager.send(channel, sessionId, { content, type: "progress" });
|
|
478193
478443
|
});
|
|
478194
478444
|
if (gatewaySetupMode) {
|
|
478195
|
-
|
|
478445
|
+
log80.info("\uD83C\uDF89 Setup mode: gateway running \u2014 open http://localhost:" + port + "/setup to configure");
|
|
478196
478446
|
} else {
|
|
478197
|
-
|
|
478447
|
+
log80.info("\u2705 Gateway initialization completed successfully");
|
|
478198
478448
|
try {
|
|
478199
478449
|
const db = getDb();
|
|
478200
478450
|
db.query(`
|
|
@@ -478208,21 +478458,21 @@ async function startGateway(config2) {
|
|
|
478208
478458
|
setSchedulerInstance(scheduler);
|
|
478209
478459
|
setSchedulerInstance2(scheduler);
|
|
478210
478460
|
setSchedulerForCleanup(scheduler);
|
|
478211
|
-
|
|
478461
|
+
log80.info(`\uD83D\uDCC5 CronScheduler initialized with ${scheduler.getStatus().length} task(s)`);
|
|
478212
478462
|
const dagScheduler = new DAGScheduler({ strategy: new ParallelStrategy, maxConcurrentWorkers: 2 });
|
|
478213
478463
|
globalThis.__dagScheduler = dagScheduler;
|
|
478214
|
-
|
|
478464
|
+
log80.info("\uD83D\uDD00 DAGScheduler ready");
|
|
478215
478465
|
} catch (err) {
|
|
478216
|
-
|
|
478466
|
+
log80.error(`\u274C CronScheduler initialization failed: ${err.message}`);
|
|
478217
478467
|
}
|
|
478218
478468
|
}
|
|
478219
478469
|
} catch (error54) {
|
|
478220
|
-
|
|
478221
|
-
|
|
478470
|
+
log80.error(`\u274C Gateway initialization failed: ${error54.message}`);
|
|
478471
|
+
log80.error("Stack trace:", error54.stack);
|
|
478222
478472
|
process.exit(1);
|
|
478223
478473
|
}
|
|
478224
478474
|
if (host === "0.0.0.0" && config2.security?.warnOnInsecureConfig !== false) {
|
|
478225
|
-
|
|
478475
|
+
log80.warn("Gateway binding to 0.0.0.0 exposes server to all network interfaces!");
|
|
478226
478476
|
}
|
|
478227
478477
|
function prepareTools(agentInstance, sessionId) {
|
|
478228
478478
|
return;
|
|
@@ -478230,8 +478480,8 @@ async function startGateway(config2) {
|
|
|
478230
478480
|
const watchers = [];
|
|
478231
478481
|
if (!gatewaySetupMode)
|
|
478232
478482
|
channelManager.onMessage(async (message) => {
|
|
478233
|
-
|
|
478234
|
-
|
|
478483
|
+
log80.info(`\uD83D\uDCE5 Message from ${message.channel}:${message.accountId}`);
|
|
478484
|
+
log80.info(` Session: ${message.sessionId}`);
|
|
478235
478485
|
const voiceConfig = voiceService.getChannelVoiceConfig(message.channel);
|
|
478236
478486
|
const visionConfig = multimodalService.getChannelVisionConfig(message.channel);
|
|
478237
478487
|
let messageContent = message.content;
|
|
@@ -478240,9 +478490,9 @@ async function startGateway(config2) {
|
|
|
478240
478490
|
let sttProviderUsed = null;
|
|
478241
478491
|
let contentParts;
|
|
478242
478492
|
if (voiceConfig.voiceEnabled && message.audio) {
|
|
478243
|
-
|
|
478493
|
+
log80.info(`\uD83C\uDF99\uFE0F Voice enabled, processing audio...`);
|
|
478244
478494
|
if (!voiceConfig.sttProvider) {
|
|
478245
|
-
|
|
478495
|
+
log80.warn(`\u26A0\uFE0F STT provider not configured for channel ${message.channel}`);
|
|
478246
478496
|
await channelManager.send(message.channel, message.sessionId, {
|
|
478247
478497
|
content: `\uD83C\uDF99\uFE0F Para usar notas de voz, necesitas configurar el proveedor STT en la configuraci\xF3n del canal. Ve a Configuraci\xF3n > Canales > [Tu canal] y configura "Prov. STT" (ej: groq-whisper o openai)`
|
|
478248
478498
|
});
|
|
@@ -478252,7 +478502,7 @@ async function startGateway(config2) {
|
|
|
478252
478502
|
const audioInput = voiceService.normalizeAudioFromChannel(message.channel, message.audio);
|
|
478253
478503
|
sttProviderUsed = voiceConfig.sttProvider || "groq-whisper";
|
|
478254
478504
|
messageContent = await voiceService.transcribe(audioInput, sttProviderUsed);
|
|
478255
|
-
|
|
478505
|
+
log80.info(`\uD83D\uDCDD Transcribed: ${messageContent.substring(0, 100)}...`);
|
|
478256
478506
|
inputType = "audio_transcribed";
|
|
478257
478507
|
preferAudioResponse = !!voiceConfig.ttsProvider;
|
|
478258
478508
|
await channelManager.send(message.channel, message.sessionId, {
|
|
@@ -478260,7 +478510,7 @@ async function startGateway(config2) {
|
|
|
478260
478510
|
type: "message"
|
|
478261
478511
|
});
|
|
478262
478512
|
} catch (error54) {
|
|
478263
|
-
|
|
478513
|
+
log80.error(`\u274C Transcription failed: ${error54.message}`);
|
|
478264
478514
|
await channelManager.send(message.channel, message.sessionId, {
|
|
478265
478515
|
content: `Error al transcribir audio: ${error54.message}`
|
|
478266
478516
|
});
|
|
@@ -478268,7 +478518,7 @@ async function startGateway(config2) {
|
|
|
478268
478518
|
}
|
|
478269
478519
|
}
|
|
478270
478520
|
if (message.image || message.document) {
|
|
478271
|
-
|
|
478521
|
+
log80.info(`\uD83D\uDDBC\uFE0F Multimodal content detected on channel ${message.channel}`);
|
|
478272
478522
|
if (message.image) {
|
|
478273
478523
|
try {
|
|
478274
478524
|
const imageInput = multimodalService.normalizeImageFromChannel(message.channel, message.image);
|
|
@@ -478278,20 +478528,20 @@ async function startGateway(config2) {
|
|
|
478278
478528
|
if (visionConfig.visionEnabled && modelHasVision) {
|
|
478279
478529
|
contentParts = await multimodalService.processImage(imageInput, visionConfig.visionModelId || undefined);
|
|
478280
478530
|
inputType = "image";
|
|
478281
|
-
|
|
478531
|
+
log80.info(`\uD83D\uDDBC\uFE0F Image sent as vision ContentParts (model supports vision)`);
|
|
478282
478532
|
} else {
|
|
478283
478533
|
const ocrProvider = visionConfig.ocrProvider || "openai";
|
|
478284
|
-
|
|
478534
|
+
log80.info(`\uD83D\uDDBC\uFE0F Model lacks vision, using OCR via ${ocrProvider}...`);
|
|
478285
478535
|
const ocrText = await multimodalService.ocrImage(imageInput, ocrProvider);
|
|
478286
478536
|
messageContent = ocrText ? `[Imagen adjunta \u2014 contenido extra\xEDdo por OCR]
|
|
478287
478537
|
${ocrText}
|
|
478288
478538
|
|
|
478289
478539
|
${messageContent || ""}` : messageContent || "";
|
|
478290
478540
|
inputType = "image";
|
|
478291
|
-
|
|
478541
|
+
log80.info(`\uD83D\uDDBC\uFE0F OCR result: ${ocrText.substring(0, 100)}...`);
|
|
478292
478542
|
}
|
|
478293
478543
|
} catch (imgError) {
|
|
478294
|
-
|
|
478544
|
+
log80.error(`\u274C Image processing failed: ${imgError.message}`);
|
|
478295
478545
|
await channelManager.send(message.channel, message.sessionId, {
|
|
478296
478546
|
content: `\u26A0\uFE0F Error al procesar la imagen: ${imgError.message}`
|
|
478297
478547
|
});
|
|
@@ -478301,7 +478551,7 @@ ${messageContent || ""}` : messageContent || "";
|
|
|
478301
478551
|
try {
|
|
478302
478552
|
const docInput = multimodalService.normalizeDocumentFromChannel(message.channel, message.document);
|
|
478303
478553
|
const ocrProvider = visionConfig.ocrProvider || "openai";
|
|
478304
|
-
|
|
478554
|
+
log80.info(`\uD83D\uDCC4 Document detected, extracting text via OCR (${ocrProvider})...`);
|
|
478305
478555
|
const docImage = {
|
|
478306
478556
|
type: docInput.type,
|
|
478307
478557
|
data: docInput.data,
|
|
@@ -478314,16 +478564,16 @@ ${ocrText}
|
|
|
478314
478564
|
|
|
478315
478565
|
${messageContent || ""}` : messageContent || "";
|
|
478316
478566
|
inputType = "document";
|
|
478317
|
-
|
|
478567
|
+
log80.info(`\uD83D\uDCC4 Document OCR result: ${ocrText.substring(0, 100)}...`);
|
|
478318
478568
|
} catch (docError) {
|
|
478319
|
-
|
|
478569
|
+
log80.error(`\u274C Document processing failed: ${docError.message}`);
|
|
478320
478570
|
await channelManager.send(message.channel, message.sessionId, {
|
|
478321
478571
|
content: `\u26A0\uFE0F Error al procesar el documento: ${docError.message}`
|
|
478322
478572
|
});
|
|
478323
478573
|
}
|
|
478324
478574
|
}
|
|
478325
478575
|
}
|
|
478326
|
-
|
|
478576
|
+
log80.info(` Content: ${messageContent.substring(0, 150)}${messageContent.length > 150 ? "..." : ""}`);
|
|
478327
478577
|
const { userId } = resolveContext({
|
|
478328
478578
|
channel: message.channel,
|
|
478329
478579
|
channelUserId: message.sessionId
|
|
@@ -478354,7 +478604,7 @@ ${messageContent || ""}` : messageContent || "";
|
|
|
478354
478604
|
${messageContent}`;
|
|
478355
478605
|
const messages2 = contentParts ? [{ role: "user", content: [{ type: "text", text: messageContentWithTime }, ...contentParts] }] : [{ role: "user", content: messageContentWithTime }];
|
|
478356
478606
|
try {
|
|
478357
|
-
|
|
478607
|
+
log80.info(`\uD83E\uDD16 Routing to agent loop...`);
|
|
478358
478608
|
const response = await runner.generate({
|
|
478359
478609
|
provider: dbProvider,
|
|
478360
478610
|
messages: messages2,
|
|
@@ -478369,28 +478619,28 @@ ${messageContent}`;
|
|
|
478369
478619
|
if (step.type === "text" && step.message) {
|
|
478370
478620
|
const trimmedMessage = (typeof step.message === "string" ? step.message : "").trim();
|
|
478371
478621
|
if (trimmedMessage) {
|
|
478372
|
-
|
|
478622
|
+
log80.debug(`[NARRATION] ${trimmedMessage.substring(0, 100)}`);
|
|
478373
478623
|
try {
|
|
478374
478624
|
await channelManager.send(message.channel, routingSessionId, {
|
|
478375
478625
|
content: trimmedMessage,
|
|
478376
478626
|
type: "progress"
|
|
478377
478627
|
});
|
|
478378
478628
|
} catch (err) {
|
|
478379
|
-
|
|
478629
|
+
log80.warn(`[onStep] Narration send failed: ${err.message}`);
|
|
478380
478630
|
}
|
|
478381
478631
|
}
|
|
478382
478632
|
return;
|
|
478383
478633
|
}
|
|
478384
478634
|
if (step.type === "tool_call" && step.toolName) {
|
|
478385
478635
|
const narration = getNarration(step.toolName);
|
|
478386
|
-
|
|
478636
|
+
log80.debug(`[TOOL] ${step.toolName} \u2192 "${narration}"`);
|
|
478387
478637
|
try {
|
|
478388
478638
|
await channelManager.send(message.channel, routingSessionId, {
|
|
478389
478639
|
content: narration,
|
|
478390
478640
|
type: "progress"
|
|
478391
478641
|
});
|
|
478392
478642
|
} catch (err) {
|
|
478393
|
-
|
|
478643
|
+
log80.warn(`[onStep] Tool narration send failed: ${err.message}`);
|
|
478394
478644
|
}
|
|
478395
478645
|
return;
|
|
478396
478646
|
}
|
|
@@ -478405,7 +478655,7 @@ ${messageContent}`;
|
|
|
478405
478655
|
type: "progress"
|
|
478406
478656
|
});
|
|
478407
478657
|
} catch (err) {
|
|
478408
|
-
|
|
478658
|
+
log80.warn(`[onStep] Tool result send failed: ${err.message}`);
|
|
478409
478659
|
}
|
|
478410
478660
|
}
|
|
478411
478661
|
} catch {}
|
|
@@ -478415,10 +478665,10 @@ ${messageContent}`;
|
|
|
478415
478665
|
});
|
|
478416
478666
|
const responseContent = response.content?.trim() || "";
|
|
478417
478667
|
if (!responseContent) {
|
|
478418
|
-
|
|
478668
|
+
log80.warn(`\uD83D\uDCE4 LLM response: empty \u2014 skipping send`);
|
|
478419
478669
|
return;
|
|
478420
478670
|
}
|
|
478421
|
-
|
|
478671
|
+
log80.info(`\uD83D\uDCE4 LLM response: ${responseContent.substring(0, 100)}${responseContent.length > 100 ? "..." : ""}`);
|
|
478422
478672
|
const shouldSpeak = preferAudioResponse;
|
|
478423
478673
|
let responseType = "text";
|
|
478424
478674
|
let ttsProviderUsed = null;
|
|
@@ -478426,7 +478676,7 @@ ${messageContent}`;
|
|
|
478426
478676
|
if (responseContent) {
|
|
478427
478677
|
if (shouldSpeak) {
|
|
478428
478678
|
if (!voiceConfig.ttsProvider) {
|
|
478429
|
-
|
|
478679
|
+
log80.warn(`\u26A0\uFE0F TTS provider not configured, user requested audio`);
|
|
478430
478680
|
await channelManager.send(message.channel, routingSessionId, {
|
|
478431
478681
|
content: `${responseContent}
|
|
478432
478682
|
|
|
@@ -478434,7 +478684,7 @@ ${messageContent}`;
|
|
|
478434
478684
|
});
|
|
478435
478685
|
} else {
|
|
478436
478686
|
try {
|
|
478437
|
-
|
|
478687
|
+
log80.info(`\uD83D\uDD0A TTS enabled, synthesizing audio...`);
|
|
478438
478688
|
const audioOutput = await voiceService.speak(responseContent, voiceConfig.ttsProvider, voiceConfig.ttsVoiceId || undefined);
|
|
478439
478689
|
ttsProviderUsed = voiceConfig.ttsProvider;
|
|
478440
478690
|
ttsMimeType = audioOutput.mimeType;
|
|
@@ -478443,17 +478693,17 @@ ${messageContent}`;
|
|
|
478443
478693
|
const channel = channelManager.getChannel(message.channel);
|
|
478444
478694
|
if (channel?.sendAudio) {
|
|
478445
478695
|
await channel.sendAudio(routingSessionId, audioOutput.data, audioOutput.mimeType);
|
|
478446
|
-
|
|
478696
|
+
log80.info(`\u2705 Audio sent to ${routingSessionId}`);
|
|
478447
478697
|
} else {
|
|
478448
|
-
|
|
478698
|
+
log80.warn(`Channel ${message.channel} does not support audio, sending text`);
|
|
478449
478699
|
await channelManager.send(message.channel, routingSessionId, { content: responseContent });
|
|
478450
478700
|
}
|
|
478451
478701
|
} catch (audioError) {
|
|
478452
|
-
|
|
478702
|
+
log80.error(`\u274C Audio send failed: ${audioError.message}, sending text instead`);
|
|
478453
478703
|
await channelManager.send(message.channel, routingSessionId, { content: responseContent });
|
|
478454
478704
|
}
|
|
478455
478705
|
} catch (ttsError) {
|
|
478456
|
-
|
|
478706
|
+
log80.error(`\u274C TTS failed: ${ttsError.message}, sending text instead`);
|
|
478457
478707
|
await channelManager.send(message.channel, routingSessionId, { content: responseContent });
|
|
478458
478708
|
}
|
|
478459
478709
|
}
|
|
@@ -478468,10 +478718,10 @@ ${messageContent}`;
|
|
|
478468
478718
|
channel: message.channel
|
|
478469
478719
|
};
|
|
478470
478720
|
await channelManager.stopTyping(message.channel, routingSessionId);
|
|
478471
|
-
|
|
478721
|
+
log80.info(`\u2705 Response sent to ${routingSessionId} via ${message.channel}`);
|
|
478472
478722
|
} catch (error54) {
|
|
478473
478723
|
await channelManager.stopTyping(message.channel, routingSessionId);
|
|
478474
|
-
|
|
478724
|
+
log80.error(`\u274C Error: ${error54.message} `);
|
|
478475
478725
|
await channelManager.send(message.channel, routingSessionId, {
|
|
478476
478726
|
content: `Error: ${error54.message} `
|
|
478477
478727
|
});
|
|
@@ -478519,9 +478769,9 @@ ${messageContent}`;
|
|
|
478519
478769
|
const method = req.method;
|
|
478520
478770
|
const logRequest = (status, duration3) => {
|
|
478521
478771
|
if (url2.pathname === "/health" || url2.pathname === "/health/") {
|
|
478522
|
-
|
|
478772
|
+
log80.debug(`${method} ${url2.pathname} - ${status} (${duration3}ms)`);
|
|
478523
478773
|
} else {
|
|
478524
|
-
|
|
478774
|
+
log80.info(`${method} ${url2.pathname} - ${status} (${duration3}ms)`);
|
|
478525
478775
|
}
|
|
478526
478776
|
};
|
|
478527
478777
|
const handleRequest = async () => {
|
|
@@ -478599,7 +478849,7 @@ ${messageContent}`;
|
|
|
478599
478849
|
if (isDev) {
|
|
478600
478850
|
const uiDir2 = path30.join(process.cwd(), "packages/hive-ui/dist");
|
|
478601
478851
|
const indexPath = path30.join(uiDir2, "index.html");
|
|
478602
|
-
if (!
|
|
478852
|
+
if (!existsSync29(indexPath)) {
|
|
478603
478853
|
return new Response(`UI build not found. Please run: cd packages/hive-ui && bun run build
|
|
478604
478854
|
|
|
478605
478855
|
` + "Or use: bun run dev (from root) which builds automatically.", { status: 503, headers: { "Content-Type": "text/plain" } });
|
|
@@ -478639,7 +478889,7 @@ ${messageContent}`;
|
|
|
478639
478889
|
const uiDirFromHive = path30.join(getHiveDir(), "ui");
|
|
478640
478890
|
const uiDirFromDist = process.env.HIVE_DIST_DIR ? path30.join(process.env.HIVE_DIST_DIR, "ui") : null;
|
|
478641
478891
|
const uiDirFromCwd = path30.join(process.cwd(), "packages/hive-ui/dist");
|
|
478642
|
-
const uiDir = uiDirFromEnv || (
|
|
478892
|
+
const uiDir = uiDirFromEnv || (existsSync29(path30.join(uiDirFromHive, "index.html")) ? uiDirFromHive : uiDirFromDist && existsSync29(path30.join(uiDirFromDist, "index.html")) ? uiDirFromDist : uiDirFromCwd);
|
|
478643
478893
|
let subPath = url2.pathname;
|
|
478644
478894
|
if (gatewaySetupMode && (subPath === "/" || subPath === "/ui" || subPath === "/ui/")) {
|
|
478645
478895
|
const _publicBase = process.env.HIVE_PUBLIC_URL?.replace(/\/$/, "") ?? `http://${host === "0.0.0.0" ? "localhost" : host}:${port}`;
|
|
@@ -478685,7 +478935,7 @@ ${messageContent}`;
|
|
|
478685
478935
|
return Response.redirect(`/ ui${tokenParam} `, 301);
|
|
478686
478936
|
}
|
|
478687
478937
|
if (!checkAuth(req, url2)) {
|
|
478688
|
-
|
|
478938
|
+
log80.warn(`[AUTH] Unauthorized request to ${url2.pathname} from ${req.headers.get("origin")} `);
|
|
478689
478939
|
return addCorsHeaders(new Response("Unauthorized", { status: 401 }), req);
|
|
478690
478940
|
}
|
|
478691
478941
|
if (url2.pathname === "/api/setup/status" || url2.pathname === "/api/setup/status/") {
|
|
@@ -478905,7 +479155,7 @@ ${messageContent}`;
|
|
|
478905
479155
|
return await handleApiReload(req, addCorsHeaders, agent);
|
|
478906
479156
|
}
|
|
478907
479157
|
if (url2.pathname === "/api/user/channels" && req.method === "POST") {
|
|
478908
|
-
return await handleLinkUserChannel(req, addCorsHeaders, config2,
|
|
479158
|
+
return await handleLinkUserChannel(req, addCorsHeaders, config2, log80);
|
|
478909
479159
|
}
|
|
478910
479160
|
if (url2.pathname === "/api/user/channels" && req.method === "GET") {
|
|
478911
479161
|
return await handleGetUserChannels(req, addCorsHeaders, config2);
|
|
@@ -479035,16 +479285,16 @@ ${messageContent}`;
|
|
|
479035
479285
|
if (active === undefined) {
|
|
479036
479286
|
return addCorsHeaders(Response.json({ success: false, error: "Missing active field" }, { status: 400 }), req);
|
|
479037
479287
|
}
|
|
479038
|
-
|
|
479288
|
+
log80.info(`[MCP] Toggle connection for ${mcpName}, active=${active}`);
|
|
479039
479289
|
getDb().query(`UPDATE mcp_servers SET active = ?, enabled = ? WHERE id = ? OR name = ?`).run(active ? 1 : 0, active ? 1 : 0, mcpName, mcpName);
|
|
479040
479290
|
try {
|
|
479041
479291
|
const mcp = agent?.getMCPManager() ?? null;
|
|
479042
479292
|
if (mcp) {
|
|
479043
|
-
|
|
479293
|
+
log80.info(`[MCP] Manager found, connecting ${mcpName}...`);
|
|
479044
479294
|
if (active) {
|
|
479045
479295
|
const server3 = getDb().query(`SELECT * FROM mcp_servers WHERE id = ? OR name = ?`).get(mcpName, mcpName);
|
|
479046
479296
|
if (server3) {
|
|
479047
|
-
|
|
479297
|
+
log80.info(`[MCP] Server config: transport=${server3.transport}, url=${server3.url}`);
|
|
479048
479298
|
const mcpServerConfig = {
|
|
479049
479299
|
transport: server3.transport,
|
|
479050
479300
|
command: server3.command,
|
|
@@ -479056,7 +479306,7 @@ ${messageContent}`;
|
|
|
479056
479306
|
try {
|
|
479057
479307
|
mcpServerConfig.headers = decryptConfig(server3.headers_encrypted, server3.headers_iv);
|
|
479058
479308
|
} catch (e) {
|
|
479059
|
-
|
|
479309
|
+
log80.warn(`Failed to decrypt headers for ${mcpName}`);
|
|
479060
479310
|
}
|
|
479061
479311
|
}
|
|
479062
479312
|
const currentConfig = mcp.config || { servers: {} };
|
|
@@ -479066,22 +479316,22 @@ ${messageContent}`;
|
|
|
479066
479316
|
...currentConfig,
|
|
479067
479317
|
servers: newServersConfig
|
|
479068
479318
|
});
|
|
479069
|
-
|
|
479319
|
+
log80.info(`[MCP] Server registered in MCP Manager`);
|
|
479070
479320
|
const tools = mcp.getServerTools(mcpName) || [];
|
|
479071
|
-
|
|
479321
|
+
log80.info(`[MCP] Connected! Tools: ${tools.length}`);
|
|
479072
479322
|
getDb().query(`UPDATE mcp_servers SET status = ?, tools_count = ? WHERE id = ? OR name = ?`).run("connected", tools.length, mcpName, mcpName);
|
|
479073
479323
|
} else {
|
|
479074
|
-
|
|
479324
|
+
log80.error(`[MCP] Server not found in DB: ${mcpName}`);
|
|
479075
479325
|
}
|
|
479076
479326
|
} else {
|
|
479077
479327
|
await mcp.disconnectServer(mcpName);
|
|
479078
479328
|
getDb().query(`UPDATE mcp_servers SET status = ? WHERE id = ? OR name = ?`).run("disconnected", mcpName, mcpName);
|
|
479079
479329
|
}
|
|
479080
479330
|
} else {
|
|
479081
|
-
|
|
479331
|
+
log80.error(`[MCP] No MCP Manager found`);
|
|
479082
479332
|
}
|
|
479083
479333
|
} catch (error54) {
|
|
479084
|
-
|
|
479334
|
+
log80.error(`[MCP] Failed to connect ${mcpName}: ${error54.message}`);
|
|
479085
479335
|
}
|
|
479086
479336
|
return addCorsHeaders(Response.json({ success: true, active, message: active ? "Servidor MCP conectado" : "Servidor MCP desconectado" }), req);
|
|
479087
479337
|
}
|
|
@@ -479108,7 +479358,7 @@ ${messageContent}`;
|
|
|
479108
479358
|
if (active) {
|
|
479109
479359
|
const server3 = getDb().query(`SELECT * FROM mcp_servers WHERE id = ? OR name = ?`).get(mcpName, mcpName);
|
|
479110
479360
|
if (server3) {
|
|
479111
|
-
|
|
479361
|
+
log80.info(`[MCP] Server config: transport=${server3.transport}, url=${server3.url}`);
|
|
479112
479362
|
const mcpServerConfig = {
|
|
479113
479363
|
transport: server3.transport,
|
|
479114
479364
|
command: server3.command,
|
|
@@ -479120,7 +479370,7 @@ ${messageContent}`;
|
|
|
479120
479370
|
try {
|
|
479121
479371
|
mcpServerConfig.headers = decryptConfig(server3.headers_encrypted, server3.headers_iv);
|
|
479122
479372
|
} catch (e) {
|
|
479123
|
-
|
|
479373
|
+
log80.warn(`Failed to decrypt headers for ${mcpName}`);
|
|
479124
479374
|
}
|
|
479125
479375
|
}
|
|
479126
479376
|
const currentConfig = mcp.config || { servers: {} };
|
|
@@ -479130,12 +479380,12 @@ ${messageContent}`;
|
|
|
479130
479380
|
...currentConfig,
|
|
479131
479381
|
servers: newServersConfig
|
|
479132
479382
|
});
|
|
479133
|
-
|
|
479383
|
+
log80.info(`[MCP] Server registered in MCP Manager`);
|
|
479134
479384
|
const tools = mcp.getServerTools(mcpName) || [];
|
|
479135
|
-
|
|
479385
|
+
log80.info(`[MCP] Connected! Tools: ${tools.length}`);
|
|
479136
479386
|
getDb().query(`UPDATE mcp_servers SET status = ?, tools_count = ? WHERE id = ? OR name = ?`).run("connected", tools.length, mcpName, mcpName);
|
|
479137
479387
|
} else {
|
|
479138
|
-
|
|
479388
|
+
log80.error(`[MCP] Server not found in DB: ${mcpName}`);
|
|
479139
479389
|
}
|
|
479140
479390
|
} else {
|
|
479141
479391
|
await mcp.disconnectServer(mcpName);
|
|
@@ -479143,7 +479393,7 @@ ${messageContent}`;
|
|
|
479143
479393
|
}
|
|
479144
479394
|
}
|
|
479145
479395
|
} catch (error54) {
|
|
479146
|
-
|
|
479396
|
+
log80.error(`[MCP] Failed to connect ${mcpName}: ${error54.message}`);
|
|
479147
479397
|
}
|
|
479148
479398
|
return addCorsHeaders(Response.json({ success: true, active, message: active ? "Servidor MCP conectado" : "Servidor MCP desconectado" }), req);
|
|
479149
479399
|
}
|
|
@@ -479332,12 +479582,12 @@ ${messageContent}`;
|
|
|
479332
479582
|
if (response) {
|
|
479333
479583
|
logRequest(response.status, duration3);
|
|
479334
479584
|
} else {
|
|
479335
|
-
|
|
479585
|
+
log80.info(`${method} ${url2.pathname} - 101 Switching Protocols(${duration3}ms)`);
|
|
479336
479586
|
}
|
|
479337
479587
|
return response;
|
|
479338
479588
|
} catch (error54) {
|
|
479339
479589
|
const duration3 = Date.now() - start;
|
|
479340
|
-
|
|
479590
|
+
log80.error(`${method} ${url2.pathname} - Internal Error(${duration3}ms): ${error54.message} `);
|
|
479341
479591
|
return addCorsHeaders(Response.json({ success: false, error: error54.message, message: "Error interno del servidor" }, { status: 500 }), req);
|
|
479342
479592
|
}
|
|
479343
479593
|
},
|
|
@@ -479346,17 +479596,17 @@ ${messageContent}`;
|
|
|
479346
479596
|
const data = ws.data;
|
|
479347
479597
|
const isBridge = data.sessionId.startsWith("bridge:");
|
|
479348
479598
|
if (isBridge) {
|
|
479349
|
-
|
|
479599
|
+
log80.info(`Bridge events client connected: ${data.sessionId}`);
|
|
479350
479600
|
subscribeBridge(ws);
|
|
479351
479601
|
ws.send(JSON.stringify({ type: "bridge:connected", sessionId: data.sessionId }));
|
|
479352
479602
|
return;
|
|
479353
479603
|
}
|
|
479354
479604
|
if (data.sessionId.startsWith("meeting:")) {
|
|
479355
|
-
|
|
479605
|
+
log80.info(`Meeting stream client connected: ${data.sessionId}`);
|
|
479356
479606
|
ws.send(JSON.stringify({ type: "meeting:connected", sessionId: data.sessionId, meetingSessionId: data.meetingSessionId }));
|
|
479357
479607
|
return;
|
|
479358
479608
|
}
|
|
479359
|
-
|
|
479609
|
+
log80.debug(`WebSocket connected: ${data.sessionId} `);
|
|
479360
479610
|
sessionManager.create(data.sessionId, ws);
|
|
479361
479611
|
const channel = channelManager?.getChannel("webchat");
|
|
479362
479612
|
if (channel?.registerConnection)
|
|
@@ -479387,7 +479637,7 @@ ${messageContent}`;
|
|
|
479387
479637
|
codeBridge: codeBridge.map((cb) => cb.id)
|
|
479388
479638
|
}));
|
|
479389
479639
|
} catch (err) {
|
|
479390
|
-
|
|
479640
|
+
log80.error("Error sending welcome message:", err);
|
|
479391
479641
|
}
|
|
479392
479642
|
},
|
|
479393
479643
|
async message(ws, message) {
|
|
@@ -479484,7 +479734,7 @@ ${messageContent}`;
|
|
|
479484
479734
|
const sourceComponentId = actionData.sourceComponentId ?? "unknown";
|
|
479485
479735
|
const context = actionData.context ?? {};
|
|
479486
479736
|
const interactionMsg = `[a2ui:action] surface=${surfaceId} action=${actionName} component=${sourceComponentId}${Object.keys(context).length > 0 ? ` context=${JSON.stringify(context)}` : ""}`;
|
|
479487
|
-
|
|
479737
|
+
log80.info(`A2UI action forwarded to agent: ${interactionMsg}`);
|
|
479488
479738
|
const sessionId = data.sessionId;
|
|
479489
479739
|
ws.send(JSON.stringify({ type: "typing", isTyping: true, sessionId }));
|
|
479490
479740
|
laneQueue.enqueue(sessionId, async (_task, signal2) => {
|
|
@@ -479514,7 +479764,7 @@ ${messageContent}`;
|
|
|
479514
479764
|
onStep: async (step) => {
|
|
479515
479765
|
if (signal2.aborted)
|
|
479516
479766
|
return;
|
|
479517
|
-
|
|
479767
|
+
log80.debug(`[a2ui:action TOOL] ${step.type}: ${step.toolName || ""}`);
|
|
479518
479768
|
}
|
|
479519
479769
|
});
|
|
479520
479770
|
ws.send(JSON.stringify({ type: "typing", isTyping: false, sessionId }));
|
|
@@ -479525,7 +479775,7 @@ ${messageContent}`;
|
|
|
479525
479775
|
} catch (error54) {
|
|
479526
479776
|
ws.send(JSON.stringify({ type: "typing", isTyping: false, sessionId }));
|
|
479527
479777
|
ws.send(JSON.stringify({ type: "error", sessionId, error: error54.message }));
|
|
479528
|
-
|
|
479778
|
+
log80.error(`A2UI action agent error: ${error54.message}`);
|
|
479529
479779
|
}
|
|
479530
479780
|
});
|
|
479531
479781
|
return;
|
|
@@ -479546,7 +479796,7 @@ ${messageContent}`;
|
|
|
479546
479796
|
if (interactionData && Object.keys(interactionData).length > 0) {
|
|
479547
479797
|
interactionMsg += `, data=${JSON.stringify(interactionData)}`;
|
|
479548
479798
|
}
|
|
479549
|
-
|
|
479799
|
+
log80.info(`Canvas interaction forwarded to agent: ${interactionMsg}`);
|
|
479550
479800
|
const sessionId = data.sessionId;
|
|
479551
479801
|
ws.send(JSON.stringify({ type: "typing", isTyping: true, sessionId }));
|
|
479552
479802
|
laneQueue.enqueue(sessionId, async (_task, signal2) => {
|
|
@@ -479576,7 +479826,7 @@ ${messageContent}`;
|
|
|
479576
479826
|
onStep: async (step) => {
|
|
479577
479827
|
if (signal2.aborted)
|
|
479578
479828
|
return;
|
|
479579
|
-
|
|
479829
|
+
log80.debug(`[canvas:interact TOOL] ${step.type}: ${step.toolName || ""}`);
|
|
479580
479830
|
}
|
|
479581
479831
|
});
|
|
479582
479832
|
ws.send(JSON.stringify({ type: "typing", isTyping: false, sessionId }));
|
|
@@ -479587,7 +479837,7 @@ ${messageContent}`;
|
|
|
479587
479837
|
} catch (error54) {
|
|
479588
479838
|
ws.send(JSON.stringify({ type: "typing", isTyping: false, sessionId }));
|
|
479589
479839
|
ws.send(JSON.stringify({ type: "error", sessionId, error: error54.message }));
|
|
479590
|
-
|
|
479840
|
+
log80.error(`Canvas interact agent error: ${error54.message}`);
|
|
479591
479841
|
}
|
|
479592
479842
|
});
|
|
479593
479843
|
}
|
|
@@ -479602,17 +479852,17 @@ ${messageContent}`;
|
|
|
479602
479852
|
}
|
|
479603
479853
|
if (msg.type === "logs_subscribe") {
|
|
479604
479854
|
logSubscribers.add(data.sessionId);
|
|
479605
|
-
|
|
479855
|
+
log80.debug(`Session ${data.sessionId} subscribed to logs`);
|
|
479606
479856
|
return;
|
|
479607
479857
|
}
|
|
479608
479858
|
if (msg.type === "logs_unsubscribe") {
|
|
479609
479859
|
logSubscribers.delete(data.sessionId);
|
|
479610
|
-
|
|
479860
|
+
log80.debug(`Session ${data.sessionId} unsubscribed from logs`);
|
|
479611
479861
|
return;
|
|
479612
479862
|
}
|
|
479613
479863
|
if (msg.type === "stop") {
|
|
479614
479864
|
const cancelled = laneQueue.cancel(msg.sessionId);
|
|
479615
|
-
|
|
479865
|
+
log80.info(`[stop] Session ${msg.sessionId} \u2014 cancelled: ${cancelled}`);
|
|
479616
479866
|
ws.send(JSON.stringify({
|
|
479617
479867
|
type: "typing",
|
|
479618
479868
|
isTyping: false,
|
|
@@ -479629,7 +479879,7 @@ ${messageContent}`;
|
|
|
479629
479879
|
}
|
|
479630
479880
|
let webchatPreferAudio = false;
|
|
479631
479881
|
if (msg.type === "audio" && msg.audio) {
|
|
479632
|
-
|
|
479882
|
+
log80.info(`WebChat audio from session ${msg.sessionId}`);
|
|
479633
479883
|
const voiceConfig = voiceService.getChannelVoiceConfig("webchat");
|
|
479634
479884
|
if (!voiceConfig.voiceEnabled) {
|
|
479635
479885
|
ws.send(JSON.stringify({
|
|
@@ -479656,7 +479906,7 @@ ${messageContent}`;
|
|
|
479656
479906
|
const audioInput = { type: "base64", data: msg.audio, mimeType: "audio/webm" };
|
|
479657
479907
|
const sttProvider = voiceConfig.sttProvider || "groq-whisper";
|
|
479658
479908
|
const messageContent = await voiceService.transcribe(audioInput, sttProvider);
|
|
479659
|
-
|
|
479909
|
+
log80.info(`\uD83D\uDCDD Transcribed: ${messageContent.substring(0, 100)}...`);
|
|
479660
479910
|
webchatPreferAudio = true;
|
|
479661
479911
|
ws.send(JSON.stringify({
|
|
479662
479912
|
type: "message",
|
|
@@ -479677,7 +479927,7 @@ ${messageContent}`;
|
|
|
479677
479927
|
try {
|
|
479678
479928
|
const unifiedSessionId = msg.sessionId;
|
|
479679
479929
|
const messages2 = [{ role: "user", content: messageContent }];
|
|
479680
|
-
|
|
479930
|
+
log80.info(`Generating response for session ${unifiedSessionId}...`);
|
|
479681
479931
|
const { userId } = resolveContext({
|
|
479682
479932
|
channel: "webchat",
|
|
479683
479933
|
channelUserId: msg.sessionId
|
|
@@ -479747,7 +479997,7 @@ ${messageContent}`;
|
|
|
479747
479997
|
}
|
|
479748
479998
|
});
|
|
479749
479999
|
const content = streamedContent || response.content?.trim() || "";
|
|
479750
|
-
|
|
480000
|
+
log80.info(`Response sent to session ${unifiedSessionId} (${content.length} chars)`);
|
|
479751
480001
|
const voiceCfg = voiceService.getChannelVoiceConfig("webchat");
|
|
479752
480002
|
const shouldSpeak = webchatPreferAudio;
|
|
479753
480003
|
let responseType = "text";
|
|
@@ -479768,13 +480018,13 @@ ${messageContent}`;
|
|
|
479768
480018
|
}));
|
|
479769
480019
|
} else {
|
|
479770
480020
|
try {
|
|
479771
|
-
|
|
480021
|
+
log80.info(`\uD83D\uDD0A TTS enabled, synthesizing audio for WebChat...`);
|
|
479772
480022
|
const audioOutput = await voiceService.speak(content, voiceCfg.ttsProvider, voiceCfg.ttsVoiceId || undefined);
|
|
479773
480023
|
ttsProviderUsed = voiceCfg.ttsProvider;
|
|
479774
480024
|
ttsMimeType = audioOutput.mimeType;
|
|
479775
480025
|
responseType = "audio";
|
|
479776
480026
|
const base64Audio = audioOutput.data.toString("base64");
|
|
479777
|
-
|
|
480027
|
+
log80.info(`Audio generated: ${base64Audio.length} bytes, mimeType: ${audioOutput.mimeType}`);
|
|
479778
480028
|
ws.send(JSON.stringify({
|
|
479779
480029
|
type: "message",
|
|
479780
480030
|
sessionId: unifiedSessionId,
|
|
@@ -479784,7 +480034,7 @@ ${messageContent}`;
|
|
|
479784
480034
|
isStep: false
|
|
479785
480035
|
}));
|
|
479786
480036
|
} catch (ttsError) {
|
|
479787
|
-
|
|
480037
|
+
log80.error(`TTS failed: ${ttsError.message}), sending text instead`);
|
|
479788
480038
|
ws.send(JSON.stringify({ type: "message", sessionId: unifiedSessionId, content, isStep: false }));
|
|
479789
480039
|
}
|
|
479790
480040
|
}
|
|
@@ -479793,10 +480043,10 @@ ${messageContent}`;
|
|
|
479793
480043
|
}
|
|
479794
480044
|
} else if (alreadyStreamed && shouldSpeak && voiceCfg.ttsProvider) {
|
|
479795
480045
|
try {
|
|
479796
|
-
|
|
480046
|
+
log80.info(`\uD83D\uDD0A TTS enabled, synthesizing audio after streaming...`);
|
|
479797
480047
|
const audioOutput = await voiceService.speak(content, voiceCfg.ttsProvider, voiceCfg.ttsVoiceId || undefined);
|
|
479798
480048
|
const base64Audio = audioOutput.data.toString("base64");
|
|
479799
|
-
|
|
480049
|
+
log80.info(`Audio generated after streaming: ${base64Audio.length} bytes`);
|
|
479800
480050
|
ws.send(JSON.stringify({
|
|
479801
480051
|
type: "message",
|
|
479802
480052
|
sessionId: unifiedSessionId,
|
|
@@ -479806,7 +480056,7 @@ ${messageContent}`;
|
|
|
479806
480056
|
isStep: false
|
|
479807
480057
|
}));
|
|
479808
480058
|
} catch (ttsError) {
|
|
479809
|
-
|
|
480059
|
+
log80.error(`TTS after streaming failed: ${ttsError.message}), skipping audio`);
|
|
479810
480060
|
}
|
|
479811
480061
|
}
|
|
479812
480062
|
} catch (error54) {
|
|
@@ -479816,7 +480066,7 @@ ${messageContent}`;
|
|
|
479816
480066
|
sessionId: msg.sessionId,
|
|
479817
480067
|
error: error54.message
|
|
479818
480068
|
}));
|
|
479819
|
-
|
|
480069
|
+
log80.error(`Error for session ${msg.sessionId}: ${error54.message}`);
|
|
479820
480070
|
}
|
|
479821
480071
|
});
|
|
479822
480072
|
} catch (error54) {
|
|
@@ -479834,7 +480084,7 @@ ${messageContent}`;
|
|
|
479834
480084
|
return;
|
|
479835
480085
|
}
|
|
479836
480086
|
if (msg.type === "message" && msg.content) {
|
|
479837
|
-
|
|
480087
|
+
log80.info(`WebChat message from session ${msg.sessionId}: ${msg.content.substring(0, 100)}`);
|
|
479838
480088
|
ws.send(JSON.stringify({
|
|
479839
480089
|
type: "typing",
|
|
479840
480090
|
isTyping: true,
|
|
@@ -479852,7 +480102,7 @@ ${messageContent}`;
|
|
|
479852
480102
|
let contentParts = undefined;
|
|
479853
480103
|
const visionConfig = multimodalService.getChannelVisionConfig("webchat");
|
|
479854
480104
|
if (msg.image || msg.document) {
|
|
479855
|
-
|
|
480105
|
+
log80.info(`\uD83D\uDDBC\uFE0F Multimodal content detected from WebChat session ${unifiedSessionId}`);
|
|
479856
480106
|
if (msg.image) {
|
|
479857
480107
|
try {
|
|
479858
480108
|
const imageInput = {
|
|
@@ -479866,25 +480116,25 @@ ${messageContent}`;
|
|
|
479866
480116
|
const modelHasVision = activeModelId && activeProviderId ? multimodalService.modelSupportsVision(activeProviderId, activeModelId) : false;
|
|
479867
480117
|
if (visionConfig.visionEnabled && modelHasVision) {
|
|
479868
480118
|
contentParts = await multimodalService.processImage(imageInput, visionConfig.visionModelId || undefined);
|
|
479869
|
-
|
|
480119
|
+
log80.info(`\uD83D\uDDBC\uFE0F Image sent as vision ContentParts (model supports vision)`);
|
|
479870
480120
|
} else {
|
|
479871
480121
|
const ocrProvider = visionConfig.ocrProvider || (["openai", "gemini", "anthropic"].includes(dbProvider) ? dbProvider : "openai");
|
|
479872
|
-
|
|
480122
|
+
log80.info(`\uD83D\uDDBC\uFE0F Model lacks vision or vision disabled, using OCR via ${ocrProvider}...`);
|
|
479873
480123
|
const ocrText = await multimodalService.ocrImage(imageInput, ocrProvider);
|
|
479874
480124
|
finalMessageContent = ocrText ? `[Imagen adjunta \u2014 contenido extra\xEDdo por OCR]
|
|
479875
480125
|
${ocrText}
|
|
479876
480126
|
|
|
479877
480127
|
${finalMessageContent || ""}` : finalMessageContent || "";
|
|
479878
|
-
|
|
480128
|
+
log80.info(`\uD83D\uDDBC\uFE0F OCR result: ${ocrText.substring(0, 100)}...`);
|
|
479879
480129
|
}
|
|
479880
480130
|
} catch (imgError) {
|
|
479881
|
-
|
|
480131
|
+
log80.error(`\u274C Image processing failed: ${imgError.message}`);
|
|
479882
480132
|
}
|
|
479883
480133
|
}
|
|
479884
480134
|
if (msg.document) {
|
|
479885
480135
|
try {
|
|
479886
480136
|
const ocrProvider = visionConfig.ocrProvider || (["openai", "gemini", "anthropic"].includes(dbProvider) ? dbProvider : "openai");
|
|
479887
|
-
|
|
480137
|
+
log80.info(`\uD83D\uDCC4 Document detected from WebChat, extracting text via OCR (${ocrProvider})...`);
|
|
479888
480138
|
const docImage = {
|
|
479889
480139
|
type: "base64",
|
|
479890
480140
|
data: msg.document.base64,
|
|
@@ -479896,14 +480146,14 @@ ${finalMessageContent || ""}` : finalMessageContent || "";
|
|
|
479896
480146
|
${ocrText}
|
|
479897
480147
|
|
|
479898
480148
|
${finalMessageContent || ""}` : finalMessageContent || "";
|
|
479899
|
-
|
|
480149
|
+
log80.info(`\uD83D\uDCC4 Document OCR result: ${ocrText.substring(0, 100)}...`);
|
|
479900
480150
|
} catch (docError) {
|
|
479901
|
-
|
|
480151
|
+
log80.error(`\u274C Document processing failed: ${docError.message}`);
|
|
479902
480152
|
}
|
|
479903
480153
|
}
|
|
479904
480154
|
}
|
|
479905
480155
|
const messages2 = contentParts ? [{ role: "user", content: contentParts }] : [{ role: "user", content: finalMessageContent }];
|
|
479906
|
-
|
|
480156
|
+
log80.info(`Generating response for session ${unifiedSessionId} (multimodal: ${!!(msg.image || msg.document)})...`);
|
|
479907
480157
|
const { userId } = resolveContext({
|
|
479908
480158
|
channel: "webchat",
|
|
479909
480159
|
channelUserId: msg.sessionId
|
|
@@ -479974,7 +480224,7 @@ ${finalMessageContent || ""}` : finalMessageContent || "";
|
|
|
479974
480224
|
}
|
|
479975
480225
|
});
|
|
479976
480226
|
const content = streamedContent || response.content?.trim() || "";
|
|
479977
|
-
|
|
480227
|
+
log80.info(`Response sent to session ${unifiedSessionId} (${content.length} chars)`);
|
|
479978
480228
|
const voiceConfig = voiceService.getChannelVoiceConfig("webchat");
|
|
479979
480229
|
const shouldSpeak = webchatPreferAudio;
|
|
479980
480230
|
let responseType = "text";
|
|
@@ -479995,7 +480245,7 @@ ${finalMessageContent || ""}` : finalMessageContent || "";
|
|
|
479995
480245
|
}));
|
|
479996
480246
|
} else {
|
|
479997
480247
|
try {
|
|
479998
|
-
|
|
480248
|
+
log80.info(`\uD83D\uDD0A TTS enabled, synthesizing audio for WebChat...`);
|
|
479999
480249
|
const audioOutput = await voiceService.speak(content, voiceConfig.ttsProvider, voiceConfig.ttsVoiceId || undefined);
|
|
480000
480250
|
ttsProviderUsed = voiceConfig.ttsProvider;
|
|
480001
480251
|
ttsMimeType = audioOutput.mimeType;
|
|
@@ -480010,7 +480260,7 @@ ${finalMessageContent || ""}` : finalMessageContent || "";
|
|
|
480010
480260
|
isStep: false
|
|
480011
480261
|
}));
|
|
480012
480262
|
} catch (ttsError) {
|
|
480013
|
-
|
|
480263
|
+
log80.error(`TTS failed: ${ttsError.message}), sending text instead`);
|
|
480014
480264
|
ws.send(JSON.stringify({ type: "message", sessionId: unifiedSessionId, content, isStep: false }));
|
|
480015
480265
|
}
|
|
480016
480266
|
}
|
|
@@ -480019,10 +480269,10 @@ ${finalMessageContent || ""}` : finalMessageContent || "";
|
|
|
480019
480269
|
}
|
|
480020
480270
|
} else if (alreadyStreamed && shouldSpeak && voiceConfig.ttsProvider) {
|
|
480021
480271
|
try {
|
|
480022
|
-
|
|
480272
|
+
log80.info(`\uD83D\uDD0A TTS enabled, synthesizing audio after streaming...`);
|
|
480023
480273
|
const audioOutput = await voiceService.speak(content, voiceConfig.ttsProvider, voiceConfig.ttsVoiceId || undefined);
|
|
480024
480274
|
const base64Audio = audioOutput.data.toString("base64");
|
|
480025
|
-
|
|
480275
|
+
log80.info(`Audio generated after streaming: ${base64Audio.length} bytes`);
|
|
480026
480276
|
ws.send(JSON.stringify({
|
|
480027
480277
|
type: "message",
|
|
480028
480278
|
sessionId: unifiedSessionId,
|
|
@@ -480032,7 +480282,7 @@ ${finalMessageContent || ""}` : finalMessageContent || "";
|
|
|
480032
480282
|
isStep: false
|
|
480033
480283
|
}));
|
|
480034
480284
|
} catch (ttsError) {
|
|
480035
|
-
|
|
480285
|
+
log80.error(`TTS after streaming failed: ${ttsError.message}), skipping audio`);
|
|
480036
480286
|
}
|
|
480037
480287
|
}
|
|
480038
480288
|
} catch (error54) {
|
|
@@ -480043,7 +480293,7 @@ ${finalMessageContent || ""}` : finalMessageContent || "";
|
|
|
480043
480293
|
sessionId: unifiedSessionId,
|
|
480044
480294
|
error: error54.message
|
|
480045
480295
|
}));
|
|
480046
|
-
|
|
480296
|
+
log80.error(`Error for session ${unifiedSessionId}: ${error54.message}`);
|
|
480047
480297
|
}
|
|
480048
480298
|
});
|
|
480049
480299
|
return;
|
|
@@ -480062,10 +480312,10 @@ ${finalMessageContent || ""}` : finalMessageContent || "";
|
|
|
480062
480312
|
return;
|
|
480063
480313
|
}
|
|
480064
480314
|
if (data.sessionId.startsWith("meeting:")) {
|
|
480065
|
-
|
|
480315
|
+
log80.info(`Meeting stream client disconnected: ${data.sessionId}`);
|
|
480066
480316
|
return;
|
|
480067
480317
|
}
|
|
480068
|
-
|
|
480318
|
+
log80.debug(`WebSocket disconnected: ${data.sessionId}`);
|
|
480069
480319
|
logSubscribers.delete(data.sessionId);
|
|
480070
480320
|
sessionManager.delete(data.sessionId);
|
|
480071
480321
|
laneQueue.cancel(data.sessionId);
|
|
@@ -480098,28 +480348,28 @@ ${finalMessageContent || ""}` : finalMessageContent || "";
|
|
|
480098
480348
|
}
|
|
480099
480349
|
}
|
|
480100
480350
|
});
|
|
480101
|
-
|
|
480351
|
+
log80.info(`Gateway started successfully`);
|
|
480102
480352
|
const isGatewayChild = process.env.HIVE_GATEWAY_CHILD === "1";
|
|
480103
480353
|
if (isDev) {
|
|
480104
480354
|
const devUrl = gatewaySetupMode ? `http://localhost:${port}/setup` : `http://localhost:${port}`;
|
|
480105
|
-
|
|
480106
|
-
|
|
480107
|
-
|
|
480108
|
-
|
|
480109
|
-
|
|
480355
|
+
log80.info(`[gateway] UI: ${devUrl}`);
|
|
480356
|
+
log80.info(`[gateway] API: http://${host}:${port}`);
|
|
480357
|
+
log80.info(`[gateway] WebSocket: ws://${host}:${port}/ws`);
|
|
480358
|
+
log80.info(`[gateway] Canvas: ws://${host}:${port}/canvas`);
|
|
480359
|
+
log80.info(`[gateway] Modo: desarrollo`);
|
|
480110
480360
|
if (!isGatewayChild) {
|
|
480111
|
-
|
|
480361
|
+
log80.info(gatewaySetupMode ? `\uD83C\uDF89 Primer arranque \u2014 abriendo setup...` : `\uD83D\uDC1D Administra tu Hive aqu\xED: ${devUrl}`);
|
|
480112
480362
|
}
|
|
480113
480363
|
} else {
|
|
480114
480364
|
const isSetupMode2 = gatewaySetupMode;
|
|
480115
480365
|
const baseUrl = process.env.HIVE_PUBLIC_URL?.replace(/\/$/, "") ?? `http://${host}:${port}`;
|
|
480116
480366
|
const uiUrl = isSetupMode2 ? `${baseUrl}/setup` : `${baseUrl}/ui`;
|
|
480117
|
-
|
|
480118
|
-
|
|
480119
|
-
|
|
480120
|
-
|
|
480367
|
+
log80.info(`[gateway] UI: ${uiUrl}`);
|
|
480368
|
+
log80.info(`[gateway] API: http://${host}:${port}`);
|
|
480369
|
+
log80.info(`[gateway] WebSocket: ws://${host}:${port}/ws`);
|
|
480370
|
+
log80.info(`[gateway] Canvas: ws://${host}:${port}/canvas`);
|
|
480121
480371
|
if (!process.env.NO_BROWSER) {
|
|
480122
|
-
|
|
480372
|
+
log80.info(isSetupMode2 ? `\uD83C\uDF89 Primer arranque \u2014 abriendo wizard de configuraci\xF3n...` : `\uD83D\uDC1D Administra tu Hive aqu\xED: ${uiUrl}`);
|
|
480123
480373
|
try {
|
|
480124
480374
|
const platform2 = process.platform;
|
|
480125
480375
|
let shellCmd;
|
|
@@ -480139,59 +480389,59 @@ ${finalMessageContent || ""}` : finalMessageContent || "";
|
|
|
480139
480389
|
});
|
|
480140
480390
|
proc.unref();
|
|
480141
480391
|
} catch (err) {
|
|
480142
|
-
|
|
480392
|
+
log80.warn(`Could not open browser: ${err.message}`);
|
|
480143
480393
|
}
|
|
480144
480394
|
}
|
|
480145
480395
|
}
|
|
480146
480396
|
if (!gatewaySetupMode)
|
|
480147
|
-
|
|
480397
|
+
log80.info(`Channels: ${channelManager.listChannels().map((c) => c.name).join(", ") || "none"}`);
|
|
480148
480398
|
process.on("SIGTERM", async () => {
|
|
480149
|
-
|
|
480399
|
+
log80.info("Received SIGTERM, shutting down gracefully...");
|
|
480150
480400
|
watchers.forEach((close) => close());
|
|
480151
480401
|
const mcp = agent?.getMCPManager();
|
|
480152
480402
|
if (mcp) {
|
|
480153
|
-
|
|
480403
|
+
log80.info("Disconnecting MCP servers...");
|
|
480154
480404
|
await mcp.disconnectAll().catch(() => {});
|
|
480155
480405
|
}
|
|
480156
480406
|
if (channelManager) {
|
|
480157
|
-
|
|
480407
|
+
log80.info("Stopping channels...");
|
|
480158
480408
|
await channelManager.stopAll();
|
|
480159
480409
|
}
|
|
480160
480410
|
try {
|
|
480161
480411
|
const mod = await Promise.resolve().then(() => (init_browser_service(), exports_browser_service));
|
|
480162
480412
|
mod.CDPClient.closeAll();
|
|
480163
|
-
|
|
480413
|
+
log80.info("Browser processes cleaned up");
|
|
480164
480414
|
} catch {}
|
|
480165
480415
|
try {
|
|
480166
480416
|
canvasManager.clearAll();
|
|
480167
|
-
|
|
480417
|
+
log80.info("Canvas sessions cleaned up");
|
|
480168
480418
|
} catch {}
|
|
480169
480419
|
try {
|
|
480170
480420
|
const { stopMCPHotReload: stopMCPHotReload2 } = await Promise.resolve().then(() => (init_hot_reload(), exports_hot_reload));
|
|
480171
480421
|
stopMCPHotReload2();
|
|
480172
|
-
|
|
480422
|
+
log80.info("MCP hot-reload stopped");
|
|
480173
480423
|
} catch {}
|
|
480174
480424
|
server.stop();
|
|
480175
480425
|
try {
|
|
480176
480426
|
unlinkSync4(pidFile);
|
|
480177
480427
|
} catch {}
|
|
480178
|
-
|
|
480428
|
+
log80.info("Gateway shutdown complete");
|
|
480179
480429
|
process.exit(0);
|
|
480180
480430
|
});
|
|
480181
480431
|
process.on("SIGHUP", async () => {
|
|
480182
|
-
|
|
480432
|
+
log80.info("Received SIGHUP, reloading configuration...");
|
|
480183
480433
|
try {
|
|
480184
480434
|
const newConfig = await loadConfig();
|
|
480185
480435
|
await agent.updateConfig(newConfig);
|
|
480186
480436
|
await agent.reload();
|
|
480187
|
-
|
|
480437
|
+
log80.info("Configuration reloaded successfully");
|
|
480188
480438
|
} catch (error54) {
|
|
480189
|
-
|
|
480439
|
+
log80.error(`Failed to reload configuration: ${error54.message}`);
|
|
480190
480440
|
}
|
|
480191
480441
|
});
|
|
480192
480442
|
}
|
|
480193
480443
|
var _pkgVersion, logSubscribers;
|
|
480194
|
-
var
|
|
480444
|
+
var init_server2 = __esm(() => {
|
|
480195
480445
|
init_loader();
|
|
480196
480446
|
init_logger();
|
|
480197
480447
|
init_session();
|
|
@@ -480242,7 +480492,7 @@ var init_server = __esm(() => {
|
|
|
480242
480492
|
_pkgVersion = (() => {
|
|
480243
480493
|
try {
|
|
480244
480494
|
const pkgPath = path30.join(import.meta.dir, "../../../package.json");
|
|
480245
|
-
return JSON.parse(
|
|
480495
|
+
return JSON.parse(readFileSync14(pkgPath, "utf-8")).version;
|
|
480246
480496
|
} catch {
|
|
480247
480497
|
return "0.0.27";
|
|
480248
480498
|
}
|
|
@@ -480253,7 +480503,7 @@ var init_server = __esm(() => {
|
|
|
480253
480503
|
// packages/core/src/gateway/index.ts
|
|
480254
480504
|
var init_gateway = __esm(() => {
|
|
480255
480505
|
init_loader();
|
|
480256
|
-
|
|
480506
|
+
init_server2();
|
|
480257
480507
|
init_logger();
|
|
480258
480508
|
});
|
|
480259
480509
|
|
|
@@ -481683,7 +481933,7 @@ var init_circuit_breaker = __esm(() => {
|
|
|
481683
481933
|
circuitBreakerRegistry = new CircuitBreakerRegistry;
|
|
481684
481934
|
});
|
|
481685
481935
|
// packages/core/src/plugins/loader.ts
|
|
481686
|
-
import { mkdirSync as
|
|
481936
|
+
import { mkdirSync as mkdirSync18, readdirSync as readdirSync7, existsSync as existsSync30 } from "fs";
|
|
481687
481937
|
import * as path31 from "path";
|
|
481688
481938
|
|
|
481689
481939
|
class PluginLoader {
|
|
@@ -481697,19 +481947,19 @@ class PluginLoader {
|
|
|
481697
481947
|
log = logger.child("plugins");
|
|
481698
481948
|
constructor(options2) {
|
|
481699
481949
|
this.options = options2;
|
|
481700
|
-
if (!
|
|
481701
|
-
|
|
481950
|
+
if (!existsSync30(options2.pluginDir)) {
|
|
481951
|
+
mkdirSync18(options2.pluginDir, { recursive: true });
|
|
481702
481952
|
}
|
|
481703
481953
|
}
|
|
481704
481954
|
async discover() {
|
|
481705
481955
|
const pluginDir = this.options.pluginDir;
|
|
481706
481956
|
const discovered = [];
|
|
481707
481957
|
try {
|
|
481708
|
-
const entries =
|
|
481958
|
+
const entries = readdirSync7(pluginDir, { withFileTypes: true });
|
|
481709
481959
|
for (const entry of entries) {
|
|
481710
481960
|
if (entry.isDirectory()) {
|
|
481711
481961
|
const manifestPath = path31.join(pluginDir, entry.name, "manifest.json");
|
|
481712
|
-
if (
|
|
481962
|
+
if (existsSync30(manifestPath)) {
|
|
481713
481963
|
discovered.push(entry.name);
|
|
481714
481964
|
}
|
|
481715
481965
|
}
|
|
@@ -482004,7 +482254,7 @@ var init_src3 = __esm(() => {
|
|
|
482004
482254
|
init_tools();
|
|
482005
482255
|
init_retry();
|
|
482006
482256
|
init_gateway();
|
|
482007
|
-
|
|
482257
|
+
init_server2();
|
|
482008
482258
|
init_service();
|
|
482009
482259
|
init_agent_loop();
|
|
482010
482260
|
init_context_compiler();
|
|
@@ -482086,7 +482336,7 @@ var init_types6 = __esm(() => {
|
|
|
482086
482336
|
|
|
482087
482337
|
// packages/cli/src/adapters/config.ts
|
|
482088
482338
|
import * as path32 from "path";
|
|
482089
|
-
import { existsSync as
|
|
482339
|
+
import { existsSync as existsSync31, readFileSync as readFileSync15 } from "fs";
|
|
482090
482340
|
function getHiveDir2(customDir) {
|
|
482091
482341
|
if (customDir) {
|
|
482092
482342
|
return path32.resolve(customDir);
|
|
@@ -482114,11 +482364,11 @@ function getDefaultPaths(hiveDir) {
|
|
|
482114
482364
|
}
|
|
482115
482365
|
function loadEnvFile(envPath) {
|
|
482116
482366
|
const filePath = envPath || path32.join(process.cwd(), ".env");
|
|
482117
|
-
if (!
|
|
482367
|
+
if (!existsSync31(filePath)) {
|
|
482118
482368
|
return {};
|
|
482119
482369
|
}
|
|
482120
482370
|
try {
|
|
482121
|
-
const content =
|
|
482371
|
+
const content = readFileSync15(filePath, "utf-8");
|
|
482122
482372
|
const env2 = {};
|
|
482123
482373
|
for (const line of content.split(`
|
|
482124
482374
|
`)) {
|
|
@@ -482186,7 +482436,7 @@ function getDistDir() {
|
|
|
482186
482436
|
return dir;
|
|
482187
482437
|
}
|
|
482188
482438
|
const distPath = path32.join(dir, "dist");
|
|
482189
|
-
if (
|
|
482439
|
+
if (existsSync31(distPath)) {
|
|
482190
482440
|
return distPath;
|
|
482191
482441
|
}
|
|
482192
482442
|
return null;
|
|
@@ -482208,7 +482458,7 @@ __export(exports_docker, {
|
|
|
482208
482458
|
});
|
|
482209
482459
|
import { spawn as spawn3, execSync } from "child_process";
|
|
482210
482460
|
import * as path33 from "path";
|
|
482211
|
-
import { existsSync as
|
|
482461
|
+
import { existsSync as existsSync32 } from "fs";
|
|
482212
482462
|
|
|
482213
482463
|
class DockerAdapter {
|
|
482214
482464
|
type = "docker";
|
|
@@ -482228,7 +482478,7 @@ class DockerAdapter {
|
|
|
482228
482478
|
path33.join(process.env.HOME || "", ".hive", "docker-compose.yml")
|
|
482229
482479
|
];
|
|
482230
482480
|
for (const composePath of standardPaths) {
|
|
482231
|
-
if (
|
|
482481
|
+
if (existsSync32(composePath)) {
|
|
482232
482482
|
return composePath;
|
|
482233
482483
|
}
|
|
482234
482484
|
}
|
|
@@ -482238,7 +482488,7 @@ class DockerAdapter {
|
|
|
482238
482488
|
try {
|
|
482239
482489
|
execSync("docker --version", { stdio: "ignore" });
|
|
482240
482490
|
execSync("docker compose version", { stdio: "ignore" });
|
|
482241
|
-
if (!
|
|
482491
|
+
if (!existsSync32(this.composeFile)) {
|
|
482242
482492
|
return false;
|
|
482243
482493
|
}
|
|
482244
482494
|
try {
|
|
@@ -482369,7 +482619,7 @@ class DockerAdapter {
|
|
|
482369
482619
|
} catch {
|
|
482370
482620
|
errors6.push("Docker Compose is not installed");
|
|
482371
482621
|
}
|
|
482372
|
-
if (!
|
|
482622
|
+
if (!existsSync32(this.composeFile)) {
|
|
482373
482623
|
errors6.push(`docker-compose.yml not found at ${this.composeFile}`);
|
|
482374
482624
|
} else {
|
|
482375
482625
|
info3.push(`Compose file: ${this.composeFile}`);
|
|
@@ -482409,7 +482659,7 @@ var init_docker = __esm(() => {
|
|
|
482409
482659
|
// packages/cli/src/adapters/bun-global.ts
|
|
482410
482660
|
import { spawn as spawn4, execSync as execSync2 } from "child_process";
|
|
482411
482661
|
import * as path34 from "path";
|
|
482412
|
-
import { existsSync as
|
|
482662
|
+
import { existsSync as existsSync33, readFileSync as readFileSync16, unlinkSync as unlinkSync5 } from "fs";
|
|
482413
482663
|
|
|
482414
482664
|
class BunGlobalAdapter {
|
|
482415
482665
|
type = "bun-global";
|
|
@@ -482429,7 +482679,7 @@ class BunGlobalAdapter {
|
|
|
482429
482679
|
stdio: ["ignore", "pipe", "ignore"]
|
|
482430
482680
|
});
|
|
482431
482681
|
const hivePath = output.trim();
|
|
482432
|
-
if (hivePath &&
|
|
482682
|
+
if (hivePath && existsSync33(hivePath)) {
|
|
482433
482683
|
return true;
|
|
482434
482684
|
}
|
|
482435
482685
|
} catch {
|
|
@@ -482457,13 +482707,13 @@ class BunGlobalAdapter {
|
|
|
482457
482707
|
}).trim();
|
|
482458
482708
|
const distDir = path34.dirname(hivePath);
|
|
482459
482709
|
const potentialUiDir = path34.join(distDir, "ui");
|
|
482460
|
-
if (
|
|
482710
|
+
if (existsSync33(potentialUiDir)) {
|
|
482461
482711
|
uiDir = potentialUiDir;
|
|
482462
482712
|
}
|
|
482463
482713
|
} catch {}
|
|
482464
482714
|
if (!uiDir) {
|
|
482465
482715
|
const cwdUiDir = path34.join(process.cwd(), "packages/hive-ui/dist");
|
|
482466
|
-
if (
|
|
482716
|
+
if (existsSync33(cwdUiDir)) {
|
|
482467
482717
|
uiDir = cwdUiDir;
|
|
482468
482718
|
}
|
|
482469
482719
|
}
|
|
@@ -482514,8 +482764,8 @@ class BunGlobalAdapter {
|
|
|
482514
482764
|
}
|
|
482515
482765
|
async stop() {
|
|
482516
482766
|
try {
|
|
482517
|
-
if (
|
|
482518
|
-
const pid = parseInt(
|
|
482767
|
+
if (existsSync33(this.pidFile)) {
|
|
482768
|
+
const pid = parseInt(readFileSync16(this.pidFile, "utf-8").trim(), 10);
|
|
482519
482769
|
if (!isNaN(pid)) {
|
|
482520
482770
|
try {
|
|
482521
482771
|
process.kill(pid, "SIGTERM");
|
|
@@ -482547,8 +482797,8 @@ class BunGlobalAdapter {
|
|
|
482547
482797
|
}
|
|
482548
482798
|
async isRunning() {
|
|
482549
482799
|
try {
|
|
482550
|
-
if (
|
|
482551
|
-
const pid = parseInt(
|
|
482800
|
+
if (existsSync33(this.pidFile)) {
|
|
482801
|
+
const pid = parseInt(readFileSync16(this.pidFile, "utf-8").trim(), 10);
|
|
482552
482802
|
if (!isNaN(pid)) {
|
|
482553
482803
|
try {
|
|
482554
482804
|
process.kill(pid, 0);
|
|
@@ -482569,8 +482819,8 @@ class BunGlobalAdapter {
|
|
|
482569
482819
|
}
|
|
482570
482820
|
async getPid() {
|
|
482571
482821
|
try {
|
|
482572
|
-
if (
|
|
482573
|
-
const pid = parseInt(
|
|
482822
|
+
if (existsSync33(this.pidFile)) {
|
|
482823
|
+
const pid = parseInt(readFileSync16(this.pidFile, "utf-8").trim(), 10);
|
|
482574
482824
|
if (!isNaN(pid) && pid > 0) {
|
|
482575
482825
|
try {
|
|
482576
482826
|
process.kill(pid, 0);
|
|
@@ -482611,11 +482861,11 @@ class BunGlobalAdapter {
|
|
|
482611
482861
|
encoding: "utf-8",
|
|
482612
482862
|
stdio: ["ignore", "pipe", "ignore"]
|
|
482613
482863
|
}).trim();
|
|
482614
|
-
if (hivePath &&
|
|
482864
|
+
if (hivePath && existsSync33(hivePath)) {
|
|
482615
482865
|
info3.push(`Hive binary: ${hivePath}`);
|
|
482616
482866
|
const distDir = path34.dirname(hivePath);
|
|
482617
482867
|
const uiDir = path34.join(distDir, "ui");
|
|
482618
|
-
if (
|
|
482868
|
+
if (existsSync33(uiDir)) {
|
|
482619
482869
|
info3.push(`UI directory: ${uiDir}`);
|
|
482620
482870
|
} else {
|
|
482621
482871
|
warnings.push("UI directory not found - may use embedded UI");
|
|
@@ -482626,7 +482876,7 @@ class BunGlobalAdapter {
|
|
|
482626
482876
|
} catch {
|
|
482627
482877
|
errors6.push("Hive is not installed globally (try: bun install -g @johpaz/hive-agents)");
|
|
482628
482878
|
}
|
|
482629
|
-
if (
|
|
482879
|
+
if (existsSync33(this.hiveDir)) {
|
|
482630
482880
|
info3.push(`Hive home: ${this.hiveDir}`);
|
|
482631
482881
|
} else {
|
|
482632
482882
|
warnings.push(`Hive home directory does not exist: ${this.hiveDir}`);
|
|
@@ -482668,7 +482918,7 @@ var init_bun_global = __esm(() => {
|
|
|
482668
482918
|
// packages/cli/src/adapters/binary.ts
|
|
482669
482919
|
import { spawn as spawn5, execSync as execSync3 } from "child_process";
|
|
482670
482920
|
import * as path35 from "path";
|
|
482671
|
-
import { existsSync as
|
|
482921
|
+
import { existsSync as existsSync34, readFileSync as readFileSync17, unlinkSync as unlinkSync6 } from "fs";
|
|
482672
482922
|
|
|
482673
482923
|
class BinaryAdapter {
|
|
482674
482924
|
type = "binary";
|
|
@@ -482680,7 +482930,7 @@ class BinaryAdapter {
|
|
|
482680
482930
|
this.hiveDir = options2?.hiveDir || getHiveDir2();
|
|
482681
482931
|
this.pidFile = path35.join(this.hiveDir, "gateway.pid");
|
|
482682
482932
|
this.binaryPath = options2?.binaryPath || this.findBinary();
|
|
482683
|
-
this.isDockerContainer = process.env.HIVE_UI_DIR === "/app/ui" || process.env.HIVE_HOST === "0.0.0.0" ||
|
|
482933
|
+
this.isDockerContainer = process.env.HIVE_UI_DIR === "/app/ui" || process.env.HIVE_HOST === "0.0.0.0" || existsSync34("/.dockerenv");
|
|
482684
482934
|
}
|
|
482685
482935
|
get name() {
|
|
482686
482936
|
return this.isDockerContainer ? "Docker Container" : "Standalone Binary";
|
|
@@ -482691,15 +482941,15 @@ class BinaryAdapter {
|
|
|
482691
482941
|
const dir = path35.dirname(scriptPath);
|
|
482692
482942
|
if (path35.basename(dir) === "dist") {
|
|
482693
482943
|
const binaryInDist = path35.join(dir, "hive");
|
|
482694
|
-
if (
|
|
482944
|
+
if (existsSync34(binaryInDist)) {
|
|
482695
482945
|
return binaryInDist;
|
|
482696
482946
|
}
|
|
482697
482947
|
const binaryWindows = path35.join(dir, "hive.exe");
|
|
482698
|
-
if (
|
|
482948
|
+
if (existsSync34(binaryWindows)) {
|
|
482699
482949
|
return binaryWindows;
|
|
482700
482950
|
}
|
|
482701
482951
|
}
|
|
482702
|
-
if (
|
|
482952
|
+
if (existsSync34(scriptPath) && !scriptPath.endsWith(".ts")) {
|
|
482703
482953
|
return scriptPath;
|
|
482704
482954
|
}
|
|
482705
482955
|
}
|
|
@@ -482712,7 +482962,7 @@ class BinaryAdapter {
|
|
|
482712
482962
|
path35.join(process.env.HOME || "", ".bun", "bin", "hive")
|
|
482713
482963
|
];
|
|
482714
482964
|
for (const binaryPath of commonPaths) {
|
|
482715
|
-
if (
|
|
482965
|
+
if (existsSync34(binaryPath)) {
|
|
482716
482966
|
return binaryPath;
|
|
482717
482967
|
}
|
|
482718
482968
|
}
|
|
@@ -482726,7 +482976,7 @@ class BinaryAdapter {
|
|
|
482726
482976
|
if (scriptPath.endsWith(".ts")) {
|
|
482727
482977
|
return false;
|
|
482728
482978
|
}
|
|
482729
|
-
if (
|
|
482979
|
+
if (existsSync34(this.binaryPath)) {
|
|
482730
482980
|
return true;
|
|
482731
482981
|
}
|
|
482732
482982
|
try {
|
|
@@ -482738,7 +482988,7 @@ class BinaryAdapter {
|
|
|
482738
482988
|
const distDir = getDistDir();
|
|
482739
482989
|
if (distDir) {
|
|
482740
482990
|
const uiDir = path35.join(distDir, "ui");
|
|
482741
|
-
if (
|
|
482991
|
+
if (existsSync34(uiDir)) {
|
|
482742
482992
|
return true;
|
|
482743
482993
|
}
|
|
482744
482994
|
}
|
|
@@ -482754,7 +483004,7 @@ class BinaryAdapter {
|
|
|
482754
483004
|
const distDir = getDistDir();
|
|
482755
483005
|
if (distDir) {
|
|
482756
483006
|
const uiDir = path35.join(distDir, "ui");
|
|
482757
|
-
if (
|
|
483007
|
+
if (existsSync34(uiDir)) {
|
|
482758
483008
|
paths.uiDir = uiDir;
|
|
482759
483009
|
}
|
|
482760
483010
|
}
|
|
@@ -482821,8 +483071,8 @@ class BinaryAdapter {
|
|
|
482821
483071
|
}
|
|
482822
483072
|
async stop() {
|
|
482823
483073
|
try {
|
|
482824
|
-
if (
|
|
482825
|
-
const pid = parseInt(
|
|
483074
|
+
if (existsSync34(this.pidFile)) {
|
|
483075
|
+
const pid = parseInt(readFileSync17(this.pidFile, "utf-8").trim(), 10);
|
|
482826
483076
|
if (!isNaN(pid)) {
|
|
482827
483077
|
try {
|
|
482828
483078
|
process.kill(pid, "SIGTERM");
|
|
@@ -482855,8 +483105,8 @@ class BinaryAdapter {
|
|
|
482855
483105
|
}
|
|
482856
483106
|
async isRunning() {
|
|
482857
483107
|
try {
|
|
482858
|
-
if (
|
|
482859
|
-
const pid = parseInt(
|
|
483108
|
+
if (existsSync34(this.pidFile)) {
|
|
483109
|
+
const pid = parseInt(readFileSync17(this.pidFile, "utf-8").trim(), 10);
|
|
482860
483110
|
if (!isNaN(pid)) {
|
|
482861
483111
|
try {
|
|
482862
483112
|
process.kill(pid, 0);
|
|
@@ -482877,8 +483127,8 @@ class BinaryAdapter {
|
|
|
482877
483127
|
}
|
|
482878
483128
|
async getPid() {
|
|
482879
483129
|
try {
|
|
482880
|
-
if (
|
|
482881
|
-
const pid = parseInt(
|
|
483130
|
+
if (existsSync34(this.pidFile)) {
|
|
483131
|
+
const pid = parseInt(readFileSync17(this.pidFile, "utf-8").trim(), 10);
|
|
482882
483132
|
if (!isNaN(pid) && pid > 0) {
|
|
482883
483133
|
try {
|
|
482884
483134
|
process.kill(pid, 0);
|
|
@@ -482910,7 +483160,7 @@ class BinaryAdapter {
|
|
|
482910
483160
|
const errors6 = [];
|
|
482911
483161
|
const warnings = [];
|
|
482912
483162
|
const info3 = [];
|
|
482913
|
-
if (
|
|
483163
|
+
if (existsSync34(this.binaryPath)) {
|
|
482914
483164
|
info3.push(`Binary: ${this.binaryPath}`);
|
|
482915
483165
|
try {
|
|
482916
483166
|
const stat3 = await import("fs/promises").then((m2) => m2.stat(this.binaryPath));
|
|
@@ -482933,13 +483183,13 @@ class BinaryAdapter {
|
|
|
482933
483183
|
const distDir = getDistDir();
|
|
482934
483184
|
if (distDir) {
|
|
482935
483185
|
const uiDir = path35.join(distDir, "ui");
|
|
482936
|
-
if (
|
|
483186
|
+
if (existsSync34(uiDir)) {
|
|
482937
483187
|
info3.push(`UI directory: ${uiDir}`);
|
|
482938
483188
|
} else if (!hasEmbeddedUI) {
|
|
482939
483189
|
warnings.push("UI directory not found and no embedded UI");
|
|
482940
483190
|
}
|
|
482941
483191
|
}
|
|
482942
|
-
if (
|
|
483192
|
+
if (existsSync34(this.hiveDir)) {
|
|
482943
483193
|
info3.push(`Hive home: ${this.hiveDir}`);
|
|
482944
483194
|
} else {
|
|
482945
483195
|
warnings.push(`Hive home directory does not exist: ${this.hiveDir}`);
|
|
@@ -482957,7 +483207,7 @@ class BinaryAdapter {
|
|
|
482957
483207
|
} else {
|
|
482958
483208
|
warnings.push("Hive Gateway is not running");
|
|
482959
483209
|
}
|
|
482960
|
-
if (process.platform !== "win32" &&
|
|
483210
|
+
if (process.platform !== "win32" && existsSync34(this.binaryPath)) {
|
|
482961
483211
|
try {
|
|
482962
483212
|
execSync3(`test -x "${this.binaryPath}"`, { stdio: "ignore" });
|
|
482963
483213
|
info3.push("Binary is executable");
|
|
@@ -483659,7 +483909,7 @@ __export(exports_gateway, {
|
|
|
483659
483909
|
resetAdapter: () => resetAdapter,
|
|
483660
483910
|
reload: () => reload
|
|
483661
483911
|
});
|
|
483662
|
-
import { existsSync as
|
|
483912
|
+
import { existsSync as existsSync35, mkdirSync as mkdirSync19, writeFileSync as writeFileSync12, readFileSync as readFileSync18, unlinkSync as unlinkSync7, openSync } from "fs";
|
|
483663
483913
|
import * as path36 from "path";
|
|
483664
483914
|
import { spawn as spawn6 } from "child_process";
|
|
483665
483915
|
async function getAdapter() {
|
|
@@ -483702,8 +483952,8 @@ async function getPidFile() {
|
|
|
483702
483952
|
}
|
|
483703
483953
|
function ensureLogDir() {
|
|
483704
483954
|
const logDir = path36.dirname(getLogFile());
|
|
483705
|
-
if (!
|
|
483706
|
-
|
|
483955
|
+
if (!existsSync35(logDir)) {
|
|
483956
|
+
mkdirSync19(logDir, { recursive: true });
|
|
483707
483957
|
}
|
|
483708
483958
|
}
|
|
483709
483959
|
function openBrowser(url2) {
|
|
@@ -483735,7 +483985,7 @@ function openBrowser(url2) {
|
|
|
483735
483985
|
async function isSetupMode2() {
|
|
483736
483986
|
const hiveDir = getHiveDir();
|
|
483737
483987
|
const dbPath = path36.join(hiveDir, "data", "hive.db");
|
|
483738
|
-
return !
|
|
483988
|
+
return !existsSync35(dbPath);
|
|
483739
483989
|
}
|
|
483740
483990
|
async function isRunning2() {
|
|
483741
483991
|
try {
|
|
@@ -483746,9 +483996,9 @@ async function isRunning2() {
|
|
|
483746
483996
|
}
|
|
483747
483997
|
} catch {}
|
|
483748
483998
|
const pidFile = await getPidFile();
|
|
483749
|
-
if (!
|
|
483999
|
+
if (!existsSync35(pidFile))
|
|
483750
484000
|
return false;
|
|
483751
|
-
const pid = parseInt(
|
|
484001
|
+
const pid = parseInt(readFileSync18(pidFile, "utf-8").trim(), 10);
|
|
483752
484002
|
if (isNaN(pid))
|
|
483753
484003
|
return false;
|
|
483754
484004
|
try {
|
|
@@ -483810,7 +484060,7 @@ async function start(flags3) {
|
|
|
483810
484060
|
\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u255A\u2588\u2588\u2588\u2588\u2554\u255D \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2551
|
|
483811
484061
|
\u2551 \u255A\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D \u2551
|
|
483812
484062
|
\u2551 \u2551
|
|
483813
|
-
\u2551 Personal Swarm AI Gateway \u2014 v0.0.
|
|
484063
|
+
\u2551 Personal Swarm AI Gateway \u2014 v0.0.32 \u2551
|
|
483814
484064
|
\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D
|
|
483815
484065
|
|
|
483816
484066
|
\uD83D\uDCE6 Installation: ${adapter.name}
|
|
@@ -483844,7 +484094,7 @@ async function handleDevMode(adapter, gatewayConfig, daemon) {
|
|
|
483844
484094
|
return;
|
|
483845
484095
|
}
|
|
483846
484096
|
const hiveUiPath = path36.join(process.cwd(), "packages/hive-ui");
|
|
483847
|
-
const hasVite =
|
|
484097
|
+
const hasVite = existsSync35(path36.join(hiveUiPath, "package.json"));
|
|
483848
484098
|
if (hasVite) {
|
|
483849
484099
|
console.log(`\uD83C\uDFA8 Iniciando Vite (UI)...
|
|
483850
484100
|
`);
|
|
@@ -484093,7 +484343,7 @@ async function handleProductionMode(adapter, gatewayConfig, daemon) {
|
|
|
484093
484343
|
} catch {
|
|
484094
484344
|
const hiveDir = getHiveDir();
|
|
484095
484345
|
const dbPath = path36.join(hiveDir, "data", "hive.db");
|
|
484096
|
-
needsSetup = !
|
|
484346
|
+
needsSetup = !existsSync35(dbPath);
|
|
484097
484347
|
}
|
|
484098
484348
|
const url2 = needsSetup ? `http://localhost:${uiPort}/setup` : `http://localhost:${uiPort}`;
|
|
484099
484349
|
if (needsSetup) {
|
|
@@ -484128,7 +484378,7 @@ async function stop() {
|
|
|
484128
484378
|
return;
|
|
484129
484379
|
}
|
|
484130
484380
|
const pidFile = await getPidFile();
|
|
484131
|
-
const pid = parseInt(
|
|
484381
|
+
const pid = parseInt(readFileSync18(pidFile, "utf-8").trim(), 10);
|
|
484132
484382
|
try {
|
|
484133
484383
|
process.kill(pid, "SIGTERM");
|
|
484134
484384
|
unlinkSync7(pidFile);
|
|
@@ -484174,7 +484424,7 @@ async function reload() {
|
|
|
484174
484424
|
return;
|
|
484175
484425
|
}
|
|
484176
484426
|
const pidFile = await getPidFile();
|
|
484177
|
-
const pid = parseInt(
|
|
484427
|
+
const pid = parseInt(readFileSync18(pidFile, "utf-8").trim(), 10);
|
|
484178
484428
|
try {
|
|
484179
484429
|
process.kill(pid, "SIGHUP");
|
|
484180
484430
|
console.log("\u2705 Configuraci\xF3n recargada");
|
|
@@ -484933,11 +485183,11 @@ async function updateSkills() {
|
|
|
484933
485183
|
} else {
|
|
484934
485184
|
console.log(` \u2705 Todas las skills est\xE1n actualizadas`);
|
|
484935
485185
|
}
|
|
484936
|
-
const { existsSync:
|
|
485186
|
+
const { existsSync: existsSync39 } = await import("fs");
|
|
484937
485187
|
const { getHiveDir: getHiveDir3 } = await Promise.resolve().then(() => (init_loader(), exports_loader));
|
|
484938
485188
|
const path40 = await import("path");
|
|
484939
485189
|
const pidFile = path40.join(getHiveDir3(), "gateway.pid");
|
|
484940
|
-
if (
|
|
485190
|
+
if (existsSync39(pidFile)) {
|
|
484941
485191
|
console.log(`
|
|
484942
485192
|
\uD83D\uDCA1 El gateway est\xE1 corriendo. Ejecuta 'hive reload' para aplicar cambios.`);
|
|
484943
485193
|
}
|
|
@@ -486211,8 +486461,8 @@ var MAIN_PACKAGE = "@johpaz/hive-agents";
|
|
|
486211
486461
|
async function update() {
|
|
486212
486462
|
console.log(`\uD83D\uDD04 Actualizando Hive...
|
|
486213
486463
|
`);
|
|
486214
|
-
const { existsSync:
|
|
486215
|
-
const isGitRepo =
|
|
486464
|
+
const { existsSync: existsSync45 } = await import("fs");
|
|
486465
|
+
const isGitRepo = existsSync45(".git") && existsSync45("package.json");
|
|
486216
486466
|
if (isGitRepo) {
|
|
486217
486467
|
await updateFromGitRepo();
|
|
486218
486468
|
} else {
|
|
@@ -486314,11 +486564,11 @@ Descargando ${MAIN_PACKAGE}@latest (via ${packageManager})...`);
|
|
|
486314
486564
|
}
|
|
486315
486565
|
}
|
|
486316
486566
|
async function applyDatabaseUpdates() {
|
|
486317
|
-
const { existsSync:
|
|
486567
|
+
const { existsSync: existsSync45 } = await import("fs");
|
|
486318
486568
|
const { getHiveDir: getHiveDir3 } = await Promise.resolve().then(() => (init_loader(), exports_loader));
|
|
486319
486569
|
const path45 = await import("path");
|
|
486320
486570
|
const dbPath = path45.join(getHiveDir3(), "data", "hive.db");
|
|
486321
|
-
if (!
|
|
486571
|
+
if (!existsSync45(dbPath)) {
|
|
486322
486572
|
console.log(` \u2139\uFE0F No se encontr\xF3 base de datos existente. Se crear\xE1 en el pr\xF3ximo 'hive start'.`);
|
|
486323
486573
|
return;
|
|
486324
486574
|
}
|
|
@@ -486356,7 +486606,7 @@ async function applyDatabaseUpdates() {
|
|
|
486356
486606
|
}
|
|
486357
486607
|
const hiveDir = getHiveDir3();
|
|
486358
486608
|
const pidFile = path45.join(hiveDir, "gateway.pid");
|
|
486359
|
-
if (
|
|
486609
|
+
if (existsSync45(pidFile)) {
|
|
486360
486610
|
console.log(`
|
|
486361
486611
|
\uD83D\uDCA1 El gateway est\xE1 corriendo. Ejecuta 'hive reload' para aplicar cambios.`);
|
|
486362
486612
|
}
|