This commit is contained in:
ViperEkura 2026-04-26 14:46:36 +08:00
parent 89d9a753b6
commit 59c723792d
4 changed files with 15 additions and 7 deletions

View File

@ -31,9 +31,9 @@
<div class="message-footer"> <div class="message-footer">
<span class="message-time">{{ formatTime(message.created_at) }}</span> <span class="message-time">{{ formatTime(message.created_at) }}</span>
<template v-if="message.role === 'assistant' && message.usage"> <template v-if="message.role === 'assistant' && message.usage">
<span class="token-item" v-if="message.usage.prompt">{{ formatNumber(message.usage.prompt) }} in</span> <span class="token-item" v-if="message.usage.prompt_tokens">{{ formatNumber(message.usage.prompt_tokens) }} in</span>
<span class="token-item" v-if="message.usage.completion">{{ formatNumber(message.usage.completion) }} out</span> <span class="token-item" v-if="message.usage.completion_tokens">{{ formatNumber(message.usage.completion_tokens) }} out</span>
<span class="token-item" v-if="message.usage.total">{{ formatNumber(message.usage.total) }} total</span> <span class="token-item" v-if="message.usage.total_tokens">{{ formatNumber(message.usage.total_tokens) }} total</span>
</template> </template>
<button v-if="message.role === 'assistant'" class="ghost-btn success" @click="$emit('regenerate', message.id)" title="重新生成"> <button v-if="message.role === 'assistant'" class="ghost-btn success" @click="$emit('regenerate', message.id)" title="重新生成">
<span v-html="regenerateIcon"></span> <span v-html="regenerateIcon"></span>

View File

@ -40,6 +40,8 @@ onMounted(async () => {
if (convs.status === 'fulfilled' && convs.value.success) { if (convs.status === 'fulfilled' && convs.value.success) {
stats.value.conversations = convs.value.data?.total || 0 stats.value.conversations = convs.value.data?.total || 0
const items = convs.value.data?.items || [] const items = convs.value.data?.items || []
console.log('[HomeView] conversations response:', convs.value.data)
console.log('[HomeView] items with token_count:', items.map(i => ({ id: i.id, token_count: i.token_count })))
stats.value.totalTokens = items.reduce((sum, c) => sum + (c.token_count || 0), 0) stats.value.totalTokens = items.reduce((sum, c) => sum + (c.token_count || 0), 0)
} }
if (tools.status === 'fulfilled' && tools.value.success) { if (tools.status === 'fulfilled' && tools.value.success) {

View File

@ -65,14 +65,17 @@ def list_conversations(
).all() ).all()
total_tokens = 0 total_tokens = 0
for msg in assistant_messages: for msg in assistant_messages:
total_tokens += msg.token_count or 0 # Get usage from the usage field (new format from LLM)
# Also try to get usage from the usage field
if msg.usage: if msg.usage:
try: try:
usage_obj = json.loads(msg.usage) usage_obj = json.loads(msg.usage)
total_tokens = usage_obj.get("total_tokens", total_tokens) total_tokens += usage_obj.get("total_tokens", 0)
except: except:
pass # Fallback to token_count field
total_tokens += msg.token_count or 0
else:
# Legacy messages without usage field
total_tokens += msg.token_count or 0
conv_dict['token_count'] = total_tokens conv_dict['token_count'] = total_tokens
items.append(conv_dict) items.append(conv_dict)

View File

@ -105,6 +105,9 @@ class ToolRegistry:
# Automatic permission check (transparent to tool function) # Automatic permission check (transparent to tool function)
if context is not None and context.user_id is not None: if context is not None and context.user_id is not None:
user_level = context.extra.get("user_permission_level", CommandPermission.READ_ONLY) user_level = context.extra.get("user_permission_level", CommandPermission.READ_ONLY)
# Ensure user_level is an enum for comparison and display
if isinstance(user_level, int):
user_level = CommandPermission(user_level)
if user_level < tool.required_permission: if user_level < tool.required_permission:
return { return {
"success": False, "success": False,