diff options
Diffstat (limited to 'personal_agent/tools/memory.py')
| -rw-r--r-- | personal_agent/tools/memory.py | 197 |
1 files changed, 197 insertions, 0 deletions
diff --git a/personal_agent/tools/memory.py b/personal_agent/tools/memory.py new file mode 100644 index 0000000..2287d4e --- /dev/null +++ b/personal_agent/tools/memory.py @@ -0,0 +1,197 @@ +from personal_agent.memory.models import WorkingMemory +from personal_agent.tools.base import Tool, ToolError, ToolResult + + +class TaskStartTool(Tool): + def __init__(self, memory: WorkingMemory) -> None: + self.memory = memory + + @property + def name(self) -> str: + return "task_start" + + @property + def description(self) -> str: + return ( + "Record the user's ongoing project or goal as the current task. " + "Use this when the user intends to work on something across multiple " + "turns or over a period of time. Do not use it for one-off requests " + "or temporary side conversations." + ) + + @property + def schema(self) -> dict[str, object]: + return { + "type": "object", + "properties": { + "objective": { + "type": "string", + "description": ( + "A concise description of the durable goal the user wants to pursue. " + "Describe what they are trying to accomplish, not mutable implementation " + "details, preferences, or constraints. For example: " + "'Build an image tagging API' or " + "'Design and implement a Rust CLI that converts directory trees into " + "static HTML.'" + ), + }, + }, + "required": ["objective"], + } + + def execute(self, arguments: dict[str, object]) -> ToolResult: + objective = arguments.get("objective") + + if not isinstance(objective, str): + raise ToolError("objective must be a string") + + if not objective.strip(): + raise ToolError("objective must not be empty") + + self.memory.start_task(objective) + + return ToolResult(content=f"Started task: {objective}") + + +class MemoryAddFactTool(Tool): + def __init__(self, memory: WorkingMemory) -> None: + self.memory = memory + + @property + def name(self) -> str: + return "memory_add_fact" + + @property + def description(self) -> str: + return "Add a useful fact to the current working memory." + + @property + def schema(self) -> dict[str, object]: + return { + "type": "object", + "properties": { + "fact": { + "type": "string", + "description": "A fact worth remembering during the current task.", + }, + }, + "required": ["fact"], + } + + def execute(self, arguments: dict[str, object]) -> ToolResult: + fact = arguments.get("fact") + + if not isinstance(fact, str): + raise ToolError("fact must be a string") + + self.memory.add_fact(fact) + + return ToolResult(content=f"Added working-memory fact: {fact}") + + +class MemoryAddNoteTool(Tool): + def __init__(self, memory: WorkingMemory) -> None: + self.memory = memory + + @property + def name(self) -> str: + return "memory_add_note" + + @property + def description(self) -> str: + return "Add a useful note to the current working memory." + + @property + def schema(self) -> dict[str, object]: + return { + "type": "object", + "properties": { + "note": { + "type": "string", + "description": "A useful observation, reminder, or note for the current task.", + }, + }, + "required": ["note"], + } + + def execute(self, arguments: dict[str, object]) -> ToolResult: + note = arguments.get("note") + + if not isinstance(note, str): + raise ToolError("note must be a string") + + self.memory.add_note(note) + + return ToolResult(content=f"Added working-memory note: {note}") + + +class MemoryRemoveFactTool(Tool): + def __init__(self, memory: WorkingMemory) -> None: + self.memory = memory + + @property + def name(self) -> str: + return "memory_remove_fact" + + @property + def description(self) -> str: + return "Remove a fact from the working memory when it is no longer true or relevant." + + @property + def schema(self) -> dict[str, object]: + return { + "type": "object", + "properties": { + "fact": { + "type": "string", + "description": "The exact fact to remove from working memory.", + }, + }, + "required": ["fact"], + } + + def execute(self, arguments: dict[str, object]) -> ToolResult: + fact = arguments.get("fact") + + if not isinstance(fact, str): + raise ToolError("fact must be a string") + + self.memory.remove_fact(fact) + + return ToolResult(content=f"Removed fact: {fact}") + + +class MemoryRemoveNoteTool(Tool): + def __init__(self, memory: WorkingMemory) -> None: + self.memory = memory + + @property + def name(self) -> str: + return "memory_remove_note" + + @property + def description(self) -> str: + return "Remove a note from the working memory when it is no longer true or relevant." + + @property + def schema(self) -> dict[str, object]: + return { + "type": "object", + "properties": { + "note": { + "type": "string", + "description": "The exact note to remove from working memory.", + }, + }, + "required": ["note"], + } + + def execute(self, arguments: dict[str, object]) -> ToolResult: + note = arguments.get("note") + + if not isinstance(note, str): + raise ToolError("note must be a string") + + self.memory.remove_note(note) + + return ToolResult(content=f"Removed note: {note}") |
