feat: add mempalace_tool for vector memory #234
@@ -158,6 +158,7 @@ def _discover_tools():
|
||||
"tools.send_message_tool",
|
||||
# "tools.honcho_tools", # Removed — Honcho is now a memory provider plugin
|
||||
"tools.homeassistant_tool",
|
||||
"tools.mempalace_tool",
|
||||
]
|
||||
import importlib
|
||||
for mod_name in _modules:
|
||||
|
||||
133
tools/mempalace_tool.py
Normal file
133
tools/mempalace_tool.py
Normal file
@@ -0,0 +1,133 @@
|
||||
"""
|
||||
mempalace_tool.py — Interface for the MemPalace vector memory system.
|
||||
|
||||
This tool allows the agent to search and record memories in a ChromaDB-backed
|
||||
vector database via the fleet_api.
|
||||
"""
|
||||
|
||||
import json
|
||||
import os
|
||||
import requests
|
||||
import logging
|
||||
from typing import Dict, Any, List, Optional
|
||||
from tools.registry import registry
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# Default to the fleet_api port defined in the-nexus
|
||||
MEMPALACE_API_URL = os.environ.get("MEMPALACE_API_URL", "http://127.0.0.1:7771")
|
||||
|
||||
def mempalace_tool(
|
||||
action: str,
|
||||
query: str = "",
|
||||
text: str = "",
|
||||
room: Optional[str] = None,
|
||||
wing: Optional[str] = None,
|
||||
n_results: int = 10,
|
||||
metadata: Optional[Dict[str, Any]] = None,
|
||||
) -> str:
|
||||
"""
|
||||
Interface for the MemPalace vector memory system.
|
||||
|
||||
Actions:
|
||||
search: Search the palace for relevant memories.
|
||||
record: Add a new memory to the palace.
|
||||
wings: List available wizard wings.
|
||||
"""
|
||||
try:
|
||||
if action == "search":
|
||||
if not query:
|
||||
return json.dumps({"success": False, "error": "Query is required for search."})
|
||||
|
||||
params = {"q": query, "n": n_results}
|
||||
if room:
|
||||
params["room"] = room
|
||||
|
||||
response = requests.get(f"{MEMPALACE_API_URL}/search", params=params, timeout=10)
|
||||
response.raise_for_status()
|
||||
return json.dumps({"success": True, "data": response.json()})
|
||||
|
||||
elif action == "record":
|
||||
if not text:
|
||||
return json.dumps({"success": False, "error": "Text is required for record."})
|
||||
|
||||
payload = {
|
||||
"text": text,
|
||||
"room": room or "general",
|
||||
"wing": wing,
|
||||
"metadata": metadata or {}
|
||||
}
|
||||
|
||||
response = requests.post(f"{MEMPALACE_API_URL}/record", json=payload, timeout=10)
|
||||
response.raise_for_status()
|
||||
return json.dumps({"success": True, "data": response.json()})
|
||||
|
||||
elif action == "wings":
|
||||
response = requests.get(f"{MEMPALACE_API_URL}/wings", timeout=10)
|
||||
response.raise_for_status()
|
||||
return json.dumps({"success": True, "data": response.json()})
|
||||
|
||||
else:
|
||||
return json.dumps({"success": False, "error": f"Unknown action: {action}"})
|
||||
|
||||
except requests.exceptions.ConnectionError:
|
||||
return json.dumps({
|
||||
"success": False,
|
||||
"error": f"Could not connect to MemPalace API at {MEMPALACE_API_URL}. Ensure fleet_api.py is running."
|
||||
})
|
||||
except Exception as e:
|
||||
logger.error(f"MemPalace tool error: {e}")
|
||||
return json.dumps({"success": False, "error": str(e)})
|
||||
|
||||
MEMPALACE_SCHEMA = {
|
||||
"name": "mempalace",
|
||||
"description": (
|
||||
"Search or record memories in the MemPalace vector database. "
|
||||
"Use this for long-term, high-volume memory that exceeds the curated memory limits. "
|
||||
"The palace is organized into 'rooms' (e.g., forge, hermes, nexus, issues, experiments)."
|
||||
),
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"action": {
|
||||
"type": "string",
|
||||
"enum": ["search", "record", "wings"],
|
||||
"description": "The action to perform."
|
||||
},
|
||||
"query": {
|
||||
"type": "string",
|
||||
"description": "The search query (required for 'search')."
|
||||
},
|
||||
"text": {
|
||||
"type": "string",
|
||||
"description": "The memory text to record (required for 'record')."
|
||||
},
|
||||
"room": {
|
||||
"type": "string",
|
||||
"description": "Optional room filter or target room (e.g., forge, hermes, nexus, issues, experiments)."
|
||||
},
|
||||
"wing": {
|
||||
"type": "string",
|
||||
"description": "Optional wizard wing filter."
|
||||
},
|
||||
"n_results": {
|
||||
"type": "integer",
|
||||
"default": 10,
|
||||
"description": "Maximum number of results to return."
|
||||
},
|
||||
"metadata": {
|
||||
"type": "object",
|
||||
"description": "Optional metadata for the memory (only for 'record')."
|
||||
}
|
||||
},
|
||||
"required": ["action"]
|
||||
}
|
||||
}
|
||||
|
||||
registry.register(
|
||||
name="mempalace",
|
||||
toolset="mempalace",
|
||||
schema=MEMPALACE_SCHEMA,
|
||||
handler=lambda args, **kw: mempalace_tool(**args),
|
||||
emoji="🏛️",
|
||||
)
|
||||
Reference in New Issue
Block a user