83 lines
3.0 KiB
Python
83 lines
3.0 KiB
Python
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:
|
|
logger.info(
|
|
"Highlight batch request: %d targets (history_id=%s)",
|
|
len(request.targets), history_id,
|
|
)
|
|
result = await service.compute_highlights_batch(request.targets)
|
|
logger.info(
|
|
"Highlight batch response: status=%s cached=%d errors=%d time=%dms",
|
|
result.status, result.cached_count, len(result.errors or []),
|
|
result.highlight_time_ms or 0,
|
|
)
|
|
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")
|