Auto-Context: Semantische Kontext-Injektion, Memory-File-Embeddings, Agent-Toggle
- Automatische Embedding-basierte Kontext-Injektion vor jeder API-Anfrage (Top 5 Chat-Ergebnisse + Top 3 Memory-File-Treffer als recalled_context) - Memory-Dateien (.md) werden embedded (Backfill + Live nach memory_write) - Neue Agent-Option 'useAutoContext' (Checkbox, Default: aktiviert) - VectorSearchService: SearchMemoryFilesAsync, EmbedMemoryFileAsync, Chunking - EmbeddingBackgroundService: Memory-File-Backfill + EnqueueMemoryFile - ToolService: memory_write löst Re-Embedding aus - embeddingBg Parameter an ExecuteTool durchgereicht
This commit is contained in:
1 parent
add111ffe1
commit
148d1459a3
11 files changed
+305
-12
No files matched your search
@@ -55,6 +55,7 @@ public class AnthropicService
|
||||
SubAgentContext finalizer = null,
|
||||
bool allowUserChoice = true,
|
||||
bool planMode = false,
|
||||
bool useAutoContext = true,
|
||||
CancellationToken workCt = default,
|
||||
CancellationToken hardCt = default,
|
||||
CancellationToken sseCt = default,
|
||||
@@ -76,6 +77,46 @@ public class AnthropicService
|
||||
|
||||
try
|
||||
{
|
||||
// ── Automatische Kontext-Injektion via Embedding-Suche ──
|
||||
if (useAutoContext && _vectorSearch != null && systemPrompt != null && messages.Count > 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Letzte User-Message als Query extrahieren
|
||||
var lastUserText = ExtractLastUserText(messages);
|
||||
if (!string.IsNullOrWhiteSpace(lastUserText))
|
||||
{
|
||||
var contextResults = await _vectorSearch.SearchAsync(lastUserText, agentId, topN: 5, minScore: 0.45f);
|
||||
// Nur Ergebnisse aus anderen Sessions (nicht aktuelle Chain) und nicht zu kurze
|
||||
contextResults.RemoveAll(r => r.ChainId == chainId || (r.TextPreview?.Length ?? 0) < 20);
|
||||
// Memory-Dateien durchsuchen
|
||||
var memoryResults = await _vectorSearch.SearchMemoryFilesAsync(lastUserText, agentId, topN: 3, minScore: 0.45f);
|
||||
|
||||
if (contextResults.Count > 0 || memoryResults.Count > 0)
|
||||
{
|
||||
var ctxSb = new StringBuilder();
|
||||
ctxSb.AppendLine("\n<recalled_context>");
|
||||
ctxSb.AppendLine("Die folgende Information wurde automatisch abgerufen und könnte relevant sein:");
|
||||
foreach (var r in contextResults)
|
||||
{
|
||||
var date = DateTime.TryParse(r.CreatedAt, out var dt) ? dt.ToString("yyyy-MM-dd HH:mm") : r.CreatedAt;
|
||||
ctxSb.AppendLine($"- [Gespräch, {r.Role}, {date}]: {r.TextPreview}");
|
||||
}
|
||||
foreach (var r in memoryResults)
|
||||
{
|
||||
ctxSb.AppendLine($"- [Memory, {r.FilePath}]: {r.TextPreview}");
|
||||
}
|
||||
ctxSb.AppendLine("</recalled_context>");
|
||||
systemPrompt.Add(new { type = "text", text = ctxSb.ToString() });
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"[AutoContext] Error: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
while (iterations < maxIterations)
|
||||
{
|
||||
// Hard-Stop: Sofortiger Abbruch aus while-Loop (Doppel-Klick Stop)
|
||||
@@ -838,7 +879,7 @@ public class AnthropicService
|
||||
|
||||
string toolResult;
|
||||
bool isError = false;
|
||||
try { toolResult = await _toolService.ExecuteTool(toolName, toolInput, agentWorkspace, _memoryService, agentId, workCt, vectorSearch: _vectorSearch); }
|
||||
try { toolResult = await _toolService.ExecuteTool(toolName, toolInput, agentWorkspace, _memoryService, agentId, workCt, vectorSearch: _vectorSearch, embeddingBg: _embeddingBg); }
|
||||
catch (OperationCanceledException) { throw; }
|
||||
catch (Exception ex) { toolResult = $"Fehler: {ex.Message}"; isError = true; }
|
||||
|
||||
@@ -1044,7 +1085,7 @@ public class AnthropicService
|
||||
|
||||
string toolResult;
|
||||
bool isError = false;
|
||||
try { toolResult = await _toolService.ExecuteTool(toolName, toolInput, ctx.Workspace, _memoryService, ctx.AgentId, vectorSearch: _vectorSearch); }
|
||||
try { toolResult = await _toolService.ExecuteTool(toolName, toolInput, ctx.Workspace, _memoryService, ctx.AgentId, vectorSearch: _vectorSearch, embeddingBg: _embeddingBg); }
|
||||
catch (OperationCanceledException) { throw; }
|
||||
catch (Exception ex) { toolResult = $"Fehler: {ex.Message}"; isError = true; }
|
||||
|
||||
@@ -1345,7 +1386,7 @@ public class AnthropicService
|
||||
|
||||
string toolResult;
|
||||
bool isError = false;
|
||||
try { toolResult = await _toolService.ExecuteTool(currentToolName, inputEl, workspace, _memoryService, agentId, workCt, remoteMgr: remoteMgr, sessionId: sessionId, vectorSearch: _vectorSearch); }
|
||||
try { toolResult = await _toolService.ExecuteTool(currentToolName, inputEl, workspace, _memoryService, agentId, workCt, remoteMgr: remoteMgr, sessionId: sessionId, vectorSearch: _vectorSearch, embeddingBg: _embeddingBg); }
|
||||
catch (OperationCanceledException) { throw; }
|
||||
catch (Exception ex) { toolResult = $"Fehler: {ex.Message}"; isError = true; }
|
||||
|
||||
@@ -1468,6 +1509,35 @@ public class AnthropicService
|
||||
: result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extrahiert den Text der letzten User-Message aus der Message-Liste.
|
||||
/// </summary>
|
||||
private static string ExtractLastUserText(List<object> messages)
|
||||
{
|
||||
for (int i = messages.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var json = JsonSerializer.Serialize(messages[i]);
|
||||
var el = JsonSerializer.Deserialize<JsonElement>(json);
|
||||
if (!el.TryGetProperty("role", out var role) || role.GetString() != "user") continue;
|
||||
if (!el.TryGetProperty("content", out var content)) continue;
|
||||
|
||||
if (content.ValueKind == JsonValueKind.String)
|
||||
return content.GetString();
|
||||
|
||||
if (content.ValueKind == JsonValueKind.Array)
|
||||
{
|
||||
foreach (var block in content.EnumerateArray())
|
||||
{
|
||||
var type = block.TryGetProperty("type", out var t) ? t.GetString() : "";
|
||||
if (type == "text" && block.TryGetProperty("text", out var txt))
|
||||
return txt.GetString();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extrahiert Web-Search-Sources aus einem web_search_tool_result-Block.
|
||||
/// </summary>
|
||||
|
||||
Reference in new issue
Block a user