Files
memind/intent-tool-confirm-gate.mjs
T
john e13df82021
Memind CI / Test, build, and release guards (push) Failing after 14m19s
fix(wechat): pass inbound messages to goose and gate side effects at MCP tools
Stop ITL regex from intercepting new messages before Agent execution; move
scheduled task and schedule write confirmation to MCP tool calls with draft commit on 确认.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-28 22:16:23 +08:00

115 lines
3.6 KiB
JavaScript

import { formatIntentActionCard } from './intent-action-card.mjs';
import { isIntentTransactionEnabled } from './intent-transaction-config.mjs';
export function isSideEffectConfirmGateEnabled(env = process.env) {
return isIntentTransactionEnabled(env);
}
function buildScheduledTaskConfirmCard(args) {
const title = String(args.title ?? args.taskSpec ?? '').trim() || '定时自动任务';
const trigger = args.recurrence === 'once'
? { at: args.runAtLocal ?? null }
: { hour: args.hour, minute: args.minute ?? 0 };
const frequency = args.recurrence === 'weekly'
? '每周自动执行'
: args.recurrence === 'once'
? null
: '每天自动执行';
return formatIntentActionCard({
title: title.slice(0, 80),
layer: 'L2',
actionLevel: 2,
trigger,
actions: ['到点自动执行任务', '推送执行结果到微信'],
frequency,
});
}
function buildScheduleItemConfirmCard(args) {
const title = String(args.title ?? '').trim() || '待办/日程';
const remindLocal = args.remindLocal ?? args.startLocal ?? null;
const trigger = remindLocal ? { at: remindLocal } : { hour: null, minute: 0 };
const actions = args.remindLocal || args.remindAt || args.startLocal || args.startAt
? ['到点发送微信提醒']
: ['记录到待办列表'];
return formatIntentActionCard({
title: title.slice(0, 80),
layer: 'L1',
actionLevel: 1,
trigger,
actions,
});
}
function buildScheduleReminderConfirmCard(args) {
const trigger = args.remindLocal ? { at: args.remindLocal } : { hour: null, minute: 0 };
return formatIntentActionCard({
title: '日程提醒',
layer: 'L1',
actionLevel: 1,
trigger,
actions: ['到点发送微信提醒'],
});
}
export async function requireUserConfirmForSideEffectTool({
userId,
toolName,
toolArgs,
intentDraftService,
env = process.env,
layer = 'L2',
actionLevel = 2,
title = null,
cardText = null,
} = {}) {
if (!isSideEffectConfirmGateEnabled(env)) {
return { proceed: true };
}
if (!intentDraftService || !userId) {
return { proceed: true };
}
const safeToolName = String(toolName ?? '').trim();
const args = { ...(toolArgs ?? {}) };
const resolvedCardText = cardText
?? (safeToolName === 'scheduled_task_create'
? buildScheduledTaskConfirmCard(args)
: safeToolName === 'schedule_create_item'
? buildScheduleItemConfirmCard(args)
: safeToolName === 'schedule_create_reminder'
? buildScheduleReminderConfirmCard(args)
: formatIntentActionCard({ title: title ?? '待确认操作', layer, actionLevel }));
const resolvedTitle = String(title ?? args.title ?? args.taskSpec ?? resolvedCardText.split('\n')[0] ?? '待确认任务').trim();
const draft = await intentDraftService.createDraft({
userId,
layer,
draftType: 'agent_tool',
actionLevel,
title: resolvedTitle.slice(0, 80),
payload: {
toolName: safeToolName,
toolArgs: args,
sourceChannel: 'agent',
sourceMessageId: args.sourceMessageId ?? null,
sourceText: args.sourceText ?? null,
},
cardText: resolvedCardText,
sourceChannel: 'agent',
sourceMessageId: args.sourceMessageId ?? null,
sourceText: args.sourceText ?? null,
});
return {
proceed: false,
response: {
status: 'needs_user_confirmation',
draftId: draft.id,
cardText: resolvedCardText,
instruction:
'这是需要用户确认的副作用操作。请把 cardText 原样发给用户,并请用户回复「确认」后再写入;在用户确认前不要声称已成功设置。',
},
};
}