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
@@ -0,0 +1,104 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
namespace Gott.Services;
|
||||
|
||||
public class MemoryService
|
||||
{
|
||||
private readonly string _dataDir;
|
||||
|
||||
public MemoryService(string dataDir)
|
||||
{
|
||||
_dataDir = dataDir;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gibt den Memory-Ordner für einen Agent zurück. Erstellt ihn bei Bedarf.
|
||||
/// </summary>
|
||||
public string GetAgentMemoryDir(string agentId)
|
||||
{
|
||||
var dir = Path.Combine(_dataDir, "agents", agentId);
|
||||
Directory.CreateDirectory(dir);
|
||||
return dir;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Liest eine Memory-Datei. Gibt null zurück wenn nicht vorhanden.
|
||||
/// </summary>
|
||||
public string ReadMemoryFile(string agentId, string fileName)
|
||||
{
|
||||
var path = ResolvePath(agentId, fileName);
|
||||
if (path == null || !File.Exists(path)) return null;
|
||||
return File.ReadAllText(path);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Schreibt/überschreibt eine Memory-Datei.
|
||||
/// </summary>
|
||||
public void WriteMemoryFile(string agentId, string fileName, string content)
|
||||
{
|
||||
var path = ResolvePath(agentId, fileName);
|
||||
if (path == null) throw new Exception("Ungültiger Dateipfad");
|
||||
var dir = Path.GetDirectoryName(path);
|
||||
if (dir != null) Directory.CreateDirectory(dir);
|
||||
File.WriteAllText(path, content);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Hängt Inhalt an eine Memory-Datei an.
|
||||
/// </summary>
|
||||
public void AppendMemoryFile(string agentId, string fileName, string content)
|
||||
{
|
||||
var path = ResolvePath(agentId, fileName);
|
||||
if (path == null) throw new Exception("Ungültiger Dateipfad");
|
||||
var dir = Path.GetDirectoryName(path);
|
||||
if (dir != null) Directory.CreateDirectory(dir);
|
||||
File.AppendAllText(path, content);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Listet alle Memory-Dateien eines Agents auf.
|
||||
/// </summary>
|
||||
public List<string> ListMemoryFiles(string agentId, string subPath = null)
|
||||
{
|
||||
var baseDir = GetAgentMemoryDir(agentId);
|
||||
var targetDir = string.IsNullOrEmpty(subPath)
|
||||
? baseDir
|
||||
: Path.GetFullPath(Path.Combine(baseDir, subPath));
|
||||
|
||||
if (!targetDir.StartsWith(baseDir))
|
||||
throw new Exception("Zugriff außerhalb des Memory-Verzeichnisses nicht erlaubt");
|
||||
|
||||
if (!Directory.Exists(targetDir))
|
||||
return new List<string>();
|
||||
|
||||
var entries = new List<string>();
|
||||
foreach (var dir in Directory.GetDirectories(targetDir))
|
||||
entries.Add(Path.GetRelativePath(baseDir, dir) + "/");
|
||||
foreach (var file in Directory.GetFiles(targetDir))
|
||||
entries.Add(Path.GetRelativePath(baseDir, file));
|
||||
return entries;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Liest MEMORY.md (das Haupt-Memory-File). Gibt leeren String zurück wenn nicht vorhanden.
|
||||
/// </summary>
|
||||
public string GetMainMemory(string agentId)
|
||||
{
|
||||
return ReadMemoryFile(agentId, "MEMORY.md") ?? "";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Löst einen Pfad relativ zum Agent-Memory-Dir auf und prüft Sandbox.
|
||||
/// </summary>
|
||||
private string ResolvePath(string agentId, string fileName)
|
||||
{
|
||||
var baseDir = GetAgentMemoryDir(agentId);
|
||||
var full = Path.GetFullPath(Path.Combine(baseDir, fileName));
|
||||
if (!full.StartsWith(baseDir))
|
||||
return null;
|
||||
return full;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user