chore(client): remove digital demo scenario residue

This commit is contained in:
baiyanyun
2026-06-09 08:49:45 +08:00
parent 48e5830b9e
commit 16eb8c691e

View File

@@ -1,292 +0,0 @@
import type { PlanMessage } from '@/lib/api';
import type {
DashboardOverview,
JournalEntry,
Mission,
MissionStep,
SkillSummary,
} from '@/lib/consoleDataAdapter';
import type { DebugPlan, DebugRun, DebugTask, FlowResponse } from '@/types/api';
function todayAt(hour: number, minute: number): string {
const date = new Date();
date.setHours(hour, minute, 0, 0);
return date.toISOString();
}
function makeTask(
missionId: string,
stepId: string,
title: string,
status: string,
skillId: string,
startedAt: string | null,
finishedAt: string | null,
): MissionStep['tasks'][number] {
return {
id: `${missionId}-${stepId}-task`,
title,
status,
assignedSkillId: skillId,
startedAt,
finishedAt,
};
}
function makeMission(
id: string,
title: string,
objective: string,
status: string,
updatedAt: string,
steps: MissionStep[],
): Mission {
return {
id,
title,
objective,
status,
createdAt: todayAt(8, 0),
updatedAt,
steps,
sourceIds: { planId: id, taskIds: steps.flatMap((step) => step.tasks.map((task) => task.id)) },
};
}
const DEMO_SKILLS: SkillSummary[] = [
{ id: 'qimingclaw-client-health-check', name: '客户端自检', version: '1.0.0', enabled: true, description: '检查 Agent、MCP、Computer Server 和会话状态。', category: '执行', capabilityLevel: 'core', source: 'skill-api' },
{ id: 'qimingclaw-remote-task-ingress', name: '远程任务接入', version: '1.0.0', enabled: true, description: '接收管理端下发任务并投射到本地执行队列。', category: '通信', capabilityLevel: 'core', source: 'skill-api' },
{ id: 'qimingclaw-acp-session-runner', name: 'ACP 会话执行', version: '1.0.0', enabled: true, description: '通过 qimingclaw ACP 引擎执行任务并记录 Run/Event。', category: '执行', capabilityLevel: 'specialized', source: 'skill-api' },
{ id: 'qimingclaw-mcp-capability-scan', name: 'MCP 能力扫描', version: '1.0.0', enabled: true, description: '读取 MCP server 和工具清单,生成数字员工技能能力池。', category: '工具', capabilityLevel: 'standard', source: 'skill-api' },
{ id: 'qimingclaw-approval-sync', name: '审批同步', version: '1.0.0', enabled: true, description: '把待确认事项回写到本地 approval 表并同步管理端。', category: '治理', capabilityLevel: 'specialized', source: 'skill-api' },
{ id: 'qimingclaw-artifact-report', name: '产物整理', version: '1.0.0', enabled: true, description: '整理本地执行产物、文件路径和日报输出。', category: '产物', capabilityLevel: 'standard', source: 'skill-api' },
{ id: 'qimingclaw-sync-diagnostics', name: '同步诊断', version: '1.0.0', enabled: true, description: '汇总 outbox 失败、重试历史和管理端同步状态。', category: '运维', capabilityLevel: 'standard', source: 'skill-api' },
{ id: 'qimingclaw-daily-report', name: '本地日报', version: '1.0.0', enabled: true, description: '基于 qimingclaw workday 投影生成本地文本日报。', category: '报表', capabilityLevel: 'standard', source: 'skill-api' },
];
const DEMO_MISSIONS: Mission[] = [
makeMission(
'qimingclaw-client-readiness',
'qimingclaw 客户端运行自检',
'检查客户端数字员工运行所需的 Agent、ACP、MCP、Computer Server 和同步配置。',
'active',
todayAt(10, 35),
[
{ id: 'agent', title: '检查 Agent 服务', status: 'completed', preferredSkills: ['qimingclaw-client-health-check'], tasks: [makeTask('qimingclaw-client-readiness', 'agent', '读取 Agent 运行状态', 'completed', 'qimingclaw-client-health-check', todayAt(8, 30), todayAt(8, 33))] },
{ id: 'mcp', title: '扫描 MCP server', status: 'completed', preferredSkills: ['qimingclaw-mcp-capability-scan'], tasks: [makeTask('qimingclaw-client-readiness', 'mcp', '生成 MCP 能力清单', 'completed', 'qimingclaw-mcp-capability-scan', todayAt(8, 35), todayAt(8, 41))] },
{ id: 'computer', title: '检查 Computer Server', status: 'completed', preferredSkills: ['qimingclaw-client-health-check'], tasks: [makeTask('qimingclaw-client-readiness', 'computer', '确认电脑控制入口', 'completed', 'qimingclaw-client-health-check', todayAt(8, 45), todayAt(8, 51))] },
{ id: 'sync', title: '读取同步队列', status: 'running', preferredSkills: ['qimingclaw-sync-diagnostics'], tasks: [makeTask('qimingclaw-client-readiness', 'sync', '汇总 outbox 状态', 'running', 'qimingclaw-sync-diagnostics', todayAt(10, 28), null)] },
],
),
makeMission('qimingclaw-remote-task-ingress', '09:00 远程任务接入', '接收管理端下发任务,进入 /computer/chat 与 ACP 执行链路。', 'completed', todayAt(9, 6), [
{ id: 'ingress', title: '接收管理端任务', status: 'completed', preferredSkills: ['qimingclaw-remote-task-ingress'], tasks: [makeTask('qimingclaw-remote-task-ingress', 'ingress', '解析远程任务 payload', 'completed', 'qimingclaw-remote-task-ingress', todayAt(9, 0), todayAt(9, 6))] },
]),
makeMission('qimingclaw-acp-run-0930', '09:30 ACP 会话执行', '用 qimingclaw ACP 会话执行本地任务并记录运行事件。', 'completed', todayAt(9, 32), [
{ id: 'run-session', title: '创建 ACP 会话', status: 'completed', preferredSkills: ['qimingclaw-acp-session-runner'], tasks: [makeTask('qimingclaw-acp-run-0930', 'run-session', '执行客户端任务', 'completed', 'qimingclaw-acp-session-runner', todayAt(9, 30), todayAt(9, 32))] },
]),
makeMission('qimingclaw-mcp-tools-1030', '10:30 MCP 工具能力投射', '读取当前 MCP 配置、server 状态和工具限制,生成技能库能力项。', 'running', todayAt(10, 35), [
{ id: 'scan-tools', title: '扫描 MCP 工具', status: 'running', preferredSkills: ['qimingclaw-mcp-capability-scan'], tasks: [makeTask('qimingclaw-mcp-tools-1030', 'scan-tools', '整理 MCP 工具清单', 'running', 'qimingclaw-mcp-capability-scan', todayAt(10, 30), null)] },
]),
makeMission('qimingclaw-approval-review-1130', '11:30 本地审批确认', '把数字员工待确认事项写回 formal approval 表并进入同步队列。', 'approved', todayAt(11, 20), [
{ id: 'approval', title: '处理 approval 决策', status: 'pending', preferredSkills: ['qimingclaw-approval-sync'], tasks: [makeTask('qimingclaw-approval-review-1130', 'approval', '回写 approval 状态', 'pending', 'qimingclaw-approval-sync', null, null)] },
]),
makeMission('qimingclaw-artifact-1430', '14:30 执行产物整理', '提取 Run/Event payload 中的文件、路径和输出,投射到 artifact 列表。', 'draft', todayAt(14, 10), [
{ id: 'artifact', title: '整理执行产物', status: 'pending', preferredSkills: ['qimingclaw-artifact-report'], tasks: [makeTask('qimingclaw-artifact-1430', 'artifact', '生成产物索引', 'pending', 'qimingclaw-artifact-report', null, null)] },
]),
makeMission('qimingclaw-sync-1630', '16:30 管理端同步诊断', '检查 outbox 失败、退避状态和最近同步尝试。', 'draft', todayAt(16, 10), [
{ id: 'sync-diagnostics', title: '生成同步诊断', status: 'pending', preferredSkills: ['qimingclaw-sync-diagnostics'], tasks: [makeTask('qimingclaw-sync-1630', 'sync-diagnostics', '导出同步诊断', 'pending', 'qimingclaw-sync-diagnostics', null, null)] },
]),
makeMission('qimingclaw-daily-report', '18:00 本地日报生成', '基于 qimingclaw workday 投影生成可下载文本日报。', 'draft', todayAt(17, 10), [
{ id: 'daily-report', title: '生成数字员工日报', status: 'pending', preferredSkills: ['qimingclaw-daily-report'], tasks: [makeTask('qimingclaw-daily-report', 'daily-report', '整理日报文本', 'pending', 'qimingclaw-daily-report', null, null)] },
]),
makeMission('zhihu-hotlist-monitor', '知乎热榜采集', '通过计划模板调用知乎热榜采集技能,导出表格文件并生成当天热点摘要。', 'approved', todayAt(10, 12), [
{ id: 'collect-zhihu', title: '采集知乎热榜', status: 'pending', preferredSkills: ['zhihu-hotlist'], tasks: [makeTask('zhihu-hotlist-monitor', 'collect-zhihu', '采集知乎热榜', 'pending', 'zhihu-hotlist', null, null)] },
{ id: 'export-xlsx', title: '导出表格文件', status: 'pending', preferredSkills: ['office-export-xlsx'], tasks: [makeTask('zhihu-hotlist-monitor', 'export-xlsx', '导出热榜表格', 'pending', 'office-export-xlsx', null, null)] },
]),
];
function cloneMission(mission: Mission): Mission {
return {
...mission,
steps: mission.steps.map((step) => ({
...step,
preferredSkills: [...step.preferredSkills],
tasks: step.tasks.map((task) => ({ ...task })),
})),
sourceIds: { planId: mission.sourceIds.planId, taskIds: [...mission.sourceIds.taskIds] },
};
}
export function getDemoMissions(): Mission[] {
return DEMO_MISSIONS.map(cloneMission);
}
export function getDemoSkills(): SkillSummary[] {
return DEMO_SKILLS.map((skill) => ({ ...skill }));
}
export function buildDemoTasks(missions: Mission[]): DebugTask[] {
return missions.flatMap((mission) => mission.steps.flatMap((step) => step.tasks.map((task) => ({
task_id: task.id,
title: task.title,
status: task.status,
plan_id: mission.id,
step_id: step.id,
assigned_skill_id: task.assignedSkillId || '',
description: `${mission.title} · ${step.title}`,
created_at: mission.createdAt || todayAt(8, 0),
updated_at: mission.updatedAt || mission.createdAt || todayAt(8, 0),
started_at: task.startedAt,
finished_at: task.finishedAt,
}))));
}
export function buildDemoRuns(tasks: DebugTask[]): DebugRun[] {
return tasks
.filter((task) => ['completed', 'running'].includes(task.status))
.map((task, index) => ({
run_id: `qimingclaw-fallback-run-${index + 1}`,
task_id: task.task_id,
plan_id: task.plan_id,
attempt_no: 1,
lifecycle: task.status === 'running' ? 'Running' : 'Succeeded',
created_at: task.started_at || task.created_at,
completed_at: task.finished_at,
}));
}
export function buildDemoOverview(tasks: DebugTask[]): DashboardOverview {
return {
generatedAt: new Date().toISOString(),
isPartial: true,
sources: [{ endpoint: 'qimingclaw-fallback', ok: true, loadedAt: new Date().toISOString() }],
taskTotals: {
total: tasks.length,
queued: tasks.filter((task) => task.status === 'pending').length,
running: tasks.filter((task) => task.status === 'running').length,
succeeded: tasks.filter((task) => task.status === 'completed').length,
failed: 0,
},
approvals: { total: 1, pending: 1 },
health: { activeTasks: tasks.filter((task) => task.status === 'running').length, failedTasks: 0, pendingConfirmations: 1 },
};
}
export function buildDemoPlans(missions: Mission[]): DebugPlan[] {
return missions.map((mission) => ({
plan_id: mission.id,
title: mission.title,
objective: mission.objective,
status: mission.status,
created_at: mission.createdAt || todayAt(8, 0),
steps: mission.steps.map((step) => ({
step_id: step.id,
title: step.title,
depends_on: [],
preferred_skills: step.preferredSkills,
tasks: step.tasks.map((task) => ({
task_id: task.id,
title: task.title,
status: task.status,
})),
})),
}));
}
export function buildDemoJournalEntries(missions: Mission[]): JournalEntry[] {
return missions
.slice(0, 8)
.map((mission, index) => ({
id: `qimingclaw-fallback-journal-${index + 1}`,
kind: mission.status === 'completed' ? 'completed' : mission.status === 'active' || mission.status === 'running' ? 'start' : 'pending_authorization',
source: 'qimingclaw-fallback',
message: `${mission.title}${mission.objective}`,
occurredAt: mission.updatedAt,
planId: mission.id,
taskId: mission.sourceIds.taskIds[0] || null,
}));
}
export function buildDemoFlowEvents(mission: Mission): NonNullable<FlowResponse['events']> {
const activeStep = mission.steps.find((step) => step.status === 'running') || mission.steps.find((step) => step.status === 'pending') || mission.steps[0];
const events: NonNullable<FlowResponse['events']> = [
{ event_id: `${mission.id}-event-1`, kind: 'entered_session', occurred_at: mission.createdAt || todayAt(8, 0), message: `已接收场景:${mission.title}` },
{ event_id: `${mission.id}-event-2`, kind: 'start', occurred_at: mission.updatedAt || mission.createdAt || todayAt(8, 0), message: `当前目标:${mission.objective}` },
];
if (activeStep) {
events.push({
event_id: `${mission.id}-event-3`,
kind: mission.status === 'completed' ? 'completed' : mission.status === 'approved' || mission.status === 'draft' ? 'pending_authorization' : 'RunStarted',
occurred_at: mission.updatedAt || mission.createdAt || todayAt(8, 0),
message: `${activeStep.title}`,
});
}
if (mission.status === 'completed') {
events.push({
event_id: `${mission.id}-event-4`,
kind: 'RunCompleted',
occurred_at: mission.updatedAt || mission.createdAt || todayAt(8, 0),
message: '已完成本场景执行并回写结果。',
});
}
return events;
}
export function buildDemoPlanMessages(mission: Mission): PlanMessage[] {
const completedSteps = mission.steps.filter((step) => step.status === 'completed').length;
const runningStep = mission.steps.find((step) => step.status === 'running');
const closing =
mission.status === 'completed'
? `当前已完成全部 ${mission.steps.length} 个步骤,结果已整理完毕。`
: runningStep
? `当前正在处理“${runningStep.title}”,已完成 ${completedSteps} 个步骤。`
: `当前场景已准备就绪,可直接发起执行。`;
return [
{ role: 'user', content: `请执行场景:${mission.title}` },
{ role: 'assistant', content: `已接收。业务目标:${mission.objective}` },
{ role: 'assistant', content: closing },
];
}
export function runDemoMissionOnce(missions: Mission[], missionId: string): Mission[] {
return missions.map((mission) => {
if (mission.id !== missionId) return mission;
return {
...mission,
status: 'running',
updatedAt: new Date().toISOString(),
steps: mission.steps.map((step, index) => ({
...step,
status: index === 0 ? 'running' : step.status === 'completed' ? 'completed' : 'pending',
tasks: step.tasks.map((task) => ({
...task,
status: index === 0 ? 'running' : task.status === 'completed' ? 'completed' : 'pending',
startedAt: index === 0 ? new Date().toISOString() : task.startedAt,
finishedAt: index === 0 ? null : task.finishedAt,
})),
})),
};
});
}
export function completeDemoMissionOnce(missions: Mission[], missionId: string): Mission[] {
return missions.map((mission) => {
if (mission.id !== missionId) return mission;
return {
...mission,
status: 'completed',
updatedAt: new Date().toISOString(),
steps: mission.steps.map((step) => ({
...step,
status: 'completed',
tasks: step.tasks.map((task) => ({
...task,
status: 'completed',
startedAt: task.startedAt || new Date().toISOString(),
finishedAt: new Date().toISOString(),
})),
})),
};
});
}