feat(frontend): restore session progress sidebar
This commit is contained in:
201
app-instance/frontend/lib/session-progress.test.ts
Normal file
201
app-instance/frontend/lib/session-progress.test.ts
Normal file
@ -0,0 +1,201 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
|
||||
import { buildSessionProgressView } from '@/lib/session-progress';
|
||||
import type { ProcessArtifact, ProcessEvent, ProcessRun } from '@/types';
|
||||
|
||||
describe('session progress view builder', () => {
|
||||
it('selects the latest active root run for the current session and builds its run tree', () => {
|
||||
const processRuns: ProcessRun[] = [
|
||||
{
|
||||
run_id: 'old-root',
|
||||
parent_run_id: null,
|
||||
session_id: 'web:current',
|
||||
actor_type: 'agent',
|
||||
actor_id: 'main',
|
||||
actor_name: 'Main Agent',
|
||||
title: '旧任务',
|
||||
status: 'done',
|
||||
started_at: '2026-05-22T08:00:00.000Z',
|
||||
finished_at: '2026-05-22T08:05:00.000Z',
|
||||
},
|
||||
{
|
||||
run_id: 'latest-root',
|
||||
parent_run_id: null,
|
||||
session_id: 'web:current',
|
||||
actor_type: 'agent',
|
||||
actor_id: 'main',
|
||||
actor_name: 'Main Agent',
|
||||
title: '销售数据分析报告生成',
|
||||
status: 'running',
|
||||
started_at: '2026-05-22T09:00:00.000Z',
|
||||
metadata: {
|
||||
step_index: 3,
|
||||
step_total: 5,
|
||||
},
|
||||
},
|
||||
{
|
||||
run_id: 'collect-data',
|
||||
parent_run_id: 'latest-root',
|
||||
session_id: 'web:current',
|
||||
actor_type: 'agent',
|
||||
actor_id: 'collector',
|
||||
actor_name: 'Data Agent',
|
||||
title: '收集销售数据',
|
||||
status: 'done',
|
||||
started_at: '2026-05-22T09:01:00.000Z',
|
||||
finished_at: '2026-05-22T09:03:00.000Z',
|
||||
summary: '已获取 Q1 销售数据',
|
||||
},
|
||||
{
|
||||
run_id: 'clean-data',
|
||||
parent_run_id: 'latest-root',
|
||||
session_id: 'web:current',
|
||||
actor_type: 'agent',
|
||||
actor_id: 'cleaner',
|
||||
actor_name: 'Cleaning Agent',
|
||||
title: '数据清洗与预处理',
|
||||
status: 'running',
|
||||
started_at: '2026-05-22T09:04:00.000Z',
|
||||
},
|
||||
{
|
||||
run_id: 'other-root',
|
||||
parent_run_id: null,
|
||||
session_id: 'web:other',
|
||||
actor_type: 'agent',
|
||||
actor_id: 'main',
|
||||
actor_name: 'Main Agent',
|
||||
title: '其他会话任务',
|
||||
status: 'running',
|
||||
started_at: '2026-05-22T10:00:00.000Z',
|
||||
},
|
||||
];
|
||||
|
||||
const processEvents: ProcessEvent[] = [
|
||||
{
|
||||
event_id: 'evt-clean',
|
||||
run_id: 'clean-data',
|
||||
parent_run_id: 'latest-root',
|
||||
kind: 'run_progress',
|
||||
actor_type: 'agent',
|
||||
actor_id: 'cleaner',
|
||||
actor_name: 'Cleaning Agent',
|
||||
text: '清洗缺失值、异常值,统一格式',
|
||||
created_at: '2026-05-22T09:05:00.000Z',
|
||||
},
|
||||
];
|
||||
|
||||
const processArtifacts: ProcessArtifact[] = [
|
||||
{
|
||||
artifact_id: 'artifact-json',
|
||||
run_id: 'collect-data',
|
||||
actor_type: 'agent',
|
||||
actor_id: 'collector',
|
||||
actor_name: 'Data Agent',
|
||||
title: '销售数据',
|
||||
artifact_type: 'json',
|
||||
data: { rows: 120 },
|
||||
created_at: '2026-05-22T09:03:30.000Z',
|
||||
},
|
||||
{
|
||||
artifact_id: 'artifact-markdown',
|
||||
run_id: 'clean-data',
|
||||
actor_type: 'agent',
|
||||
actor_id: 'cleaner',
|
||||
actor_name: 'Cleaning Agent',
|
||||
title: '清洗说明',
|
||||
artifact_type: 'markdown',
|
||||
content: '已完成数据标准化。',
|
||||
created_at: '2026-05-22T09:05:30.000Z',
|
||||
},
|
||||
{
|
||||
artifact_id: 'artifact-other-session',
|
||||
run_id: 'other-root',
|
||||
actor_type: 'agent',
|
||||
actor_id: 'main',
|
||||
title: '其他会话产物',
|
||||
artifact_type: 'text',
|
||||
content: '不应出现',
|
||||
created_at: '2026-05-22T10:01:00.000Z',
|
||||
},
|
||||
];
|
||||
|
||||
const view = buildSessionProgressView({
|
||||
sessionId: 'web:current',
|
||||
processRuns,
|
||||
processEvents,
|
||||
processArtifacts,
|
||||
locale: 'zh-CN',
|
||||
});
|
||||
|
||||
expect(view).not.toBeNull();
|
||||
expect(view?.rootRunId).toBe('latest-root');
|
||||
expect(view?.title).toBe('销售数据分析报告生成');
|
||||
expect(view?.progress).toMatchObject({
|
||||
value: 3,
|
||||
max: 5,
|
||||
percent: 60,
|
||||
label: '运行中:3 / 5 步',
|
||||
});
|
||||
expect(view?.steps.map((step) => step.runId)).toEqual(['collect-data', 'clean-data', 'latest-root']);
|
||||
expect(view?.steps.find((step) => step.runId === 'clean-data')?.description).toBe('清洗缺失值、异常值,统一格式');
|
||||
expect(view?.artifactTypeSummaries).toEqual([
|
||||
{ type: 'json', count: 1, label: 'JSON' },
|
||||
{ type: 'markdown', count: 1, label: 'Markdown' },
|
||||
]);
|
||||
expect(view?.artifacts.map((artifact) => artifact.artifactId)).toEqual(['artifact-markdown', 'artifact-json']);
|
||||
});
|
||||
|
||||
it('falls back to completed child run counts when no explicit progress metadata exists', () => {
|
||||
const processRuns: ProcessRun[] = [
|
||||
{
|
||||
run_id: 'root',
|
||||
parent_run_id: null,
|
||||
session_id: 'web:current',
|
||||
actor_type: 'agent',
|
||||
actor_id: 'main',
|
||||
actor_name: 'Main Agent',
|
||||
title: '生成总结',
|
||||
status: 'running',
|
||||
started_at: '2026-05-22T09:00:00.000Z',
|
||||
},
|
||||
{
|
||||
run_id: 'done-child',
|
||||
parent_run_id: 'root',
|
||||
session_id: 'web:current',
|
||||
actor_type: 'agent',
|
||||
actor_id: 'writer',
|
||||
actor_name: 'Writer',
|
||||
title: '整理结果',
|
||||
status: 'done',
|
||||
started_at: '2026-05-22T09:01:00.000Z',
|
||||
finished_at: '2026-05-22T09:02:00.000Z',
|
||||
},
|
||||
{
|
||||
run_id: 'running-child',
|
||||
parent_run_id: 'root',
|
||||
session_id: 'web:current',
|
||||
actor_type: 'agent',
|
||||
actor_id: 'reviewer',
|
||||
actor_name: 'Reviewer',
|
||||
title: '复核结果',
|
||||
status: 'running',
|
||||
started_at: '2026-05-22T09:03:00.000Z',
|
||||
},
|
||||
];
|
||||
|
||||
const view = buildSessionProgressView({
|
||||
sessionId: 'web:current',
|
||||
processRuns,
|
||||
processEvents: [],
|
||||
processArtifacts: [],
|
||||
locale: 'zh-CN',
|
||||
});
|
||||
|
||||
expect(view?.progress).toMatchObject({
|
||||
value: 1,
|
||||
max: 2,
|
||||
percent: 50,
|
||||
label: '已完成 1 / 2 步',
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user