]> git.djapps.eu Git - pkg/ggml/sources/llama.cpp/blob
0c1fb9e432d9274bd231f30fd23c150ae1a85859
[pkg/ggml/sources/llama.cpp] /
1 // Meta parser for `edit_file` tool calls. Reads the file path and the
2 // array of edits from the streamed args (partial JSON for incremental
3 // rendering), plus the result blob for `result` / `edits_applied` /
4 // `error` fields.
5
6 import { parseToolArgs } from './_shared';
7 import { FILE_PATH_SEPARATOR_REGEX } from '$lib/constants';
8 import { BuiltInTool } from '$lib/enums';
9 import { type AgenticSection, tryParseToolResultObject } from '$lib/utils';
10
11 export type EditFileEdit = {
12 oldText: string;
13 newText: string;
14 };
15
16 export type EditFileMeta = {
17 fileName: string;
18 filePath: string;
19 edits: EditFileEdit[];
20 resultMessage?: string;
21 editsApplied?: number;
22 errorMessage?: string;
23 };
24
25 export function parseEditFileMeta(section: AgenticSection): EditFileMeta | null {
26 const args = parseToolArgs(BuiltInTool.EDIT_FILE, section, { partial: true });
27
28 if (!args) return null;
29
30 const rawPath = args.path ?? args.file_path ?? args.filePath;
31
32 if (typeof rawPath !== 'string' || !rawPath) return null;
33
34 const fileName = rawPath.split(FILE_PATH_SEPARATOR_REGEX).pop() || rawPath;
35 // Filter the streamed edits array strictly: each entry must be an
36 // object with a non-empty `old_text`. Edits without an old_text
37 // would diff against empty and render as a full re-write.
38 const rawEdits = Array.isArray(args.edits) ? args.edits : [];
39 const edits: EditFileEdit[] = [];
40
41 for (const e of rawEdits) {
42 if (!e || typeof e !== 'object' || Array.isArray(e)) continue;
43
44 const obj = e as Record<string, unknown>;
45 const oldText = typeof obj.old_text === 'string' ? obj.old_text : '';
46
47 if (!oldText) continue;
48
49 const newText = typeof obj.new_text === 'string' ? obj.new_text : '';
50
51 edits.push({ newText, oldText });
52 }
53
54 const resultObj = tryParseToolResultObject(section.toolResult);
55
56 let resultMessage: string | undefined;
57 let editsApplied: number | undefined;
58 let errorMessage: string | undefined;
59
60 if (typeof resultObj?.error === 'string') {
61 errorMessage = resultObj.error;
62 } else if (resultObj) {
63 if (typeof resultObj.result === 'string') {
64 resultMessage = resultObj.result;
65 }
66
67 if (Number.isFinite(Number(resultObj.edits_applied))) {
68 editsApplied = Number(resultObj.edits_applied);
69 }
70 }
71
72 return {
73 edits,
74 editsApplied,
75 errorMessage,
76 fileName,
77 filePath: rawPath,
78 resultMessage
79 };
80 }