Files
linkedstorm/app/api/routes/rag.py
T
pluto 59014f6fe7 feat: API routes — speakers, rooms, search, RAG
Full implementations replacing stubs: speakers CRUD with utterance count,
rooms list + mute/unmute via pipeline, FTS5-based search, RAG /ask and
/summary endpoints. 15 route tests (8 new) all passing; 35 total.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-28 10:46:24 -05:00

67 lines
2.2 KiB
Python

import sqlite3
import httpx
from typing import Optional
from fastapi import APIRouter, HTTPException
from pydantic import BaseModel
from app.shared.config import Settings
class AskRequest(BaseModel):
question: str
date: Optional[str] = None
def make_router(settings: Settings, db_factory):
router = APIRouter(prefix="/api")
@router.post("/ask")
def ask(body: AskRequest):
db: sqlite3.Connection = db_factory()
rows = db.execute("""
SELECT u.start_time, u.transcript, r.name as room_name, s.name as speaker_name
FROM utterances u
JOIN rooms r ON u.room_id = r.id
LEFT JOIN speakers s ON u.speaker_id = s.id
WHERE date(u.start_time) = date(?)
ORDER BY u.start_time ASC
LIMIT 200
""", (body.date or "now",)).fetchall()
context_lines = [
f"[{r['room_name']} {r['start_time']}] {r['speaker_name'] or 'Unknown'}: {r['transcript']}"
for r in rows
]
context = "\n".join(context_lines) if context_lines else "(no transcripts for this date)"
prompt = (
f"You are a helpful assistant with access to household conversation transcripts.\n\n"
f"Transcripts:\n{context}\n\n"
f"Question: {body.question}\n\n"
f"Answer based only on the transcripts above. Cite the time and room when relevant."
)
resp = httpx.post(
f"{settings.ollama_url}/api/chat",
json={
"model": settings.ollama_model,
"messages": [{"role": "user", "content": prompt}],
"stream": False,
},
timeout=60.0,
)
resp.raise_for_status()
answer = resp.json()["message"]["content"]
return {"answer": answer, "context_count": len(rows)}
@router.get("/summary/{date}")
def get_summary(date: str):
db: sqlite3.Connection = db_factory()
row = db.execute(
"SELECT * FROM daily_summaries WHERE date=?", (date,)
).fetchone()
if not row:
raise HTTPException(404, f"No summary for {date}")
return dict(row)
return router