from uuid import UUID from fastapi import APIRouter, Depends, Query from sqlalchemy import select from sqlalchemy.orm import Session from app.db.session import get_db from app.models.vectors import EmbeddingSpace, VectorPublication, VectorVersion from app.schemas.catalog import Page from app.schemas.indexing import PublicationRead, PublishIndex from app.schemas.vectors import ( ActiveVectors, BuildVectors, SpaceRead, VectorRead, VectorRequest, VectorRetrievalResponse, ) from app.services.auth import CurrentSession, require_admin from app.services.catalog import page_result from app.services.embedding_runtime import get_embedding_provider from app.services.vectors import ( active_vectors, build_vectors, publish_vectors, retrieve_vectors, vector_or_404, ) router = APIRouter( prefix="/vector-indexes", tags=["vector-indexes"], dependencies=[Depends(require_admin)] ) retrieval_router = APIRouter(tags=["retrieval"]) @router.post("", response_model=VectorRead, status_code=201) def build( payload: BuildVectors, current: CurrentSession = Depends(require_admin), db: Session = Depends(get_db), provider=Depends(get_embedding_provider), ): return build_vectors(db, payload.text_index_version_id, current.user.id, provider) @router.get("", response_model=Page[VectorRead]) def versions( page: int = Query(1, ge=1), page_size: int = Query(20, ge=1, le=100), db: Session = Depends(get_db), ): return page_result( db, select(VectorVersion).order_by(VectorVersion.created_at.desc(), VectorVersion.id), page, page_size, ) @router.get("/active", response_model=ActiveVectors) def active(db: Session = Depends(get_db)): return active_vectors(db) @router.get("/spaces", response_model=Page[SpaceRead]) def spaces( page: int = Query(1, ge=1), page_size: int = Query(20, ge=1, le=100), db: Session = Depends(get_db), ): return page_result(db, select(EmbeddingSpace).order_by(EmbeddingSpace.id), page, page_size) @router.get("/publications", response_model=Page[PublicationRead]) def publications( page: int = Query(1, ge=1), page_size: int = Query(20, ge=1, le=100), db: Session = Depends(get_db), ): return page_result( db, select(VectorPublication).order_by(VectorPublication.generation.desc()), page, page_size ) @router.get("/{version_id}", response_model=VectorRead) def read_version(version_id: UUID, db: Session = Depends(get_db)): return vector_or_404(db, str(version_id)) @router.post("/{version_id}/publish", response_model=ActiveVectors) def publish( version_id: UUID, payload: PublishIndex, current: CurrentSession = Depends(require_admin), db: Session = Depends(get_db), ): return publish_vectors(db, version_id, payload.expected_generation, current.user.id) @retrieval_router.post("/retrieval/vector", response_model=VectorRetrievalResponse) def search( payload: VectorRequest, db: Session = Depends(get_db), provider=Depends(get_embedding_provider), ): return retrieve_vectors(db, payload, provider)