rashimittal's picture
Upload 34 files
d9ac377 verified
Raw
History Blame Contribute Delete
4.82 kB
import uuid
from contextlib import asynccontextmanager
from datetime import datetime, timezone
from fastapi import FastAPI, Query
from pydantic import BaseModel
from app.db.store import init_db, save_decision, get_history, get_stats
from app.engine.decision import decide
from app.engine.explain import explain
from app.nlp.emotion import detect_emotion
from app.nlp.emoji_map import sentiment_emoji, emotion_emoji
from app.nlp.language import detect_language
from app.nlp.sentiment import analyze_sentiment
from app.nlp.signals import extract_signals
from app.engine.priority import compute_priority
@asynccontextmanager
async def lifespan(app: FastAPI):
init_db()
yield
app = FastAPI(title="AI Decision Maker", lifespan=lifespan)
# ── Request / Response models ──────────────────────────────────────────────────
class DecideRequest(BaseModel):
text: str
class SentimentOut(BaseModel):
label: str
score: float
confidence: float
class SignalsOut(BaseModel):
urgency: str
intent: str
keywords: list[str]
class DecideResponse(BaseModel):
id: str
timestamp: str
text: str
sentiment: SentimentOut
signals: SignalsOut
decision: str
confidence: float
explanation: str
emotion: str
emotion_score: float
sentiment_emoji: str
emotion_emoji: str
priority_score: int
priority_level: str
factors: dict[str, int]
detected_language: str
class HistoryRecord(BaseModel):
id: str
text: str
sentiment_label: str
score: float
urgency: str
intent: str
decision: str
confidence: float
explanation: str
created_at: str
emotion: str = "neutral"
emotion_score: float = 0.0
priority_score: int = 0
priority_level: str = "LOW"
detected_language: str = "en"
class StatsResponse(BaseModel):
total: int
by_decision: dict[str, int]
by_sentiment: dict[str, int]
avg_priority_score: float = 0.0
by_priority_level: dict[str, int] = {}
# ── Endpoints ──────────────────────────────────────────────────────────────────
@app.get("/health")
def health():
return {"status": "ok"}
@app.post("/decide", response_model=DecideResponse)
def post_decide(body: DecideRequest):
language = detect_language(body.text)
sentiment = analyze_sentiment(body.text, language=language)
signals = extract_signals(body.text)
decision_result = decide(sentiment, signals)
explanation_text = explain(sentiment, signals, decision_result)
emotion_result = detect_emotion(body.text)
priority_result = compute_priority(sentiment, signals, emotion_result)
sent_emoji = sentiment_emoji(sentiment["label"], sentiment["confidence"])
emo_emoji = emotion_emoji(emotion_result["emotion"])
record_id = str(uuid.uuid4())
timestamp = datetime.now(timezone.utc).isoformat()
save_decision({
"id": record_id,
"text": body.text,
"sentiment_label": sentiment["label"],
"score": sentiment["score"],
"urgency": signals["urgency"],
"intent": signals["intent"],
"decision": decision_result["decision"],
"confidence": decision_result["confidence"],
"explanation": explanation_text,
"created_at": timestamp,
"emotion": emotion_result["emotion"],
"emotion_score": emotion_result["score"],
"priority_score": priority_result["priority_score"],
"priority_level": priority_result["priority_level"],
"detected_language": language,
})
return DecideResponse(
id=record_id,
timestamp=timestamp,
text=body.text,
sentiment=SentimentOut(**sentiment),
signals=SignalsOut(**signals),
decision=decision_result["decision"],
confidence=decision_result["confidence"],
explanation=explanation_text,
emotion=emotion_result["emotion"],
emotion_score=emotion_result["score"],
sentiment_emoji=sent_emoji,
emotion_emoji=emo_emoji,
priority_score=priority_result["priority_score"],
priority_level=priority_result["priority_level"],
factors=priority_result["factors"],
detected_language=language,
)
@app.get("/history", response_model=list[HistoryRecord])
def history(limit: int = Query(default=50, ge=1, le=500)):
return get_history(limit)
@app.get("/stats", response_model=StatsResponse)
def stats():
return get_stats()