Files
ai-agent/backend/memories/routes.py
Gabriel Vidal 0ff9e40242 refactor(backend): split main.py into domain packages with app.state injection
main.py (5146 lines, 106 routes) becomes an assembly only: one package per
domain — core, files, settings, dashboards, conversations, diff,
notifications, forms, runs, accounts, workers, models, cron, agents,
projects, services, goals, memories, plans, templates — each exposing an
APIRouter; the flat domain modules move into their package behind a barrel
that keeps the old `import conversations` / `import projects` spellings.

The shared singletons (store, meta_store, hub, indexer, …) are built once by
core.state.build_state() and attached to app.state.ai; routes take them as
the `deps: State` dependency and helpers as an explicit `deps: AppState`.
conversations/pricing.py carries the per-model rates out of the parser.

Verified: route table and OpenAPI byte-identical; 90 read endpoints
golden-diffed against the monolith on a copy of the live data (identical);
write routes smoke-tested; 66 backend tests pass.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-06 23:55:47 +02:00

51 lines
1.7 KiB
Python

"""Memories routes."""
from fastapi import APIRouter, HTTPException
import memories as memories_mod
import schemas
from conversations.catalog import _conv_card
from core.http import _r
from core.state import State
router = APIRouter()
# ── memories (the assistant's persistent file-based memory for this repo) ─────
@router.get("/api/memories", responses=_r(schemas.MemoriesResponse))
def memories_list():
"""All memory summaries (projects + links derived), newest-updated first."""
return {"memories": memories_mod.list_memories()}
@router.get("/api/memory", responses=_r(schemas.MemoryDetail))
def memory_detail(deps: State, slug: str):
"""One memory + its body, with the conversations that created / read it."""
mem = memories_mod.memory_detail(slug)
if mem is None:
raise HTTPException(404, "memory not found")
origin = mem.get("originSessionId")
created_in, read_in = [], []
created_sids: set[str] = set()
for path, s in deps.store.all_summaries():
if not s.get("messages"):
continue
sid = s.get("sessionId")
if sid and sid == origin:
created_in.append(_conv_card(deps, path, s))
created_sids.add(sid)
for path, s in deps.store.all_summaries():
if not s.get("messages"):
continue
# don't repeat the originating conversation under "read"
if s.get("sessionId") in created_sids:
continue
if slug in (s.get("memoriesRead") or []):
read_in.append(_conv_card(deps, path, s))
created_in.sort(key=lambda c: c.get("endedAt") or "", reverse=True)
read_in.sort(key=lambda c: c.get("endedAt") or "", reverse=True)
mem["createdIn"] = created_in
mem["readIn"] = read_in
return mem