From bbce75fcda4b3db603bd747d157b885bf9cd0e7e Mon Sep 17 00:00:00 2001 From: LaoYueHanNi <597694450@qq.com> Date: Mon, 18 May 2026 10:00:57 +0800 Subject: [PATCH] =?UTF-8?q?fix(session):=20=E4=BF=AE=E5=A4=8Dsession=20log?= =?UTF-8?q?=E6=A8=A1=E5=BC=8F=E4=B8=8B=E5=AD=90Agent=20token=E7=BB=9F?= =?UTF-8?q?=E8=AE=A1=E9=81=97=E6=BC=8F=20(#2821)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(session): 修复session log模式下子Agent token统计遗漏 collect_jsonl_files() 只扫描了两层目录,遗漏了子Agent的JSONL日志文件, 导致子Agent的独立token使用数据完全未统计到session费用中。 (仅影响session log模式,proxy代理模式不受影响) * refactor(session): optimize collect_jsonl_files logic - Replace two independent if statements with if-else for mutually exclusive conditions - Remove unnecessary clone() when pushing file paths - Add clarifying comments for main session vs subagent files - Apply cargo fmt for consistent formatting Performance improvement: Eliminates redundant clone() operations when processing .jsonl files, as a path cannot be both a file and a directory. --------- Co-authored-by: Jason --- src-tauri/src/services/session_usage.rs | 44 ++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/src-tauri/src/services/session_usage.rs b/src-tauri/src/services/session_usage.rs index 254371c02..27f71700a 100644 --- a/src-tauri/src/services/session_usage.rs +++ b/src-tauri/src/services/session_usage.rs @@ -107,7 +107,11 @@ pub fn sync_claude_session_logs(db: &Database) -> Result Vec { let mut files = Vec::new(); @@ -126,7 +130,22 @@ fn collect_jsonl_files(projects_dir: &Path) -> Vec { for sub_entry in sub_entries.flatten() { let sub_path = sub_entry.path(); if sub_path.extension().and_then(|e| e.to_str()) == Some("jsonl") { + // 主会话 JSONL 文件 files.push(sub_path); + } else if sub_path.is_dir() { + // 扫描子 agent 目录: 项目/SESSION_ID/subagents/*.jsonl + let subagents_dir = sub_path.join("subagents"); + if subagents_dir.is_dir() { + if let Ok(agent_entries) = fs::read_dir(&subagents_dir) { + for agent_entry in agent_entries.flatten() { + let agent_path = agent_entry.path(); + if agent_path.extension().and_then(|e| e.to_str()) == Some("jsonl") + { + files.push(agent_path); + } + } + } + } } } } @@ -637,4 +656,27 @@ mod tests { Ok(()) } + + #[test] + fn test_collect_jsonl_files_includes_subagents() { + let tmp = std::env::temp_dir().join(format!("cc-switch-test-{}", uuid::Uuid::new_v4())); + let project = tmp.join("project"); + let session_dir = project.join("test-session"); + let subagents_dir = session_dir.join("subagents"); + fs::create_dir_all(&subagents_dir).unwrap(); + + fs::write(project.join("main.jsonl"), "{}").unwrap(); + fs::write(subagents_dir.join("agent-abc.jsonl"), "{}").unwrap(); + + let files = collect_jsonl_files(&tmp); + assert_eq!(files.len(), 2); + let paths: Vec = files + .iter() + .map(|p| p.to_string_lossy().to_string()) + .collect(); + assert!(paths.iter().any(|p| p.contains("main.jsonl"))); + assert!(paths.iter().any(|p| p.contains("agent-abc.jsonl"))); + + fs::remove_dir_all(&tmp).ok(); + } }