1 Commits

Author SHA1 Message Date
3ca29993f2 improve(qmd-brain): avoid shell execution in embed trigger 2026-03-16 15:03:28 +08:00

View File

@@ -7,10 +7,10 @@
* - embed_to_pg.py (Python venv at /home/selig/apps/qmd-pg/) * - embed_to_pg.py (Python venv at /home/selig/apps/qmd-pg/)
*/ */
import { exec, execFile } from 'child_process'; import { spawn, execFile } from 'child_process';
import { promisify } from 'util'; import { promisify } from 'util';
import { openSync, closeSync } from 'fs';
const execAsync = promisify(exec);
const execFileAsync = promisify(execFile); const execFileAsync = promisify(execFile);
const QMD_CMD = '/home/selig/.nvm/versions/node/v24.13.1/bin/qmd'; const QMD_CMD = '/home/selig/.nvm/versions/node/v24.13.1/bin/qmd';
@@ -66,12 +66,28 @@ function formatPgResults(results: SearchResult[]): string {
/** 觸發向量索引更新 */ /** 觸發向量索引更新 */
async function triggerEmbed(): Promise<string> { async function triggerEmbed(): Promise<string> {
const env = { ...process.env, HOME: '/home/selig' };
const logPath = '/tmp/qmd-embed.log';
try { try {
// 背景執行,不等待完成 const fdQmd = openSync(logPath, 'a');
exec( const qmdProc = spawn(QMD_CMD, ['embed'], {
`${QMD_CMD} embed 2>&1 >> /tmp/qmd-embed.log & ${EMBED_PY_BIN} ${EMBED_PY_SCRIPT} embed 2>&1 >> /tmp/qmd-embed.log &`, env,
{ env: { ...process.env, HOME: '/home/selig' } } detached: true,
); stdio: ['ignore', fdQmd, fdQmd],
});
qmdProc.unref();
closeSync(fdQmd);
const fdPg = openSync(logPath, 'a');
const pgProc = spawn(EMBED_PY_BIN, [EMBED_PY_SCRIPT, 'embed'], {
env,
detached: true,
stdio: ['ignore', fdPg, fdPg],
});
pgProc.unref();
closeSync(fdPg);
return '✅ 索引更新已在背景啟動,約需 1-5 分鐘完成。'; return '✅ 索引更新已在背景啟動,約需 1-5 分鐘完成。';
} catch (e: any) { } catch (e: any) {
return `❌ 索引啟動失敗: ${e.message}`; return `❌ 索引啟動失敗: ${e.message}`;