返回 DeepSeek-Reasonix
turnFiles.ts
根目录 / desktop / frontend / src / lib / turnFiles.ts
1 import type { Item } from "./useController";
2 import { fileIdentity } from "./filePaths";
3
4 type ToolItem = Extract<Item, { kind: "tool" }>;
5 export type TurnFileOperation = "written" | "modified";
6 export interface TurnFileView {
7 path: string;
8 toolCallId: string;
9 operation: TurnFileOperation;
10 }
11
12 const MUTATION_PATHS: Record<string, { field: string; operation: TurnFileOperation }> = {
13 write_file: { field: "path", operation: "written" },
14 edit_file: { field: "path", operation: "modified" },
15 multi_edit: { field: "path", operation: "modified" },
16 notebook_edit: { field: "path", operation: "modified" },
17 delete_range: { field: "path", operation: "modified" },
18 delete_symbol: { field: "path", operation: "modified" },
19 move_file: { field: "destination_path", operation: "written" },
20 };
21
22 export { fileIdentity };
23 /** Derive file facts only from successful native mutation tools. */
24 export function deriveTurnFiles(calls: readonly ToolItem[]): TurnFileView[] {
25 const files = new Map<string, TurnFileView>();
26 for (const call of calls) {
27 const definition = MUTATION_PATHS[call.name];
28 if (!definition || call.status !== "done" || call.error || call.readOnly) continue;
29 if (/\bno changes made\b/i.test(call.output ?? "")) continue;
30 let args: Record<string, unknown>;
31 try {
32 const parsed: unknown = JSON.parse(call.args || "{}");
33 if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) continue;
34 args = parsed as Record<string, unknown>;
35 } catch { continue; }
36 const path = args[definition.field];
37 if (typeof path !== "string" || !path.trim()) continue;
38 const key = fileIdentity(path);
39 if (!key) continue;
40 const existing = files.get(key);
41 const value = { path: path.trim(), toolCallId: call.id, operation: definition.operation };
42 if (existing) files.set(key, { ...value, path: existing.path });
43 else files.set(key, value);
44 }
45 return [...files.values()];
46 }
47
47 lines TYPESCRIPT