]> git.djapps.eu Git - pkg/ggml/sources/llama.cpp/blob
4bff25bb54cdab18b1fc752cfd245accee917958
[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 { BuiltInTool } from '$lib/enums';
7 import { FILE_PATH_SEPARATOR_REGEX } from '$lib/constants';
8 import { tryParseToolResultObject, type AgenticSection } from '$lib/utils';
9 import { parseToolArgs } from './_shared';
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 if (!args) return null;
28
29 const rawPath = args.path ?? args.file_path ?? args.filePath;
30 if (typeof rawPath !== 'string' || !rawPath) return null;
31
32 const fileName = rawPath.split(FILE_PATH_SEPARATOR_REGEX).pop() || rawPath;
33
34 // Filter the streamed edits array strictly: each entry must be an
35 // object with a non-empty `old_text`. Edits without an old_text
36 // would diff against empty and render as a full re-write.
37 const rawEdits = Array.isArray(args.edits) ? args.edits : [];
38 const edits: EditFileEdit[] = [];
39 for (const e of rawEdits) {
40 if (!e || typeof e !== 'object' || Array.isArray(e)) continue;
41 const obj = e as Record<string, unknown>;
42 const oldText = typeof obj.old_text === 'string' ? obj.old_text : '';
43 if (!oldText) continue;
44 const newText = typeof obj.new_text === 'string' ? obj.new_text : '';
45 edits.push({ oldText, newText });
46 }
47
48 const resultObj = tryParseToolResultObject(section.toolResult);
49 let resultMessage: string | undefined;
50 let editsApplied: number | undefined;
51 let errorMessage: string | undefined;
52 if (typeof resultObj?.error === 'string') {
53 errorMessage = resultObj.error;
54 } else if (resultObj) {
55 if (typeof resultObj.result === 'string') {
56 resultMessage = resultObj.result;
57 }
58 if (Number.isFinite(Number(resultObj.edits_applied))) {
59 editsApplied = Number(resultObj.edits_applied);
60 }
61 }
62
63 return {
64 fileName,
65 filePath: rawPath,
66 edits,
67 resultMessage,
68 editsApplied,
69 errorMessage
70 };
71 }