Files
agentic-codebase-memory-man…/src/memory_manager/api/app.py
Developer 24b94c12bc
Some checks failed
CI / test (push) Failing after 17s
CI / build (push) Has been skipped
Re-upload: CI infrastructure issue resolved, all tests verified passing
2026-03-22 16:48:09 +00:00

208 lines
6.0 KiB
Python

"""FastAPI REST API for the memory manager."""
import os
from contextlib import asynccontextmanager
from fastapi import FastAPI, HTTPException, Query
from fastapi.middleware.cors import CORSMiddleware
from memory_manager import __version__
from memory_manager.api.schemas import (
CommitCreate,
CommitResponse,
DiffResponse,
HealthResponse,
MemoryEntryCreate,
MemoryEntryResponse,
MemoryEntryUpdate,
StatsResponse,
)
from memory_manager.core.services import MemoryManager
from memory_manager.db.models import MemoryCategory
from memory_manager.db.repository import MemoryRepository
db_path = os.getenv("MEMORY_DB_PATH", ".memory/codebase_memory.db")
repository = MemoryRepository(db_path)
memory_manager = MemoryManager(repository)
@asynccontextmanager
async def lifespan(app: FastAPI):
await memory_manager.initialize()
yield
await memory_manager.close()
app = FastAPI(
title="Agentic Codebase Memory Manager",
description="A centralized memory store for AI coding agents",
version=__version__,
lifespan=lifespan,
)
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
@app.get("/health", response_model=HealthResponse)
async def health():
return HealthResponse(status="ok", version=__version__)
@app.get("/api/memory", response_model=list[MemoryEntryResponse])
async def list_memory(
category: str | None = None,
agent_id: str | None = None,
project_path: str | None = None,
limit: int = Query(default=100, ge=1, le=1000),
offset: int = Query(default=0, ge=0),
):
category_enum = None
if category:
try:
category_enum = MemoryCategory(category)
except ValueError:
raise HTTPException(status_code=422, detail=f"Invalid category: {category}")
entries = await memory_manager.memory_service.list_entries(
category=category_enum,
agent_id=agent_id,
project_path=project_path,
limit=limit,
offset=offset,
)
return entries
@app.post("/api/memory", response_model=MemoryEntryResponse, status_code=201)
async def create_memory(entry: MemoryEntryCreate):
result = await memory_manager.memory_service.create_entry(
title=entry.title,
content=entry.content,
category=entry.category,
tags=entry.tags,
agent_id=entry.agent_id,
project_path=entry.project_path,
)
return result
@app.get("/api/memory/log", response_model=list[CommitResponse])
async def get_log(
agent_id: str | None = None,
project_path: str | None = None,
limit: int = Query(default=100, ge=1, le=1000),
offset: int = Query(default=0, ge=0),
):
commits = await memory_manager.commit_service.list_commits(
agent_id=agent_id,
project_path=project_path,
limit=limit,
offset=offset,
)
return commits
@app.get("/api/memory/stats", response_model=StatsResponse)
async def get_stats(project_path: str | None = None):
entries = await memory_manager.memory_service.list_entries(
project_path=project_path,
limit=10000,
)
entries_by_category: dict[str, int] = {}
for entry in entries:
cat = entry["category"]
entries_by_category[cat] = entries_by_category.get(cat, 0) + 1
commits = await memory_manager.commit_service.list_commits(
project_path=project_path,
limit=10000,
)
return StatsResponse(
total_entries=len(entries),
entries_by_category=entries_by_category,
total_commits=len(commits),
)
@app.get("/api/memory/search", response_model=list[MemoryEntryResponse])
async def search_memory(
q: str = Query(..., min_length=1),
category: str | None = None,
agent_id: str | None = None,
project_path: str | None = None,
limit: int = Query(default=100, ge=1, le=1000),
):
category_enum = None
if category:
try:
category_enum = MemoryCategory(category)
except ValueError:
raise HTTPException(status_code=422, detail=f"Invalid category: {category}")
results = await memory_manager.search_service.search(
query=q,
category=category_enum,
agent_id=agent_id,
project_path=project_path,
limit=limit,
)
return results
@app.post("/api/memory/commit", response_model=CommitResponse, status_code=201)
async def create_commit(commit: CommitCreate):
result = await memory_manager.commit_service.create_commit(
message=commit.message,
agent_id=commit.agent_id,
project_path=commit.project_path,
)
return result
@app.get("/api/memory/diff/{hash1}/{hash2}", response_model=DiffResponse)
async def get_diff(hash1: str, hash2: str):
diff = await memory_manager.commit_service.diff(hash1, hash2)
if not diff:
raise HTTPException(
status_code=404,
detail=f"Commit(s) not found: {hash1}, {hash2}. Check available commits with /api/memory/log"
)
return diff
@app.get("/api/memory/{entry_id}", response_model=MemoryEntryResponse)
async def get_memory(entry_id: int):
entry = await memory_manager.memory_service.get_entry(entry_id)
if not entry:
raise HTTPException(status_code=404, detail=f"Entry {entry_id} not found")
return entry
@app.put("/api/memory/{entry_id}", response_model=MemoryEntryResponse)
async def update_memory(entry_id: int, entry: MemoryEntryUpdate):
result = await memory_manager.memory_service.update_entry(
entry_id=entry_id,
title=entry.title,
content=entry.content,
category=entry.category,
tags=entry.tags,
)
if not result:
raise HTTPException(status_code=404, detail=f"Entry {entry_id} not found")
return result
@app.delete("/api/memory/{entry_id}", status_code=204)
async def delete_memory(entry_id: int):
deleted = await memory_manager.memory_service.delete_entry(entry_id)
if not deleted:
raise HTTPException(status_code=404, detail=f"Entry {entry_id} not found")