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