- Moved 20 root-level markdown files to readmes/ - Includes COMMANDS.md, CONFIG_README.md, all UNO docs, all completion reports - Added new: MEMORY_EDITOR_FEATURE.md, MEMORY_EDITOR_ESCAPING_FIX.md, CONFIG_SOURCES_ANALYSIS.md, MCP_TOOL_CALLING_ANALYSIS.md, and others - Root directory is now clean of documentation clutter
9.7 KiB
Memory Editor UI - Comprehensive CRUD Interface
Overview
Implemented comprehensive memory management UI in the Web Control Panel (Tab 9: Memories) with full CRUD operations. Users can now manually edit, create, delete, and search memories through an intuitive interface.
Features
1. Edit Existing Memories
- Edit Button (✏️) next to each memory/fact
- Modal dialog with textarea for content editing
- Source field for tracking where the memory came from
- Preserves vector embeddings when only metadata changes
- Re-embeds content when text is modified
2. Create New Memories
- "➕ Add Fact" button for declarative memories
- "➕ Add Memory" button for episodic memories
- Modal dialog with:
- Content textarea
- Optional User ID (for user-specific memories)
- Source field (defaults to "manual")
- Automatically generates proper embeddings and metadata
3. Search/Filter Memories
- Search input above each memory list
- Real-time filtering as you type
- Case-insensitive search across content and metadata
- Shows/hides matching items dynamically
4. Delete Operations
- Individual delete (🗑️ button) - single confirmation
- Delete All - multi-step safety flow (unchanged)
Implementation Details
Backend API (bot/api.py)
New Pydantic Models:
class MemoryEditRequest(BaseModel):
content: str
metadata: Optional[dict] = None
class MemoryCreateRequest(BaseModel):
content: str
collection: str # "declarative" or "episodic"
user_id: Optional[str] = None
source: Optional[str] = None
metadata: Optional[dict] = None
New Endpoints:
PUT /memory/point/{collection}/{point_id}- Edit existing memoryPOST /memory/create- Create new memory point
Cat Client (bot/utils/cat_client.py)
New Methods:
update_memory_point(collection, point_id, content, metadata=None):
- Fetches existing point from Qdrant (includes vector)
- Checks if content changed
- If content changed: Re-embeds via Cat's
/embedderendpoint - If only metadata changed: Preserves existing vector
- Updates point in Qdrant with new payload
- Returns
Trueon success
create_memory_point(collection, content, user_id=None, source=None):
- Generates UUID for new point_id
- Embeds content via Cat's
/embedderendpoint - Builds payload with metadata:
source: Tracking field (e.g., "manual", "discord", "autonomous")when: Unix timestampuser_id: For declarative memories, identifies user
- Inserts into Qdrant collection
- Returns
point_idon success,Noneon failure
Key Details:
- Uses Qdrant REST API:
http://cheshire-cat-vector-memory:6333 - Leverages Cat's
/embedderendpoint for consistent vector generation - Proper error handling with try/except blocks
- Async operations with aiohttp
Frontend UI (bot/static/index.html)
Modal Dialogs Added:
Edit Memory Modal:
<div id="edit-memory-modal">
<textarea id="edit-memory-content"></textarea>
<input id="edit-memory-source" placeholder="Source">
<button onclick="saveMemoryEdit()">Save Changes</button>
<button onclick="closeEditMemoryModal()">Cancel</button>
</div>
Create Memory Modal:
<div id="create-memory-modal">
<textarea id="create-memory-content"></textarea>
<input id="create-memory-user-id" placeholder="User ID (optional)">
<input id="create-memory-source" value="manual">
<button onclick="saveNewMemory()">Create Memory</button>
<button onclick="closeCreateMemoryModal()">Cancel</button>
</div>
JavaScript Functions Added:
showEditMemoryModal(collection, pointId, memoryData)- Open edit modal with datacloseEditMemoryModal()- Close edit modalsaveMemoryEdit()- PUT request to update memoryshowCreateMemoryModal(collection)- Open create modal for collection typecloseCreateMemoryModal()- Close create modalsaveNewMemory()- POST request to create memoryfilterMemories(listId, searchTerm)- Real-time search/filter
UI Enhancements:
- Added
memory-itemclass to all memory divs for filtering - Edit button (✏️) styled with blue color (#5599cc)
- Delete button (🗑️) kept in red (#993333)
- Search inputs with
oninputhandlers for live filtering - Flex layout for button groups
Usage Guide
Editing a Memory
- Navigate to Tab 9: Memories in Web UI
- Load facts or episodic memories
- Click the ✏️ Edit button next to any memory
- Modal opens with current content and source
- Modify the content and/or source
- Click "Save Changes"
- Memory is updated in Qdrant and list refreshes
Creating a New Memory
For Declarative Facts:
- Click "➕ Add Fact" button
- Enter the fact content (e.g., "Miku's favorite color is cyan")
- Optionally add User ID (for user-specific facts)
- Set source (defaults to "manual")
- Click "Create Memory"
- Fact is embedded and stored in declarative collection
For Episodic Memories:
- Click "➕ Add Memory" button
- Enter the memory content (conversation context)
- Optionally add User ID
- Set source (e.g., "manual", "test", "import")
- Click "Create Memory"
- Memory is embedded and stored in episodic collection
Searching Memories
- Type in the search box above the memory list
- Results filter in real-time
- Clear the search box to see all memories again
- Search matches content and metadata
Testing the Feature
Create a Test Fact:
// In browser console or through UI:
// Click "Add Fact" button, enter:
Content: "Miku's favorite color is cyan"
User ID: (leave empty for general fact)
Source: "test"
Verify Through Chat:
User: "What is your favorite color?"
Miku: "My favorite color is cyan!" (should recall the fact)
Edit the Fact:
// Click ✏️ next to the fact, change:
Content: "Miku's favorite color is teal"
Source: "test_edit"
Delete the Fact:
// Click 🗑️ button, confirm deletion
Technical Architecture
Data Flow
Edit Memory:
User clicks ✏️
→ showEditMemoryModal() populates form
→ User edits and clicks "Save"
→ saveMemoryEdit() → PUT /memory/point/{collection}/{id}
→ api.py validates with MemoryEditRequest
→ cat_adapter.update_memory_point()
→ Fetches existing point from Qdrant
→ Re-embeds if content changed
→ Updates point in Qdrant
→ Returns success
→ UI reloads memory list
Create Memory:
User clicks ➕ Add Fact
→ showCreateMemoryModal('declarative')
→ User fills form and clicks "Create"
→ saveNewMemory() → POST /memory/create
→ api.py validates with MemoryCreateRequest
→ cat_adapter.create_memory_point()
→ Generates UUID
→ Embeds content via Cat's /embedder
→ Builds payload with metadata
→ Inserts into Qdrant
→ Returns point_id
→ UI reloads memory list and refreshes stats
Error Handling
Backend:
- Validates collection name (only "declarative" and "episodic" allowed)
- Checks for empty content
- Handles Qdrant connection errors
- Returns proper error messages in JSON
Frontend:
- Shows user-friendly notifications
- Disables buttons during operations
- Reverts button text on error
- Validates required fields before submission
Metadata Structure
Declarative Memories
{
"source": "manual",
"when": 1734567890.123,
"user_id": "user_discord_id_here" // Optional, for user-specific facts
}
Episodic Memories
{
"source": "manual",
"when": 1734567890.123
}
Note: user_id is only used in declarative memories to associate facts with specific users.
Future Enhancements
Potential Features:
-
Batch Operations
- Select multiple memories with checkboxes
- Bulk delete selected
- Bulk export selected
-
Import/Export
- Export memories as JSON file
- Import memories from JSON
- Bulk memory migration
-
Advanced Filtering
- Filter by date range
- Filter by source
- Filter by user_id
- Sort by similarity score
-
Memory History
- Track edit history
- Show who edited and when
- Ability to revert changes
-
Memory Insights
- Show most recalled memories
- Identify unused/stale memories
- Suggest memory consolidation
-
Rich Text Editing
- Markdown support in memory content
- Syntax highlighting for code snippets
- Preview mode
Testing Checklist
- Backend API endpoints respond correctly
- Cat client methods communicate with Qdrant
- Edit modal opens and populates correctly
- Edit saves and updates memory in Qdrant
- Create modal opens for both fact and memory types
- Create generates proper embeddings and stores in Qdrant
- Search/filter works in real-time
- Delete still works as expected
- UI refreshes after operations
- Error notifications display properly
- Test with actual chat queries to verify LLM recalls edited facts
- Test user-specific facts with user_id parameter
- Performance test with large memory sets (1000+ items)
Related Files
Backend:
/bot/api.py- Lines 2778-2788 (models), 2918-2968 (endpoints)/bot/utils/cat_client.py- Lines 382-541 (new methods)
Frontend:
/bot/static/index.html- Lines 1613-1781 (UI sections and modals), 5268-5685 (JavaScript functions)
Documentation:
/readmes/MEMORY_EDITOR_FEATURE.md- This file/readmes/AUTONOMOUS_V2_DECISION_LOGIC.md- Memory usage in autonomous system
Notes
- Container must be restarted after API changes:
docker restart miku-bot - Modals use flexbox centering with semi-transparent backdrop
- Memory items use
class="memory-item"for filtering - Edit button uses ✏️ emoji with blue color (#5599cc)
- Create buttons use ➕ emoji
- All operations show loading states (button text changes)
- Success/error notifications use existing
showNotification()function