Chat: User-Nachrichten [Datei:]-Tags als klickbare Chips rendern, System-Prompt mit Workspace-Pfad und Leerzeilen-Hinweis erweitern
This commit is contained in:
1 parent
bba82aad7e
commit
3cb468f4e8
5 files changed
+75
-4
No files matched your search
@@ -78,15 +78,32 @@ public static class ChatEndpoint
|
|||||||
|
|
||||||
var promptParts = new List<string>();
|
var promptParts = new List<string>();
|
||||||
promptParts.Add($"Du bist {agent.Name}.");
|
promptParts.Add($"Du bist {agent.Name}.");
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(agent.Persona))
|
if (!string.IsNullOrWhiteSpace(agent.Persona))
|
||||||
|
{
|
||||||
promptParts.Add($"## Persona\n{agent.Persona}");
|
promptParts.Add($"## Persona\n{agent.Persona}");
|
||||||
|
}
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(agent.Instructions))
|
if (!string.IsNullOrWhiteSpace(agent.Instructions))
|
||||||
|
{
|
||||||
promptParts.Add($"## Instructions\n{agent.Instructions}");
|
promptParts.Add($"## Instructions\n{agent.Instructions}");
|
||||||
|
}
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(session.Workspace))
|
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))
|
if (!string.IsNullOrWhiteSpace(session.Context))
|
||||||
|
{
|
||||||
promptParts.Add($"## Kontext\n{session.Context}");
|
promptParts.Add($"## Kontext\n{session.Context}");
|
||||||
|
}
|
||||||
|
|
||||||
var systemPromptText = string.Join("\n\n", promptParts);
|
var systemPromptText = string.Join("\n\n", promptParts);
|
||||||
|
|
||||||
|
|||||||
@@ -12,4 +12,5 @@
|
|||||||
|
|
||||||
## Frontend
|
## 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: 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
|
||||||
@@ -328,6 +328,24 @@
|
|||||||
opacity: 1;
|
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 */
|
/* Attachments in History */
|
||||||
|
|
||||||
.attachment-indicator {
|
.attachment-indicator {
|
||||||
|
|||||||
@@ -112,7 +112,7 @@ async function loadLatestArchive() {
|
|||||||
case 'text':
|
case 'text':
|
||||||
if (msg.role === 'user') {
|
if (msg.role === 'user') {
|
||||||
div.className = 'msg user archived';
|
div.className = 'msg user archived';
|
||||||
div.textContent = (msg.content || '').trim();
|
renderUserContent(div, msg.content);
|
||||||
} else {
|
} else {
|
||||||
div.className = 'msg assistant markdown archived';
|
div.className = 'msg assistant markdown archived';
|
||||||
div.innerHTML = renderMarkdown(msg.content);
|
div.innerHTML = renderMarkdown(msg.content);
|
||||||
|
|||||||
+36
-1
@@ -30,11 +30,46 @@ function truncate(s, max) {
|
|||||||
|
|
||||||
// ── Message Bubbles ──
|
// ── 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) {
|
function addUserBubble(text, streamed = false) {
|
||||||
const div = document.createElement('div');
|
const div = document.createElement('div');
|
||||||
div.className = 'msg user';
|
div.className = 'msg user';
|
||||||
if (streamed) div.classList.add('streamed');
|
if (streamed) div.classList.add('streamed');
|
||||||
div.textContent = (text || '').trim();
|
renderUserContent(div, text);
|
||||||
chatEl().appendChild(div);
|
chatEl().appendChild(div);
|
||||||
scrollDown();
|
scrollDown();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user