bookworm-smart-assistant/hooks/pre-agent-gate.js

99 lines
2.4 KiB
JavaScript
Raw Permalink Normal View History

#!/usr/bin/env node
/**
* pre-agent-gate.js Agent 派遣前置门 (P1, 2026-04-19)
* PRE_AGENT_GATE_P1
*
* PreToolUse(Task) 钩子 general-purpose + 轻量查询 建议改用 explore agent
* fail-open: exit 0 始终, 不阻断派遣
*/
'use strict';
const fs = require('fs');
const path = require('path');
const LIGHTWEIGHT_KEYWORDS = [
/\bfind\b/i, /\blocate\b/i, /\bsearch\b/i, /\blist\b/i,
/\bwhich\b/i, /\bwhere\s+is\b/i, /\blook\s+up\b/i, /\bgrep\b/i,
/查找/, /搜索/, /定位/, /列出/, /哪里/, /哪个文件/,
];
const SHORT_PROMPT_THRESHOLD = 200;
function getLogPath() {
try {
const root = require('./lib/root.js');
return path.join(root, 'debug', 'pre-agent-gate.jsonl');
} catch {
return path.join(__dirname, '..', 'debug', 'pre-agent-gate.jsonl');
}
}
function readStdinSync() {
try {
const raw = fs.readFileSync(0, 'utf8');
return JSON.parse(raw);
} catch {
return null;
}
}
function isLightweight(prompt) {
if (!prompt || typeof prompt !== 'string') return false;
if (prompt.length < SHORT_PROMPT_THRESHOLD) return true;
return LIGHTWEIGHT_KEYWORDS.some(re => re.test(prompt));
}
function logEvent(record) {
try {
fs.appendFileSync(getLogPath(), JSON.stringify(record) + '\n');
} catch {}
}
function main() {
const input = readStdinSync();
if (!input || !input.tool_input) {
process.exit(0);
}
const ti = input.tool_input || {};
const subagentType = ti.subagent_type || '';
const prompt = ti.prompt || '';
const description = ti.description || '';
const record = {
ts: new Date().toISOString(),
sessionId: input.session_id || '',
subagent_type: subagentType,
promptLen: prompt.length,
description,
hint: false,
};
if (subagentType !== 'general-purpose') {
logEvent(record);
process.exit(0);
}
if (!isLightweight(prompt)) {
logEvent(record);
process.exit(0);
}
record.hint = true;
logEvent(record);
const hint = '[pre-agent-gate] 检测到轻量查询使用 general-purpose agent。' +
'建议改用 explore agent (haiku 模型, 成本约 1/5)。' +
'若确需 general-purpose 请忽略此提示。';
const out = {
hookSpecificOutput: {
hookEventName: 'PreToolUse',
additionalContext: hint,
},
};
process.stdout.write(JSON.stringify(out));
process.exit(0);
}
main();