@johpaz/hive-agents 0.0.30 → 0.0.31
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 +377 -276
- package/package.json +1 -1
package/dist/hive.js
CHANGED
|
@@ -476741,18 +476741,147 @@ 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/core/src/gateway/routes/tts-local.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";
|
|
476747
476876
|
function isInstalled() {
|
|
476748
|
-
const piperExists =
|
|
476877
|
+
const piperExists = existsSync26(BIN_PATH);
|
|
476749
476878
|
const voiceExists = getInstalledVoices().length > 0;
|
|
476750
476879
|
return { piperExists, voiceExists, installed: piperExists && voiceExists };
|
|
476751
476880
|
}
|
|
476752
476881
|
function getInstalledVoices() {
|
|
476753
|
-
if (!
|
|
476882
|
+
if (!existsSync26(VOICES_DIR))
|
|
476754
476883
|
return [];
|
|
476755
|
-
const files =
|
|
476884
|
+
const files = readdirSync5(VOICES_DIR);
|
|
476756
476885
|
return files.filter((f2) => f2.endsWith(".onnx")).map((f2) => f2.replace(".onnx", ""));
|
|
476757
476886
|
}
|
|
476758
476887
|
async function isRunning() {
|
|
@@ -476789,57 +476918,28 @@ async function handleInstallLocalTTS(req, addCors) {
|
|
|
476789
476918
|
if (isInstalled().installed) {
|
|
476790
476919
|
return addCors(Response.json({ started: false, reason: "Piper ya est\xE1 instalado" }), req);
|
|
476791
476920
|
}
|
|
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
476921
|
installing = true;
|
|
476800
476922
|
installLogs = [`[${new Date().toISOString()}] Iniciando instalaci\xF3n de Piper...`];
|
|
476801
476923
|
installLogs.push(` TTS_ROOT: ${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}`);
|
|
476924
|
+
const origLog = console.log;
|
|
476925
|
+
const origWarn = console.warn;
|
|
476926
|
+
console.log = (...args) => {
|
|
476927
|
+
installLogs.push(args.join(" "));
|
|
476928
|
+
origLog(...args);
|
|
476929
|
+
};
|
|
476930
|
+
console.warn = (...args) => {
|
|
476931
|
+
installLogs.push(`[warn] ${args.join(" ")}`);
|
|
476932
|
+
origWarn(...args);
|
|
476933
|
+
};
|
|
476934
|
+
runInstall(TTS_ROOT).then(() => {
|
|
476935
|
+
installLogs.push(`[${new Date().toISOString()}] Instalaci\xF3n completada`);
|
|
476840
476936
|
}).catch((err) => {
|
|
476937
|
+
installLogs.push(`[error] ${err instanceof Error ? err.message : String(err)}`);
|
|
476938
|
+
console.error(`[hive-tts install] Fall\xF3: ${err}`);
|
|
476939
|
+
}).finally(() => {
|
|
476841
476940
|
installing = false;
|
|
476842
|
-
|
|
476941
|
+
console.log = origLog;
|
|
476942
|
+
console.warn = origWarn;
|
|
476843
476943
|
});
|
|
476844
476944
|
return addCors(Response.json({ started: true }), req);
|
|
476845
476945
|
}
|
|
@@ -476850,7 +476950,7 @@ async function handleStartLocalTTS(req, addCors) {
|
|
|
476850
476950
|
if (!isInstalled().installed) {
|
|
476851
476951
|
return addCors(Response.json({ started: false, reason: "Piper no est\xE1 instalado. Inst\xE1lalo primero." }, { status: 400 }), req);
|
|
476852
476952
|
}
|
|
476853
|
-
const serverScript =
|
|
476953
|
+
const serverScript = join19(TTS_ROOT, "src", "server.ts");
|
|
476854
476954
|
ttsProcess = Bun.spawn([process.execPath, serverScript], {
|
|
476855
476955
|
stdout: "pipe",
|
|
476856
476956
|
stderr: "pipe",
|
|
@@ -476900,8 +477000,8 @@ async function ensureTTSRunning() {
|
|
|
476900
477000
|
return true;
|
|
476901
477001
|
if (!isInstalled().installed)
|
|
476902
477002
|
return false;
|
|
476903
|
-
const serverScript =
|
|
476904
|
-
if (!
|
|
477003
|
+
const serverScript = join19(TTS_ROOT, "src", "server.ts");
|
|
477004
|
+
if (!existsSync26(serverScript))
|
|
476905
477005
|
return false;
|
|
476906
477006
|
ttsProcess = Bun.spawn([process.execPath, serverScript], {
|
|
476907
477007
|
stdout: "pipe",
|
|
@@ -476965,8 +477065,8 @@ async function handleGetInstalledVoices(req, addCors) {
|
|
|
476965
477065
|
const voices = getInstalledVoices().map((id) => {
|
|
476966
477066
|
const model = getModelById(id);
|
|
476967
477067
|
let inferenceConfig = { length_scale: 1, noise_scale: 0.667, noise_w: 0.8 };
|
|
476968
|
-
const configPath =
|
|
476969
|
-
if (
|
|
477068
|
+
const configPath = join19(VOICES_DIR, `${id}.onnx.json`);
|
|
477069
|
+
if (existsSync26(configPath)) {
|
|
476970
477070
|
try {
|
|
476971
477071
|
const config2 = JSON.parse(readFileSync12(configPath, "utf-8"));
|
|
476972
477072
|
inferenceConfig = { ...inferenceConfig, ...config2.inference };
|
|
@@ -477010,8 +477110,8 @@ async function handleDownloadModel(req, addCors) {
|
|
|
477010
477110
|
downloadLogs = [`[${new Date().toISOString()}] Iniciando descarga de ${model.name}...`];
|
|
477011
477111
|
(async () => {
|
|
477012
477112
|
try {
|
|
477013
|
-
const modelDest =
|
|
477014
|
-
const configDest =
|
|
477113
|
+
const modelDest = join19(VOICES_DIR, `${modelId}.onnx`);
|
|
477114
|
+
const configDest = join19(VOICES_DIR, `${modelId}.onnx.json`);
|
|
477015
477115
|
downloadLogs.push(` Descargando modelo: ${model.size}`);
|
|
477016
477116
|
downloadLogs.push(` URL: ${model.modelUrl}`);
|
|
477017
477117
|
const modelRes = await fetch(model.modelUrl);
|
|
@@ -477049,9 +477149,10 @@ async function handleGetDownloadLogs(req, addCors) {
|
|
|
477049
477149
|
var TTS_ROOT, BIN_PATH, VOICES_DIR, TTS_PORT, ttsProcess = null, installing = false, installLogs, downloadingModelId = null, downloadLogs;
|
|
477050
477150
|
var init_tts_local = __esm(() => {
|
|
477051
477151
|
init_models5();
|
|
477052
|
-
|
|
477053
|
-
|
|
477054
|
-
|
|
477152
|
+
init_install();
|
|
477153
|
+
TTS_ROOT = process.env.HIVE_TTS_ROOT ?? join19(process.env.HIVE_HOME ?? join19(homedir3(), ".hive"), "tts");
|
|
477154
|
+
BIN_PATH = join19(TTS_ROOT, "bin", process.platform === "win32" ? "piper.exe" : "piper");
|
|
477155
|
+
VOICES_DIR = join19(TTS_ROOT, "voices");
|
|
477055
477156
|
TTS_PORT = Number(process.env.TTS_PORT ?? 5500);
|
|
477056
477157
|
installLogs = [];
|
|
477057
477158
|
downloadLogs = [];
|
|
@@ -477067,10 +477168,10 @@ async function handleCreateMeeting(req, addCorsHeaders) {
|
|
|
477067
477168
|
const result = db.query(`INSERT INTO meeting_sessions (title, stt_model)
|
|
477068
477169
|
VALUES (?, ?)
|
|
477069
477170
|
RETURNING id, title, status, stt_model, started_at`).get(title, sttModel);
|
|
477070
|
-
|
|
477171
|
+
log77.info(`Meeting session created: ${result.id}`);
|
|
477071
477172
|
return addCorsHeaders(Response.json({ ok: true, session: result }), req);
|
|
477072
477173
|
} catch (error54) {
|
|
477073
|
-
|
|
477174
|
+
log77.error(`handleCreateMeeting: ${error54.message}`);
|
|
477074
477175
|
return addCorsHeaders(Response.json({ ok: false, error: error54.message }, { status: 500 }), req);
|
|
477075
477176
|
}
|
|
477076
477177
|
}
|
|
@@ -477085,7 +477186,7 @@ async function handleListMeetings(req, addCorsHeaders) {
|
|
|
477085
477186
|
LIMIT 50`).all();
|
|
477086
477187
|
return addCorsHeaders(Response.json({ ok: true, sessions }), req);
|
|
477087
477188
|
} catch (error54) {
|
|
477088
|
-
|
|
477189
|
+
log77.error(`handleListMeetings: ${error54.message}`);
|
|
477089
477190
|
return addCorsHeaders(Response.json({ ok: false, error: error54.message }, { status: 500 }), req);
|
|
477090
477191
|
}
|
|
477091
477192
|
}
|
|
@@ -477100,7 +477201,7 @@ async function handleGetMeeting(req, addCorsHeaders, sessionId) {
|
|
|
477100
477201
|
WHERE session_id = ? ORDER BY seq ASC`).all(sessionId);
|
|
477101
477202
|
return addCorsHeaders(Response.json({ ok: true, session, segments }), req);
|
|
477102
477203
|
} catch (error54) {
|
|
477103
|
-
|
|
477204
|
+
log77.error(`handleGetMeeting: ${error54.message}`);
|
|
477104
477205
|
return addCorsHeaders(Response.json({ ok: false, error: error54.message }, { status: 500 }), req);
|
|
477105
477206
|
}
|
|
477106
477207
|
}
|
|
@@ -477128,7 +477229,7 @@ async function handleAddMeetingSegment(req, addCorsHeaders, sessionId) {
|
|
|
477128
477229
|
db.query(`INSERT INTO meeting_segments (session_id, seq, speaker, text) VALUES (?, ?, ?, ?)`).run(sessionId, seq, speaker, transcription);
|
|
477129
477230
|
return addCorsHeaders(Response.json({ ok: true, seq, speaker, text: transcription }), req);
|
|
477130
477231
|
} catch (error54) {
|
|
477131
|
-
|
|
477232
|
+
log77.error(`handleAddMeetingSegment: ${error54.message}`);
|
|
477132
477233
|
return addCorsHeaders(Response.json({ ok: false, error: error54.message }, { status: 500 }), req);
|
|
477133
477234
|
}
|
|
477134
477235
|
}
|
|
@@ -477145,7 +477246,7 @@ async function handleStopMeeting(req, addCorsHeaders, sessionId) {
|
|
|
477145
477246
|
}
|
|
477146
477247
|
db.query(`UPDATE meeting_sessions SET status = 'stopped', stopped_at = unixepoch() WHERE id = ?`).run(sessionId);
|
|
477147
477248
|
const countResult = db.query(`SELECT COUNT(*) as count FROM meeting_segments WHERE session_id = ?`).get(sessionId);
|
|
477148
|
-
|
|
477249
|
+
log77.info(`Meeting stopped: ${sessionId} \u2014 ${countResult.count} segments`);
|
|
477149
477250
|
return addCorsHeaders(Response.json({
|
|
477150
477251
|
ok: true,
|
|
477151
477252
|
session_id: sessionId,
|
|
@@ -477153,16 +477254,16 @@ async function handleStopMeeting(req, addCorsHeaders, sessionId) {
|
|
|
477153
477254
|
segment_count: countResult.count
|
|
477154
477255
|
}), req);
|
|
477155
477256
|
} catch (error54) {
|
|
477156
|
-
|
|
477257
|
+
log77.error(`handleStopMeeting: ${error54.message}`);
|
|
477157
477258
|
return addCorsHeaders(Response.json({ ok: false, error: error54.message }, { status: 500 }), req);
|
|
477158
477259
|
}
|
|
477159
477260
|
}
|
|
477160
|
-
var
|
|
477261
|
+
var log77;
|
|
477161
477262
|
var init_meeting2 = __esm(() => {
|
|
477162
477263
|
init_sqlite();
|
|
477163
477264
|
init_voice();
|
|
477164
477265
|
init_logger();
|
|
477165
|
-
|
|
477266
|
+
log77 = logger.child("meeting-routes");
|
|
477166
477267
|
});
|
|
477167
477268
|
|
|
477168
477269
|
// package.json
|
|
@@ -477170,7 +477271,7 @@ var package_default;
|
|
|
477170
477271
|
var init_package = __esm(() => {
|
|
477171
477272
|
package_default = {
|
|
477172
477273
|
name: "@johpaz/hive-agents",
|
|
477173
|
-
version: "0.0.
|
|
477274
|
+
version: "0.0.31",
|
|
477174
477275
|
description: "Tu colmena de agentes IA. Local-first. Multi-canal. Open source. Construido desde Colombia para el mundo.",
|
|
477175
477276
|
private: false,
|
|
477176
477277
|
bin: {
|
|
@@ -477667,7 +477768,7 @@ async function handleChat(req, addCorsHeaders) {
|
|
|
477667
477768
|
const finalUserId = userId || resolveUserId({ channel }) || "default";
|
|
477668
477769
|
const finalAgentId = agentId || resolveAgentId(null) || "main";
|
|
477669
477770
|
const threadId = thread_id || `${finalUserId}-${Date.now()}`;
|
|
477670
|
-
|
|
477771
|
+
log78.info(`[chat] Processing message from user=${finalUserId} agent=${finalAgentId} thread=${threadId}`);
|
|
477671
477772
|
const userRow = db.query("SELECT timezone FROM users WHERE id = ?").get(finalUserId);
|
|
477672
477773
|
const userTimezone = userRow?.timezone || "UTC";
|
|
477673
477774
|
const now = new Date;
|
|
@@ -477700,7 +477801,7 @@ ${message}`;
|
|
|
477700
477801
|
if (signal2.aborted)
|
|
477701
477802
|
return;
|
|
477702
477803
|
try {
|
|
477703
|
-
|
|
477804
|
+
log78.info(`[chat] Generating response for thread ${threadId}...`);
|
|
477704
477805
|
const response = await runner.generate({
|
|
477705
477806
|
provider,
|
|
477706
477807
|
messages: messages2,
|
|
@@ -477712,17 +477813,17 @@ ${message}`;
|
|
|
477712
477813
|
channel,
|
|
477713
477814
|
onStep: async (step) => {
|
|
477714
477815
|
if (step.type === "text" && step.message) {
|
|
477715
|
-
|
|
477816
|
+
log78.debug(`[chat] Step: ${step.message.substring(0, 100)}`);
|
|
477716
477817
|
}
|
|
477717
477818
|
if (step.type === "tool_result" && step.message) {
|
|
477718
|
-
|
|
477819
|
+
log78.debug(`[chat] Tool result: ${step.message.substring(0, 100)}`);
|
|
477719
477820
|
}
|
|
477720
477821
|
}
|
|
477721
477822
|
});
|
|
477722
477823
|
responseContent = response.content?.trim() || "Task completed.";
|
|
477723
|
-
|
|
477824
|
+
log78.info(`[chat] Response generated: ${responseContent.substring(0, 100)}...`);
|
|
477724
477825
|
} catch (error54) {
|
|
477725
|
-
|
|
477826
|
+
log78.error(`[chat] Error for thread ${threadId}: ${error54.message}`);
|
|
477726
477827
|
responseError = error54.message;
|
|
477727
477828
|
}
|
|
477728
477829
|
});
|
|
@@ -477751,7 +477852,7 @@ ${message}`;
|
|
|
477751
477852
|
content: responseContent
|
|
477752
477853
|
}), req);
|
|
477753
477854
|
} catch (error54) {
|
|
477754
|
-
|
|
477855
|
+
log78.error(`[chat] Handler error: ${error54.message}`);
|
|
477755
477856
|
return addCorsHeaders(Response.json({
|
|
477756
477857
|
success: false,
|
|
477757
477858
|
error: error54.message,
|
|
@@ -477780,7 +477881,7 @@ async function handleGetNotes(req, addCorsHeaders) {
|
|
|
477780
477881
|
`).all();
|
|
477781
477882
|
return addCorsHeaders(Response.json({ notes }), req);
|
|
477782
477883
|
}
|
|
477783
|
-
var
|
|
477884
|
+
var log78;
|
|
477784
477885
|
var init_chat3 = __esm(() => {
|
|
477785
477886
|
init_sqlite();
|
|
477786
477887
|
init_onboarding();
|
|
@@ -477788,7 +477889,7 @@ var init_chat3 = __esm(() => {
|
|
|
477788
477889
|
init_conversation_store();
|
|
477789
477890
|
init_providers3();
|
|
477790
477891
|
init_logger();
|
|
477791
|
-
|
|
477892
|
+
log78 = logger.child("api:chat");
|
|
477792
477893
|
});
|
|
477793
477894
|
|
|
477794
477895
|
// packages/core/src/gateway/helpers/redact.ts
|
|
@@ -477844,7 +477945,7 @@ async function handleGetConfig(req, addCorsHeaders, config2) {
|
|
|
477844
477945
|
var init_config = () => {};
|
|
477845
477946
|
|
|
477846
477947
|
// packages/core/src/gateway/routes/workspace.ts
|
|
477847
|
-
import { mkdirSync as
|
|
477948
|
+
import { mkdirSync as mkdirSync16, existsSync as existsSync27, accessSync, constants as constants2 } from "fs";
|
|
477848
477949
|
import * as path28 from "path";
|
|
477849
477950
|
import { exec as exec2 } from "child_process";
|
|
477850
477951
|
import { promisify as promisify4 } from "util";
|
|
@@ -477870,7 +477971,7 @@ async function handleValidateWorkspace(req, addCorsHeaders) {
|
|
|
477870
477971
|
isAbsolute: false
|
|
477871
477972
|
}), req);
|
|
477872
477973
|
}
|
|
477873
|
-
const exists =
|
|
477974
|
+
const exists = existsSync27(workspacePath);
|
|
477874
477975
|
if (!exists) {
|
|
477875
477976
|
return addCorsHeaders(Response.json({
|
|
477876
477977
|
ok: true,
|
|
@@ -477923,7 +478024,7 @@ async function handleCreateWorkspace(req, addCorsHeaders) {
|
|
|
477923
478024
|
error: "El path debe ser absoluto"
|
|
477924
478025
|
}), req);
|
|
477925
478026
|
}
|
|
477926
|
-
|
|
478027
|
+
mkdirSync16(workspacePath, { recursive: true });
|
|
477927
478028
|
return addCorsHeaders(Response.json({
|
|
477928
478029
|
ok: true,
|
|
477929
478030
|
path: workspacePath,
|
|
@@ -477952,7 +478053,7 @@ async function handleOpenWorkspace(req, addCorsHeaders) {
|
|
|
477952
478053
|
error: "El path debe ser absoluto"
|
|
477953
478054
|
}), req);
|
|
477954
478055
|
}
|
|
477955
|
-
if (!
|
|
478056
|
+
if (!existsSync27(workspacePath)) {
|
|
477956
478057
|
return addCorsHeaders(Response.json({
|
|
477957
478058
|
ok: false,
|
|
477958
478059
|
error: "El directorio no existe"
|
|
@@ -477999,7 +478100,7 @@ Define ethical guidelines here.`
|
|
|
477999
478100
|
async function handleUpdateWorkspace(req, addCorsHeaders, workspacePath, wsType, reloadFn) {
|
|
478000
478101
|
const content = await req.text();
|
|
478001
478102
|
const filePath = path28.join(workspacePath, `${wsType.toUpperCase()}.md`);
|
|
478002
|
-
|
|
478103
|
+
mkdirSync16(workspacePath, { recursive: true });
|
|
478003
478104
|
await Bun.write(filePath, content);
|
|
478004
478105
|
if (reloadFn) {
|
|
478005
478106
|
await reloadFn(wsType);
|
|
@@ -478111,7 +478212,7 @@ var init_helpers = __esm(() => {
|
|
|
478111
478212
|
});
|
|
478112
478213
|
|
|
478113
478214
|
// packages/core/src/gateway/server.ts
|
|
478114
|
-
import { mkdirSync as
|
|
478215
|
+
import { mkdirSync as mkdirSync17, unlinkSync as unlinkSync4, existsSync as existsSync28, writeFileSync as writeFileSync11, readFileSync as readFileSync13 } from "fs";
|
|
478115
478216
|
import * as path30 from "path";
|
|
478116
478217
|
import { cpus as osCpus } from "os";
|
|
478117
478218
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
@@ -478123,23 +478224,23 @@ async function startGateway(config2) {
|
|
|
478123
478224
|
const numCores = osCpus().length || 1;
|
|
478124
478225
|
let lastCpuSample = process.cpuUsage();
|
|
478125
478226
|
let lastCpuSampleTime = Date.now();
|
|
478126
|
-
const
|
|
478127
|
-
|
|
478227
|
+
const log79 = logger.child("gateway");
|
|
478228
|
+
log79.info(`Starting gateway on ${host}:${port}`);
|
|
478128
478229
|
const tokenFile = path30.join(getHiveDir(), ".auth_token");
|
|
478129
478230
|
if (!process.env.HIVE_AUTH_TOKEN) {
|
|
478130
|
-
if (
|
|
478231
|
+
if (existsSync28(tokenFile)) {
|
|
478131
478232
|
process.env.HIVE_AUTH_TOKEN = readFileSync13(tokenFile, "utf-8").trim();
|
|
478132
|
-
|
|
478233
|
+
log79.info("\uD83D\uDD11 Auth token loaded from persistent storage");
|
|
478133
478234
|
} else {
|
|
478134
478235
|
const generated = randomUUID2().replace(/-/g, "");
|
|
478135
478236
|
process.env.HIVE_AUTH_TOKEN = generated;
|
|
478136
|
-
|
|
478237
|
+
mkdirSync17(path30.dirname(tokenFile), { recursive: true });
|
|
478137
478238
|
writeFileSync11(tokenFile, generated, { mode: 384 });
|
|
478138
|
-
|
|
478239
|
+
log79.info("\uD83D\uDD11 Auth token auto-generated and persisted");
|
|
478139
478240
|
}
|
|
478140
478241
|
} else {
|
|
478141
478242
|
writeFileSync11(tokenFile, process.env.HIVE_AUTH_TOKEN, { mode: 384 });
|
|
478142
|
-
|
|
478243
|
+
log79.info("\uD83D\uDD11 Auth token loaded from environment variable");
|
|
478143
478244
|
}
|
|
478144
478245
|
let agent;
|
|
478145
478246
|
let runner;
|
|
@@ -478169,7 +478270,7 @@ async function startGateway(config2) {
|
|
|
478169
478270
|
},
|
|
478170
478271
|
websocket: { open() {}, message() {}, close() {} }
|
|
478171
478272
|
});
|
|
478172
|
-
|
|
478273
|
+
log79.info(`Port ${port} bound (initializing gateway...)`);
|
|
478173
478274
|
try {
|
|
478174
478275
|
const db = initializeDatabase();
|
|
478175
478276
|
seedAllData();
|
|
@@ -478192,9 +478293,9 @@ async function startGateway(config2) {
|
|
|
478192
478293
|
await channelManager.send(channel, sessionId, { content, type: "progress" });
|
|
478193
478294
|
});
|
|
478194
478295
|
if (gatewaySetupMode) {
|
|
478195
|
-
|
|
478296
|
+
log79.info("\uD83C\uDF89 Setup mode: gateway running \u2014 open http://localhost:" + port + "/setup to configure");
|
|
478196
478297
|
} else {
|
|
478197
|
-
|
|
478298
|
+
log79.info("\u2705 Gateway initialization completed successfully");
|
|
478198
478299
|
try {
|
|
478199
478300
|
const db = getDb();
|
|
478200
478301
|
db.query(`
|
|
@@ -478208,21 +478309,21 @@ async function startGateway(config2) {
|
|
|
478208
478309
|
setSchedulerInstance(scheduler);
|
|
478209
478310
|
setSchedulerInstance2(scheduler);
|
|
478210
478311
|
setSchedulerForCleanup(scheduler);
|
|
478211
|
-
|
|
478312
|
+
log79.info(`\uD83D\uDCC5 CronScheduler initialized with ${scheduler.getStatus().length} task(s)`);
|
|
478212
478313
|
const dagScheduler = new DAGScheduler({ strategy: new ParallelStrategy, maxConcurrentWorkers: 2 });
|
|
478213
478314
|
globalThis.__dagScheduler = dagScheduler;
|
|
478214
|
-
|
|
478315
|
+
log79.info("\uD83D\uDD00 DAGScheduler ready");
|
|
478215
478316
|
} catch (err) {
|
|
478216
|
-
|
|
478317
|
+
log79.error(`\u274C CronScheduler initialization failed: ${err.message}`);
|
|
478217
478318
|
}
|
|
478218
478319
|
}
|
|
478219
478320
|
} catch (error54) {
|
|
478220
|
-
|
|
478221
|
-
|
|
478321
|
+
log79.error(`\u274C Gateway initialization failed: ${error54.message}`);
|
|
478322
|
+
log79.error("Stack trace:", error54.stack);
|
|
478222
478323
|
process.exit(1);
|
|
478223
478324
|
}
|
|
478224
478325
|
if (host === "0.0.0.0" && config2.security?.warnOnInsecureConfig !== false) {
|
|
478225
|
-
|
|
478326
|
+
log79.warn("Gateway binding to 0.0.0.0 exposes server to all network interfaces!");
|
|
478226
478327
|
}
|
|
478227
478328
|
function prepareTools(agentInstance, sessionId) {
|
|
478228
478329
|
return;
|
|
@@ -478230,8 +478331,8 @@ async function startGateway(config2) {
|
|
|
478230
478331
|
const watchers = [];
|
|
478231
478332
|
if (!gatewaySetupMode)
|
|
478232
478333
|
channelManager.onMessage(async (message) => {
|
|
478233
|
-
|
|
478234
|
-
|
|
478334
|
+
log79.info(`\uD83D\uDCE5 Message from ${message.channel}:${message.accountId}`);
|
|
478335
|
+
log79.info(` Session: ${message.sessionId}`);
|
|
478235
478336
|
const voiceConfig = voiceService.getChannelVoiceConfig(message.channel);
|
|
478236
478337
|
const visionConfig = multimodalService.getChannelVisionConfig(message.channel);
|
|
478237
478338
|
let messageContent = message.content;
|
|
@@ -478240,9 +478341,9 @@ async function startGateway(config2) {
|
|
|
478240
478341
|
let sttProviderUsed = null;
|
|
478241
478342
|
let contentParts;
|
|
478242
478343
|
if (voiceConfig.voiceEnabled && message.audio) {
|
|
478243
|
-
|
|
478344
|
+
log79.info(`\uD83C\uDF99\uFE0F Voice enabled, processing audio...`);
|
|
478244
478345
|
if (!voiceConfig.sttProvider) {
|
|
478245
|
-
|
|
478346
|
+
log79.warn(`\u26A0\uFE0F STT provider not configured for channel ${message.channel}`);
|
|
478246
478347
|
await channelManager.send(message.channel, message.sessionId, {
|
|
478247
478348
|
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
478349
|
});
|
|
@@ -478252,7 +478353,7 @@ async function startGateway(config2) {
|
|
|
478252
478353
|
const audioInput = voiceService.normalizeAudioFromChannel(message.channel, message.audio);
|
|
478253
478354
|
sttProviderUsed = voiceConfig.sttProvider || "groq-whisper";
|
|
478254
478355
|
messageContent = await voiceService.transcribe(audioInput, sttProviderUsed);
|
|
478255
|
-
|
|
478356
|
+
log79.info(`\uD83D\uDCDD Transcribed: ${messageContent.substring(0, 100)}...`);
|
|
478256
478357
|
inputType = "audio_transcribed";
|
|
478257
478358
|
preferAudioResponse = !!voiceConfig.ttsProvider;
|
|
478258
478359
|
await channelManager.send(message.channel, message.sessionId, {
|
|
@@ -478260,7 +478361,7 @@ async function startGateway(config2) {
|
|
|
478260
478361
|
type: "message"
|
|
478261
478362
|
});
|
|
478262
478363
|
} catch (error54) {
|
|
478263
|
-
|
|
478364
|
+
log79.error(`\u274C Transcription failed: ${error54.message}`);
|
|
478264
478365
|
await channelManager.send(message.channel, message.sessionId, {
|
|
478265
478366
|
content: `Error al transcribir audio: ${error54.message}`
|
|
478266
478367
|
});
|
|
@@ -478268,7 +478369,7 @@ async function startGateway(config2) {
|
|
|
478268
478369
|
}
|
|
478269
478370
|
}
|
|
478270
478371
|
if (message.image || message.document) {
|
|
478271
|
-
|
|
478372
|
+
log79.info(`\uD83D\uDDBC\uFE0F Multimodal content detected on channel ${message.channel}`);
|
|
478272
478373
|
if (message.image) {
|
|
478273
478374
|
try {
|
|
478274
478375
|
const imageInput = multimodalService.normalizeImageFromChannel(message.channel, message.image);
|
|
@@ -478278,20 +478379,20 @@ async function startGateway(config2) {
|
|
|
478278
478379
|
if (visionConfig.visionEnabled && modelHasVision) {
|
|
478279
478380
|
contentParts = await multimodalService.processImage(imageInput, visionConfig.visionModelId || undefined);
|
|
478280
478381
|
inputType = "image";
|
|
478281
|
-
|
|
478382
|
+
log79.info(`\uD83D\uDDBC\uFE0F Image sent as vision ContentParts (model supports vision)`);
|
|
478282
478383
|
} else {
|
|
478283
478384
|
const ocrProvider = visionConfig.ocrProvider || "openai";
|
|
478284
|
-
|
|
478385
|
+
log79.info(`\uD83D\uDDBC\uFE0F Model lacks vision, using OCR via ${ocrProvider}...`);
|
|
478285
478386
|
const ocrText = await multimodalService.ocrImage(imageInput, ocrProvider);
|
|
478286
478387
|
messageContent = ocrText ? `[Imagen adjunta \u2014 contenido extra\xEDdo por OCR]
|
|
478287
478388
|
${ocrText}
|
|
478288
478389
|
|
|
478289
478390
|
${messageContent || ""}` : messageContent || "";
|
|
478290
478391
|
inputType = "image";
|
|
478291
|
-
|
|
478392
|
+
log79.info(`\uD83D\uDDBC\uFE0F OCR result: ${ocrText.substring(0, 100)}...`);
|
|
478292
478393
|
}
|
|
478293
478394
|
} catch (imgError) {
|
|
478294
|
-
|
|
478395
|
+
log79.error(`\u274C Image processing failed: ${imgError.message}`);
|
|
478295
478396
|
await channelManager.send(message.channel, message.sessionId, {
|
|
478296
478397
|
content: `\u26A0\uFE0F Error al procesar la imagen: ${imgError.message}`
|
|
478297
478398
|
});
|
|
@@ -478301,7 +478402,7 @@ ${messageContent || ""}` : messageContent || "";
|
|
|
478301
478402
|
try {
|
|
478302
478403
|
const docInput = multimodalService.normalizeDocumentFromChannel(message.channel, message.document);
|
|
478303
478404
|
const ocrProvider = visionConfig.ocrProvider || "openai";
|
|
478304
|
-
|
|
478405
|
+
log79.info(`\uD83D\uDCC4 Document detected, extracting text via OCR (${ocrProvider})...`);
|
|
478305
478406
|
const docImage = {
|
|
478306
478407
|
type: docInput.type,
|
|
478307
478408
|
data: docInput.data,
|
|
@@ -478314,16 +478415,16 @@ ${ocrText}
|
|
|
478314
478415
|
|
|
478315
478416
|
${messageContent || ""}` : messageContent || "";
|
|
478316
478417
|
inputType = "document";
|
|
478317
|
-
|
|
478418
|
+
log79.info(`\uD83D\uDCC4 Document OCR result: ${ocrText.substring(0, 100)}...`);
|
|
478318
478419
|
} catch (docError) {
|
|
478319
|
-
|
|
478420
|
+
log79.error(`\u274C Document processing failed: ${docError.message}`);
|
|
478320
478421
|
await channelManager.send(message.channel, message.sessionId, {
|
|
478321
478422
|
content: `\u26A0\uFE0F Error al procesar el documento: ${docError.message}`
|
|
478322
478423
|
});
|
|
478323
478424
|
}
|
|
478324
478425
|
}
|
|
478325
478426
|
}
|
|
478326
|
-
|
|
478427
|
+
log79.info(` Content: ${messageContent.substring(0, 150)}${messageContent.length > 150 ? "..." : ""}`);
|
|
478327
478428
|
const { userId } = resolveContext({
|
|
478328
478429
|
channel: message.channel,
|
|
478329
478430
|
channelUserId: message.sessionId
|
|
@@ -478354,7 +478455,7 @@ ${messageContent || ""}` : messageContent || "";
|
|
|
478354
478455
|
${messageContent}`;
|
|
478355
478456
|
const messages2 = contentParts ? [{ role: "user", content: [{ type: "text", text: messageContentWithTime }, ...contentParts] }] : [{ role: "user", content: messageContentWithTime }];
|
|
478356
478457
|
try {
|
|
478357
|
-
|
|
478458
|
+
log79.info(`\uD83E\uDD16 Routing to agent loop...`);
|
|
478358
478459
|
const response = await runner.generate({
|
|
478359
478460
|
provider: dbProvider,
|
|
478360
478461
|
messages: messages2,
|
|
@@ -478369,28 +478470,28 @@ ${messageContent}`;
|
|
|
478369
478470
|
if (step.type === "text" && step.message) {
|
|
478370
478471
|
const trimmedMessage = (typeof step.message === "string" ? step.message : "").trim();
|
|
478371
478472
|
if (trimmedMessage) {
|
|
478372
|
-
|
|
478473
|
+
log79.debug(`[NARRATION] ${trimmedMessage.substring(0, 100)}`);
|
|
478373
478474
|
try {
|
|
478374
478475
|
await channelManager.send(message.channel, routingSessionId, {
|
|
478375
478476
|
content: trimmedMessage,
|
|
478376
478477
|
type: "progress"
|
|
478377
478478
|
});
|
|
478378
478479
|
} catch (err) {
|
|
478379
|
-
|
|
478480
|
+
log79.warn(`[onStep] Narration send failed: ${err.message}`);
|
|
478380
478481
|
}
|
|
478381
478482
|
}
|
|
478382
478483
|
return;
|
|
478383
478484
|
}
|
|
478384
478485
|
if (step.type === "tool_call" && step.toolName) {
|
|
478385
478486
|
const narration = getNarration(step.toolName);
|
|
478386
|
-
|
|
478487
|
+
log79.debug(`[TOOL] ${step.toolName} \u2192 "${narration}"`);
|
|
478387
478488
|
try {
|
|
478388
478489
|
await channelManager.send(message.channel, routingSessionId, {
|
|
478389
478490
|
content: narration,
|
|
478390
478491
|
type: "progress"
|
|
478391
478492
|
});
|
|
478392
478493
|
} catch (err) {
|
|
478393
|
-
|
|
478494
|
+
log79.warn(`[onStep] Tool narration send failed: ${err.message}`);
|
|
478394
478495
|
}
|
|
478395
478496
|
return;
|
|
478396
478497
|
}
|
|
@@ -478405,7 +478506,7 @@ ${messageContent}`;
|
|
|
478405
478506
|
type: "progress"
|
|
478406
478507
|
});
|
|
478407
478508
|
} catch (err) {
|
|
478408
|
-
|
|
478509
|
+
log79.warn(`[onStep] Tool result send failed: ${err.message}`);
|
|
478409
478510
|
}
|
|
478410
478511
|
}
|
|
478411
478512
|
} catch {}
|
|
@@ -478415,10 +478516,10 @@ ${messageContent}`;
|
|
|
478415
478516
|
});
|
|
478416
478517
|
const responseContent = response.content?.trim() || "";
|
|
478417
478518
|
if (!responseContent) {
|
|
478418
|
-
|
|
478519
|
+
log79.warn(`\uD83D\uDCE4 LLM response: empty \u2014 skipping send`);
|
|
478419
478520
|
return;
|
|
478420
478521
|
}
|
|
478421
|
-
|
|
478522
|
+
log79.info(`\uD83D\uDCE4 LLM response: ${responseContent.substring(0, 100)}${responseContent.length > 100 ? "..." : ""}`);
|
|
478422
478523
|
const shouldSpeak = preferAudioResponse;
|
|
478423
478524
|
let responseType = "text";
|
|
478424
478525
|
let ttsProviderUsed = null;
|
|
@@ -478426,7 +478527,7 @@ ${messageContent}`;
|
|
|
478426
478527
|
if (responseContent) {
|
|
478427
478528
|
if (shouldSpeak) {
|
|
478428
478529
|
if (!voiceConfig.ttsProvider) {
|
|
478429
|
-
|
|
478530
|
+
log79.warn(`\u26A0\uFE0F TTS provider not configured, user requested audio`);
|
|
478430
478531
|
await channelManager.send(message.channel, routingSessionId, {
|
|
478431
478532
|
content: `${responseContent}
|
|
478432
478533
|
|
|
@@ -478434,7 +478535,7 @@ ${messageContent}`;
|
|
|
478434
478535
|
});
|
|
478435
478536
|
} else {
|
|
478436
478537
|
try {
|
|
478437
|
-
|
|
478538
|
+
log79.info(`\uD83D\uDD0A TTS enabled, synthesizing audio...`);
|
|
478438
478539
|
const audioOutput = await voiceService.speak(responseContent, voiceConfig.ttsProvider, voiceConfig.ttsVoiceId || undefined);
|
|
478439
478540
|
ttsProviderUsed = voiceConfig.ttsProvider;
|
|
478440
478541
|
ttsMimeType = audioOutput.mimeType;
|
|
@@ -478443,17 +478544,17 @@ ${messageContent}`;
|
|
|
478443
478544
|
const channel = channelManager.getChannel(message.channel);
|
|
478444
478545
|
if (channel?.sendAudio) {
|
|
478445
478546
|
await channel.sendAudio(routingSessionId, audioOutput.data, audioOutput.mimeType);
|
|
478446
|
-
|
|
478547
|
+
log79.info(`\u2705 Audio sent to ${routingSessionId}`);
|
|
478447
478548
|
} else {
|
|
478448
|
-
|
|
478549
|
+
log79.warn(`Channel ${message.channel} does not support audio, sending text`);
|
|
478449
478550
|
await channelManager.send(message.channel, routingSessionId, { content: responseContent });
|
|
478450
478551
|
}
|
|
478451
478552
|
} catch (audioError) {
|
|
478452
|
-
|
|
478553
|
+
log79.error(`\u274C Audio send failed: ${audioError.message}, sending text instead`);
|
|
478453
478554
|
await channelManager.send(message.channel, routingSessionId, { content: responseContent });
|
|
478454
478555
|
}
|
|
478455
478556
|
} catch (ttsError) {
|
|
478456
|
-
|
|
478557
|
+
log79.error(`\u274C TTS failed: ${ttsError.message}, sending text instead`);
|
|
478457
478558
|
await channelManager.send(message.channel, routingSessionId, { content: responseContent });
|
|
478458
478559
|
}
|
|
478459
478560
|
}
|
|
@@ -478468,10 +478569,10 @@ ${messageContent}`;
|
|
|
478468
478569
|
channel: message.channel
|
|
478469
478570
|
};
|
|
478470
478571
|
await channelManager.stopTyping(message.channel, routingSessionId);
|
|
478471
|
-
|
|
478572
|
+
log79.info(`\u2705 Response sent to ${routingSessionId} via ${message.channel}`);
|
|
478472
478573
|
} catch (error54) {
|
|
478473
478574
|
await channelManager.stopTyping(message.channel, routingSessionId);
|
|
478474
|
-
|
|
478575
|
+
log79.error(`\u274C Error: ${error54.message} `);
|
|
478475
478576
|
await channelManager.send(message.channel, routingSessionId, {
|
|
478476
478577
|
content: `Error: ${error54.message} `
|
|
478477
478578
|
});
|
|
@@ -478519,9 +478620,9 @@ ${messageContent}`;
|
|
|
478519
478620
|
const method = req.method;
|
|
478520
478621
|
const logRequest = (status, duration3) => {
|
|
478521
478622
|
if (url2.pathname === "/health" || url2.pathname === "/health/") {
|
|
478522
|
-
|
|
478623
|
+
log79.debug(`${method} ${url2.pathname} - ${status} (${duration3}ms)`);
|
|
478523
478624
|
} else {
|
|
478524
|
-
|
|
478625
|
+
log79.info(`${method} ${url2.pathname} - ${status} (${duration3}ms)`);
|
|
478525
478626
|
}
|
|
478526
478627
|
};
|
|
478527
478628
|
const handleRequest = async () => {
|
|
@@ -478599,7 +478700,7 @@ ${messageContent}`;
|
|
|
478599
478700
|
if (isDev) {
|
|
478600
478701
|
const uiDir2 = path30.join(process.cwd(), "packages/hive-ui/dist");
|
|
478601
478702
|
const indexPath = path30.join(uiDir2, "index.html");
|
|
478602
|
-
if (!
|
|
478703
|
+
if (!existsSync28(indexPath)) {
|
|
478603
478704
|
return new Response(`UI build not found. Please run: cd packages/hive-ui && bun run build
|
|
478604
478705
|
|
|
478605
478706
|
` + "Or use: bun run dev (from root) which builds automatically.", { status: 503, headers: { "Content-Type": "text/plain" } });
|
|
@@ -478639,7 +478740,7 @@ ${messageContent}`;
|
|
|
478639
478740
|
const uiDirFromHive = path30.join(getHiveDir(), "ui");
|
|
478640
478741
|
const uiDirFromDist = process.env.HIVE_DIST_DIR ? path30.join(process.env.HIVE_DIST_DIR, "ui") : null;
|
|
478641
478742
|
const uiDirFromCwd = path30.join(process.cwd(), "packages/hive-ui/dist");
|
|
478642
|
-
const uiDir = uiDirFromEnv || (
|
|
478743
|
+
const uiDir = uiDirFromEnv || (existsSync28(path30.join(uiDirFromHive, "index.html")) ? uiDirFromHive : uiDirFromDist && existsSync28(path30.join(uiDirFromDist, "index.html")) ? uiDirFromDist : uiDirFromCwd);
|
|
478643
478744
|
let subPath = url2.pathname;
|
|
478644
478745
|
if (gatewaySetupMode && (subPath === "/" || subPath === "/ui" || subPath === "/ui/")) {
|
|
478645
478746
|
const _publicBase = process.env.HIVE_PUBLIC_URL?.replace(/\/$/, "") ?? `http://${host === "0.0.0.0" ? "localhost" : host}:${port}`;
|
|
@@ -478685,7 +478786,7 @@ ${messageContent}`;
|
|
|
478685
478786
|
return Response.redirect(`/ ui${tokenParam} `, 301);
|
|
478686
478787
|
}
|
|
478687
478788
|
if (!checkAuth(req, url2)) {
|
|
478688
|
-
|
|
478789
|
+
log79.warn(`[AUTH] Unauthorized request to ${url2.pathname} from ${req.headers.get("origin")} `);
|
|
478689
478790
|
return addCorsHeaders(new Response("Unauthorized", { status: 401 }), req);
|
|
478690
478791
|
}
|
|
478691
478792
|
if (url2.pathname === "/api/setup/status" || url2.pathname === "/api/setup/status/") {
|
|
@@ -478905,7 +479006,7 @@ ${messageContent}`;
|
|
|
478905
479006
|
return await handleApiReload(req, addCorsHeaders, agent);
|
|
478906
479007
|
}
|
|
478907
479008
|
if (url2.pathname === "/api/user/channels" && req.method === "POST") {
|
|
478908
|
-
return await handleLinkUserChannel(req, addCorsHeaders, config2,
|
|
479009
|
+
return await handleLinkUserChannel(req, addCorsHeaders, config2, log79);
|
|
478909
479010
|
}
|
|
478910
479011
|
if (url2.pathname === "/api/user/channels" && req.method === "GET") {
|
|
478911
479012
|
return await handleGetUserChannels(req, addCorsHeaders, config2);
|
|
@@ -479035,16 +479136,16 @@ ${messageContent}`;
|
|
|
479035
479136
|
if (active === undefined) {
|
|
479036
479137
|
return addCorsHeaders(Response.json({ success: false, error: "Missing active field" }, { status: 400 }), req);
|
|
479037
479138
|
}
|
|
479038
|
-
|
|
479139
|
+
log79.info(`[MCP] Toggle connection for ${mcpName}, active=${active}`);
|
|
479039
479140
|
getDb().query(`UPDATE mcp_servers SET active = ?, enabled = ? WHERE id = ? OR name = ?`).run(active ? 1 : 0, active ? 1 : 0, mcpName, mcpName);
|
|
479040
479141
|
try {
|
|
479041
479142
|
const mcp = agent?.getMCPManager() ?? null;
|
|
479042
479143
|
if (mcp) {
|
|
479043
|
-
|
|
479144
|
+
log79.info(`[MCP] Manager found, connecting ${mcpName}...`);
|
|
479044
479145
|
if (active) {
|
|
479045
479146
|
const server3 = getDb().query(`SELECT * FROM mcp_servers WHERE id = ? OR name = ?`).get(mcpName, mcpName);
|
|
479046
479147
|
if (server3) {
|
|
479047
|
-
|
|
479148
|
+
log79.info(`[MCP] Server config: transport=${server3.transport}, url=${server3.url}`);
|
|
479048
479149
|
const mcpServerConfig = {
|
|
479049
479150
|
transport: server3.transport,
|
|
479050
479151
|
command: server3.command,
|
|
@@ -479056,7 +479157,7 @@ ${messageContent}`;
|
|
|
479056
479157
|
try {
|
|
479057
479158
|
mcpServerConfig.headers = decryptConfig(server3.headers_encrypted, server3.headers_iv);
|
|
479058
479159
|
} catch (e) {
|
|
479059
|
-
|
|
479160
|
+
log79.warn(`Failed to decrypt headers for ${mcpName}`);
|
|
479060
479161
|
}
|
|
479061
479162
|
}
|
|
479062
479163
|
const currentConfig = mcp.config || { servers: {} };
|
|
@@ -479066,22 +479167,22 @@ ${messageContent}`;
|
|
|
479066
479167
|
...currentConfig,
|
|
479067
479168
|
servers: newServersConfig
|
|
479068
479169
|
});
|
|
479069
|
-
|
|
479170
|
+
log79.info(`[MCP] Server registered in MCP Manager`);
|
|
479070
479171
|
const tools = mcp.getServerTools(mcpName) || [];
|
|
479071
|
-
|
|
479172
|
+
log79.info(`[MCP] Connected! Tools: ${tools.length}`);
|
|
479072
479173
|
getDb().query(`UPDATE mcp_servers SET status = ?, tools_count = ? WHERE id = ? OR name = ?`).run("connected", tools.length, mcpName, mcpName);
|
|
479073
479174
|
} else {
|
|
479074
|
-
|
|
479175
|
+
log79.error(`[MCP] Server not found in DB: ${mcpName}`);
|
|
479075
479176
|
}
|
|
479076
479177
|
} else {
|
|
479077
479178
|
await mcp.disconnectServer(mcpName);
|
|
479078
479179
|
getDb().query(`UPDATE mcp_servers SET status = ? WHERE id = ? OR name = ?`).run("disconnected", mcpName, mcpName);
|
|
479079
479180
|
}
|
|
479080
479181
|
} else {
|
|
479081
|
-
|
|
479182
|
+
log79.error(`[MCP] No MCP Manager found`);
|
|
479082
479183
|
}
|
|
479083
479184
|
} catch (error54) {
|
|
479084
|
-
|
|
479185
|
+
log79.error(`[MCP] Failed to connect ${mcpName}: ${error54.message}`);
|
|
479085
479186
|
}
|
|
479086
479187
|
return addCorsHeaders(Response.json({ success: true, active, message: active ? "Servidor MCP conectado" : "Servidor MCP desconectado" }), req);
|
|
479087
479188
|
}
|
|
@@ -479108,7 +479209,7 @@ ${messageContent}`;
|
|
|
479108
479209
|
if (active) {
|
|
479109
479210
|
const server3 = getDb().query(`SELECT * FROM mcp_servers WHERE id = ? OR name = ?`).get(mcpName, mcpName);
|
|
479110
479211
|
if (server3) {
|
|
479111
|
-
|
|
479212
|
+
log79.info(`[MCP] Server config: transport=${server3.transport}, url=${server3.url}`);
|
|
479112
479213
|
const mcpServerConfig = {
|
|
479113
479214
|
transport: server3.transport,
|
|
479114
479215
|
command: server3.command,
|
|
@@ -479120,7 +479221,7 @@ ${messageContent}`;
|
|
|
479120
479221
|
try {
|
|
479121
479222
|
mcpServerConfig.headers = decryptConfig(server3.headers_encrypted, server3.headers_iv);
|
|
479122
479223
|
} catch (e) {
|
|
479123
|
-
|
|
479224
|
+
log79.warn(`Failed to decrypt headers for ${mcpName}`);
|
|
479124
479225
|
}
|
|
479125
479226
|
}
|
|
479126
479227
|
const currentConfig = mcp.config || { servers: {} };
|
|
@@ -479130,12 +479231,12 @@ ${messageContent}`;
|
|
|
479130
479231
|
...currentConfig,
|
|
479131
479232
|
servers: newServersConfig
|
|
479132
479233
|
});
|
|
479133
|
-
|
|
479234
|
+
log79.info(`[MCP] Server registered in MCP Manager`);
|
|
479134
479235
|
const tools = mcp.getServerTools(mcpName) || [];
|
|
479135
|
-
|
|
479236
|
+
log79.info(`[MCP] Connected! Tools: ${tools.length}`);
|
|
479136
479237
|
getDb().query(`UPDATE mcp_servers SET status = ?, tools_count = ? WHERE id = ? OR name = ?`).run("connected", tools.length, mcpName, mcpName);
|
|
479137
479238
|
} else {
|
|
479138
|
-
|
|
479239
|
+
log79.error(`[MCP] Server not found in DB: ${mcpName}`);
|
|
479139
479240
|
}
|
|
479140
479241
|
} else {
|
|
479141
479242
|
await mcp.disconnectServer(mcpName);
|
|
@@ -479143,7 +479244,7 @@ ${messageContent}`;
|
|
|
479143
479244
|
}
|
|
479144
479245
|
}
|
|
479145
479246
|
} catch (error54) {
|
|
479146
|
-
|
|
479247
|
+
log79.error(`[MCP] Failed to connect ${mcpName}: ${error54.message}`);
|
|
479147
479248
|
}
|
|
479148
479249
|
return addCorsHeaders(Response.json({ success: true, active, message: active ? "Servidor MCP conectado" : "Servidor MCP desconectado" }), req);
|
|
479149
479250
|
}
|
|
@@ -479332,12 +479433,12 @@ ${messageContent}`;
|
|
|
479332
479433
|
if (response) {
|
|
479333
479434
|
logRequest(response.status, duration3);
|
|
479334
479435
|
} else {
|
|
479335
|
-
|
|
479436
|
+
log79.info(`${method} ${url2.pathname} - 101 Switching Protocols(${duration3}ms)`);
|
|
479336
479437
|
}
|
|
479337
479438
|
return response;
|
|
479338
479439
|
} catch (error54) {
|
|
479339
479440
|
const duration3 = Date.now() - start;
|
|
479340
|
-
|
|
479441
|
+
log79.error(`${method} ${url2.pathname} - Internal Error(${duration3}ms): ${error54.message} `);
|
|
479341
479442
|
return addCorsHeaders(Response.json({ success: false, error: error54.message, message: "Error interno del servidor" }, { status: 500 }), req);
|
|
479342
479443
|
}
|
|
479343
479444
|
},
|
|
@@ -479346,17 +479447,17 @@ ${messageContent}`;
|
|
|
479346
479447
|
const data = ws.data;
|
|
479347
479448
|
const isBridge = data.sessionId.startsWith("bridge:");
|
|
479348
479449
|
if (isBridge) {
|
|
479349
|
-
|
|
479450
|
+
log79.info(`Bridge events client connected: ${data.sessionId}`);
|
|
479350
479451
|
subscribeBridge(ws);
|
|
479351
479452
|
ws.send(JSON.stringify({ type: "bridge:connected", sessionId: data.sessionId }));
|
|
479352
479453
|
return;
|
|
479353
479454
|
}
|
|
479354
479455
|
if (data.sessionId.startsWith("meeting:")) {
|
|
479355
|
-
|
|
479456
|
+
log79.info(`Meeting stream client connected: ${data.sessionId}`);
|
|
479356
479457
|
ws.send(JSON.stringify({ type: "meeting:connected", sessionId: data.sessionId, meetingSessionId: data.meetingSessionId }));
|
|
479357
479458
|
return;
|
|
479358
479459
|
}
|
|
479359
|
-
|
|
479460
|
+
log79.debug(`WebSocket connected: ${data.sessionId} `);
|
|
479360
479461
|
sessionManager.create(data.sessionId, ws);
|
|
479361
479462
|
const channel = channelManager?.getChannel("webchat");
|
|
479362
479463
|
if (channel?.registerConnection)
|
|
@@ -479387,7 +479488,7 @@ ${messageContent}`;
|
|
|
479387
479488
|
codeBridge: codeBridge.map((cb) => cb.id)
|
|
479388
479489
|
}));
|
|
479389
479490
|
} catch (err) {
|
|
479390
|
-
|
|
479491
|
+
log79.error("Error sending welcome message:", err);
|
|
479391
479492
|
}
|
|
479392
479493
|
},
|
|
479393
479494
|
async message(ws, message) {
|
|
@@ -479484,7 +479585,7 @@ ${messageContent}`;
|
|
|
479484
479585
|
const sourceComponentId = actionData.sourceComponentId ?? "unknown";
|
|
479485
479586
|
const context = actionData.context ?? {};
|
|
479486
479587
|
const interactionMsg = `[a2ui:action] surface=${surfaceId} action=${actionName} component=${sourceComponentId}${Object.keys(context).length > 0 ? ` context=${JSON.stringify(context)}` : ""}`;
|
|
479487
|
-
|
|
479588
|
+
log79.info(`A2UI action forwarded to agent: ${interactionMsg}`);
|
|
479488
479589
|
const sessionId = data.sessionId;
|
|
479489
479590
|
ws.send(JSON.stringify({ type: "typing", isTyping: true, sessionId }));
|
|
479490
479591
|
laneQueue.enqueue(sessionId, async (_task, signal2) => {
|
|
@@ -479514,7 +479615,7 @@ ${messageContent}`;
|
|
|
479514
479615
|
onStep: async (step) => {
|
|
479515
479616
|
if (signal2.aborted)
|
|
479516
479617
|
return;
|
|
479517
|
-
|
|
479618
|
+
log79.debug(`[a2ui:action TOOL] ${step.type}: ${step.toolName || ""}`);
|
|
479518
479619
|
}
|
|
479519
479620
|
});
|
|
479520
479621
|
ws.send(JSON.stringify({ type: "typing", isTyping: false, sessionId }));
|
|
@@ -479525,7 +479626,7 @@ ${messageContent}`;
|
|
|
479525
479626
|
} catch (error54) {
|
|
479526
479627
|
ws.send(JSON.stringify({ type: "typing", isTyping: false, sessionId }));
|
|
479527
479628
|
ws.send(JSON.stringify({ type: "error", sessionId, error: error54.message }));
|
|
479528
|
-
|
|
479629
|
+
log79.error(`A2UI action agent error: ${error54.message}`);
|
|
479529
479630
|
}
|
|
479530
479631
|
});
|
|
479531
479632
|
return;
|
|
@@ -479546,7 +479647,7 @@ ${messageContent}`;
|
|
|
479546
479647
|
if (interactionData && Object.keys(interactionData).length > 0) {
|
|
479547
479648
|
interactionMsg += `, data=${JSON.stringify(interactionData)}`;
|
|
479548
479649
|
}
|
|
479549
|
-
|
|
479650
|
+
log79.info(`Canvas interaction forwarded to agent: ${interactionMsg}`);
|
|
479550
479651
|
const sessionId = data.sessionId;
|
|
479551
479652
|
ws.send(JSON.stringify({ type: "typing", isTyping: true, sessionId }));
|
|
479552
479653
|
laneQueue.enqueue(sessionId, async (_task, signal2) => {
|
|
@@ -479576,7 +479677,7 @@ ${messageContent}`;
|
|
|
479576
479677
|
onStep: async (step) => {
|
|
479577
479678
|
if (signal2.aborted)
|
|
479578
479679
|
return;
|
|
479579
|
-
|
|
479680
|
+
log79.debug(`[canvas:interact TOOL] ${step.type}: ${step.toolName || ""}`);
|
|
479580
479681
|
}
|
|
479581
479682
|
});
|
|
479582
479683
|
ws.send(JSON.stringify({ type: "typing", isTyping: false, sessionId }));
|
|
@@ -479587,7 +479688,7 @@ ${messageContent}`;
|
|
|
479587
479688
|
} catch (error54) {
|
|
479588
479689
|
ws.send(JSON.stringify({ type: "typing", isTyping: false, sessionId }));
|
|
479589
479690
|
ws.send(JSON.stringify({ type: "error", sessionId, error: error54.message }));
|
|
479590
|
-
|
|
479691
|
+
log79.error(`Canvas interact agent error: ${error54.message}`);
|
|
479591
479692
|
}
|
|
479592
479693
|
});
|
|
479593
479694
|
}
|
|
@@ -479602,17 +479703,17 @@ ${messageContent}`;
|
|
|
479602
479703
|
}
|
|
479603
479704
|
if (msg.type === "logs_subscribe") {
|
|
479604
479705
|
logSubscribers.add(data.sessionId);
|
|
479605
|
-
|
|
479706
|
+
log79.debug(`Session ${data.sessionId} subscribed to logs`);
|
|
479606
479707
|
return;
|
|
479607
479708
|
}
|
|
479608
479709
|
if (msg.type === "logs_unsubscribe") {
|
|
479609
479710
|
logSubscribers.delete(data.sessionId);
|
|
479610
|
-
|
|
479711
|
+
log79.debug(`Session ${data.sessionId} unsubscribed from logs`);
|
|
479611
479712
|
return;
|
|
479612
479713
|
}
|
|
479613
479714
|
if (msg.type === "stop") {
|
|
479614
479715
|
const cancelled = laneQueue.cancel(msg.sessionId);
|
|
479615
|
-
|
|
479716
|
+
log79.info(`[stop] Session ${msg.sessionId} \u2014 cancelled: ${cancelled}`);
|
|
479616
479717
|
ws.send(JSON.stringify({
|
|
479617
479718
|
type: "typing",
|
|
479618
479719
|
isTyping: false,
|
|
@@ -479629,7 +479730,7 @@ ${messageContent}`;
|
|
|
479629
479730
|
}
|
|
479630
479731
|
let webchatPreferAudio = false;
|
|
479631
479732
|
if (msg.type === "audio" && msg.audio) {
|
|
479632
|
-
|
|
479733
|
+
log79.info(`WebChat audio from session ${msg.sessionId}`);
|
|
479633
479734
|
const voiceConfig = voiceService.getChannelVoiceConfig("webchat");
|
|
479634
479735
|
if (!voiceConfig.voiceEnabled) {
|
|
479635
479736
|
ws.send(JSON.stringify({
|
|
@@ -479656,7 +479757,7 @@ ${messageContent}`;
|
|
|
479656
479757
|
const audioInput = { type: "base64", data: msg.audio, mimeType: "audio/webm" };
|
|
479657
479758
|
const sttProvider = voiceConfig.sttProvider || "groq-whisper";
|
|
479658
479759
|
const messageContent = await voiceService.transcribe(audioInput, sttProvider);
|
|
479659
|
-
|
|
479760
|
+
log79.info(`\uD83D\uDCDD Transcribed: ${messageContent.substring(0, 100)}...`);
|
|
479660
479761
|
webchatPreferAudio = true;
|
|
479661
479762
|
ws.send(JSON.stringify({
|
|
479662
479763
|
type: "message",
|
|
@@ -479677,7 +479778,7 @@ ${messageContent}`;
|
|
|
479677
479778
|
try {
|
|
479678
479779
|
const unifiedSessionId = msg.sessionId;
|
|
479679
479780
|
const messages2 = [{ role: "user", content: messageContent }];
|
|
479680
|
-
|
|
479781
|
+
log79.info(`Generating response for session ${unifiedSessionId}...`);
|
|
479681
479782
|
const { userId } = resolveContext({
|
|
479682
479783
|
channel: "webchat",
|
|
479683
479784
|
channelUserId: msg.sessionId
|
|
@@ -479747,7 +479848,7 @@ ${messageContent}`;
|
|
|
479747
479848
|
}
|
|
479748
479849
|
});
|
|
479749
479850
|
const content = streamedContent || response.content?.trim() || "";
|
|
479750
|
-
|
|
479851
|
+
log79.info(`Response sent to session ${unifiedSessionId} (${content.length} chars)`);
|
|
479751
479852
|
const voiceCfg = voiceService.getChannelVoiceConfig("webchat");
|
|
479752
479853
|
const shouldSpeak = webchatPreferAudio;
|
|
479753
479854
|
let responseType = "text";
|
|
@@ -479768,13 +479869,13 @@ ${messageContent}`;
|
|
|
479768
479869
|
}));
|
|
479769
479870
|
} else {
|
|
479770
479871
|
try {
|
|
479771
|
-
|
|
479872
|
+
log79.info(`\uD83D\uDD0A TTS enabled, synthesizing audio for WebChat...`);
|
|
479772
479873
|
const audioOutput = await voiceService.speak(content, voiceCfg.ttsProvider, voiceCfg.ttsVoiceId || undefined);
|
|
479773
479874
|
ttsProviderUsed = voiceCfg.ttsProvider;
|
|
479774
479875
|
ttsMimeType = audioOutput.mimeType;
|
|
479775
479876
|
responseType = "audio";
|
|
479776
479877
|
const base64Audio = audioOutput.data.toString("base64");
|
|
479777
|
-
|
|
479878
|
+
log79.info(`Audio generated: ${base64Audio.length} bytes, mimeType: ${audioOutput.mimeType}`);
|
|
479778
479879
|
ws.send(JSON.stringify({
|
|
479779
479880
|
type: "message",
|
|
479780
479881
|
sessionId: unifiedSessionId,
|
|
@@ -479784,7 +479885,7 @@ ${messageContent}`;
|
|
|
479784
479885
|
isStep: false
|
|
479785
479886
|
}));
|
|
479786
479887
|
} catch (ttsError) {
|
|
479787
|
-
|
|
479888
|
+
log79.error(`TTS failed: ${ttsError.message}), sending text instead`);
|
|
479788
479889
|
ws.send(JSON.stringify({ type: "message", sessionId: unifiedSessionId, content, isStep: false }));
|
|
479789
479890
|
}
|
|
479790
479891
|
}
|
|
@@ -479793,10 +479894,10 @@ ${messageContent}`;
|
|
|
479793
479894
|
}
|
|
479794
479895
|
} else if (alreadyStreamed && shouldSpeak && voiceCfg.ttsProvider) {
|
|
479795
479896
|
try {
|
|
479796
|
-
|
|
479897
|
+
log79.info(`\uD83D\uDD0A TTS enabled, synthesizing audio after streaming...`);
|
|
479797
479898
|
const audioOutput = await voiceService.speak(content, voiceCfg.ttsProvider, voiceCfg.ttsVoiceId || undefined);
|
|
479798
479899
|
const base64Audio = audioOutput.data.toString("base64");
|
|
479799
|
-
|
|
479900
|
+
log79.info(`Audio generated after streaming: ${base64Audio.length} bytes`);
|
|
479800
479901
|
ws.send(JSON.stringify({
|
|
479801
479902
|
type: "message",
|
|
479802
479903
|
sessionId: unifiedSessionId,
|
|
@@ -479806,7 +479907,7 @@ ${messageContent}`;
|
|
|
479806
479907
|
isStep: false
|
|
479807
479908
|
}));
|
|
479808
479909
|
} catch (ttsError) {
|
|
479809
|
-
|
|
479910
|
+
log79.error(`TTS after streaming failed: ${ttsError.message}), skipping audio`);
|
|
479810
479911
|
}
|
|
479811
479912
|
}
|
|
479812
479913
|
} catch (error54) {
|
|
@@ -479816,7 +479917,7 @@ ${messageContent}`;
|
|
|
479816
479917
|
sessionId: msg.sessionId,
|
|
479817
479918
|
error: error54.message
|
|
479818
479919
|
}));
|
|
479819
|
-
|
|
479920
|
+
log79.error(`Error for session ${msg.sessionId}: ${error54.message}`);
|
|
479820
479921
|
}
|
|
479821
479922
|
});
|
|
479822
479923
|
} catch (error54) {
|
|
@@ -479834,7 +479935,7 @@ ${messageContent}`;
|
|
|
479834
479935
|
return;
|
|
479835
479936
|
}
|
|
479836
479937
|
if (msg.type === "message" && msg.content) {
|
|
479837
|
-
|
|
479938
|
+
log79.info(`WebChat message from session ${msg.sessionId}: ${msg.content.substring(0, 100)}`);
|
|
479838
479939
|
ws.send(JSON.stringify({
|
|
479839
479940
|
type: "typing",
|
|
479840
479941
|
isTyping: true,
|
|
@@ -479852,7 +479953,7 @@ ${messageContent}`;
|
|
|
479852
479953
|
let contentParts = undefined;
|
|
479853
479954
|
const visionConfig = multimodalService.getChannelVisionConfig("webchat");
|
|
479854
479955
|
if (msg.image || msg.document) {
|
|
479855
|
-
|
|
479956
|
+
log79.info(`\uD83D\uDDBC\uFE0F Multimodal content detected from WebChat session ${unifiedSessionId}`);
|
|
479856
479957
|
if (msg.image) {
|
|
479857
479958
|
try {
|
|
479858
479959
|
const imageInput = {
|
|
@@ -479866,25 +479967,25 @@ ${messageContent}`;
|
|
|
479866
479967
|
const modelHasVision = activeModelId && activeProviderId ? multimodalService.modelSupportsVision(activeProviderId, activeModelId) : false;
|
|
479867
479968
|
if (visionConfig.visionEnabled && modelHasVision) {
|
|
479868
479969
|
contentParts = await multimodalService.processImage(imageInput, visionConfig.visionModelId || undefined);
|
|
479869
|
-
|
|
479970
|
+
log79.info(`\uD83D\uDDBC\uFE0F Image sent as vision ContentParts (model supports vision)`);
|
|
479870
479971
|
} else {
|
|
479871
479972
|
const ocrProvider = visionConfig.ocrProvider || (["openai", "gemini", "anthropic"].includes(dbProvider) ? dbProvider : "openai");
|
|
479872
|
-
|
|
479973
|
+
log79.info(`\uD83D\uDDBC\uFE0F Model lacks vision or vision disabled, using OCR via ${ocrProvider}...`);
|
|
479873
479974
|
const ocrText = await multimodalService.ocrImage(imageInput, ocrProvider);
|
|
479874
479975
|
finalMessageContent = ocrText ? `[Imagen adjunta \u2014 contenido extra\xEDdo por OCR]
|
|
479875
479976
|
${ocrText}
|
|
479876
479977
|
|
|
479877
479978
|
${finalMessageContent || ""}` : finalMessageContent || "";
|
|
479878
|
-
|
|
479979
|
+
log79.info(`\uD83D\uDDBC\uFE0F OCR result: ${ocrText.substring(0, 100)}...`);
|
|
479879
479980
|
}
|
|
479880
479981
|
} catch (imgError) {
|
|
479881
|
-
|
|
479982
|
+
log79.error(`\u274C Image processing failed: ${imgError.message}`);
|
|
479882
479983
|
}
|
|
479883
479984
|
}
|
|
479884
479985
|
if (msg.document) {
|
|
479885
479986
|
try {
|
|
479886
479987
|
const ocrProvider = visionConfig.ocrProvider || (["openai", "gemini", "anthropic"].includes(dbProvider) ? dbProvider : "openai");
|
|
479887
|
-
|
|
479988
|
+
log79.info(`\uD83D\uDCC4 Document detected from WebChat, extracting text via OCR (${ocrProvider})...`);
|
|
479888
479989
|
const docImage = {
|
|
479889
479990
|
type: "base64",
|
|
479890
479991
|
data: msg.document.base64,
|
|
@@ -479896,14 +479997,14 @@ ${finalMessageContent || ""}` : finalMessageContent || "";
|
|
|
479896
479997
|
${ocrText}
|
|
479897
479998
|
|
|
479898
479999
|
${finalMessageContent || ""}` : finalMessageContent || "";
|
|
479899
|
-
|
|
480000
|
+
log79.info(`\uD83D\uDCC4 Document OCR result: ${ocrText.substring(0, 100)}...`);
|
|
479900
480001
|
} catch (docError) {
|
|
479901
|
-
|
|
480002
|
+
log79.error(`\u274C Document processing failed: ${docError.message}`);
|
|
479902
480003
|
}
|
|
479903
480004
|
}
|
|
479904
480005
|
}
|
|
479905
480006
|
const messages2 = contentParts ? [{ role: "user", content: contentParts }] : [{ role: "user", content: finalMessageContent }];
|
|
479906
|
-
|
|
480007
|
+
log79.info(`Generating response for session ${unifiedSessionId} (multimodal: ${!!(msg.image || msg.document)})...`);
|
|
479907
480008
|
const { userId } = resolveContext({
|
|
479908
480009
|
channel: "webchat",
|
|
479909
480010
|
channelUserId: msg.sessionId
|
|
@@ -479974,7 +480075,7 @@ ${finalMessageContent || ""}` : finalMessageContent || "";
|
|
|
479974
480075
|
}
|
|
479975
480076
|
});
|
|
479976
480077
|
const content = streamedContent || response.content?.trim() || "";
|
|
479977
|
-
|
|
480078
|
+
log79.info(`Response sent to session ${unifiedSessionId} (${content.length} chars)`);
|
|
479978
480079
|
const voiceConfig = voiceService.getChannelVoiceConfig("webchat");
|
|
479979
480080
|
const shouldSpeak = webchatPreferAudio;
|
|
479980
480081
|
let responseType = "text";
|
|
@@ -479995,7 +480096,7 @@ ${finalMessageContent || ""}` : finalMessageContent || "";
|
|
|
479995
480096
|
}));
|
|
479996
480097
|
} else {
|
|
479997
480098
|
try {
|
|
479998
|
-
|
|
480099
|
+
log79.info(`\uD83D\uDD0A TTS enabled, synthesizing audio for WebChat...`);
|
|
479999
480100
|
const audioOutput = await voiceService.speak(content, voiceConfig.ttsProvider, voiceConfig.ttsVoiceId || undefined);
|
|
480000
480101
|
ttsProviderUsed = voiceConfig.ttsProvider;
|
|
480001
480102
|
ttsMimeType = audioOutput.mimeType;
|
|
@@ -480010,7 +480111,7 @@ ${finalMessageContent || ""}` : finalMessageContent || "";
|
|
|
480010
480111
|
isStep: false
|
|
480011
480112
|
}));
|
|
480012
480113
|
} catch (ttsError) {
|
|
480013
|
-
|
|
480114
|
+
log79.error(`TTS failed: ${ttsError.message}), sending text instead`);
|
|
480014
480115
|
ws.send(JSON.stringify({ type: "message", sessionId: unifiedSessionId, content, isStep: false }));
|
|
480015
480116
|
}
|
|
480016
480117
|
}
|
|
@@ -480019,10 +480120,10 @@ ${finalMessageContent || ""}` : finalMessageContent || "";
|
|
|
480019
480120
|
}
|
|
480020
480121
|
} else if (alreadyStreamed && shouldSpeak && voiceConfig.ttsProvider) {
|
|
480021
480122
|
try {
|
|
480022
|
-
|
|
480123
|
+
log79.info(`\uD83D\uDD0A TTS enabled, synthesizing audio after streaming...`);
|
|
480023
480124
|
const audioOutput = await voiceService.speak(content, voiceConfig.ttsProvider, voiceConfig.ttsVoiceId || undefined);
|
|
480024
480125
|
const base64Audio = audioOutput.data.toString("base64");
|
|
480025
|
-
|
|
480126
|
+
log79.info(`Audio generated after streaming: ${base64Audio.length} bytes`);
|
|
480026
480127
|
ws.send(JSON.stringify({
|
|
480027
480128
|
type: "message",
|
|
480028
480129
|
sessionId: unifiedSessionId,
|
|
@@ -480032,7 +480133,7 @@ ${finalMessageContent || ""}` : finalMessageContent || "";
|
|
|
480032
480133
|
isStep: false
|
|
480033
480134
|
}));
|
|
480034
480135
|
} catch (ttsError) {
|
|
480035
|
-
|
|
480136
|
+
log79.error(`TTS after streaming failed: ${ttsError.message}), skipping audio`);
|
|
480036
480137
|
}
|
|
480037
480138
|
}
|
|
480038
480139
|
} catch (error54) {
|
|
@@ -480043,7 +480144,7 @@ ${finalMessageContent || ""}` : finalMessageContent || "";
|
|
|
480043
480144
|
sessionId: unifiedSessionId,
|
|
480044
480145
|
error: error54.message
|
|
480045
480146
|
}));
|
|
480046
|
-
|
|
480147
|
+
log79.error(`Error for session ${unifiedSessionId}: ${error54.message}`);
|
|
480047
480148
|
}
|
|
480048
480149
|
});
|
|
480049
480150
|
return;
|
|
@@ -480062,10 +480163,10 @@ ${finalMessageContent || ""}` : finalMessageContent || "";
|
|
|
480062
480163
|
return;
|
|
480063
480164
|
}
|
|
480064
480165
|
if (data.sessionId.startsWith("meeting:")) {
|
|
480065
|
-
|
|
480166
|
+
log79.info(`Meeting stream client disconnected: ${data.sessionId}`);
|
|
480066
480167
|
return;
|
|
480067
480168
|
}
|
|
480068
|
-
|
|
480169
|
+
log79.debug(`WebSocket disconnected: ${data.sessionId}`);
|
|
480069
480170
|
logSubscribers.delete(data.sessionId);
|
|
480070
480171
|
sessionManager.delete(data.sessionId);
|
|
480071
480172
|
laneQueue.cancel(data.sessionId);
|
|
@@ -480098,28 +480199,28 @@ ${finalMessageContent || ""}` : finalMessageContent || "";
|
|
|
480098
480199
|
}
|
|
480099
480200
|
}
|
|
480100
480201
|
});
|
|
480101
|
-
|
|
480202
|
+
log79.info(`Gateway started successfully`);
|
|
480102
480203
|
const isGatewayChild = process.env.HIVE_GATEWAY_CHILD === "1";
|
|
480103
480204
|
if (isDev) {
|
|
480104
480205
|
const devUrl = gatewaySetupMode ? `http://localhost:${port}/setup` : `http://localhost:${port}`;
|
|
480105
|
-
|
|
480106
|
-
|
|
480107
|
-
|
|
480108
|
-
|
|
480109
|
-
|
|
480206
|
+
log79.info(`[gateway] UI: ${devUrl}`);
|
|
480207
|
+
log79.info(`[gateway] API: http://${host}:${port}`);
|
|
480208
|
+
log79.info(`[gateway] WebSocket: ws://${host}:${port}/ws`);
|
|
480209
|
+
log79.info(`[gateway] Canvas: ws://${host}:${port}/canvas`);
|
|
480210
|
+
log79.info(`[gateway] Modo: desarrollo`);
|
|
480110
480211
|
if (!isGatewayChild) {
|
|
480111
|
-
|
|
480212
|
+
log79.info(gatewaySetupMode ? `\uD83C\uDF89 Primer arranque \u2014 abriendo setup...` : `\uD83D\uDC1D Administra tu Hive aqu\xED: ${devUrl}`);
|
|
480112
480213
|
}
|
|
480113
480214
|
} else {
|
|
480114
480215
|
const isSetupMode2 = gatewaySetupMode;
|
|
480115
480216
|
const baseUrl = process.env.HIVE_PUBLIC_URL?.replace(/\/$/, "") ?? `http://${host}:${port}`;
|
|
480116
480217
|
const uiUrl = isSetupMode2 ? `${baseUrl}/setup` : `${baseUrl}/ui`;
|
|
480117
|
-
|
|
480118
|
-
|
|
480119
|
-
|
|
480120
|
-
|
|
480218
|
+
log79.info(`[gateway] UI: ${uiUrl}`);
|
|
480219
|
+
log79.info(`[gateway] API: http://${host}:${port}`);
|
|
480220
|
+
log79.info(`[gateway] WebSocket: ws://${host}:${port}/ws`);
|
|
480221
|
+
log79.info(`[gateway] Canvas: ws://${host}:${port}/canvas`);
|
|
480121
480222
|
if (!process.env.NO_BROWSER) {
|
|
480122
|
-
|
|
480223
|
+
log79.info(isSetupMode2 ? `\uD83C\uDF89 Primer arranque \u2014 abriendo wizard de configuraci\xF3n...` : `\uD83D\uDC1D Administra tu Hive aqu\xED: ${uiUrl}`);
|
|
480123
480224
|
try {
|
|
480124
480225
|
const platform2 = process.platform;
|
|
480125
480226
|
let shellCmd;
|
|
@@ -480139,54 +480240,54 @@ ${finalMessageContent || ""}` : finalMessageContent || "";
|
|
|
480139
480240
|
});
|
|
480140
480241
|
proc.unref();
|
|
480141
480242
|
} catch (err) {
|
|
480142
|
-
|
|
480243
|
+
log79.warn(`Could not open browser: ${err.message}`);
|
|
480143
480244
|
}
|
|
480144
480245
|
}
|
|
480145
480246
|
}
|
|
480146
480247
|
if (!gatewaySetupMode)
|
|
480147
|
-
|
|
480248
|
+
log79.info(`Channels: ${channelManager.listChannels().map((c) => c.name).join(", ") || "none"}`);
|
|
480148
480249
|
process.on("SIGTERM", async () => {
|
|
480149
|
-
|
|
480250
|
+
log79.info("Received SIGTERM, shutting down gracefully...");
|
|
480150
480251
|
watchers.forEach((close) => close());
|
|
480151
480252
|
const mcp = agent?.getMCPManager();
|
|
480152
480253
|
if (mcp) {
|
|
480153
|
-
|
|
480254
|
+
log79.info("Disconnecting MCP servers...");
|
|
480154
480255
|
await mcp.disconnectAll().catch(() => {});
|
|
480155
480256
|
}
|
|
480156
480257
|
if (channelManager) {
|
|
480157
|
-
|
|
480258
|
+
log79.info("Stopping channels...");
|
|
480158
480259
|
await channelManager.stopAll();
|
|
480159
480260
|
}
|
|
480160
480261
|
try {
|
|
480161
480262
|
const mod = await Promise.resolve().then(() => (init_browser_service(), exports_browser_service));
|
|
480162
480263
|
mod.CDPClient.closeAll();
|
|
480163
|
-
|
|
480264
|
+
log79.info("Browser processes cleaned up");
|
|
480164
480265
|
} catch {}
|
|
480165
480266
|
try {
|
|
480166
480267
|
canvasManager.clearAll();
|
|
480167
|
-
|
|
480268
|
+
log79.info("Canvas sessions cleaned up");
|
|
480168
480269
|
} catch {}
|
|
480169
480270
|
try {
|
|
480170
480271
|
const { stopMCPHotReload: stopMCPHotReload2 } = await Promise.resolve().then(() => (init_hot_reload(), exports_hot_reload));
|
|
480171
480272
|
stopMCPHotReload2();
|
|
480172
|
-
|
|
480273
|
+
log79.info("MCP hot-reload stopped");
|
|
480173
480274
|
} catch {}
|
|
480174
480275
|
server.stop();
|
|
480175
480276
|
try {
|
|
480176
480277
|
unlinkSync4(pidFile);
|
|
480177
480278
|
} catch {}
|
|
480178
|
-
|
|
480279
|
+
log79.info("Gateway shutdown complete");
|
|
480179
480280
|
process.exit(0);
|
|
480180
480281
|
});
|
|
480181
480282
|
process.on("SIGHUP", async () => {
|
|
480182
|
-
|
|
480283
|
+
log79.info("Received SIGHUP, reloading configuration...");
|
|
480183
480284
|
try {
|
|
480184
480285
|
const newConfig = await loadConfig();
|
|
480185
480286
|
await agent.updateConfig(newConfig);
|
|
480186
480287
|
await agent.reload();
|
|
480187
|
-
|
|
480288
|
+
log79.info("Configuration reloaded successfully");
|
|
480188
480289
|
} catch (error54) {
|
|
480189
|
-
|
|
480290
|
+
log79.error(`Failed to reload configuration: ${error54.message}`);
|
|
480190
480291
|
}
|
|
480191
480292
|
});
|
|
480192
480293
|
}
|
|
@@ -481683,7 +481784,7 @@ var init_circuit_breaker = __esm(() => {
|
|
|
481683
481784
|
circuitBreakerRegistry = new CircuitBreakerRegistry;
|
|
481684
481785
|
});
|
|
481685
481786
|
// packages/core/src/plugins/loader.ts
|
|
481686
|
-
import { mkdirSync as
|
|
481787
|
+
import { mkdirSync as mkdirSync18, readdirSync as readdirSync6, existsSync as existsSync29 } from "fs";
|
|
481687
481788
|
import * as path31 from "path";
|
|
481688
481789
|
|
|
481689
481790
|
class PluginLoader {
|
|
@@ -481697,19 +481798,19 @@ class PluginLoader {
|
|
|
481697
481798
|
log = logger.child("plugins");
|
|
481698
481799
|
constructor(options2) {
|
|
481699
481800
|
this.options = options2;
|
|
481700
|
-
if (!
|
|
481701
|
-
|
|
481801
|
+
if (!existsSync29(options2.pluginDir)) {
|
|
481802
|
+
mkdirSync18(options2.pluginDir, { recursive: true });
|
|
481702
481803
|
}
|
|
481703
481804
|
}
|
|
481704
481805
|
async discover() {
|
|
481705
481806
|
const pluginDir = this.options.pluginDir;
|
|
481706
481807
|
const discovered = [];
|
|
481707
481808
|
try {
|
|
481708
|
-
const entries =
|
|
481809
|
+
const entries = readdirSync6(pluginDir, { withFileTypes: true });
|
|
481709
481810
|
for (const entry of entries) {
|
|
481710
481811
|
if (entry.isDirectory()) {
|
|
481711
481812
|
const manifestPath = path31.join(pluginDir, entry.name, "manifest.json");
|
|
481712
|
-
if (
|
|
481813
|
+
if (existsSync29(manifestPath)) {
|
|
481713
481814
|
discovered.push(entry.name);
|
|
481714
481815
|
}
|
|
481715
481816
|
}
|
|
@@ -482086,7 +482187,7 @@ var init_types6 = __esm(() => {
|
|
|
482086
482187
|
|
|
482087
482188
|
// packages/cli/src/adapters/config.ts
|
|
482088
482189
|
import * as path32 from "path";
|
|
482089
|
-
import { existsSync as
|
|
482190
|
+
import { existsSync as existsSync30, readFileSync as readFileSync14 } from "fs";
|
|
482090
482191
|
function getHiveDir2(customDir) {
|
|
482091
482192
|
if (customDir) {
|
|
482092
482193
|
return path32.resolve(customDir);
|
|
@@ -482114,7 +482215,7 @@ function getDefaultPaths(hiveDir) {
|
|
|
482114
482215
|
}
|
|
482115
482216
|
function loadEnvFile(envPath) {
|
|
482116
482217
|
const filePath = envPath || path32.join(process.cwd(), ".env");
|
|
482117
|
-
if (!
|
|
482218
|
+
if (!existsSync30(filePath)) {
|
|
482118
482219
|
return {};
|
|
482119
482220
|
}
|
|
482120
482221
|
try {
|
|
@@ -482186,7 +482287,7 @@ function getDistDir() {
|
|
|
482186
482287
|
return dir;
|
|
482187
482288
|
}
|
|
482188
482289
|
const distPath = path32.join(dir, "dist");
|
|
482189
|
-
if (
|
|
482290
|
+
if (existsSync30(distPath)) {
|
|
482190
482291
|
return distPath;
|
|
482191
482292
|
}
|
|
482192
482293
|
return null;
|
|
@@ -482208,7 +482309,7 @@ __export(exports_docker, {
|
|
|
482208
482309
|
});
|
|
482209
482310
|
import { spawn as spawn3, execSync } from "child_process";
|
|
482210
482311
|
import * as path33 from "path";
|
|
482211
|
-
import { existsSync as
|
|
482312
|
+
import { existsSync as existsSync31 } from "fs";
|
|
482212
482313
|
|
|
482213
482314
|
class DockerAdapter {
|
|
482214
482315
|
type = "docker";
|
|
@@ -482228,7 +482329,7 @@ class DockerAdapter {
|
|
|
482228
482329
|
path33.join(process.env.HOME || "", ".hive", "docker-compose.yml")
|
|
482229
482330
|
];
|
|
482230
482331
|
for (const composePath of standardPaths) {
|
|
482231
|
-
if (
|
|
482332
|
+
if (existsSync31(composePath)) {
|
|
482232
482333
|
return composePath;
|
|
482233
482334
|
}
|
|
482234
482335
|
}
|
|
@@ -482238,7 +482339,7 @@ class DockerAdapter {
|
|
|
482238
482339
|
try {
|
|
482239
482340
|
execSync("docker --version", { stdio: "ignore" });
|
|
482240
482341
|
execSync("docker compose version", { stdio: "ignore" });
|
|
482241
|
-
if (!
|
|
482342
|
+
if (!existsSync31(this.composeFile)) {
|
|
482242
482343
|
return false;
|
|
482243
482344
|
}
|
|
482244
482345
|
try {
|
|
@@ -482369,7 +482470,7 @@ class DockerAdapter {
|
|
|
482369
482470
|
} catch {
|
|
482370
482471
|
errors6.push("Docker Compose is not installed");
|
|
482371
482472
|
}
|
|
482372
|
-
if (!
|
|
482473
|
+
if (!existsSync31(this.composeFile)) {
|
|
482373
482474
|
errors6.push(`docker-compose.yml not found at ${this.composeFile}`);
|
|
482374
482475
|
} else {
|
|
482375
482476
|
info3.push(`Compose file: ${this.composeFile}`);
|
|
@@ -482409,7 +482510,7 @@ var init_docker = __esm(() => {
|
|
|
482409
482510
|
// packages/cli/src/adapters/bun-global.ts
|
|
482410
482511
|
import { spawn as spawn4, execSync as execSync2 } from "child_process";
|
|
482411
482512
|
import * as path34 from "path";
|
|
482412
|
-
import { existsSync as
|
|
482513
|
+
import { existsSync as existsSync32, readFileSync as readFileSync15, unlinkSync as unlinkSync5 } from "fs";
|
|
482413
482514
|
|
|
482414
482515
|
class BunGlobalAdapter {
|
|
482415
482516
|
type = "bun-global";
|
|
@@ -482429,7 +482530,7 @@ class BunGlobalAdapter {
|
|
|
482429
482530
|
stdio: ["ignore", "pipe", "ignore"]
|
|
482430
482531
|
});
|
|
482431
482532
|
const hivePath = output.trim();
|
|
482432
|
-
if (hivePath &&
|
|
482533
|
+
if (hivePath && existsSync32(hivePath)) {
|
|
482433
482534
|
return true;
|
|
482434
482535
|
}
|
|
482435
482536
|
} catch {
|
|
@@ -482457,13 +482558,13 @@ class BunGlobalAdapter {
|
|
|
482457
482558
|
}).trim();
|
|
482458
482559
|
const distDir = path34.dirname(hivePath);
|
|
482459
482560
|
const potentialUiDir = path34.join(distDir, "ui");
|
|
482460
|
-
if (
|
|
482561
|
+
if (existsSync32(potentialUiDir)) {
|
|
482461
482562
|
uiDir = potentialUiDir;
|
|
482462
482563
|
}
|
|
482463
482564
|
} catch {}
|
|
482464
482565
|
if (!uiDir) {
|
|
482465
482566
|
const cwdUiDir = path34.join(process.cwd(), "packages/hive-ui/dist");
|
|
482466
|
-
if (
|
|
482567
|
+
if (existsSync32(cwdUiDir)) {
|
|
482467
482568
|
uiDir = cwdUiDir;
|
|
482468
482569
|
}
|
|
482469
482570
|
}
|
|
@@ -482514,7 +482615,7 @@ class BunGlobalAdapter {
|
|
|
482514
482615
|
}
|
|
482515
482616
|
async stop() {
|
|
482516
482617
|
try {
|
|
482517
|
-
if (
|
|
482618
|
+
if (existsSync32(this.pidFile)) {
|
|
482518
482619
|
const pid = parseInt(readFileSync15(this.pidFile, "utf-8").trim(), 10);
|
|
482519
482620
|
if (!isNaN(pid)) {
|
|
482520
482621
|
try {
|
|
@@ -482547,7 +482648,7 @@ class BunGlobalAdapter {
|
|
|
482547
482648
|
}
|
|
482548
482649
|
async isRunning() {
|
|
482549
482650
|
try {
|
|
482550
|
-
if (
|
|
482651
|
+
if (existsSync32(this.pidFile)) {
|
|
482551
482652
|
const pid = parseInt(readFileSync15(this.pidFile, "utf-8").trim(), 10);
|
|
482552
482653
|
if (!isNaN(pid)) {
|
|
482553
482654
|
try {
|
|
@@ -482569,7 +482670,7 @@ class BunGlobalAdapter {
|
|
|
482569
482670
|
}
|
|
482570
482671
|
async getPid() {
|
|
482571
482672
|
try {
|
|
482572
|
-
if (
|
|
482673
|
+
if (existsSync32(this.pidFile)) {
|
|
482573
482674
|
const pid = parseInt(readFileSync15(this.pidFile, "utf-8").trim(), 10);
|
|
482574
482675
|
if (!isNaN(pid) && pid > 0) {
|
|
482575
482676
|
try {
|
|
@@ -482611,11 +482712,11 @@ class BunGlobalAdapter {
|
|
|
482611
482712
|
encoding: "utf-8",
|
|
482612
482713
|
stdio: ["ignore", "pipe", "ignore"]
|
|
482613
482714
|
}).trim();
|
|
482614
|
-
if (hivePath &&
|
|
482715
|
+
if (hivePath && existsSync32(hivePath)) {
|
|
482615
482716
|
info3.push(`Hive binary: ${hivePath}`);
|
|
482616
482717
|
const distDir = path34.dirname(hivePath);
|
|
482617
482718
|
const uiDir = path34.join(distDir, "ui");
|
|
482618
|
-
if (
|
|
482719
|
+
if (existsSync32(uiDir)) {
|
|
482619
482720
|
info3.push(`UI directory: ${uiDir}`);
|
|
482620
482721
|
} else {
|
|
482621
482722
|
warnings.push("UI directory not found - may use embedded UI");
|
|
@@ -482626,7 +482727,7 @@ class BunGlobalAdapter {
|
|
|
482626
482727
|
} catch {
|
|
482627
482728
|
errors6.push("Hive is not installed globally (try: bun install -g @johpaz/hive-agents)");
|
|
482628
482729
|
}
|
|
482629
|
-
if (
|
|
482730
|
+
if (existsSync32(this.hiveDir)) {
|
|
482630
482731
|
info3.push(`Hive home: ${this.hiveDir}`);
|
|
482631
482732
|
} else {
|
|
482632
482733
|
warnings.push(`Hive home directory does not exist: ${this.hiveDir}`);
|
|
@@ -482668,7 +482769,7 @@ var init_bun_global = __esm(() => {
|
|
|
482668
482769
|
// packages/cli/src/adapters/binary.ts
|
|
482669
482770
|
import { spawn as spawn5, execSync as execSync3 } from "child_process";
|
|
482670
482771
|
import * as path35 from "path";
|
|
482671
|
-
import { existsSync as
|
|
482772
|
+
import { existsSync as existsSync33, readFileSync as readFileSync16, unlinkSync as unlinkSync6 } from "fs";
|
|
482672
482773
|
|
|
482673
482774
|
class BinaryAdapter {
|
|
482674
482775
|
type = "binary";
|
|
@@ -482680,7 +482781,7 @@ class BinaryAdapter {
|
|
|
482680
482781
|
this.hiveDir = options2?.hiveDir || getHiveDir2();
|
|
482681
482782
|
this.pidFile = path35.join(this.hiveDir, "gateway.pid");
|
|
482682
482783
|
this.binaryPath = options2?.binaryPath || this.findBinary();
|
|
482683
|
-
this.isDockerContainer = process.env.HIVE_UI_DIR === "/app/ui" || process.env.HIVE_HOST === "0.0.0.0" ||
|
|
482784
|
+
this.isDockerContainer = process.env.HIVE_UI_DIR === "/app/ui" || process.env.HIVE_HOST === "0.0.0.0" || existsSync33("/.dockerenv");
|
|
482684
482785
|
}
|
|
482685
482786
|
get name() {
|
|
482686
482787
|
return this.isDockerContainer ? "Docker Container" : "Standalone Binary";
|
|
@@ -482691,15 +482792,15 @@ class BinaryAdapter {
|
|
|
482691
482792
|
const dir = path35.dirname(scriptPath);
|
|
482692
482793
|
if (path35.basename(dir) === "dist") {
|
|
482693
482794
|
const binaryInDist = path35.join(dir, "hive");
|
|
482694
|
-
if (
|
|
482795
|
+
if (existsSync33(binaryInDist)) {
|
|
482695
482796
|
return binaryInDist;
|
|
482696
482797
|
}
|
|
482697
482798
|
const binaryWindows = path35.join(dir, "hive.exe");
|
|
482698
|
-
if (
|
|
482799
|
+
if (existsSync33(binaryWindows)) {
|
|
482699
482800
|
return binaryWindows;
|
|
482700
482801
|
}
|
|
482701
482802
|
}
|
|
482702
|
-
if (
|
|
482803
|
+
if (existsSync33(scriptPath) && !scriptPath.endsWith(".ts")) {
|
|
482703
482804
|
return scriptPath;
|
|
482704
482805
|
}
|
|
482705
482806
|
}
|
|
@@ -482712,7 +482813,7 @@ class BinaryAdapter {
|
|
|
482712
482813
|
path35.join(process.env.HOME || "", ".bun", "bin", "hive")
|
|
482713
482814
|
];
|
|
482714
482815
|
for (const binaryPath of commonPaths) {
|
|
482715
|
-
if (
|
|
482816
|
+
if (existsSync33(binaryPath)) {
|
|
482716
482817
|
return binaryPath;
|
|
482717
482818
|
}
|
|
482718
482819
|
}
|
|
@@ -482726,7 +482827,7 @@ class BinaryAdapter {
|
|
|
482726
482827
|
if (scriptPath.endsWith(".ts")) {
|
|
482727
482828
|
return false;
|
|
482728
482829
|
}
|
|
482729
|
-
if (
|
|
482830
|
+
if (existsSync33(this.binaryPath)) {
|
|
482730
482831
|
return true;
|
|
482731
482832
|
}
|
|
482732
482833
|
try {
|
|
@@ -482738,7 +482839,7 @@ class BinaryAdapter {
|
|
|
482738
482839
|
const distDir = getDistDir();
|
|
482739
482840
|
if (distDir) {
|
|
482740
482841
|
const uiDir = path35.join(distDir, "ui");
|
|
482741
|
-
if (
|
|
482842
|
+
if (existsSync33(uiDir)) {
|
|
482742
482843
|
return true;
|
|
482743
482844
|
}
|
|
482744
482845
|
}
|
|
@@ -482754,7 +482855,7 @@ class BinaryAdapter {
|
|
|
482754
482855
|
const distDir = getDistDir();
|
|
482755
482856
|
if (distDir) {
|
|
482756
482857
|
const uiDir = path35.join(distDir, "ui");
|
|
482757
|
-
if (
|
|
482858
|
+
if (existsSync33(uiDir)) {
|
|
482758
482859
|
paths.uiDir = uiDir;
|
|
482759
482860
|
}
|
|
482760
482861
|
}
|
|
@@ -482821,7 +482922,7 @@ class BinaryAdapter {
|
|
|
482821
482922
|
}
|
|
482822
482923
|
async stop() {
|
|
482823
482924
|
try {
|
|
482824
|
-
if (
|
|
482925
|
+
if (existsSync33(this.pidFile)) {
|
|
482825
482926
|
const pid = parseInt(readFileSync16(this.pidFile, "utf-8").trim(), 10);
|
|
482826
482927
|
if (!isNaN(pid)) {
|
|
482827
482928
|
try {
|
|
@@ -482855,7 +482956,7 @@ class BinaryAdapter {
|
|
|
482855
482956
|
}
|
|
482856
482957
|
async isRunning() {
|
|
482857
482958
|
try {
|
|
482858
|
-
if (
|
|
482959
|
+
if (existsSync33(this.pidFile)) {
|
|
482859
482960
|
const pid = parseInt(readFileSync16(this.pidFile, "utf-8").trim(), 10);
|
|
482860
482961
|
if (!isNaN(pid)) {
|
|
482861
482962
|
try {
|
|
@@ -482877,7 +482978,7 @@ class BinaryAdapter {
|
|
|
482877
482978
|
}
|
|
482878
482979
|
async getPid() {
|
|
482879
482980
|
try {
|
|
482880
|
-
if (
|
|
482981
|
+
if (existsSync33(this.pidFile)) {
|
|
482881
482982
|
const pid = parseInt(readFileSync16(this.pidFile, "utf-8").trim(), 10);
|
|
482882
482983
|
if (!isNaN(pid) && pid > 0) {
|
|
482883
482984
|
try {
|
|
@@ -482910,7 +483011,7 @@ class BinaryAdapter {
|
|
|
482910
483011
|
const errors6 = [];
|
|
482911
483012
|
const warnings = [];
|
|
482912
483013
|
const info3 = [];
|
|
482913
|
-
if (
|
|
483014
|
+
if (existsSync33(this.binaryPath)) {
|
|
482914
483015
|
info3.push(`Binary: ${this.binaryPath}`);
|
|
482915
483016
|
try {
|
|
482916
483017
|
const stat3 = await import("fs/promises").then((m2) => m2.stat(this.binaryPath));
|
|
@@ -482933,13 +483034,13 @@ class BinaryAdapter {
|
|
|
482933
483034
|
const distDir = getDistDir();
|
|
482934
483035
|
if (distDir) {
|
|
482935
483036
|
const uiDir = path35.join(distDir, "ui");
|
|
482936
|
-
if (
|
|
483037
|
+
if (existsSync33(uiDir)) {
|
|
482937
483038
|
info3.push(`UI directory: ${uiDir}`);
|
|
482938
483039
|
} else if (!hasEmbeddedUI) {
|
|
482939
483040
|
warnings.push("UI directory not found and no embedded UI");
|
|
482940
483041
|
}
|
|
482941
483042
|
}
|
|
482942
|
-
if (
|
|
483043
|
+
if (existsSync33(this.hiveDir)) {
|
|
482943
483044
|
info3.push(`Hive home: ${this.hiveDir}`);
|
|
482944
483045
|
} else {
|
|
482945
483046
|
warnings.push(`Hive home directory does not exist: ${this.hiveDir}`);
|
|
@@ -482957,7 +483058,7 @@ class BinaryAdapter {
|
|
|
482957
483058
|
} else {
|
|
482958
483059
|
warnings.push("Hive Gateway is not running");
|
|
482959
483060
|
}
|
|
482960
|
-
if (process.platform !== "win32" &&
|
|
483061
|
+
if (process.platform !== "win32" && existsSync33(this.binaryPath)) {
|
|
482961
483062
|
try {
|
|
482962
483063
|
execSync3(`test -x "${this.binaryPath}"`, { stdio: "ignore" });
|
|
482963
483064
|
info3.push("Binary is executable");
|
|
@@ -483659,7 +483760,7 @@ __export(exports_gateway, {
|
|
|
483659
483760
|
resetAdapter: () => resetAdapter,
|
|
483660
483761
|
reload: () => reload
|
|
483661
483762
|
});
|
|
483662
|
-
import { existsSync as
|
|
483763
|
+
import { existsSync as existsSync34, mkdirSync as mkdirSync19, writeFileSync as writeFileSync12, readFileSync as readFileSync17, unlinkSync as unlinkSync7, openSync } from "fs";
|
|
483663
483764
|
import * as path36 from "path";
|
|
483664
483765
|
import { spawn as spawn6 } from "child_process";
|
|
483665
483766
|
async function getAdapter() {
|
|
@@ -483702,8 +483803,8 @@ async function getPidFile() {
|
|
|
483702
483803
|
}
|
|
483703
483804
|
function ensureLogDir() {
|
|
483704
483805
|
const logDir = path36.dirname(getLogFile());
|
|
483705
|
-
if (!
|
|
483706
|
-
|
|
483806
|
+
if (!existsSync34(logDir)) {
|
|
483807
|
+
mkdirSync19(logDir, { recursive: true });
|
|
483707
483808
|
}
|
|
483708
483809
|
}
|
|
483709
483810
|
function openBrowser(url2) {
|
|
@@ -483735,7 +483836,7 @@ function openBrowser(url2) {
|
|
|
483735
483836
|
async function isSetupMode2() {
|
|
483736
483837
|
const hiveDir = getHiveDir();
|
|
483737
483838
|
const dbPath = path36.join(hiveDir, "data", "hive.db");
|
|
483738
|
-
return !
|
|
483839
|
+
return !existsSync34(dbPath);
|
|
483739
483840
|
}
|
|
483740
483841
|
async function isRunning2() {
|
|
483741
483842
|
try {
|
|
@@ -483746,7 +483847,7 @@ async function isRunning2() {
|
|
|
483746
483847
|
}
|
|
483747
483848
|
} catch {}
|
|
483748
483849
|
const pidFile = await getPidFile();
|
|
483749
|
-
if (!
|
|
483850
|
+
if (!existsSync34(pidFile))
|
|
483750
483851
|
return false;
|
|
483751
483852
|
const pid = parseInt(readFileSync17(pidFile, "utf-8").trim(), 10);
|
|
483752
483853
|
if (isNaN(pid))
|
|
@@ -483810,7 +483911,7 @@ async function start(flags3) {
|
|
|
483810
483911
|
\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
483912
|
\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
483913
|
\u2551 \u2551
|
|
483813
|
-
\u2551 Personal Swarm AI Gateway \u2014 v0.0.
|
|
483914
|
+
\u2551 Personal Swarm AI Gateway \u2014 v0.0.31 \u2551
|
|
483814
483915
|
\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
483916
|
|
|
483816
483917
|
\uD83D\uDCE6 Installation: ${adapter.name}
|
|
@@ -483844,7 +483945,7 @@ async function handleDevMode(adapter, gatewayConfig, daemon) {
|
|
|
483844
483945
|
return;
|
|
483845
483946
|
}
|
|
483846
483947
|
const hiveUiPath = path36.join(process.cwd(), "packages/hive-ui");
|
|
483847
|
-
const hasVite =
|
|
483948
|
+
const hasVite = existsSync34(path36.join(hiveUiPath, "package.json"));
|
|
483848
483949
|
if (hasVite) {
|
|
483849
483950
|
console.log(`\uD83C\uDFA8 Iniciando Vite (UI)...
|
|
483850
483951
|
`);
|
|
@@ -484093,7 +484194,7 @@ async function handleProductionMode(adapter, gatewayConfig, daemon) {
|
|
|
484093
484194
|
} catch {
|
|
484094
484195
|
const hiveDir = getHiveDir();
|
|
484095
484196
|
const dbPath = path36.join(hiveDir, "data", "hive.db");
|
|
484096
|
-
needsSetup = !
|
|
484197
|
+
needsSetup = !existsSync34(dbPath);
|
|
484097
484198
|
}
|
|
484098
484199
|
const url2 = needsSetup ? `http://localhost:${uiPort}/setup` : `http://localhost:${uiPort}`;
|
|
484099
484200
|
if (needsSetup) {
|
|
@@ -484933,11 +485034,11 @@ async function updateSkills() {
|
|
|
484933
485034
|
} else {
|
|
484934
485035
|
console.log(` \u2705 Todas las skills est\xE1n actualizadas`);
|
|
484935
485036
|
}
|
|
484936
|
-
const { existsSync:
|
|
485037
|
+
const { existsSync: existsSync38 } = await import("fs");
|
|
484937
485038
|
const { getHiveDir: getHiveDir3 } = await Promise.resolve().then(() => (init_loader(), exports_loader));
|
|
484938
485039
|
const path40 = await import("path");
|
|
484939
485040
|
const pidFile = path40.join(getHiveDir3(), "gateway.pid");
|
|
484940
|
-
if (
|
|
485041
|
+
if (existsSync38(pidFile)) {
|
|
484941
485042
|
console.log(`
|
|
484942
485043
|
\uD83D\uDCA1 El gateway est\xE1 corriendo. Ejecuta 'hive reload' para aplicar cambios.`);
|
|
484943
485044
|
}
|
|
@@ -486211,8 +486312,8 @@ var MAIN_PACKAGE = "@johpaz/hive-agents";
|
|
|
486211
486312
|
async function update() {
|
|
486212
486313
|
console.log(`\uD83D\uDD04 Actualizando Hive...
|
|
486213
486314
|
`);
|
|
486214
|
-
const { existsSync:
|
|
486215
|
-
const isGitRepo =
|
|
486315
|
+
const { existsSync: existsSync44 } = await import("fs");
|
|
486316
|
+
const isGitRepo = existsSync44(".git") && existsSync44("package.json");
|
|
486216
486317
|
if (isGitRepo) {
|
|
486217
486318
|
await updateFromGitRepo();
|
|
486218
486319
|
} else {
|
|
@@ -486314,11 +486415,11 @@ Descargando ${MAIN_PACKAGE}@latest (via ${packageManager})...`);
|
|
|
486314
486415
|
}
|
|
486315
486416
|
}
|
|
486316
486417
|
async function applyDatabaseUpdates() {
|
|
486317
|
-
const { existsSync:
|
|
486418
|
+
const { existsSync: existsSync44 } = await import("fs");
|
|
486318
486419
|
const { getHiveDir: getHiveDir3 } = await Promise.resolve().then(() => (init_loader(), exports_loader));
|
|
486319
486420
|
const path45 = await import("path");
|
|
486320
486421
|
const dbPath = path45.join(getHiveDir3(), "data", "hive.db");
|
|
486321
|
-
if (!
|
|
486422
|
+
if (!existsSync44(dbPath)) {
|
|
486322
486423
|
console.log(` \u2139\uFE0F No se encontr\xF3 base de datos existente. Se crear\xE1 en el pr\xF3ximo 'hive start'.`);
|
|
486323
486424
|
return;
|
|
486324
486425
|
}
|
|
@@ -486356,7 +486457,7 @@ async function applyDatabaseUpdates() {
|
|
|
486356
486457
|
}
|
|
486357
486458
|
const hiveDir = getHiveDir3();
|
|
486358
486459
|
const pidFile = path45.join(hiveDir, "gateway.pid");
|
|
486359
|
-
if (
|
|
486460
|
+
if (existsSync44(pidFile)) {
|
|
486360
486461
|
console.log(`
|
|
486361
486462
|
\uD83D\uDCA1 El gateway est\xE1 corriendo. Ejecuta 'hive reload' para aplicar cambios.`);
|
|
486362
486463
|
}
|