fischer-agentkit/src/agentkit/server/routes/memory.py

122 lines
3.5 KiB
Python

"""Memory API routes"""
import asyncio
import logging
from fastapi import APIRouter, HTTPException, Request
logger = logging.getLogger(__name__)
router = APIRouter(prefix="/memory", tags=["memory"])
def _get_memory_retriever(request: Request):
retriever = getattr(request.app.state, "memory_retriever", None)
if retriever is None:
raise HTTPException(
status_code=503,
detail="Memory retriever is not configured",
)
return retriever
@router.get("/episodic")
async def search_episodic_memory(
query: str,
top_k: int = 5,
agent_name: str | None = None,
req: Request = None,
):
"""Search episodic memory."""
retriever = _get_memory_retriever(req)
if retriever._episodic is None:
raise HTTPException(
status_code=503,
detail="Episodic memory is not configured",
)
try:
filters = {}
if agent_name:
filters["agent_name"] = agent_name
items = await retriever._episodic.search(query, top_k=top_k, filters=filters or None)
except asyncio.CancelledError:
raise
except Exception as e:
logger.error(f"Failed to search episodic memory: {e}")
raise HTTPException(status_code=500, detail="Failed to search episodic memory")
results = []
for item in items:
results.append({
"key": item.key,
"value": item.value,
"score": item.score,
"metadata": item.metadata,
})
return {"query": query, "results": results, "total": len(results)}
@router.get("/semantic/search")
async def search_semantic_memory(
query: str,
knowledge_base_ids: str | None = None,
top_k: int = 5,
req: Request = None,
):
"""Search semantic memory (knowledge bases)."""
retriever = _get_memory_retriever(req)
if retriever._semantic is None:
raise HTTPException(
status_code=503,
detail="Semantic memory is not configured",
)
try:
filters = {}
if knowledge_base_ids:
filters["knowledge_base_ids"] = [kid.strip() for kid in knowledge_base_ids.split(",")]
items = await retriever._semantic.search(query, top_k=top_k, filters=filters or None)
except asyncio.CancelledError:
raise
except Exception as e:
logger.error(f"Failed to search semantic memory: {e}")
raise HTTPException(status_code=500, detail="Failed to search semantic memory")
results = []
for item in items:
results.append({
"key": item.key,
"value": item.value,
"score": item.score,
"metadata": item.metadata,
})
return {"query": query, "results": results, "total": len(results)}
@router.delete("/episodic/{key}")
async def delete_episodic_memory(key: str, req: Request = None):
"""Delete an episodic memory entry."""
retriever = _get_memory_retriever(req)
if retriever._episodic is None:
raise HTTPException(
status_code=503,
detail="Episodic memory is not configured",
)
try:
deleted = await retriever._episodic.delete(key)
except asyncio.CancelledError:
raise
except Exception as e:
logger.error(f"Failed to delete episodic memory '{key}': {e}")
raise HTTPException(status_code=500, detail="Failed to delete episodic memory")
if not deleted:
raise HTTPException(status_code=404, detail=f"Episodic memory '{key}' not found")
return {"key": key, "deleted": True}