fix: make acceptance timeline dedupe robust
This commit is contained in:
@ -258,7 +258,10 @@ describe('buildTaskTimelineCards', () => {
|
||||
actor_id: 'task-system',
|
||||
actor_name: 'Task System',
|
||||
text: '可以',
|
||||
created_at: '2026-05-26T10:05:00.000Z',
|
||||
created_at: '2026-05-26T10:05:02.000Z',
|
||||
metadata: {
|
||||
acceptance_type: 'accept',
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
|
||||
@ -168,6 +168,10 @@ function feedbackSummary(feedback: Record<string, unknown>): string | undefined
|
||||
return firstString(feedback.comment, feedback.summary, feedback.acceptance_type);
|
||||
}
|
||||
|
||||
function acceptanceTypeFromRecord(record: Record<string, unknown> | undefined): string | null {
|
||||
return firstString(record?.acceptance_type, record?.feedback_type)?.toLowerCase() ?? null;
|
||||
}
|
||||
|
||||
function resultSummary(task: BackendTask): string | undefined {
|
||||
return firstString(
|
||||
task.metadata?.result_summary,
|
||||
@ -209,8 +213,29 @@ function compareCardsByCreatedAt(
|
||||
return aTime - bTime || a.index - b.index;
|
||||
}
|
||||
|
||||
function acceptanceKey(runId: string | null | undefined, createdAt: string): string {
|
||||
return `${runId ?? ''}:${createdAt}`;
|
||||
type AcceptanceEventIdentity = {
|
||||
runId: string | null;
|
||||
acceptanceType: string | null;
|
||||
};
|
||||
|
||||
function isCoveredByAcceptanceEvent(
|
||||
feedback: Record<string, unknown>,
|
||||
acceptanceEvents: AcceptanceEventIdentity[],
|
||||
): boolean {
|
||||
const feedbackType = acceptanceTypeFromRecord(feedback);
|
||||
if (!feedbackType) return false;
|
||||
|
||||
const feedbackRunId = firstString(feedback.run_id) ?? null;
|
||||
const matchingTypeEvents = acceptanceEvents.filter((event) => event.acceptanceType === feedbackType);
|
||||
|
||||
if (feedbackRunId) {
|
||||
return (
|
||||
matchingTypeEvents.some((event) => event.runId === feedbackRunId) ||
|
||||
(matchingTypeEvents.length === 1 && !matchingTypeEvents[0].runId)
|
||||
);
|
||||
}
|
||||
|
||||
return matchingTypeEvents.length === 1;
|
||||
}
|
||||
|
||||
export function buildTaskTimelineCards(input: BuildTaskTimelineCardsInput): TaskTimelineCard[] {
|
||||
@ -220,7 +245,7 @@ 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>();
|
||||
const acceptanceEvents: AcceptanceEventIdentity[] = [];
|
||||
let hasResultEventCard = false;
|
||||
const cards: TaskTimelineCard[] = [
|
||||
{
|
||||
@ -246,7 +271,10 @@ export function buildTaskTimelineCards(input: BuildTaskTimelineCardsInput): Task
|
||||
hasResultEventCard = true;
|
||||
}
|
||||
if (type === 'acceptance') {
|
||||
acceptanceEventKeys.add(acceptanceKey(event.run_id, event.created_at));
|
||||
acceptanceEvents.push({
|
||||
runId: firstString(event.run_id) ?? null,
|
||||
acceptanceType: acceptanceTypeFromRecord(event.metadata),
|
||||
});
|
||||
}
|
||||
|
||||
cards.push({
|
||||
@ -322,7 +350,7 @@ export function buildTaskTimelineCards(input: BuildTaskTimelineCardsInput): Task
|
||||
const feedback = task.feedback[index];
|
||||
const runId = firstString(feedback.run_id) ?? null;
|
||||
const createdAt = feedbackCreatedAt(feedback, task);
|
||||
if (acceptanceEventKeys.has(acceptanceKey(runId, createdAt))) continue;
|
||||
if (isCoveredByAcceptanceEvent(feedback, acceptanceEvents)) continue;
|
||||
|
||||
cards.push({
|
||||
id: `${task.task_id}:acceptance:${index}`,
|
||||
|
||||
Reference in New Issue
Block a user