feat(AgentAudit): 添加进度日志功能支持

添加 progress 日志类型,支持通过 progressKey 更新或添加进度日志
在日志组件中增加进度日志的样式和显示
处理进度消息的匹配和更新逻辑,避免重复添加日志
This commit is contained in:
lintsinghua 2025-12-16 18:04:09 +08:00
parent 18a91f25b2
commit 2bba972272
5 changed files with 136 additions and 27 deletions

View File

@ -24,6 +24,7 @@ const LOG_TYPE_LABELS: Record<string, string> = {
info: 'INFO',
error: 'ERROR',
user: 'USER',
progress: 'PROGRESS',
};
// Helper to format title (remove emojis and clean up)
@ -73,6 +74,7 @@ export const LogEntry = memo(function LogEntry({ item, isExpanded, onToggle }: L
const isFinding = item.type === 'finding';
const isError = item.type === 'error';
const isInfo = item.type === 'info';
const isProgress = item.type === 'progress';
const showContent = isThinking || isExpanded;
const isCollapsible = !isThinking && item.content;
@ -124,6 +126,7 @@ export const LogEntry = memo(function LogEntry({ item, isExpanded, onToggle }: L
${isFinding ? 'bg-rose-500/25 text-rose-300' : ''}
${isError ? 'bg-red-500/25 text-red-300' : ''}
${isInfo ? 'bg-slate-500/25 text-slate-300' : ''}
${isProgress ? 'bg-cyan-500/25 text-cyan-300' : ''}
${item.type === 'dispatch' ? 'bg-sky-500/25 text-sky-300' : ''}
${item.type === 'phase' ? 'bg-teal-500/25 text-teal-300' : ''}
${item.type === 'user' ? 'bg-indigo-500/25 text-indigo-300' : ''}

View File

@ -78,6 +78,11 @@ export const LOG_TYPE_CONFIG: Record<string, {
borderColor: "border-l-indigo-500",
bgColor: "bg-indigo-500/10"
},
progress: {
icon: React.createElement(Loader2, { className: "w-4 h-4 text-cyan-400 animate-spin" }),
borderColor: "border-l-cyan-500",
bgColor: "bg-cyan-500/10"
},
};
// ============ Agent Status Configurations ============

View File

@ -101,6 +101,34 @@ function agentAuditReducer(state: AgentAuditState, action: AgentAuditAction): Ag
return { ...state, logs: updatedLogs };
}
case 'UPDATE_OR_ADD_PROGRESS_LOG': {
const { progressKey, title, agentName } = action.payload;
// 查找是否已存在相同 progressKey 的进度日志
const existingIndex = state.logs.findIndex(
log => log.type === 'progress' && log.progressKey === progressKey
);
if (existingIndex >= 0) {
// 更新现有日志的 title 和 time
const updatedLogs = [...state.logs];
updatedLogs[existingIndex] = {
...updatedLogs[existingIndex],
title,
time: new Date().toLocaleTimeString('en-US', { hour12: false }),
};
return { ...state, logs: updatedLogs };
} else {
// 添加新的进度日志
const newLog = createLogItem({
type: 'progress',
title,
progressKey,
agentName,
});
return { ...state, logs: [...state.logs, newLog] };
}
}
case 'SELECT_AGENT':
return {
...state,

View File

@ -317,16 +317,36 @@ function AgentAuditPageContent() {
// 进度事件
case 'progress':
// 进度事件可以选择显示或跳过
// 进度事件使用 UPDATE_OR_ADD_PROGRESS_LOG 来更新而不是添加
if (event.message) {
dispatch({
type: 'ADD_LOG',
payload: {
type: 'info',
title: event.message,
agentName,
}
});
const progressPatterns: { pattern: RegExp; key: string }[] = [
{ pattern: /索引进度[:]?\s*\d+\/\d+/, key: 'index_progress' },
{ pattern: /克隆进度[:]?\s*\d+%/, key: 'clone_progress' },
{ pattern: /下载进度[:]?\s*\d+%/, key: 'download_progress' },
{ pattern: /上传进度[:]?\s*\d+%/, key: 'upload_progress' },
{ pattern: /扫描进度[:]?\s*\d+/, key: 'scan_progress' },
{ pattern: /分析进度[:]?\s*\d+/, key: 'analyze_progress' },
];
const matchedProgress = progressPatterns.find(p => p.pattern.test(event.message || ''));
if (matchedProgress) {
dispatch({
type: 'UPDATE_OR_ADD_PROGRESS_LOG',
payload: {
progressKey: matchedProgress.key,
title: event.message,
agentName,
}
});
} else {
dispatch({
type: 'ADD_LOG',
payload: {
type: 'info',
title: event.message,
agentName,
}
});
}
processedCount++;
}
break;
@ -335,17 +355,40 @@ function AgentAuditPageContent() {
case 'info':
case 'complete':
case 'error':
case 'warning':
dispatch({
type: 'ADD_LOG',
payload: {
type: event.event_type === 'error' ? 'error' : 'info',
title: event.message || `${event.event_type}`,
agentName,
}
});
case 'warning': {
const message = event.message || `${event.event_type}`;
// 检测进度类型消息
const progressPatterns: { pattern: RegExp; key: string }[] = [
{ pattern: /索引进度[:]?\s*\d+\/\d+/, key: 'index_progress' },
{ pattern: /克隆进度[:]?\s*\d+%/, key: 'clone_progress' },
{ pattern: /下载进度[:]?\s*\d+%/, key: 'download_progress' },
{ pattern: /上传进度[:]?\s*\d+%/, key: 'upload_progress' },
{ pattern: /扫描进度[:]?\s*\d+/, key: 'scan_progress' },
{ pattern: /分析进度[:]?\s*\d+/, key: 'analyze_progress' },
];
const matchedProgress = progressPatterns.find(p => p.pattern.test(message));
if (matchedProgress) {
dispatch({
type: 'UPDATE_OR_ADD_PROGRESS_LOG',
payload: {
progressKey: matchedProgress.key,
title: message,
agentName,
}
});
} else {
dispatch({
type: 'ADD_LOG',
payload: {
type: event.event_type === 'error' ? 'error' : 'info',
title: message,
agentName,
}
});
}
processedCount++;
break;
}
// 跳过 thinking_token 等高频事件(它们不会被保存到数据库)
case 'thinking_token':
@ -410,14 +453,41 @@ function AgentAuditPageContent() {
// 🔥 处理 info、warning、error 类型事件(克隆进度、索引进度等)
const infoEvents = ['info', 'warning', 'error', 'progress'];
if (infoEvents.includes(event.type)) {
dispatch({
type: 'ADD_LOG',
payload: {
type: event.type === 'error' ? 'error' : 'info',
title: event.message || event.type,
agentName: getCurrentAgentName() || undefined,
}
});
const message = event.message || event.type;
// 🔥 检测进度类型消息,使用更新而不是添加
const progressPatterns: { pattern: RegExp; key: string }[] = [
{ pattern: /索引进度[:]?\s*\d+\/\d+/, key: 'index_progress' },
{ pattern: /克隆进度[:]?\s*\d+%/, key: 'clone_progress' },
{ pattern: /下载进度[:]?\s*\d+%/, key: 'download_progress' },
{ pattern: /上传进度[:]?\s*\d+%/, key: 'upload_progress' },
{ pattern: /扫描进度[:]?\s*\d+/, key: 'scan_progress' },
{ pattern: /分析进度[:]?\s*\d+/, key: 'analyze_progress' },
];
const matchedProgress = progressPatterns.find(p => p.pattern.test(message));
if (matchedProgress) {
// 使用 UPDATE_OR_ADD_PROGRESS_LOG 来更新进度而不是添加新日志
dispatch({
type: 'UPDATE_OR_ADD_PROGRESS_LOG',
payload: {
progressKey: matchedProgress.key,
title: message,
agentName: getCurrentAgentName() || undefined,
}
});
} else {
// 非进度消息正常添加
dispatch({
type: 'ADD_LOG',
payload: {
type: event.type === 'error' ? 'error' : 'info',
title: message,
agentName: getCurrentAgentName() || undefined,
}
});
}
return;
}
},

View File

@ -15,7 +15,8 @@ export type LogType =
| 'info'
| 'error'
| 'user'
| 'dispatch';
| 'dispatch'
| 'progress';
export type ToolStatus = 'running' | 'completed' | 'failed';
@ -33,6 +34,7 @@ export interface LogItem {
};
severity?: string;
agentName?: string;
progressKey?: string; // 用于标识进度日志的唯一键,如 "index_progress"
}
// ============ Connection Types ============
@ -76,6 +78,7 @@ export type AgentAuditAction =
| { type: 'SET_LOGS'; payload: LogItem[] }
| { type: 'ADD_LOG'; payload: Omit<LogItem, 'id' | 'time'> & { id?: string } }
| { type: 'UPDATE_LOG'; payload: { id: string; updates: Partial<LogItem> } }
| { type: 'UPDATE_OR_ADD_PROGRESS_LOG'; payload: { progressKey: string; title: string; agentName?: string } }
| { type: 'COMPLETE_TOOL_LOG'; payload: { toolName: string; output: string; duration: number } }
| { type: 'REMOVE_LOG'; payload: string }
| { type: 'SELECT_AGENT'; payload: string | null }