fix: dedupe task timeline milestones

This commit is contained in:
2026-05-26 11:59:49 +08:00
parent a1164dc49a
commit 2e4f8541ee
2 changed files with 67 additions and 3 deletions

View File

@ -209,6 +209,10 @@ function compareCardsByCreatedAt(
return aTime - bTime || a.index - b.index;
}
function acceptanceKey(runId: string | null | undefined, createdAt: string): string {
return `${runId ?? ''}:${createdAt}`;
}
export function buildTaskTimelineCards(input: BuildTaskTimelineCardsInput): TaskTimelineCard[] {
const { task } = input;
const processRuns = input.processRuns ?? task.process_runs ?? [];
@ -216,6 +220,8 @@ export function buildTaskTimelineCards(input: BuildTaskTimelineCardsInput): Task
const processArtifacts = input.processArtifacts ?? task.process_artifacts ?? [];
const runsById = buildRunMap(processRuns);
const runsWithProgressEvents = new Set<string>();
const acceptanceEventKeys = new Set<string>();
let hasResultEventCard = false;
const cards: TaskTimelineCard[] = [
{
id: `${task.task_id}:created`,
@ -236,6 +242,12 @@ export function buildTaskTimelineCards(input: BuildTaskTimelineCardsInput): Task
if (type === 'agent_progress') {
runsWithProgressEvents.add(event.run_id);
}
if (type === 'result') {
hasResultEventCard = true;
}
if (type === 'acceptance') {
acceptanceEventKeys.add(acceptanceKey(event.run_id, event.created_at));
}
cards.push({
id: event.event_id,
@ -292,7 +304,7 @@ export function buildTaskTimelineCards(input: BuildTaskTimelineCardsInput): Task
});
}
if (RESULT_STATUSES.has(task.status)) {
if (RESULT_STATUSES.has(task.status) && !hasResultEventCard) {
cards.push({
id: `${task.task_id}:result`,
taskId: task.task_id,
@ -308,15 +320,19 @@ export function buildTaskTimelineCards(input: BuildTaskTimelineCardsInput): Task
for (let index = 0; index < task.feedback.length; index += 1) {
const feedback = task.feedback[index];
const runId = firstString(feedback.run_id) ?? null;
const createdAt = feedbackCreatedAt(feedback, task);
if (acceptanceEventKeys.has(acceptanceKey(runId, createdAt))) continue;
cards.push({
id: `${task.task_id}:acceptance:${index}`,
taskId: task.task_id,
runId: firstString(feedback.run_id) ?? null,
runId,
type: 'acceptance',
title: titleForCard('acceptance'),
summary: feedbackSummary(feedback),
status: firstString(feedback.acceptance_type),
createdAt: feedbackCreatedAt(feedback, task),
createdAt,
details: feedback,
});
}