mirror of
https://github.com/farion1231/cc-switch.git
synced 2026-07-25 13:45:03 +08:00
feat(usage): add Hermes Agent tracking + fix zero-cost bug + perf
Hermes: - Parse ~/.hermes/state.db sessions (incl. profiles/*/state.db) into proxy_request_logs with data_source='hermes_session', WAL-aware incremental sync, Hermes-reported cost preferred over model_pricing fallback Zero-cost bug (dashboard showed \$0 totals): - GPT-5.5 family default pricing (~83% of affected rows used GPT-5.5) - find_model_pricing_row: ASCII-lowercase normalization so "OpenAI/GPT-5.5@HIGH" matches seeded "gpt-5.5" - Startup cost backfill in async task: scan rows where total_cost <= 0 but tokens > 0, recompute via model_pricing in a single transaction Performance: - Add (app_type, created_at DESC) covering index for dashboard range queries - Add expression index on COALESCE(data_source, 'proxy') so dedup EXISTS subqueries use index lookup instead of full scan; drop superseded idx_request_logs_dedup_lookup Refactor: - row_to_request_log_detail helper (3-way de-dup; fixes cost_multiplier \"1\" vs \"1.0\" drift between callers) - Promote get_sync_state/update_sync_state to shared session_usage module (4 copies -> 1) - run_step helper in lib.rs replaces 9 if-let-Err blocks - maybe_backfill_log_costs returns bool to skip duplicate total_cost parsing in caller
This commit is contained in:
@@ -17,6 +17,7 @@ const DATA_SOURCE_ICONS: Record<string, React.ReactNode> = {
|
||||
codex_db: <Database className="h-3.5 w-3.5" />,
|
||||
codex_session: <FileText className="h-3.5 w-3.5" />,
|
||||
gemini_session: <FileText className="h-3.5 w-3.5" />,
|
||||
hermes_session: <Database className="h-3.5 w-3.5" />,
|
||||
};
|
||||
|
||||
export function DataSourceBar({ refreshIntervalMs }: DataSourceBarProps) {
|
||||
|
||||
@@ -141,6 +141,7 @@ export function RequestLogTable({
|
||||
<SelectItem value="claude">Claude</SelectItem>
|
||||
<SelectItem value="codex">Codex</SelectItem>
|
||||
<SelectItem value="gemini">Gemini</SelectItem>
|
||||
<SelectItem value="hermes">Hermes</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@ const APP_FILTER_OPTIONS: AppTypeFilter[] = [
|
||||
"claude",
|
||||
"codex",
|
||||
"gemini",
|
||||
"hermes",
|
||||
];
|
||||
|
||||
export function UsageDashboard() {
|
||||
|
||||
@@ -1120,7 +1120,8 @@
|
||||
"all": "All",
|
||||
"claude": "Claude Code",
|
||||
"codex": "Codex",
|
||||
"gemini": "Gemini"
|
||||
"gemini": "Gemini",
|
||||
"hermes": "Hermes"
|
||||
},
|
||||
"dataSources": "Data Sources",
|
||||
"dataSource": {
|
||||
@@ -1128,7 +1129,8 @@
|
||||
"session_log": "Session Log",
|
||||
"codex_db": "Codex DB",
|
||||
"codex_session": "Codex Session",
|
||||
"gemini_session": "Gemini Session"
|
||||
"gemini_session": "Gemini Session",
|
||||
"hermes_session": "Hermes Session"
|
||||
},
|
||||
"sessionSync": {
|
||||
"trigger": "Sync session logs",
|
||||
|
||||
@@ -1120,7 +1120,8 @@
|
||||
"all": "すべて",
|
||||
"claude": "Claude Code",
|
||||
"codex": "Codex",
|
||||
"gemini": "Gemini"
|
||||
"gemini": "Gemini",
|
||||
"hermes": "Hermes"
|
||||
},
|
||||
"dataSources": "データソース",
|
||||
"dataSource": {
|
||||
@@ -1128,7 +1129,8 @@
|
||||
"session_log": "セッションログ",
|
||||
"codex_db": "Codex DB",
|
||||
"codex_session": "Codex セッション",
|
||||
"gemini_session": "Gemini セッション"
|
||||
"gemini_session": "Gemini セッション",
|
||||
"hermes_session": "Hermes セッション"
|
||||
},
|
||||
"sessionSync": {
|
||||
"trigger": "セッションログを同期",
|
||||
|
||||
@@ -1120,7 +1120,8 @@
|
||||
"all": "全部",
|
||||
"claude": "Claude Code",
|
||||
"codex": "Codex",
|
||||
"gemini": "Gemini"
|
||||
"gemini": "Gemini",
|
||||
"hermes": "Hermes"
|
||||
},
|
||||
"dataSources": "数据来源",
|
||||
"dataSource": {
|
||||
@@ -1128,7 +1129,8 @@
|
||||
"session_log": "会话日志",
|
||||
"codex_db": "Codex 数据库",
|
||||
"codex_session": "Codex 会话日志",
|
||||
"gemini_session": "Gemini 会话日志"
|
||||
"gemini_session": "Gemini 会话日志",
|
||||
"hermes_session": "Hermes 会话日志"
|
||||
},
|
||||
"sessionSync": {
|
||||
"trigger": "同步会话日志",
|
||||
|
||||
+1
-1
@@ -129,7 +129,7 @@ export interface UsageRangeSelection {
|
||||
customEndDate?: number;
|
||||
}
|
||||
|
||||
export type AppTypeFilter = "all" | "claude" | "codex" | "gemini";
|
||||
export type AppTypeFilter = "all" | "claude" | "codex" | "gemini" | "hermes";
|
||||
|
||||
export interface StatsFilters {
|
||||
timeRange: UsageRangePreset;
|
||||
|
||||
Reference in New Issue
Block a user