batuta/serve/banco/
handlers_rag.rs1use axum::{extract::State, http::StatusCode, response::Json};
4
5use super::rag::RagStatus;
6use super::state::BancoState;
7
8pub 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
29pub async fn rag_status_handler(State(state): State<BancoState>) -> Json<RagStatus> {
31 Json(state.rag.status())
32}
33
34pub async fn rag_clear_handler(State(state): State<BancoState>) -> StatusCode {
36 state.rag.clear();
37 StatusCode::NO_CONTENT
38}
39
40pub 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#[derive(Debug, serde::Serialize)]
67pub struct RagIndexResponse {
68 pub indexed_files: usize,
69 pub status: RagStatus,
70}