File size: 1,783 Bytes
edabb92
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
import logging
from threading import Lock
from fastapi import FastAPI, HTTPException
from fastapi.responses import FileResponse
from fastapi.staticfiles import StaticFiles
from pydantic import BaseModel
from ingest import ingest_books
from query import ask_question, clear_history


app = FastAPI(title="MindBot API", version="1.0.0")
logger = logging.getLogger(__name__)
app.mount("/static", StaticFiles(directory="static"), name="static")

_ingest_lock = Lock()
_knowledge_ready = False


class AskRequest(BaseModel):
    question: str


@app.get("/")
def index():
    return FileResponse("static/index.html")


def ensure_knowledge_ready() -> None:
    global _knowledge_ready
    if _knowledge_ready:
        return

    with _ingest_lock:
        if _knowledge_ready:
            return
        ingest_books("knowledge")
        _knowledge_ready = True


@app.post("/ask")
def ask(payload: AskRequest):
    question = payload.question.strip()
    if not question:
        raise HTTPException(status_code=400, detail="question is required")

    if question.lower() in {"/end", "/reset"}:
        clear_history()
        return {
            "answer": "Conversation history cleared.",
            "sources": [],
        }

    try:
        ensure_knowledge_ready()
        answer, docs = ask_question(question)
    except Exception:
        logger.exception("Failed to process ask request")
        raise HTTPException(status_code=500, detail="failed to process question")

    sources = []
    seen = set()
    for doc in docs:
        book = doc.metadata.get("book") if hasattr(doc, "metadata") else None
        if book and book not in seen:
            seen.add(book)
            sources.append(book)

    return {
        "answer": answer,
        "sources": sources,
    }