Files
memind/intent-transaction-commit.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

160 lines
5.3 KiB
JavaScript

import { commitAgentSideEffectTool } from './agent-side-effect-tools.mjs';
import { resolveScheduleTimestamp } from './schedule-time.mjs';
import { buildScheduledTaskCreatePayload } from './scheduled-task-intent.mjs';
import { isUnifiedTasksEnabled } from './task-unified-config.mjs';
async function maybeSyncUnifiedTask({
taskUnifiedService,
userId,
kind,
committed,
env,
}) {
if (!isUnifiedTasksEnabled(env) || !taskUnifiedService) return null;
try {
return await taskUnifiedService.syncFromCommit({ userId, kind, committed });
} catch (err) {
console.warn?.(
'[intent-transaction-commit] unified task sync failed open:',
err instanceof Error ? err.message : err,
);
return null;
}
}
export async function commitIntentDraft({
draft,
userId,
scheduleService,
scheduledTaskService,
taskUnifiedService = null,
timezone = 'Asia/Shanghai',
env = process.env,
}) {
if (!draft || draft.status !== 'draft') throw new Error('草稿不可提交');
const payload = draft.payload ?? {};
const kind = draft.draftType;
if (kind === 'timed_reminder') {
if (!scheduleService) throw new Error('scheduleService 不可用');
const remindAt = resolveScheduleTimestamp({
localString: payload.remindLocal,
timezone,
fieldName: '提醒时间',
});
const item = await scheduleService.createItem({
userId,
kind: 'event',
title: payload.title ?? draft.title,
startAt: remindAt,
timezone,
sourceChannel: payload.sourceChannel ?? 'wechat',
sourceMessageId: payload.sourceMessageId ?? draft.sourceMessageId,
sourceText: payload.sourceText ?? draft.sourceText,
metadata: {
source: 'intent_transaction_layer',
...(payload.recurrence === 'daily'
? {
recurrence: 'daily',
dailyHour: Number(payload.hour),
dailyMinute: Number(payload.minute ?? 0),
}
: {}),
},
});
const reminder = await scheduleService.createReminder({
userId,
itemId: item.id,
remindAt,
channel: 'wechat',
});
const committed = { kind, item, reminder };
await maybeSyncUnifiedTask({ taskUnifiedService, userId, kind, committed, env });
return committed;
}
if (kind === 'create_todo') {
if (!scheduleService) throw new Error('scheduleService 不可用');
const item = await scheduleService.createItem({
userId,
kind: 'task',
title: payload.title ?? draft.title,
timezone,
sourceChannel: payload.sourceChannel ?? 'wechat',
sourceMessageId: payload.sourceMessageId ?? draft.sourceMessageId,
sourceText: payload.sourceText ?? draft.sourceText,
metadata: { source: 'intent_transaction_layer' },
});
const committed = { kind, item };
await maybeSyncUnifiedTask({ taskUnifiedService, userId, kind, committed, env });
return committed;
}
if (kind === 'create_daily_todo_digest') {
if (!scheduleService) throw new Error('scheduleService 不可用');
const subscription = await scheduleService.createDailyTodoDigest({
userId,
hour: payload.hour,
minute: payload.minute ?? 0,
timezone,
channel: 'wechat',
sourceChannel: payload.sourceChannel ?? 'wechat',
sourceMessageId: payload.sourceMessageId ?? draft.sourceMessageId,
sourceText: payload.sourceText ?? draft.sourceText,
});
const committed = { kind, subscription };
await maybeSyncUnifiedTask({ taskUnifiedService, userId, kind, committed, env });
return committed;
}
if (kind === 'create_balance_alert') {
if (!scheduleService) throw new Error('scheduleService 不可用');
const subscription = await scheduleService.createBalanceLowAlert({
userId,
thresholdCents: payload.thresholdCents,
channel: 'wechat',
sourceChannel: payload.sourceChannel ?? 'wechat',
sourceMessageId: payload.sourceMessageId ?? draft.sourceMessageId,
sourceText: payload.sourceText ?? draft.sourceText,
});
const committed = { kind, subscription };
await maybeSyncUnifiedTask({ taskUnifiedService, userId, kind, committed, env });
return committed;
}
if (kind === 'scheduled_task') {
if (!scheduledTaskService) throw new Error('scheduledTaskService 不可用');
const createPayload = payload.createPayload ?? buildScheduledTaskCreatePayload(payload.intentDetail ?? payload, {
userId,
sourceChannel: 'wechat',
sourceMessageId: payload.sourceMessageId ?? draft.sourceMessageId,
sourceText: payload.sourceText ?? draft.sourceText,
timezone,
});
const task = await scheduledTaskService.createTask(createPayload);
const committed = { kind, task };
await maybeSyncUnifiedTask({ taskUnifiedService, userId, kind, committed, env });
return committed;
}
if (kind === 'agent_tool') {
const committed = await commitAgentSideEffectTool(payload.toolName, payload.toolArgs, {
userId,
scheduleService,
scheduledTaskService,
timezone,
env,
});
await maybeSyncUnifiedTask({
taskUnifiedService,
userId,
kind: committed.kind === 'scheduled_task' ? 'scheduled_task' : kind,
committed,
env,
});
return committed;
}
throw new Error(`不支持的草稿类型:${kind}`);
}