]> git.djapps.eu Git - pkg/ggml/sources/llama.cpp/blob
6f30060f54c450aa467da560c9862e8a9ad32b84
[pkg/ggml/sources/llama.cpp] /
1 <script lang="ts">
2 import { XCircle } from '@lucide/svelte';
3 import { MAX_HEIGHT_CODE_BLOCK, RESULT_STAT_SEPARATOR } from '$lib/constants';
4 import { computeLineDiff, prefixFor, type AgenticSection } from '$lib/utils';
5 import { parseEditFileMeta } from './parsers/edit-file';
6 import ToolCallBlock from './ToolCallBlock.svelte';
7
8 interface Props {
9 section: AgenticSection;
10 open: boolean;
11 isStreaming: boolean;
12 onToggle?: () => void;
13 }
14
15 let { section, open, isStreaming, onToggle }: Props = $props();
16
17 const editFileMeta = $derived(parseEditFileMeta(section));
18
19 const editDiffs = $derived(
20 (editFileMeta?.edits ?? []).map((edit) => computeLineDiff(edit.oldText, edit.newText))
21 );
22 </script>
23
24 <ToolCallBlock {section} {open} {isStreaming} meta={editFileMeta} {onToggle}>
25 {#snippet titleSnippet()}
26 <span class="text-muted-foreground">Edit file </span>
27 <span class="font-mono">{editFileMeta?.filePath}</span>
28 {#if editFileMeta?.errorMessage}
29 <span class="ml-1 text-xs italic text-muted-foreground/70">(failed)</span>
30 {/if}
31 {/snippet}
32
33 {#snippet children(meta, _ctx)}
34 {#if meta?.errorMessage}
35 <div
36 class="flex items-start gap-2 rounded bg-red-500/10 p-2 text-xs text-red-600 italic dark:text-red-400"
37 >
38 <XCircle class="mt-0.5 h-3 w-3 shrink-0" />
39 <span>{meta.errorMessage}</span>
40 </div>
41 {:else if meta && meta.edits.length > 0}
42 {#each editDiffs as diffLines, ei (ei)}
43 <div class={ei === 0 ? '' : 'mt-3'}>
44 <div class="mb-1.5 text-xs text-muted-foreground/70 italic">
45 Edit {ei + 1}&nbsp;of&nbsp;{meta.edits.length}
46 </div>
47 <div class="diff-block" style:max-height={MAX_HEIGHT_CODE_BLOCK}>
48 <div class="diff-pre">
49 {#each diffLines as line, li (li)}
50 <div class="diff-line diff-{line.kind}">
51 <span class="diff-old-num">{line.oldLine ?? ''}</span>
52 <span class="diff-marker">{prefixFor(line.kind)}</span>
53 <span class="diff-new-num">{line.newLine ?? ''}</span>
54 <span class="diff-text">{line.text || ' '}</span>
55 </div>
56 {/each}
57 </div>
58 </div>
59 </div>
60 {/each}
61 <div class="mt-1.5 text-xs text-muted-foreground/70 italic">
62 {#if meta.resultMessage}
63 {meta.resultMessage}{meta.editsApplied != null ? RESULT_STAT_SEPARATOR : ''}{/if}
64 {#if meta.editsApplied != null}
65 <span class="font-mono">{meta.editsApplied}</span>
66 {meta.editsApplied === 1 ? 'edit' : 'edits'}&nbsp;applied
67 {/if}
68 </div>
69 {:else}
70 <div class="rounded bg-muted/20 p-2 text-xs text-muted-foreground/70 italic">No edits</div>
71 {/if}
72 {/snippet}
73 </ToolCallBlock>
74
75 <style>
76 .diff-block {
77 overflow: auto;
78 border-radius: 0.75rem;
79 border-width: 1px;
80 border-color: color-mix(in oklch, var(--border) 30%, transparent);
81 background: var(--code-background);
82 box-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);
83 }
84
85 :global(.dark) .diff-block {
86 border-color: color-mix(in oklch, var(--border) 20%, transparent);
87 }
88
89 /* Each row is a 4-column grid: old-line#, marker, new-line#, text.
90 * The gutters stay fixed-width so the text column lines up unversally. */
91 .diff-line {
92 display: grid;
93 grid-template-columns: 3.25rem 1.5rem 3.25rem 1fr;
94 font-family: var(--font-mono);
95 font-size: 11px;
96 line-height: 1.65;
97 align-items: stretch;
98 }
99
100 .diff-old-num,
101 .diff-new-num {
102 text-align: right;
103 padding-right: 0.5rem;
104 user-select: none;
105 color: color-mix(in oklch, var(--muted-foreground) 70%, transparent);
106 font-variant-numeric: tabular-nums;
107 }
108
109 .diff-marker {
110 text-align: center;
111 color: color-mix(in oklch, var(--muted-foreground) 70%, transparent);
112 user-select: none;
113 }
114
115 .diff-line.diff-add {
116 background-color: #f0fff4;
117 color: #22863a;
118 }
119 .diff-line.diff-add .diff-new-num,
120 .diff-line.diff-add .diff-marker {
121 color: #22863a;
122 }
123
124 .diff-line.diff-remove {
125 background-color: #ffeef0;
126 color: #b31d28;
127 }
128 .diff-line.diff-remove .diff-old-num,
129 .diff-line.diff-remove .diff-marker {
130 color: #b31d28;
131 }
132
133 .diff-line.diff-add .diff-old-num,
134 .diff-line.diff-remove .diff-new-num {
135 /* Empty gutter columns for add/remove rows mirror git unification
136 * (added lines don't have an old number, removed lines don't have a
137 * new number). Keep them visible so columns stay aligned across
138 * mixed rows. */
139 opacity: 0;
140 }
141
142 .diff-text {
143 padding-left: 0.4rem;
144 padding-right: 0.5rem;
145 white-space: pre;
146 overflow-x: auto;
147 min-width: 0;
148 }
149
150 :global(.dark) .diff-line.diff-add {
151 background-color: #033a16;
152 color: #aff5b4;
153 }
154 :global(.dark) .diff-line.diff-add .diff-new-num,
155 :global(.dark) .diff-line.diff-add .diff-marker {
156 color: #aff5b4;
157 }
158 :global(.dark) .diff-line.diff-remove {
159 background-color: #67060c;
160 color: #ffdcd7;
161 }
162 :global(.dark) .diff-line.diff-remove .diff-old-num,
163 :global(.dark) .diff-line.diff-remove .diff-marker {
164 color: #ffdcd7;
165 }
166 </style>