diff --git a/apps/ai-game-creator-shell/src-tauri/src/agent/direct_tool_calls.rs b/apps/ai-game-creator-shell/src-tauri/src/agent/direct_tool_calls.rs index 72bd90dfb..005e9e333 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/agent/direct_tool_calls.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/agent/direct_tool_calls.rs @@ -1277,4 +1277,35 @@ mod tests { "回读必须按时间正序" ); } + + /// 判据:项目内路径的 `\` / `/` 两种写法与大小写变体都要落成同一份项目相对路径 + /// (Codex 上报的路径分隔符与盘符大小写不受我们控制)。 + #[test] + fn tool_call_paths_normalize_separators_and_case() { + let root = init_tool_call_project("tool-call-path-variants"); + let native = root.path().to_string_lossy().to_string(); + let variants = [native.replace('\\', "/"), native.to_ascii_uppercase()]; + let mut paths = Vec::new(); + for (index, variant) in variants.into_iter().enumerate() { + let call = direct_tool_call_from_item( + root.path(), + &json!({ + "id": format!("item-path-variant-{index}"), + "type": "fileChange", + "changes": [{"path": format!("{variant}/game/src/y.ts"), "kind": "update"}], + "startedAtMs": 1000, + }), + "turn-1", + false, + 1000, + ) + .expect("variant path tool call"); + paths.push(call.detail.changes[0].path.clone()); + } + assert_eq!(paths[0], "game/src/y.ts", "`/` 写法同样要落成项目相对路径"); + assert_eq!( + paths[1], "game/src/y.ts", + "大小写变体同样要落成项目相对路径" + ); + } }