pi: 档位判定 tool_call hook + 心跳报 native
- worker.mjs: mailContext 加 permissionMode 字段(从 SSE payload 读入) - tool_call hook 增加档位判定: full → 不拦截任何工具(直接 return) plan → 被守卫工具(bash/write/edit)一律 block + 返回原因说明 workspace → 走原有问人流程(不变) - index.mjs 心跳上报 mode_enforcement: 'native' - 导入 normalizeMode/MODE_FULL/MODE_PLAN 从 lib/permission-mode.js - 377 测试全过
This commit is contained in:
@ -322,6 +322,7 @@ async function main() {
|
||||
const beat = async () => {
|
||||
const [platform_sessions, models] = await Promise.all([reportSessions(), reportModels()]);
|
||||
const body = {};
|
||||
body.mode_enforcement = 'native'; // tool_call hook 能 block bash/write/edit
|
||||
if (platform_sessions) body.platform_sessions = platform_sessions;
|
||||
if (models) body.models = models;
|
||||
try {
|
||||
|
||||
@ -54,6 +54,7 @@ import { explicitSends, shouldSkipAutoRelay } from '../lib/relay-dedup.js';
|
||||
import { autoRelayDecision } from '../lib/relay-policy.js';
|
||||
import { adoptedSessionID, adoptMissingMessage } from '../lib/adopt.js';
|
||||
import { isApproval, isAlwaysDecision } from '../lib/permission-grants.js';
|
||||
import { normalizeMode, MODE_FULL, MODE_PLAN } from '../lib/permission-mode.js';
|
||||
import { clampRelayKey, isPermanentFailure } from '../lib/relay-key.js';
|
||||
|
||||
// ─── 与主进程的通道 ───
|
||||
@ -90,7 +91,7 @@ let job = null;
|
||||
let client = null;
|
||||
let modelRuntime = null;
|
||||
let piSessionId = '';
|
||||
let mailContext = { replyTo: '', subject: '', mailID: '' };
|
||||
let mailContext = { replyTo: '', subject: '', mailID: '', permissionMode: 'workspace' };
|
||||
let lastSyncedName = '';
|
||||
let relayedKey = '';
|
||||
let finished = false;
|
||||
@ -110,6 +111,18 @@ function permissionExtension() {
|
||||
|
||||
return (pi) => {
|
||||
pi.on('tool_call', async (event, ctx) => {
|
||||
// ── 档位判定 ──
|
||||
// plan: 被守卫的工具一律直接拒绝(该档语义是「不动手」,没什么可问人的)
|
||||
// full: 不拦截(已声明全权)
|
||||
// workspace: 走原有问人流程
|
||||
const mode = normalizeMode(mailContext.permissionMode);
|
||||
if (mode === MODE_FULL) return; // full 档不拦任何工具
|
||||
if (mode === MODE_PLAN && GUARDED.has(event.toolName)) {
|
||||
return {
|
||||
block: true,
|
||||
reason: `plan 档下不允许执行 ${event.toolName}。本档只允许读与查,请把方案写在回信里。如需动手请让发件人把档位改成 workspace。`,
|
||||
};
|
||||
}
|
||||
if (!GUARDED.has(event.toolName)) return;
|
||||
|
||||
const sid = ctx?.sessionManager?.getSessionId?.() || '';
|
||||
@ -559,6 +572,7 @@ process.on('message', (msg) => {
|
||||
replyTo: msg.data?.from_name || '',
|
||||
subject: msg.data?.subject || '',
|
||||
mailID: msg.data?.mail_id || '',
|
||||
permissionMode: msg.data?.permission_mode || 'workspace',
|
||||
};
|
||||
lastSyncedName = msg.lastSyncedName || '';
|
||||
for (const t of msg.grants || []) grants.add(t);
|
||||
|
||||
Reference in New Issue
Block a user