From 260d38a83b9776263920f34256a1f7d6116c4233 Mon Sep 17 00:00:00 2001 From: Soulter <905617992@qq.com> Date: Mon, 27 Apr 2026 10:27:50 +0800 Subject: [PATCH 1/2] fix(stats): TPM now only counts output tokens - Add range_total_output_tokens accumulation, separate from total tokens - Change range_avg_tpm formula to use output tokens only - Update i18n labels to reflect Output TPM --- astrbot/dashboard/routes/stat.py | 4 +++- dashboard/src/i18n/locales/en-US/features/stats.json | 2 +- dashboard/src/i18n/locales/ru-RU/features/stats.json | 2 +- dashboard/src/i18n/locales/zh-CN/features/stats.json | 2 +- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/astrbot/dashboard/routes/stat.py b/astrbot/dashboard/routes/stat.py index 2eb3cd400e..82eec4021c 100644 --- a/astrbot/dashboard/routes/stat.py +++ b/astrbot/dashboard/routes/stat.py @@ -243,6 +243,7 @@ async def get_provider_token_stats(self): total_by_umo: dict[str, int] = defaultdict(int) total_by_bucket: dict[int, int] = defaultdict(int) range_total_tokens = 0 + range_total_output_tokens = 0 range_total_calls = 0 range_success_calls = 0 range_ttft_total_ms = 0.0 @@ -275,6 +276,7 @@ async def get_provider_token_stats(self): total_by_umo[record.umo or "unknown"] += token_total total_by_bucket[bucket_ts] += token_total range_total_tokens += token_total + range_total_output_tokens += record.token_output range_total_calls += 1 if record.status != "error": range_success_calls += 1 @@ -371,7 +373,7 @@ async def get_provider_token_stats(self): else 0 ), "range_avg_tpm": ( - range_total_tokens / (range_duration_total_ms / 1000 / 60) + range_total_output_tokens / (range_duration_total_ms / 1000 / 60) if range_duration_total_ms > 0 else 0 ), diff --git a/dashboard/src/i18n/locales/en-US/features/stats.json b/dashboard/src/i18n/locales/en-US/features/stats.json index b6349011ee..18c2e28132 100644 --- a/dashboard/src/i18n/locales/en-US/features/stats.json +++ b/dashboard/src/i18n/locales/en-US/features/stats.json @@ -67,7 +67,7 @@ "callCount": "{count} calls", "avgTtft": "Average TTFT", "avgDuration": "Average Response Time", - "avgTpm": "Average TPM", + "avgTpm": "Average Output TPM", "successRate": "Success Rate" }, "modelRanking": { diff --git a/dashboard/src/i18n/locales/ru-RU/features/stats.json b/dashboard/src/i18n/locales/ru-RU/features/stats.json index 45cc3ed6c4..572ac35859 100644 --- a/dashboard/src/i18n/locales/ru-RU/features/stats.json +++ b/dashboard/src/i18n/locales/ru-RU/features/stats.json @@ -67,7 +67,7 @@ "callCount": "{count} вызовов", "avgTtft": "Средний TTFT", "avgDuration": "Среднее время ответа", - "avgTpm": "Средний TPM", + "avgTpm": "Средний Output TPM", "successRate": "Доля успешных вызовов" }, "modelRanking": { diff --git a/dashboard/src/i18n/locales/zh-CN/features/stats.json b/dashboard/src/i18n/locales/zh-CN/features/stats.json index 64c8bb84a2..6dc717511b 100644 --- a/dashboard/src/i18n/locales/zh-CN/features/stats.json +++ b/dashboard/src/i18n/locales/zh-CN/features/stats.json @@ -67,7 +67,7 @@ "callCount": "共 {count} 次调用", "avgTtft": "平均首字延迟(TTFT)", "avgDuration": "平均响应时间", - "avgTpm": "平均每分钟词元数(TPM)", + "avgTpm": "平均每分钟输出(TPM)", "successRate": "调用成功率" }, "modelRanking": { From a88e0adc632d7164f9f3da1ea893fdddd9fc4f57 Mon Sep 17 00:00:00 2001 From: Soulter <905617992@qq.com> Date: Mon, 27 Apr 2026 10:37:58 +0800 Subject: [PATCH 2/2] fix(stats): range --- astrbot/dashboard/routes/stat.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/astrbot/dashboard/routes/stat.py b/astrbot/dashboard/routes/stat.py index 82eec4021c..b02091d5d4 100644 --- a/astrbot/dashboard/routes/stat.py +++ b/astrbot/dashboard/routes/stat.py @@ -276,7 +276,6 @@ async def get_provider_token_stats(self): total_by_umo[record.umo or "unknown"] += token_total total_by_bucket[bucket_ts] += token_total range_total_tokens += token_total - range_total_output_tokens += record.token_output range_total_calls += 1 if record.status != "error": range_success_calls += 1 @@ -288,6 +287,7 @@ async def get_provider_token_stats(self): record.end_time - record.start_time ) * 1000 range_duration_samples += 1 + range_total_output_tokens += record.token_output if created_at_local >= today_start_local: today_total_calls += 1 @@ -373,7 +373,8 @@ async def get_provider_token_stats(self): else 0 ), "range_avg_tpm": ( - range_total_output_tokens / (range_duration_total_ms / 1000 / 60) + range_total_output_tokens + / (range_duration_total_ms / 1000 / 60) if range_duration_total_ms > 0 else 0 ),