Chat: User-Nachrichten [Datei:]-Tags als klickbare Chips rendern, System-Prompt mit Workspace-Pfad und Leerzeilen-Hinweis erweitern

This commit is contained in:
Meleki committed 2026-02-28 11:53:50 +01:00
1 parent bba82aad7e
commit 3cb468f4e8
5 files changed
+75 -4

No files matched your search

+18 -1
View File
@@ -78,15 +78,32 @@ public static class ChatEndpoint
var promptParts = new List<string>();
promptParts.Add($"Du bist {agent.Name}.");
if (!string.IsNullOrWhiteSpace(agent.Persona))
{
promptParts.Add($"## Persona\n{agent.Persona}");
}
if (!string.IsNullOrWhiteSpace(agent.Instructions))
{
promptParts.Add($"## Instructions\n{agent.Instructions}");
}
if (!string.IsNullOrWhiteSpace(session.Workspace))
promptParts.Add("## Tools\nDu 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. Beschreibe NICHT was du tun würdest - tu es einfach über die Tools.");
{
promptParts.Add(@$"## Tools
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.");
}
if (!string.IsNullOrWhiteSpace(session.Context))
{
promptParts.Add($"## Kontext\n{session.Context}");
}
var systemPromptText = string.Join("\n\n", promptParts);
+2 -1
View File
@@ -12,4 +12,5 @@
## Frontend
- [ ] Chat: Es scrollt beim Laden nicht ganz nach unten, ich denke weil im DOM noch etwas nachgeladen wird (ich denke es ist die Schriftart), und die Höhe sich beim Laden nochmal verändert
- [ ] Chat: User-Nachrichten mit dem Tag [Datei: pfat/zur/datei.xyz:1-10] wird nicht als HTML geparsed
- [x] Chat: User-Nachrichten mit dem Tag [Datei: pfat/zur/datei.xyz:1-10] wird nicht als HTML geparsed
- [ ] Chat: Wird zwar erkannt und ist klickbar, aber es öffnet sich einfach nur der File Explorer, ohne dass sich die Datei öffnet und die Darstellung in Monospace ist auch nicht schön
+18
View File
@@ -328,6 +328,24 @@
opacity: 1;
}
/* File Ref Chips in User-Bubbles */
.file-ref-chip {
display: inline-block;
padding: var(--badge-padding);
background: var(--f2-bg);
border: var(--border-width) solid var(--f2-border);
border-radius: var(--border-radius);
font-family: var(--mono);
font-size: .85em;
white-space: nowrap;
}
.file-ref-chip:hover {
border-color: var(--f3-border);
background: var(--f3-bg);
}
/* Attachments in History */
.attachment-indicator {
+1 -1
View File
@@ -112,7 +112,7 @@ async function loadLatestArchive() {
case 'text':
if (msg.role === 'user') {
div.className = 'msg user archived';
div.textContent = (msg.content || '').trim();
renderUserContent(div, msg.content);
} else {
div.className = 'msg assistant markdown archived';
div.innerHTML = renderMarkdown(msg.content);
+36 -1
View File
@@ -30,11 +30,46 @@ function truncate(s, max) {
// ── Message Bubbles ──
function renderUserContent(container, text) {
const raw = (text || '').trim();
// [Datei: path] oder [Datei: path:1-10] erkennen
const pattern = /\[Datei: ([^\]]+)\]/g;
let last = 0;
let match;
const frag = document.createDocumentFragment();
while ((match = pattern.exec(raw)) !== null) {
// Text vor dem Tag
if (match.index > last) {
frag.appendChild(document.createTextNode(raw.slice(last, match.index)));
}
const ref = match[1]; // z.B. "src/foo.cs:10-25"
const chip = document.createElement('span');
chip.className = 'file-ref-chip';
chip.textContent = match[0];
chip.title = ref;
chip.style.cursor = 'pointer';
chip.addEventListener('click', () => {
openFileExplorer({ sessionId: getCurrentSessionId() });
});
frag.appendChild(chip);
last = match.index + match[0].length;
}
// Resttext
if (last < raw.length) {
frag.appendChild(document.createTextNode(raw.slice(last)));
}
container.appendChild(frag);
}
function addUserBubble(text, streamed = false) {
const div = document.createElement('div');
div.className = 'msg user';
if (streamed) div.classList.add('streamed');
div.textContent = (text || '').trim();
renderUserContent(div, text);
chatEl().appendChild(div);
scrollDown();
}