feat: auto-notify user on paired task completion with @mention

- done →  작업 완료
- escalated → ⚠️ 자동 해결 불가
- arbiter_escalated → ⚠️ 중재자: 사람 개입 필요
- stopped → no notification (user initiated)
This commit is contained in:
Eyejoker
2026-03-31 04:29:24 +09:00
parent 60408cc1fa
commit 7085711a7f
2 changed files with 29 additions and 1 deletions

View File

@@ -131,7 +131,8 @@ export async function runAgentForGroup(
group.agentType,
);
// Arbiter always starts fresh — never resume a previous session
const sessionId = activeRole === 'arbiter' ? undefined : sessions[sessionFolder];
const sessionId =
activeRole === 'arbiter' ? undefined : sessions[sessionFolder];
const memoryBriefing = sessionId
? undefined
: await buildRoomMemoryBriefing({
@@ -1047,6 +1048,29 @@ export async function runAgentForGroup(
}
}
// Notify user when paired task reaches a terminal state that requires attention.
if (pairedExecutionContext) {
const finishedTask = getPairedTaskById(pairedExecutionContext.task.id);
if (finishedTask?.status === 'completed' && finishedTask.completion_reason) {
const sender = getLastHumanMessageSender(chatJid);
const mention = sender ? `<@${sender}>` : '';
const notifications: Record<string, string> = {
done: `${mention} ✅ 작업 완료.`,
escalated: `${mention} ⚠️ 자동 해결 불가 — 확인이 필요합니다.`,
arbiter_escalated: `${mention} ⚠️ 중재자 판단: 사람 개입이 필요합니다.`,
};
const message = notifications[finishedTask.completion_reason];
if (message) {
await args.onOutput?.({
status: 'success',
result: message,
output: { visibility: 'public', text: message },
phase: 'final',
});
}
}
}
// After owner/reviewer completes, enqueue the next turn so
// the message loop picks it up without waiting for a new message.
// Skip if owner produced no output — likely interrupted by /stop.