最新 - 给 AVA.analysis() 方法加入分步进度报告能力,并在 site 侧新增 AnalysisSteps UI 组件实现可视化展示 - #960
最新 - 给 AVA.analysis() 方法加入分步进度报告能力,并在 site 侧新增 AnalysisSteps UI 组件实现可视化展示#960ninelcc336 wants to merge 6 commits into
Conversation
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
|
🎊 PR Preview ac4a466 has been successfully built and deployed to https://antvis-AVA-preview-pr-960.surge.sh 🕐 Build time: 0.016s 🤖 By surge-preview |
There was a problem hiding this comment.
Code Review
This pull request introduces an analysis progress tracking feature to the AVA framework. It adds a new AnalysisSteps component to visualize the step-by-step progress of the analysis, updates the AVA class to emit progress events via an onProgress callback during SQL generation, execution, JS code generation, summarization, and visualization, and exposes the necessary types (AnalysisStep, StepStatus, etc.). Additionally, it updates GPTVisRenderer to re-render when dimensions change. The reviewer feedback suggests adding a startTime field to AnalysisStep to accurately track individual step durations, avoiding sorting steps by timestamp in the UI to prevent rendering instability, and replacing non-standard Tailwind CSS classes like ml-6.5 with standard ones like ml-6.
| /** Unix millisecond timestamp, updated on step status change */ | ||
| timestamp: number; | ||
| } |
There was a problem hiding this comment.
为了准确计算每个步骤的耗时(特别是第一步,因为调用 LLM 通常耗时最长),我们需要记录步骤的初始启动时间。否则,在状态更新时重写 timestamp 会覆盖掉启动时间,导致无法计算第一步的耗时。
建议在 AnalysisStep 接口中增加 startTime 字段。
/** Unix millisecond timestamp, updated on step status change */
timestamp: number;
/** Unix millisecond timestamp when the step was first created */
startTime: number;
}| } else { | ||
| steps.push({ | ||
| id: String(id++), | ||
| agent: 'main', | ||
| phase: item.phase, | ||
| label, | ||
| status: item.params.status, | ||
| timestamp: Date.now(), | ||
| detail: item.params.detail, | ||
| error: item.params.error, | ||
| }); | ||
| } |
There was a problem hiding this comment.
| function getStepTime(step: AnalysisStep, index: number, sorted: AnalysisStep[]): string | null { | ||
| if (step.status !== 'done') return null; | ||
| if (index === 0) return null; | ||
| const prevTimestamp = sorted[index - 1].timestamp; | ||
| const duration = (step.timestamp - prevTimestamp) / 1000; | ||
| if (duration <= 0) return null; | ||
| return `${duration.toFixed(1)}s`; | ||
| } |
There was a problem hiding this comment.
| const sorted = useMemo(() => { | ||
| return [...steps].sort((a, b) => a.timestamp - b.timestamp); | ||
| }, [steps]); | ||
|
|
||
| const totalDuration = useMemo(() => { | ||
| if (sorted.length <= 1) return null; | ||
| const duration = (sorted[sorted.length - 1].timestamp - sorted[0].timestamp) / 1000; | ||
| if (duration <= 0) return null; | ||
| return duration; | ||
| }, [sorted]); | ||
|
|
||
| const hasError = sorted.some((s) => s.status === 'error'); | ||
| const allDone = sorted.every((s) => s.status === 'done'); |
There was a problem hiding this comment.
按 timestamp 排序是不稳定且不必要的。由于步骤是按照创建的先后顺序自然追加到 steps 数组中的,我们可以直接使用 steps。这可以避免在同一批次中更新/创建多个步骤时(例如,前一步完成和下一步开始在同一毫秒内发生),由于时间戳相同导致排序不稳定,从而在 UI 中出现步骤顺序错乱或跳动的问题。
const totalDuration = useMemo(() => {
if (steps.length <= 1) return null;
const duration = (steps[steps.length - 1].timestamp - steps[0].timestamp) / 1000;
if (duration <= 0) return null;
return duration;
}, [steps]);
const hasError = steps.some((s) => s.status === 'error');
const allDone = steps.every((s) => s.status === 'done');
| const title = ( | ||
| <span className="flex items-center gap-2 text-sm"> | ||
| <DoneIcon /> | ||
| <span> | ||
| Analysis complete · {sorted.length} steps{totalDuration !== null && ` · ${totalDuration.toFixed(1)}s`} | ||
| </span> | ||
| </span> | ||
| ); |
There was a problem hiding this comment.
将 title 中的 sorted.length 更新为 steps.length。
| const title = ( | |
| <span className="flex items-center gap-2 text-sm"> | |
| <DoneIcon /> | |
| <span> | |
| Analysis complete · {sorted.length} steps{totalDuration !== null && ` · ${totalDuration.toFixed(1)}s`} | |
| </span> | |
| </span> | |
| ); | |
| const title = ( | |
| <span className="flex items-center gap-2 text-sm"> | |
| <DoneIcon /> | |
| <span> | |
| Analysis complete · {steps.length} steps{totalDuration !== null && ' · ' + totalDuration.toFixed(1) + 's'} | |
| </span> | |
| </span> | |
| ); |
| {sorted.map((step, index) => { | ||
| const stepTime = getStepTime(step, index, sorted); |
| {step.status === 'error' && step.error && ( | ||
| <div className="mt-1 ml-6.5 text-xs text-red-500">{step.error}</div> | ||
| )} |
There was a problem hiding this comment.
Tailwind CSS 的默认间距中没有 ml-6.5。除非在 tailwind.config.js 中自定义了 6.5,否则该类将不会生效。建议使用标准类 ml-6 (24px) 或任意值 ml-[26px],以便与图标下方的文本完美对齐。
| {step.status === 'error' && step.error && ( | |
| <div className="mt-1 ml-6.5 text-xs text-red-500">{step.error}</div> | |
| )} | |
| {step.status === 'error' && step.error && ( | |
| <div className="mt-1 ml-6 text-xs text-red-500">{step.error}</div> | |
| )} |
| {isExpanded && step.detail && ( | ||
| <div className="mt-1.5 ml-6.5"> | ||
| <pre className="p-3 bg-gray-900 text-gray-100 rounded-lg text-xs overflow-x-auto font-mono leading-relaxed"> | ||
| {step.detail} |
There was a problem hiding this comment.
同样,ml-6.5 不是标准的 Tailwind 间距类。建议在此处也使用 ml-6 或 ml-[26px]。
| {isExpanded && step.detail && ( | |
| <div className="mt-1.5 ml-6.5"> | |
| <pre className="p-3 bg-gray-900 text-gray-100 rounded-lg text-xs overflow-x-auto font-mono leading-relaxed"> | |
| {step.detail} | |
| {/* Expanded detail code block */} | |
| {isExpanded && step.detail && ( | |
| <div className="mt-1.5 ml-6"> | |
| <pre className="p-3 bg-gray-900 text-gray-100 rounded-lg text-xs overflow-x-auto font-mono leading-relaxed"> |

新开分支实现 #958
以下是原PR描述
=============================================

点击 Generate 后,只有按钮变成loading,没有其他的提示了,用户只能干等着,不清楚运行情况,加上了分析步骤
变动
分析流程改造 (
src/ava.ts)analysis()方法新增options?: AnalysisOptions参数,支持onProgress回调createStepEmitter工厂函数:内部维护步骤数组,按 phase 去重(同 phase 状态更新而非新增),每次 emit 后回调传出完整的AnalysisStep[]进度组件 (
site/components/AnalysisSteps.tsx)Site 集成 (
site/components/Visualization.tsx)onProgress回调,驱动AnalysisSteps实时更新