fix: require discord evidence for legacy dashboard outbound
This commit is contained in:
@@ -442,6 +442,84 @@ describe('web dashboard room activity data', () => {
|
||||
]);
|
||||
});
|
||||
|
||||
it('hides legacy delivered work items without discord delivery evidence', () => {
|
||||
const activity = buildWebDashboardRoomActivity({
|
||||
serviceId: 'codex-main',
|
||||
entry: {
|
||||
jid: 'dc:ops',
|
||||
name: '#ops',
|
||||
folder: 'ops',
|
||||
agentType: 'codex',
|
||||
status: 'inactive',
|
||||
elapsedMs: null,
|
||||
pendingMessages: false,
|
||||
pendingTasks: 0,
|
||||
},
|
||||
pairedTask: null,
|
||||
turns: [],
|
||||
attempts: [],
|
||||
outputs: [],
|
||||
outboundItems: [
|
||||
makeDeliveredWorkItem({
|
||||
id: 103,
|
||||
delivery_role: null,
|
||||
delivery_message_id: null,
|
||||
result_payload: '서비스 재시작으로 이전 작업이 중단됐습니다.',
|
||||
}),
|
||||
],
|
||||
messages: [],
|
||||
});
|
||||
|
||||
expect(activity.messages).toEqual([]);
|
||||
});
|
||||
|
||||
it('keeps legacy delivered work items when a discord echo exists', () => {
|
||||
const activity = buildWebDashboardRoomActivity({
|
||||
serviceId: 'codex-main',
|
||||
entry: {
|
||||
jid: 'dc:ops',
|
||||
name: '#ops',
|
||||
folder: 'ops',
|
||||
agentType: 'codex',
|
||||
status: 'inactive',
|
||||
elapsedMs: null,
|
||||
pendingMessages: false,
|
||||
pendingTasks: 0,
|
||||
},
|
||||
pairedTask: null,
|
||||
turns: [],
|
||||
attempts: [],
|
||||
outputs: [],
|
||||
outboundItems: [
|
||||
makeDeliveredWorkItem({
|
||||
id: 104,
|
||||
delivery_message_id: null,
|
||||
result_payload: 'TASK_DONE\n\nlegacy delivered output',
|
||||
}),
|
||||
],
|
||||
messages: [
|
||||
{
|
||||
id: 'discord-legacy-echo',
|
||||
chat_jid: 'dc:ops',
|
||||
sender: 'bot-owner',
|
||||
sender_name: '오너',
|
||||
content: 'TASK_DONE\n\nlegacy delivered output',
|
||||
timestamp: '2026-04-26T05:30:11.000Z',
|
||||
is_from_me: true,
|
||||
is_bot_message: true,
|
||||
message_source_kind: 'bot',
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
expect(activity.messages).toEqual([
|
||||
expect.objectContaining({
|
||||
id: 'work:104',
|
||||
content: 'TASK_DONE\n\nlegacy delivered output',
|
||||
}),
|
||||
]);
|
||||
});
|
||||
|
||||
it('merges canonical outbound and recent messages in chronological order', () => {
|
||||
const activity = buildWebDashboardRoomActivity({
|
||||
serviceId: 'codex-main',
|
||||
|
||||
@@ -575,6 +575,15 @@ function isDuplicateOfCanonicalOutbound(
|
||||
});
|
||||
}
|
||||
|
||||
function hasDiscordEchoForCanonicalOutbound(
|
||||
canonical: WebDashboardRoomMessage,
|
||||
messages: WebDashboardRoomMessage[],
|
||||
): boolean {
|
||||
return messages.some((message) =>
|
||||
isDuplicateOfCanonicalOutbound(message, [canonical]),
|
||||
);
|
||||
}
|
||||
|
||||
function compareRoomMessagesByTimestamp(
|
||||
a: WebDashboardRoomMessage,
|
||||
b: WebDashboardRoomMessage,
|
||||
@@ -670,19 +679,36 @@ export function buildWebDashboardRoomActivity(args: {
|
||||
? (latestAttemptByTurnId.get(currentTurn.turn_id) ?? null)
|
||||
: null;
|
||||
const outputLimit = args.outputLimit ?? 4;
|
||||
const canonicalOutboundMessages = (args.outboundItems ?? [])
|
||||
.map(sanitizeCanonicalOutboundMessage)
|
||||
const sanitizedRecentMessages = args.messages
|
||||
.filter((message) => !isTaskStatusMessage(message))
|
||||
.map(sanitizeRoomMessage)
|
||||
.filter((message): message is WebDashboardRoomMessage => Boolean(message));
|
||||
const canonicalOutboundMessages = (args.outboundItems ?? [])
|
||||
.map((item) => ({
|
||||
item,
|
||||
message: sanitizeCanonicalOutboundMessage(item),
|
||||
}))
|
||||
.filter(
|
||||
(
|
||||
candidate,
|
||||
): candidate is {
|
||||
item: WorkItem;
|
||||
message: WebDashboardRoomMessage;
|
||||
} => Boolean(candidate.message),
|
||||
)
|
||||
.filter(
|
||||
({ item, message }) =>
|
||||
Boolean(item.delivery_message_id) ||
|
||||
hasDiscordEchoForCanonicalOutbound(message, sanitizedRecentMessages),
|
||||
)
|
||||
.map(({ message }) => message);
|
||||
const canonicalDeliveryMessageIds = new Set(
|
||||
(args.outboundItems ?? [])
|
||||
.map((item) => item.delivery_message_id)
|
||||
.filter((id): id is string => Boolean(id)),
|
||||
);
|
||||
const recentMessages = args.messages
|
||||
const recentMessages = sanitizedRecentMessages
|
||||
.filter((message) => !canonicalDeliveryMessageIds.has(message.id))
|
||||
.filter((message) => !isTaskStatusMessage(message))
|
||||
.map(sanitizeRoomMessage)
|
||||
.filter((message): message is WebDashboardRoomMessage => Boolean(message))
|
||||
.filter(
|
||||
(message) =>
|
||||
!isDuplicateOfCanonicalOutbound(message, canonicalOutboundMessages),
|
||||
|
||||
Reference in New Issue
Block a user