feat: Auto-Context im Frontend anzeigen und in DB persistieren
- recalled_context-Header verstärkt (klare Nutzungs-Anweisung statt passivem Hinweis) - SSE-Event 'auto_context' ans Frontend senden für Live-Anzeige - Auto-Context als Message (type=auto_context) in DB speichern - Aufklappbare Auto-Context-Box im Chat-Stream und History-Rendering Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
3f2baa1639
commit
9fe6bed59b
6 files changed
+67
-1
No files matched your search
@@ -64,7 +64,17 @@ public partial class AnthropicService
|
||||
{
|
||||
var autoCtx = await BuildAutoContextAsync(messages, chainId, agentId);
|
||||
if (autoCtx != null)
|
||||
{
|
||||
systemPrompt.Add(new { type = "text", text = autoCtx });
|
||||
await SseHelper.TryWriteSse(response, "auto_context", new { context = autoCtx }, sseCt);
|
||||
await _db.SaveMessage(new MessageRecord
|
||||
{
|
||||
ChainId = chainId,
|
||||
Role = "system",
|
||||
Type = "auto_context",
|
||||
Content = autoCtx
|
||||
});
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
@@ -190,7 +190,7 @@ public partial class AnthropicService
|
||||
|
||||
var ctxSb = new StringBuilder();
|
||||
ctxSb.AppendLine("\n<recalled_context>");
|
||||
ctxSb.AppendLine("Die folgende Information wurde automatisch abgerufen und könnte relevant sein:");
|
||||
ctxSb.AppendLine("WICHTIG: Der folgende Kontext wurde automatisch per Vektor-Suche aus früheren Gesprächen und Memory abgerufen. Prüfe diesen Kontext ZUERST, bevor du antwortest. Wenn er zur aktuellen Frage passt, beziehe dich aktiv darauf und nutze die Informationen in deiner Antwort. Ignoriere ihn nur, wenn er eindeutig irrelevant ist.");
|
||||
foreach (var r in contextResults)
|
||||
{
|
||||
var date = DateTime.TryParse(r.CreatedAt, out var dt) ? dt.ToString("yyyy-MM-dd HH:mm") : r.CreatedAt;
|
||||
|
||||
@@ -1136,6 +1136,18 @@
|
||||
padding: var(--box-padding);
|
||||
}
|
||||
|
||||
/* Auto-Context Bubble */
|
||||
|
||||
.auto-context-box .tool-box-header .tool-name {
|
||||
color: var(--info);
|
||||
}
|
||||
|
||||
.auto-context-box .auto-context-content {
|
||||
padding: var(--box-padding);
|
||||
font-size: 0.85em;
|
||||
opacity: 0.85;
|
||||
}
|
||||
|
||||
/* Review Bubbles */
|
||||
|
||||
.review-bubble {
|
||||
|
||||
@@ -127,6 +127,10 @@ function handleStreamEvent(eventType, data) {
|
||||
finalizeReviewBubble('done', data, 'finalizer');
|
||||
break;
|
||||
|
||||
case 'auto_context':
|
||||
addAutoContextBubble(data.context);
|
||||
break;
|
||||
|
||||
case 'info':
|
||||
addWarningBubble(data.message, true);
|
||||
break;
|
||||
|
||||
@@ -259,6 +259,24 @@ function _renderMessagesIntoFragment(fragment, msgs, imageMessageIds, opts) {
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'auto_context': {
|
||||
if (msg.content) {
|
||||
var acDiv = document.createElement('div');
|
||||
acDiv.className = 'tool-box auto-context-box' + (archived ? ' archived' : '');
|
||||
var acHeader = document.createElement('div');
|
||||
acHeader.className = 'tool-box-header clickable';
|
||||
acHeader.innerHTML = '<span class="tool-name">Auto-Context</span>';
|
||||
var acContent = document.createElement('div');
|
||||
acContent.className = 'auto-context-content';
|
||||
acContent.textContent = msg.content.replace(/<\/?recalled_context>/g, '').trim();
|
||||
acContent.hidden = true;
|
||||
acHeader.addEventListener('click', function() { acContent.hidden = !acContent.hidden; });
|
||||
acDiv.appendChild(acHeader);
|
||||
acDiv.appendChild(acContent);
|
||||
fragment.appendChild(acDiv);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'thinking': {
|
||||
if (msg.role === 'assistant' && msg.content) {
|
||||
var thinkDiv = document.createElement('div');
|
||||
|
||||
@@ -103,6 +103,28 @@ function endThinkingBubble() {
|
||||
_thinkingText = '';
|
||||
}
|
||||
|
||||
// ── Auto-Context Bubble ──
|
||||
|
||||
function addAutoContextBubble(contextText) {
|
||||
if (!contextText) return;
|
||||
var box = document.createElement('div');
|
||||
box.className = 'tool-box auto-context-box streamed';
|
||||
var header = document.createElement('div');
|
||||
header.className = 'tool-box-header clickable';
|
||||
header.innerHTML = '<span class="tool-name">Auto-Context</span>';
|
||||
var content = document.createElement('div');
|
||||
content.className = 'auto-context-content markdown';
|
||||
content.hidden = true;
|
||||
// recalled_context aus XML-Tags extrahieren
|
||||
var inner = contextText.replace(/<\/?recalled_context>/g, '').trim();
|
||||
content.innerHTML = renderMarkdown(inner);
|
||||
header.addEventListener('click', function() { content.hidden = !content.hidden; });
|
||||
box.appendChild(header);
|
||||
box.appendChild(content);
|
||||
chatEl().appendChild(box);
|
||||
scrollDown();
|
||||
}
|
||||
|
||||
// ── Review Bubbles (Streaming) ──
|
||||
|
||||
let _reviewBubble = null;
|
||||
|
||||
Reference in new issue
Block a user