fix: Token统计准确性修复 + 仪表盘增强

1. 修复eval_count只记最后一轮的bug:改为每轮累加
2. 新增prompt_eval_count(输入token)统计
3. 修复total_duration使用Ollama实际推理时间而非墙钟时间
4. 数据库messages表新增prompt_eval_count列(含兼容迁移)
5. 仪表盘显示输入/输出token分项统计
6. 柱状图堆叠显示输入(紫色)+输出(橙色)比例
7. 明细表格新增输入/输出/合计三列
This commit is contained in:
thzxx
2026-04-23 16:11:17 +08:00
parent e96b2a840e
commit 21b9a14824
8 changed files with 125 additions and 29 deletions
+6 -9
View File
@@ -349,6 +349,7 @@ async function handleRetry(): Promise<void> {
...(retryThinkContent && { think: retryThinkContent }),
...(toolRecords?.length && { toolCalls: toolRecords }),
...(loopStats?.eval_count && { eval_count: loopStats.eval_count }),
...(loopStats?.prompt_eval_count && { prompt_eval_count: loopStats.prompt_eval_count }),
...(loopStats?.total_duration && { total_duration: loopStats.total_duration }),
};
state.update(KEYS.CURRENT_SESSION, (s: ChatSession | null) => ({
@@ -362,6 +363,7 @@ async function handleRetry(): Promise<void> {
...(retryThinkContent && { think: retryThinkContent }),
...(toolRecords?.length && { toolCalls: toolRecords }),
...(loopStats?.eval_count && { eval_count: loopStats.eval_count }),
...(loopStats?.prompt_eval_count && { prompt_eval_count: loopStats.prompt_eval_count }),
...(loopStats?.total_duration && { total_duration: loopStats.total_duration }),
};
state.update(KEYS.CURRENT_SESSION, (s: ChatSession | null) => ({
@@ -1056,7 +1058,8 @@ async function sendMessageWithAgentLoop(text: string, currentSession: ChatSessio
...(thinkContent && { think: thinkContent }),
...(toolRecords?.length && { toolCalls: toolRecords }),
...(loopStats?.eval_count && { eval_count: loopStats.eval_count }),
...(lastIterDuration > 0 && { total_duration: lastIterDuration }),
...(loopStats?.prompt_eval_count && { prompt_eval_count: loopStats.prompt_eval_count }),
...(loopStats?.total_duration && { total_duration: loopStats.total_duration }),
};
state.update(KEYS.CURRENT_SESSION, (session: ChatSession | null) => ({
...session,
@@ -1064,14 +1067,7 @@ async function sendMessageWithAgentLoop(text: string, currentSession: ChatSessio
updatedAt: Date.now()
}));
}
const perIterStats = {
eval_count: loopStats?.eval_count,
total_duration: (() => {
const dur = (Date.now() - lastIterationStartTime) * 1e6;
return dur > 0 ? dur : undefined;
})(),
};
updateLastAssistantMessage(assistantContent, thinkContent || null, perIterStats);
updateLastAssistantMessage(assistantContent, thinkContent || null, loopStats || null);
} else {
// 单迭代模式:正常保存
const assistantMsg: ChatMessage = {
@@ -1081,6 +1077,7 @@ async function sendMessageWithAgentLoop(text: string, currentSession: ChatSessio
...(thinkContent && { think: thinkContent }),
...(toolRecords?.length && { toolCalls: toolRecords }),
...(loopStats?.eval_count && { eval_count: loopStats.eval_count }),
...(loopStats?.prompt_eval_count && { prompt_eval_count: loopStats.prompt_eval_count }),
...(loopStats?.total_duration && { total_duration: loopStats.total_duration }),
};
state.update(KEYS.CURRENT_SESSION, (session: ChatSession | null) => ({