a digital person for bluesky

Add reason and confirm fields to memory deletion tool

Enhances the flag_archival_memory_for_deletion tool with safety guards:
- Added 'reason' field (required, first argument) to force reasoning
- Added 'confirm' boolean field (required, last argument) for explicit confirmation
- Tool only processes deletions when confirm=true
- Deletion handler extracts and logs the reason with each deletion

This pattern ensures the agent must:
1. Explain why it's deleting (reason)
2. Specify what it's deleting (memory_text)
3. Explicitly confirm the deletion (confirm)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

Changed files
+32 -7
tools
+17 -5
bsky.py
··· 772 772 elif message.tool_call.name == 'flag_archival_memory_for_deletion': 773 773 try: 774 774 args = json.loads(message.tool_call.arguments) 775 + reason = args.get('reason', '') 775 776 memory_text = args.get('memory_text', '') 776 - if memory_text: 777 - flagged_memories.append(memory_text) 778 - logger.debug(f"Found memory flagged for deletion: {memory_text[:50]}...") 777 + confirm = args.get('confirm', False) 778 + 779 + # Only flag for deletion if confirmed 780 + if confirm and memory_text: 781 + flagged_memories.append({ 782 + 'reason': reason, 783 + 'memory_text': memory_text 784 + }) 785 + logger.debug(f"Found memory flagged for deletion (reason: {reason}): {memory_text[:50]}...") 786 + elif not confirm: 787 + logger.debug(f"Memory deletion not confirmed, skipping: {memory_text[:50]}...") 779 788 except json.JSONDecodeError as e: 780 789 logger.error(f"Failed to parse flag_archival_memory_for_deletion arguments: {e}") 781 790 ··· 803 812 # Handle archival memory deletion if any were flagged (only if no halt was received) 804 813 if flagged_memories: 805 814 logger.info(f"Processing {len(flagged_memories)} flagged memories for deletion") 806 - for memory_text in flagged_memories: 815 + for flagged_memory in flagged_memories: 816 + reason = flagged_memory['reason'] 817 + memory_text = flagged_memory['memory_text'] 818 + 807 819 try: 808 820 # Search for passages with this exact text 809 821 logger.debug(f"Searching for passages matching: {memory_text[:100]}...") ··· 832 844 logger.error(f"Failed to delete passage {passage.id}: {delete_error}") 833 845 834 846 if deleted_count > 0: 835 - logger.info(f"🗑️ Deleted {deleted_count} archival memory passage(s): {memory_text[:50]}...") 847 + logger.info(f"🗑️ Deleted {deleted_count} archival memory passage(s) (reason: {reason}): {memory_text[:50]}...") 836 848 else: 837 849 logger.warning(f"No exact matches found for deletion: {memory_text[:50]}...") 838 850
+15 -2
tools/flag_memory_deletion.py
··· 3 3 4 4 5 5 class FlagArchivalMemoryForDeletionArgs(BaseModel): 6 + reason: str = Field( 7 + ..., 8 + description="The reason why this memory should be deleted" 9 + ) 6 10 memory_text: str = Field( 7 11 ..., 8 12 description="The exact text content of the archival memory to delete" 9 13 ) 14 + confirm: bool = Field( 15 + ..., 16 + description="Confirmation that you want to delete this memory (must be true to proceed)" 17 + ) 10 18 11 19 12 - def flag_archival_memory_for_deletion(memory_text: str) -> str: 20 + def flag_archival_memory_for_deletion(reason: str, memory_text: str, confirm: bool) -> str: 13 21 """ 14 22 Flag an archival memory for deletion based on its exact text content. 15 23 ··· 20 28 The system will search for all archival memories with this exact text and delete them. 21 29 22 30 Args: 31 + reason: The reason why this memory should be deleted 23 32 memory_text: The exact text content of the archival memory to delete 33 + confirm: Confirmation that you want to delete this memory (must be true) 24 34 25 35 Returns: 26 36 Confirmation message 27 37 """ 28 38 # This is a dummy tool - it just returns a confirmation 29 39 # The actual deletion will be handled by the bot loop after the agent's turn completes 30 - return f"Memory flagged for deletion. Will be removed at the end of this turn if no halt is received." 40 + if not confirm: 41 + return "Deletion cancelled - confirm must be set to true to delete the memory." 42 + 43 + return f"Memory flagged for deletion (reason: {reason}). Will be removed at the end of this turn if no halt is received."