fix: align usage analytics with Hermes state db (#350)

This commit is contained in:
Zhicheng Han
2026-04-30 13:46:31 +02:00
committed by GitHub
parent 05f15da90b
commit dac9006b3e
10 changed files with 591 additions and 113 deletions
+7 -2
View File
@@ -103,6 +103,8 @@ export interface UsageStatsResponse {
total_reasoning_tokens: number
total_sessions: number
total_cost: number
total_api_calls?: number
period_days?: number
model_usage: Array<{
model: string
input_tokens: number
@@ -121,8 +123,11 @@ export interface UsageStatsResponse {
}>
}
export async function fetchUsageStats(): Promise<UsageStatsResponse> {
return request<UsageStatsResponse>('/api/hermes/usage/stats')
export async function fetchUsageStats(days = 30): Promise<UsageStatsResponse> {
const safeDays = Number.isFinite(days) ? Math.max(1, Math.floor(days)) : 30
const params = new URLSearchParams()
params.set('days', String(safeDays))
return request<UsageStatsResponse>(`/api/hermes/usage/stats?${params}`)
}
export async function fetchSessionUsage(ids: string[]): Promise<Record<string, { input_tokens: number; output_tokens: number }>> {
@@ -1,9 +1,11 @@
<script setup lang="ts">
import { computed } from 'vue'
import { useI18n } from 'vue-i18n'
import { useUsageStore } from '@/stores/hermes/usage'
const { t } = useI18n()
const usageStore = useUsageStore()
const maxModelTokens = computed(() => Math.max(usageStore.modelUsage[0]?.totalTokens || 0, 1))
function formatTokens(n: number): string {
if (n >= 1000000) return (n / 1000000).toFixed(1) + 'M'
@@ -21,7 +23,7 @@ function formatTokens(n: number): string {
<div class="model-bar-wrap">
<div
class="model-bar"
:style="{ width: (m.totalTokens / usageStore.modelUsage[0].totalTokens * 100) + '%' }"
:style="{ width: (m.totalTokens / maxModelTokens * 100) + '%' }"
/>
</div>
<span class="model-tokens">{{ formatTokens(m.totalTokens) }}</span>
+3 -3
View File
@@ -23,10 +23,10 @@ export const useUsageStore = defineStore('usage', () => {
const stats = ref<UsageStatsResponse | null>(null)
const isLoading = ref(false)
async function loadSessions() {
async function loadSessions(days = 30) {
isLoading.value = true
try {
stats.value = await fetchUsageStats()
stats.value = await fetchUsageStats(days)
} catch (err) {
console.error('Failed to load usage stats:', err)
} finally {
@@ -54,7 +54,7 @@ export const useUsageStore = defineStore('usage', () => {
const modelUsage = computed<ModelUsage[]>(() => {
if (!stats.value) return []
return stats.value.model_usage.map(m => ({
model: m.model,
model: m.model || 'unknown',
inputTokens: m.input_tokens,
outputTokens: m.output_tokens,
cacheTokens: m.cache_read_tokens,