From 07ea0fcafbbfb1626368c6f3cb6969337819bbc3 Mon Sep 17 00:00:00 2001 From: Meleki Date: Wed, 4 Mar 2026 11:59:19 +0100 Subject: [PATCH] =?UTF-8?q?Zeilenreferenz-Hinweis=20(cat=20-n)=20aus=20Sys?= =?UTF-8?q?tem-Prompt=20entfernt=20und=20automatisch=20an=20User-Nachricht?= =?UTF-8?q?=20angeh=C3=A4ngt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - System-Prompt: 3x cat-n Hinweise entfernt (Workspace-Block, toolAny-Erinnerung, Workspace-Erinnerung) - chat.js: Tag mit cat-n Hinweis wird automatisch angehängt wenn Datei-Refs Zeilennummern haben - chat.js: Einzelne Zeilen (path:11) werden jetzt korrekt geparst und angezeigt - chat.css: hint Tag Styling, file-ref-chip Spacing angepasst --- Services/SystemPromptBuilder.cs | 19 +++---------------- wwwroot/css/chat.css | 10 ++++++++-- wwwroot/js/chat.js | 26 ++++++++++++++++++-------- 3 files changed, 29 insertions(+), 26 deletions(-) diff --git a/Services/SystemPromptBuilder.cs b/Services/SystemPromptBuilder.cs index 01a3caa..58be1c5 100644 --- a/Services/SystemPromptBuilder.cs +++ b/Services/SystemPromptBuilder.cs @@ -68,9 +68,7 @@ JEDE Datei-Operation und JEDER Shell-Befehl MUSS über einen Tool-Aufruf erfolge Du hast Tools zur Verfügung (read_file, write_file, edit_file, list_files, delete_file, execute). Benutze sie um Dateien zu lesen, schreiben und bearbeiten. Der Workspace-Pfad ist: `{session.Workspace}` -Alle Dateipfade in Tool-Aufrufen müssen relativ zu diesem Workspace sein oder absolute Pfade verwenden, die mit diesem Pfad beginnen. - -Wenn der User auf eine bestimmte Zeile in einer Datei verweist (z.B. `[Datei: foo.txt:11]`), zähle Leerzeilen immer mit. Verwende `cat -n` oder ein ähnliches Tool um Zeilennummern exakt zu bestimmen - NIEMALS Leerzeilen beim Zählen überspringen." +Alle Dateipfade in Tool-Aufrufen müssen relativ zu diesem Workspace sein oder absolute Pfade verwenden, die mit diesem Pfad beginnen." }); } @@ -193,21 +191,10 @@ Wenn der User auf eine bestimmte Zeile in einer Datei verweist (z.B. `[Datei: fo Icon = "fa-exclamation-circle", Label = "System · Erinnerung (Workspace + ToolChoice: any)", Content = @"## ERINNERUNG -Diese Regel hat höchste Priorität und gilt für JEDE Antwort: Wenn eine Datei gelesen, geschrieben, bearbeitet, erstellt oder gelöscht werden soll, oder ein Befehl ausgeführt werden soll, MUSS der entsprechende Tool-Aufruf erfolgen. Ohne Tool-Aufruf ist NICHTS passiert. Beschreibe keine Änderungen - führe sie durch. - -Bei Zeilenreferenzen (z.B. `[Datei: foo.txt:11]`) IMMER `cat -n` verwenden um die exakte Zeile zu bestimmen. NIEMALS Leerzeilen beim Zählen überspringen." - }); - } - else if (!string.IsNullOrWhiteSpace(session.Workspace)) - { - // Zeilenreferenz-Hinweis als eigener Erinnerungsblock wenn kein toolAny - blocks.Add(new PromptBlock - { - Icon = "fa-exclamation-circle", - Label = "System · Erinnerung (Workspace)", - Content = "## ERINNERUNG\nBei Zeilenreferenzen (z.B. `[Datei: foo.txt:11]`) IMMER `cat -n` verwenden um die exakte Zeile zu bestimmen. NIEMALS Leerzeilen beim Zählen überspringen." +Diese Regel hat höchste Priorität und gilt für JEDE Antwort: Wenn eine Datei gelesen, geschrieben, bearbeitet, erstellt oder gelöscht werden soll, oder ein Befehl ausgeführt werden soll, MUSS der entsprechende Tool-Aufruf erfolgen. Ohne Tool-Aufruf ist NICHTS passiert. Beschreibe keine Änderungen - führe sie durch." }); } + // kein extra Erinnerungsblock ohne toolAny – Zeilenreferenz-Hinweise kommen direkt über die Nachricht var marked = markedMessages?.Where(m => !string.IsNullOrWhiteSpace(m.Content)).ToList(); if (marked != null && marked.Count > 0) diff --git a/wwwroot/css/chat.css b/wwwroot/css/chat.css index a889b5d..de09a5e 100644 --- a/wwwroot/css/chat.css +++ b/wwwroot/css/chat.css @@ -88,6 +88,11 @@ word-break: break-word; } +.msg hint { + opacity: var(--semi-transparent); + font-size: var(--font-size); +} + .msg:not(.markdown) { white-space: pre-wrap; } @@ -610,8 +615,9 @@ .file-ref-chip { display: inline-flex; align-items: center; - gap: .3em; - padding: .15em .5em; + gap: var(--badge-spacing); + margin: 0 2px 3px 0; + padding: var(--badge-padding); background: var(--f2-bg); border: var(--border-width) solid var(--f2-border); border-radius: var(--border-radius); diff --git a/wwwroot/js/chat.js b/wwwroot/js/chat.js index 7125eb0..10e54d5 100644 --- a/wwwroot/js/chat.js +++ b/wwwroot/js/chat.js @@ -85,11 +85,18 @@ async function sendMessage() { // Refs in den Text einbauen if (pendingRefs.length > 0) { - const refTags = pendingRefs.map(r => { - if (r.from && r.to) return `[Datei: ${r.path}:${r.from}-${r.to}]`; + const refLines = pendingRefs.map(r => { + if (r.from && r.to && r.from !== r.to) return `[Datei: ${r.path}:${r.from}-${r.to}]`; + if (r.from) return `[Datei: ${r.path}:${r.from}]`; return `[Datei: ${r.path}]`; }); - msgText = refTags.join('\n') + (msgText ? '\n' + msgText : ''); + msgText = refLines.join(' ') + '\n' + msgText; + if (pendingRefs.some(r => r.from)) { + if (pendingRefs.length > 1) + msgText += `\nLies referenzierte Dateien mit \`cat -n\`.`; + else + msgText += `\nLies die referenzierte Datei mit \`cat -n\`.`; + } clearPendingRefs(); } @@ -330,10 +337,13 @@ function removePendingFile(index) { // ── Workspace Refs ── function addPendingRef(ref) { - // ref = "path" oder "path:from-to" - const match = ref.match(/^(.+?):(\d+)-(\d+)$/); - if (match) { - pendingRefs.push({ path: match[1], from: parseInt(match[2]), to: parseInt(match[3]) }); + // ref = "path", "path:line" oder "path:from-to" + const rangeMatch = ref.match(/^(.+?):(\d+)-(\d+)$/); + const lineMatch = !rangeMatch && ref.match(/^(.+?):(\d+)$/); + if (rangeMatch) { + pendingRefs.push({ path: rangeMatch[1], from: parseInt(rangeMatch[2]), to: parseInt(rangeMatch[3]) }); + } else if (lineMatch) { + pendingRefs.push({ path: lineMatch[1], from: parseInt(lineMatch[2]), to: parseInt(lineMatch[2]) }); } else { pendingRefs.push({ path: ref, from: null, to: null }); } @@ -361,7 +371,7 @@ function renderRefPreview() { } container.innerHTML = pendingRefs.map((r, i) => { - const label = r.from && r.to ? `${r.path}:${r.from}-${r.to}` : r.path; + const label = r.from && r.to && r.from !== r.to ? `${r.path}:${r.from}-${r.to}` : r.from ? `${r.path}:${r.from}` : r.path; return `
${esc(label)}