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