Skip to main content

batuta/serve/banco/
handlers_rag.rs

1//! RAG endpoint handlers — index management and status.
2
3use axum::{extract::State, http::StatusCode, response::Json};
4
5use super::rag::RagStatus;
6use super::state::BancoState;
7
8/// POST /api/v1/rag/index — force re-index all uploaded documents.
9pub async fn rag_index_handler(State(state): State<BancoState>) -> Json<RagIndexResponse> {
10    let files = state.files.list();
11    let mut indexed = 0;
12
13    for file_info in &files {
14        if let Some(content) = state.files.read_content(&file_info.id) {
15            let text = String::from_utf8_lossy(&content);
16            state.rag.index_document(&file_info.id, &file_info.name, &text);
17            indexed += 1;
18        }
19    }
20
21    let status = state.rag.status();
22    state.events.emit(&super::events::BancoEvent::RagIndexed {
23        doc_count: status.doc_count,
24        chunk_count: status.chunk_count,
25    });
26    Json(RagIndexResponse { indexed_files: indexed, status })
27}
28
29/// GET /api/v1/rag/status — index stats.
30pub async fn rag_status_handler(State(state): State<BancoState>) -> Json<RagStatus> {
31    Json(state.rag.status())
32}
33
34/// DELETE /api/v1/rag/index — clear the RAG index.
35pub async fn rag_clear_handler(State(state): State<BancoState>) -> StatusCode {
36    state.rag.clear();
37    StatusCode::NO_CONTENT
38}
39
40/// GET /api/v1/rag/search?q=query&top_k=5 — search indexed documents.
41pub async fn rag_search_handler(
42    State(state): State<BancoState>,
43    axum::extract::Query(params): axum::extract::Query<RagSearchParams>,
44) -> Json<RagSearchResponse> {
45    let query = params.q.unwrap_or_default();
46    let top_k = params.top_k.unwrap_or(5);
47    let min_score = params.min_score.unwrap_or(0.0);
48    let results = state.rag.search(&query, top_k, min_score);
49    Json(RagSearchResponse { query, results })
50}
51
52#[derive(Debug, serde::Deserialize)]
53pub struct RagSearchParams {
54    pub q: Option<String>,
55    pub top_k: Option<usize>,
56    pub min_score: Option<f64>,
57}
58
59#[derive(Debug, serde::Serialize)]
60pub struct RagSearchResponse {
61    pub query: String,
62    pub results: Vec<super::rag::RagResult>,
63}
64
65/// Response from index rebuild.
66#[derive(Debug, serde::Serialize)]
67pub struct RagIndexResponse {
68    pub indexed_files: usize,
69    pub status: RagStatus,
70}