import logging from typing import Optional from fastapi import APIRouter, HTTPException, Query, Response from app.core.config import get_settings from app.models.highlight import ( HighlightBatchRequest, HighlightBatchResponse, ) from app.services.chunk_highlight_service import ChunkHighlightService from app.services.highlight_cache import HighlightCache, compute_cache_key from app.services.history_service import HistoryService from app.services.llm_client import LLMClient from app.services.rag import RAGService logger = logging.getLogger(__name__) router = APIRouter(tags=["chunks"]) HIGHLIGHTS_DB_FILENAME = "highlights.db" def _highlights_db_path(settings) -> str: return str(settings.prompts_db_path).replace("prompts.db", HIGHLIGHTS_DB_FILENAME) @router.post("/api/v1/v2/highlights/batch", response_model=HighlightBatchResponse) async def compute_highlights_batch( request: HighlightBatchRequest, history_id: Optional[int] = Query(default=None), ): """Compute and cache highlighted chunk views for cited chunks.""" settings = get_settings() cache = HighlightCache(db_path=_highlights_db_path(settings)) llm_client = LLMClient(settings) rag = RAGService(settings=settings) service = ChunkHighlightService( rag_service=rag, llm_client=llm_client, highlight_cache=cache, settings=settings, ) try: result = await service.compute_highlights_batch(request.targets) if history_id is not None: history_service = HistoryService(settings.history_db_path) history_service.update_highlights( history_id, result.highlight_prompt or "", result.highlight_response_json or "", result.highlight_time_ms, ) return result except Exception as e: logger.error("Highlight batch computation failed: %s", e, exc_info=True) return HighlightBatchResponse(status="failed", cached_count=0, errors=[str(e)]) @router.get("/api/v1/v2/highlights", response_class=Response) async def get_highlight( document_id: str = Query(...), chunk_index: int = Query(...), sub_question: str = Query(...), ): """Serve a cached highlighted chunk view as HTML.""" settings = get_settings() cache = HighlightCache(db_path=_highlights_db_path(settings)) cache_key = compute_cache_key(document_id, chunk_index, sub_question) html = cache.get_highlight(cache_key) if html is None: raise HTTPException(status_code=404, detail="Highlight not found. Batch may not have been computed.") return Response(content=html, media_type="text/html")