LibBee / src /api /agent.py
nikeshn's picture
Upload 5 files
2167c4f verified
Raw
History Blame Contribute Delete
2.76 kB
"""
LibBee /agent endpoint - thin FastAPI router.
The pipeline itself lives in ``src/agentcore`` split by stage:
models.py Stage 0 Pydantic I/O contracts
constants.py regexes, URLs, prompts (no logic)
utils.py shared helpers, LLM factory, URL builders
classify.py Stage 2-3 rule pre-classifier + LLM intent classifier
libcal.py live hours/events via Cloudflare Worker proxy
scholarly.py Semantic Scholar / OpenAlex / Crossref / Unpaywall
rendering.py HTML fragments (badges, trace, AI-tools footer)
intents_library.py Stage 4 library_info handlers
intents_search.py Stage 4 search_academic / search_medical machinery
intents_general.py Stage 4 general / social handlers
orchestrator.py Stage 1+4 injection gate, routing pipeline, D1 logging
This file only wires HTTP to the orchestrator.
"""
import time
from fastapi import APIRouter, Request
from src.agentcore.models import AgentRequest, AgentResponse
from src.agentcore.orchestrator import _agent_query_inner, _log_agent_query
from src.agentcore.utils import (
_get_runtime_config,
_normalize_whitespace,
_safe_metrics_increment,
_sanitize_llm_response,
)
from src.services.staff_service import STAFF_DIRECTORY
router = APIRouter()
@router.post("", response_model=AgentResponse)
async def agent_query(request: Request, req: AgentRequest):
start_time = time.time()
question = _normalize_whitespace(req.question)
history = req.history
model = req.model
client_state = req.client_state
_safe_metrics_increment("agent_requests")
response = await _agent_query_inner(question, history, model, client_state, start_time)
response.answer = _sanitize_llm_response(response.answer)
_log_agent_query(question, response, start_time)
_rcfg = _get_runtime_config()
_ann = _rcfg.get("announcement", "").strip()
if _ann and response.intent not in ("social_greeting", "social"):
_ann_html = (
'<div style="margin-top:14px;padding:10px 14px;border-radius:10px;'
'background:#fffbeb;border:1px solid #fde68a;font-size:.82rem;color:#92400e">'
f'📢 {_ann}</div>'
)
response.answer = response.answer + _ann_html
return response
@router.get("/test")
async def test():
return {
"status": "ok",
"message": "Agent endpoint is working!",
"staff_loaded": len(STAFF_DIRECTORY),
}
@router.get("/rag-status")
async def rag_status():
try:
from app import get_rag_service
return get_rag_service().get_stats()
except Exception as e:
return {"error": str(e), "ready": False}