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}`); }