feat(message-token-usage): 速度条图例按当前速度只显示对应颜色

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
AdministratorandClaude Opus 4.8 committed 2026-06-25 20:29:26 +08:00
1 parent fe7c6cb8f7
commit 5f01e8dd03
1 file changed
+32 -23
@@ -32,39 +32,43 @@ export function formatDuration(ms: number): string {
}
/**
* 速度条颜色含义图例 —— 生成结束后常驻在速度条下方一行,向用户解释进度条
* 颜色代表的「模型生成延迟」状态。进度条本身仍是 5 档(极快/流畅/一般/偏慢/
* 缓慢)的连续配色;这里把它归并成用户视角的 3 类延迟 + 「无响应」来说明:
* 速度条颜色含义图例 —— 生成结束后显示在速度条下方一行,向用户解释当前
* 进度条颜色代表的「模型生成延迟」状态。进度条本身仍是 5 档(极快/流畅/一般/
* 偏慢/缓慢)的连续配色;这里把它归并成用户视角的 3 类延迟 + 「无响应」:
* 绿(#16a34a,极快/流畅) → 延迟正常
* 黄(#eab308,一般) → 延迟微长
* 红(#ef4444,偏慢/缓慢) → 延迟长,可能失败
* 灰(#9ca3af) → 无响应(无进度条/0 tok/s),任务失败,请重试
* 根据本次问答的实际速度,只显示对应那一档的提示。
*/
const SPEED_LEGEND: { color: string; label: string }[] = [
{ color: "#16a34a", label: "延迟正常" },
{ color: "#eab308", label: "延迟微长" },
{ color: "#ef4444", label: "延迟长,可能失败" },
{ color: "#9ca3af", label: "无响应,任务失败,请重试" },
];
function legendForSpeed(tps: number): { color: string; label: string } {
if (tps <= 0) return { color: "#9ca3af", label: "无响应,任务失败,请重试" };
if (tps >= 30) return { color: "#16a34a", label: "延迟正常" };
if (tps >= 15) return { color: "#eab308", label: "延迟微长" };
return { color: "#ef4444", label: "延迟长,可能失败" };
}
export function SpeedLegend({ className }: { className?: string }) {
export function SpeedLegend({
className,
tokensPerSec,
}: {
className?: string;
tokensPerSec: number;
}) {
const item = legendForSpeed(tokensPerSec);
return (
<span
className={cn(
"text-muted-foreground inline-flex flex-wrap items-center gap-x-2.5 gap-y-0.5",
"text-muted-foreground inline-flex items-center gap-1",
className,
)}
>
{SPEED_LEGEND.map((item) => (
<span className="inline-flex items-center gap-1" key={item.label}>
<span
aria-hidden
className="inline-block size-2 shrink-0 rounded-full"
style={{ backgroundColor: item.color }}
/>
{item.label}
</span>
))}
<span
aria-hidden
className="inline-block size-2 shrink-0 rounded-full"
style={{ backgroundColor: item.color }}
/>
{item.label}
</span>
);
}
@@ -170,8 +174,13 @@ export function MessageTokenUsage({
{formatDuration(resolvedMetric.durationMs)}
</span>
)}
{/* 生成结束(非流式中)后常驻一行颜色含义说明。 */}
{!resolvedMetric.isActive && <SpeedLegend className="basis-full" />}
{/* 生成结束(非流式中)后只显示与本次速度对应那一档的颜色含义说明。 */}
{!resolvedMetric.isActive && (
<SpeedLegend
className="basis-full"
tokensPerSec={resolvedMetric.tokensPerSec}
/>
)}
</>
) : null}
</div>