feat: Memory-System mit persistenten Markdown-Dateien pro Agent
- MemoryService: Verwaltet data/agents/{agentId}/ Verzeichnisse
- MEMORY.md als Haupt-Memory-File
- memory/ Unterordner für Tages-Logs und thematische Notizen
- Sandbox-Prüfung verhindert Zugriff außerhalb des Agent-Dirs
- Memory-Tools für den Agent:
- memory_read: Liest Memory-Dateien
- memory_write: Schreibt/überschreibt oder hängt an (append)
- memory_list: Listet alle Memory-Dateien auf
- SystemPromptBuilder: Memory-Abschnitt mit Regeln und aktuellem
MEMORY.md-Inhalt wird in den System-Prompt injiziert
- ToolService/AnthropicService: Memory-Tools werden automatisch
eingebunden wenn MemoryService und AgentId verfügbar sind
- TODO.md: Embedding-basierte Suche und Subagents als Features
This commit is contained in:
1 parent
875229964c
commit
d913557173
8 files changed
+250
-14
No files matched your search
+98
-2
@@ -11,7 +11,21 @@ namespace Gott.Services;
|
||||
|
||||
public class ToolService
|
||||
{
|
||||
public object[] GetToolDefinitions()
|
||||
public object[] GetToolDefinitions(bool includeMemory = false)
|
||||
{
|
||||
var tools = GetFileTools();
|
||||
if (includeMemory)
|
||||
{
|
||||
var memTools = GetMemoryToolDefinitions();
|
||||
var all = new object[tools.Length + memTools.Length];
|
||||
tools.CopyTo(all, 0);
|
||||
memTools.CopyTo(all, tools.Length);
|
||||
return all;
|
||||
}
|
||||
return tools;
|
||||
}
|
||||
|
||||
private object[] GetFileTools()
|
||||
{
|
||||
return new object[]
|
||||
{
|
||||
@@ -105,7 +119,58 @@ public class ToolService
|
||||
};
|
||||
}
|
||||
|
||||
public async Task<string> ExecuteTool(string name, JsonElement input, string workspace)
|
||||
private object[] GetMemoryToolDefinitions()
|
||||
{
|
||||
return new object[]
|
||||
{
|
||||
new
|
||||
{
|
||||
name = "memory_read",
|
||||
description = "Liest eine Memory-Datei des Agents. Nutze dies um gespeicherte Erinnerungen, Notizen oder Kontextinformationen abzurufen.",
|
||||
input_schema = new
|
||||
{
|
||||
type = "object",
|
||||
properties = new Dictionary<string, object>
|
||||
{
|
||||
["path"] = new { type = "string", description = "Relativer Pfad zur Memory-Datei (z.B. 'MEMORY.md' oder 'memory/2025-01-15.md')" }
|
||||
},
|
||||
required = new[] { "path" }
|
||||
}
|
||||
},
|
||||
new
|
||||
{
|
||||
name = "memory_write",
|
||||
description = "Schreibt oder überschreibt eine Memory-Datei. Nutze dies um wichtige Informationen, Entscheidungen oder Präferenzen dauerhaft zu speichern.",
|
||||
input_schema = new
|
||||
{
|
||||
type = "object",
|
||||
properties = new Dictionary<string, object>
|
||||
{
|
||||
["path"] = new { type = "string", description = "Relativer Pfad zur Memory-Datei (z.B. 'MEMORY.md' oder 'memory/2025-01-15.md')" },
|
||||
["content"] = new { type = "string", description = "Inhalt der Datei" },
|
||||
["append"] = new { type = "boolean", description = "Wenn true, wird der Inhalt angehängt statt überschrieben (Default: false)" }
|
||||
},
|
||||
required = new[] { "path", "content" }
|
||||
}
|
||||
},
|
||||
new
|
||||
{
|
||||
name = "memory_list",
|
||||
description = "Listet alle Memory-Dateien des Agents auf.",
|
||||
input_schema = new
|
||||
{
|
||||
type = "object",
|
||||
properties = new Dictionary<string, object>
|
||||
{
|
||||
["path"] = new { type = "string", description = "Optionaler Unterpfad zum Auflisten (leer = Root)" }
|
||||
},
|
||||
required = Array.Empty<string>()
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public async Task<string> ExecuteTool(string name, JsonElement input, string workspace, MemoryService memoryService = null, string agentId = null)
|
||||
{
|
||||
switch (name)
|
||||
{
|
||||
@@ -206,6 +271,37 @@ public class ToolService
|
||||
else if (proc.ExitCode != 0) result.Append($"\n(exit code {proc.ExitCode})");
|
||||
return result.ToString();
|
||||
}
|
||||
case "memory_read":
|
||||
{
|
||||
if (memoryService == null || string.IsNullOrEmpty(agentId))
|
||||
return "Fehler: Memory-Service nicht verfügbar";
|
||||
var path = input.GetProperty("path").GetString() ?? "";
|
||||
var content = memoryService.ReadMemoryFile(agentId, path);
|
||||
if (content == null)
|
||||
return $"Datei nicht gefunden: {path}";
|
||||
return content;
|
||||
}
|
||||
case "memory_write":
|
||||
{
|
||||
if (memoryService == null || string.IsNullOrEmpty(agentId))
|
||||
return "Fehler: Memory-Service nicht verfügbar";
|
||||
var path = input.GetProperty("path").GetString() ?? "";
|
||||
var content = input.GetProperty("content").GetString() ?? "";
|
||||
var append = input.TryGetProperty("append", out var a) && a.GetBoolean();
|
||||
if (append)
|
||||
memoryService.AppendMemoryFile(agentId, path, content);
|
||||
else
|
||||
memoryService.WriteMemoryFile(agentId, path, content);
|
||||
return $"Memory-Datei {(append ? "erweitert" : "geschrieben")}: {path} ({content.Length} Zeichen)";
|
||||
}
|
||||
case "memory_list":
|
||||
{
|
||||
if (memoryService == null || string.IsNullOrEmpty(agentId))
|
||||
return "Fehler: Memory-Service nicht verfügbar";
|
||||
var subPath = input.TryGetProperty("path", out var p) ? p.GetString() ?? "" : "";
|
||||
var files = memoryService.ListMemoryFiles(agentId, subPath);
|
||||
return files.Count == 0 ? "(keine Memory-Dateien vorhanden)" : string.Join("\n", files);
|
||||
}
|
||||
default:
|
||||
return $"Fehler: Unbekanntes Tool: {name}";
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user