Spaces:
Running
Running
XQ commited on
Commit ·
6a54ecb
1
Parent(s): f2cefbd
Update intro
Browse files- src/api/routes.py +28 -1
- src/ui/app.py +60 -42
src/api/routes.py
CHANGED
|
@@ -90,6 +90,10 @@ class HealthResponse(BaseModel):
|
|
| 90 |
|
| 91 |
status: str
|
| 92 |
version: str
|
|
|
|
|
|
|
|
|
|
|
|
|
| 93 |
|
| 94 |
|
| 95 |
@router.get("/health", response_model=HealthResponse)
|
|
@@ -99,7 +103,30 @@ async def health_check() -> HealthResponse:
|
|
| 99 |
Returns:
|
| 100 |
HealthResponse with service status and version.
|
| 101 |
"""
|
| 102 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 103 |
|
| 104 |
|
| 105 |
@router.post("/query", response_model=QueryResponse)
|
|
|
|
| 90 |
|
| 91 |
status: str
|
| 92 |
version: str
|
| 93 |
+
llm_provider: str = ""
|
| 94 |
+
llm_model: str = ""
|
| 95 |
+
embedding_provider: str = ""
|
| 96 |
+
embedding_model: str = ""
|
| 97 |
|
| 98 |
|
| 99 |
@router.get("/health", response_model=HealthResponse)
|
|
|
|
| 103 |
Returns:
|
| 104 |
HealthResponse with service status and version.
|
| 105 |
"""
|
| 106 |
+
llm_provider = ""
|
| 107 |
+
llm_model = ""
|
| 108 |
+
embedding_provider = ""
|
| 109 |
+
embedding_model = ""
|
| 110 |
+
if _settings is not None:
|
| 111 |
+
llm_provider = _settings.llm_provider
|
| 112 |
+
embedding_provider = _settings.embedding_provider
|
| 113 |
+
embedding_model = _settings.embedding_model
|
| 114 |
+
model_map = {
|
| 115 |
+
"ollama": _settings.ollama_model,
|
| 116 |
+
"openai": _settings.openai_model,
|
| 117 |
+
"azure_openai": _settings.azure_openai_deployment,
|
| 118 |
+
"anthropic": _settings.anthropic_model,
|
| 119 |
+
"google_genai": _settings.google_model,
|
| 120 |
+
}
|
| 121 |
+
llm_model = model_map.get(llm_provider, _settings.generation_model)
|
| 122 |
+
return HealthResponse(
|
| 123 |
+
status="ok",
|
| 124 |
+
version="0.1.0",
|
| 125 |
+
llm_provider=llm_provider,
|
| 126 |
+
llm_model=llm_model,
|
| 127 |
+
embedding_provider=embedding_provider,
|
| 128 |
+
embedding_model=embedding_model,
|
| 129 |
+
)
|
| 130 |
|
| 131 |
|
| 132 |
@router.post("/query", response_model=QueryResponse)
|
src/ui/app.py
CHANGED
|
@@ -21,27 +21,22 @@ TEXTS: Dict[str, Dict[str, str]] = {
|
|
| 21 |
"lang_label": "Sprog",
|
| 22 |
"sidebar_heading": "Om systemet",
|
| 23 |
"sidebar_body": (
|
| 24 |
-
"
|
| 25 |
-
"
|
| 26 |
-
"
|
| 27 |
-
"
|
| 28 |
-
"
|
| 29 |
-
"
|
| 30 |
-
"
|
| 31 |
-
"- **
|
| 32 |
-
"
|
| 33 |
-
"-
|
| 34 |
-
"
|
| 35 |
-
"**
|
| 36 |
-
"
|
| 37 |
-
"- **
|
| 38 |
-
"- **
|
| 39 |
-
"
|
| 40 |
-
"- **Sentence-Transformers** -- cross-encoder reranking\n"
|
| 41 |
-
"- **PyMuPDF** -- PDF-parsing og tekstudtraek\n"
|
| 42 |
-
"- **Streamlit** -- frontend brugerflade\n"
|
| 43 |
-
"- **RAGAS** -- evaluering af hentekvalitet\n"
|
| 44 |
-
"- **HuggingFace** -- flersprogede embedding-modeller"
|
| 45 |
),
|
| 46 |
"chunking_label": "Chunking-strategi",
|
| 47 |
"chunking_help": "Vaelg hvordan dokumenterne opdeles i tekststykker.",
|
|
@@ -71,33 +66,32 @@ TEXTS: Dict[str, Dict[str, str]] = {
|
|
| 71 |
"err_api": "API-fejl",
|
| 72 |
"err_timeout": "Forespoorgslen tog for lang tid. Prøv igen.",
|
| 73 |
"unknown": "ukendt",
|
|
|
|
|
|
|
|
|
|
|
|
|
| 74 |
},
|
| 75 |
"en": {
|
| 76 |
"page_title": "Document Assistant",
|
| 77 |
"lang_label": "Language",
|
| 78 |
"sidebar_heading": "About the system",
|
| 79 |
"sidebar_body": (
|
| 80 |
-
"
|
| 81 |
-
"document
|
| 82 |
-
"
|
| 83 |
-
"
|
| 84 |
-
"
|
| 85 |
-
"
|
| 86 |
-
"
|
| 87 |
-
"- **
|
| 88 |
-
"
|
| 89 |
-
"-
|
| 90 |
-
"
|
| 91 |
-
"**
|
| 92 |
-
"
|
| 93 |
-
"- **
|
| 94 |
-
"- **
|
| 95 |
-
"
|
| 96 |
-
"- **Sentence-Transformers** -- cross-encoder reranking\n"
|
| 97 |
-
"- **PyMuPDF** -- PDF parsing and text extraction\n"
|
| 98 |
-
"- **Streamlit** -- frontend user interface\n"
|
| 99 |
-
"- **RAGAS** -- retrieval quality evaluation\n"
|
| 100 |
-
"- **HuggingFace** -- multilingual embedding models"
|
| 101 |
),
|
| 102 |
"chunking_label": "Chunking strategy",
|
| 103 |
"chunking_help": "Choose how documents are split into text chunks.",
|
|
@@ -127,6 +121,10 @@ TEXTS: Dict[str, Dict[str, str]] = {
|
|
| 127 |
"err_api": "API error",
|
| 128 |
"err_timeout": "The request took too long. Please try again.",
|
| 129 |
"unknown": "unknown",
|
|
|
|
|
|
|
|
|
|
|
|
|
| 130 |
},
|
| 131 |
}
|
| 132 |
|
|
@@ -333,6 +331,26 @@ with st.sidebar:
|
|
| 333 |
help=t["topk_help"],
|
| 334 |
)
|
| 335 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 336 |
# ---------------------------------------------------------------------------
|
| 337 |
# Main content
|
| 338 |
# ---------------------------------------------------------------------------
|
|
|
|
| 21 |
"lang_label": "Sprog",
|
| 22 |
"sidebar_heading": "Om systemet",
|
| 23 |
"sidebar_body": (
|
| 24 |
+
"End-to-end RAG-prototype der goer dansksproget "
|
| 25 |
+
"dokumenthaandtering selvbetjent.\n\n"
|
| 26 |
+
"- **Python + FastAPI** REST-backend\n"
|
| 27 |
+
"- **Ustruktureret data** — PDF-parsing, preprocessing, "
|
| 28 |
+
"tre chunking-strategier\n"
|
| 29 |
+
"- **Embedding-modeller** — flersproget semantisk "
|
| 30 |
+
"vektorrepraesentation\n"
|
| 31 |
+
"- **Vektordatabase + hybrid soegning** — Qdrant (semantisk) "
|
| 32 |
+
"+ BM25 (leksikalsk)\n"
|
| 33 |
+
"- **Reranking** — cross-encoder for praecis relevans\n"
|
| 34 |
+
"- **RAG-arkitektur** — LangChain-orkestreret pipeline\n"
|
| 35 |
+
"- **LLM-integration** — provider-agnostisk, prompt-styret "
|
| 36 |
+
"svargenerering\n"
|
| 37 |
+
"- **Evaluering** — RAGAS-baseret kvalitetsmaaling\n"
|
| 38 |
+
"- **Agent-routing** — intent-klassifikation og "
|
| 39 |
+
"forespørgselsdirigering"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 40 |
),
|
| 41 |
"chunking_label": "Chunking-strategi",
|
| 42 |
"chunking_help": "Vaelg hvordan dokumenterne opdeles i tekststykker.",
|
|
|
|
| 66 |
"err_api": "API-fejl",
|
| 67 |
"err_timeout": "Forespoorgslen tog for lang tid. Prøv igen.",
|
| 68 |
"unknown": "ukendt",
|
| 69 |
+
"model_heading": "Aktuel model",
|
| 70 |
+
"model_llm": "LLM",
|
| 71 |
+
"model_embedding": "Embedding",
|
| 72 |
+
"model_unavailable": "Kunne ikke hente modelinfo.",
|
| 73 |
},
|
| 74 |
"en": {
|
| 75 |
"page_title": "Document Assistant",
|
| 76 |
"lang_label": "Language",
|
| 77 |
"sidebar_heading": "About the system",
|
| 78 |
"sidebar_body": (
|
| 79 |
+
"End-to-end RAG prototype that makes Danish-language "
|
| 80 |
+
"document Q&A self-service.\n\n"
|
| 81 |
+
"- **Python + FastAPI** REST backend\n"
|
| 82 |
+
"- **Unstructured data** — PDF parsing, preprocessing, "
|
| 83 |
+
"three chunking strategies\n"
|
| 84 |
+
"- **Embedding models** — multilingual semantic vector "
|
| 85 |
+
"representations\n"
|
| 86 |
+
"- **Vector database + hybrid search** — Qdrant (semantic) "
|
| 87 |
+
"+ BM25 (lexical)\n"
|
| 88 |
+
"- **Reranking** — cross-encoder for precise relevance\n"
|
| 89 |
+
"- **RAG architecture** — LangChain-orchestrated pipeline\n"
|
| 90 |
+
"- **LLM integration** — provider-agnostic, prompt-driven "
|
| 91 |
+
"answer generation\n"
|
| 92 |
+
"- **Evaluation** — RAGAS-based quality measurement\n"
|
| 93 |
+
"- **Agent routing** — intent classification and query "
|
| 94 |
+
"dispatch"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 95 |
),
|
| 96 |
"chunking_label": "Chunking strategy",
|
| 97 |
"chunking_help": "Choose how documents are split into text chunks.",
|
|
|
|
| 121 |
"err_api": "API error",
|
| 122 |
"err_timeout": "The request took too long. Please try again.",
|
| 123 |
"unknown": "unknown",
|
| 124 |
+
"model_heading": "Current model",
|
| 125 |
+
"model_llm": "LLM",
|
| 126 |
+
"model_embedding": "Embedding",
|
| 127 |
+
"model_unavailable": "Could not fetch model info.",
|
| 128 |
},
|
| 129 |
}
|
| 130 |
|
|
|
|
| 331 |
help=t["topk_help"],
|
| 332 |
)
|
| 333 |
|
| 334 |
+
st.markdown("---")
|
| 335 |
+
|
| 336 |
+
# Fetch and display current model info from backend
|
| 337 |
+
try:
|
| 338 |
+
_health = requests.get(f"{API_BASE}/health", timeout=5).json()
|
| 339 |
+
_llm = _health.get("llm_model", "")
|
| 340 |
+
_llm_prov = _health.get("llm_provider", "")
|
| 341 |
+
_emb = _health.get("embedding_model", "")
|
| 342 |
+
_emb_prov = _health.get("embedding_provider", "")
|
| 343 |
+
st.markdown(
|
| 344 |
+
f'<div class="ku-sidebar-heading">{t["model_heading"]}</div>',
|
| 345 |
+
unsafe_allow_html=True,
|
| 346 |
+
)
|
| 347 |
+
st.markdown(
|
| 348 |
+
f'**{t["model_llm"]}:** {_llm} ({_llm_prov}) \n'
|
| 349 |
+
f'**{t["model_embedding"]}:** {_emb} ({_emb_prov})'
|
| 350 |
+
)
|
| 351 |
+
except Exception:
|
| 352 |
+
st.caption(t["model_unavailable"])
|
| 353 |
+
|
| 354 |
# ---------------------------------------------------------------------------
|
| 355 |
# Main content
|
| 356 |
# ---------------------------------------------------------------------------
|