import os from typing import Dict, Any from app.core.config import settings def get_deployment_health() -> Dict[str, Any]: return { "status": "healthy", "service": settings.APP_NAME, "version": settings.APP_VERSION, "environment": settings.ENVIRONMENT, "deployment_target": "hugging_face_spaces", "port": os.getenv("PORT", "7860"), "message": "FastAPI app is running and ready for Hugging Face Spaces." } def get_deployment_config() -> Dict[str, Any]: return { "deployment_target": "hugging_face_spaces", "llm_provider": settings.LLM_PROVIDER, "local_llm_enabled": settings.ENABLE_LOCAL_LLM, "hf_model": settings.HF_INFERENCE_MODEL, "hf_token_present": bool(settings.HF_API_TOKEN), "upload_dir": str(settings.UPLOAD_DIR), "processed_dir": str(settings.PROCESSED_DIR), "qdrant_path": str(settings.QDRANT_LOCAL_PATH), "evaluation_dir": str(settings.EVALUATION_DIR), "reranker_enabled": settings.ENABLE_RERANKER, "storage_warning": "Local Space storage can reset after restart unless persistent storage is attached." } def get_demo_html() -> str: return """ GraphRAG Research Scientist

đź§  GraphRAG Research Scientist

Deployment demo for document upload, indexing, retrieval, citations, hosted LLM, and fallback answering.

1. System Status

Use this to quickly confirm that deployment and LLM provider are alive.

Status output will appear here.

2. Upload Document

Upload a small PDF/TXT/DOCX/CSV file for demo. On Hugging Face free CPU, keep files small.



No document uploaded yet.

3. Index Document

Indexing creates embeddings and stores chunks in the vector database.

Document not indexed yet.

4. Ask Question



Ask output will appear here.

Raw Response

{}
""" def get_graphrag_demo_html() -> str: return """ GraphRAG Demo - GraphRAG Research Scientist

GraphRAG Demo Console

Test graph build, graph visualization, graph context, graph retrieval fusion, and GraphRAG evaluation.

1. Document Setup

Paste a document_id from your uploaded/indexed document. If using Hugging Face, upload and index from /demo or /docs first.



Ready.

2. Graph Actions

Build graph first, then test context/retrieve/view.

3. Evaluation Actions

Evaluation compares normal retrieval vs graph-guided retrieval vs fused retrieval.

4. Ask with GraphRAG



GraphRAG answer summary will appear here.

5. Output Summary

No output yet

6. Raw JSON Output

{}
""" def get_product_app_html() -> str: return """ GraphResearcher App
Ready
Tip: ask follow-ups like “explain it simply” or “how is it different?” The app sends recent chat context with your question.
""" def get_home_html() -> str: return """ GraphResearcher
GraphRAG Research Assistant

Chat with your documents using graph-powered RAG.

Upload a research paper, report, PDF, or notes and ask questions naturally. GraphResearcher retrieves evidence, builds an entity-relation graph, generates grounded answers, and shows citations without forcing users to handle technical document IDs.

1. Upload
User uploads a document. The app stores the document ID internally.
2. Build Graph
Entities and relations are extracted for graph-guided retrieval.
3. Chat
User asks follow-up questions like ChatGPT or Gemini.
4. Verify
Answers include citations, source chunks, and fusion metrics.

Document Workspace

Upload, select, chat with, and delete documents from a normal user interface.

GraphRAG Retrieval

Combines hybrid retrieval with graph context, graph-guided chunks, and fusion evaluation.

Professional Demo

Includes app UI, GraphRAG console, API docs, health checks, and deployment status.

""" def get_product_app_html() -> str: return """ GraphResearcher App
No document selected Upload or select a document from the left sidebar.
Ready
Ask naturally. Example: “Summarize this”, “What is the main idea?”, “Explain this simply”.
""" # ===================================================== # Phase 27 override: clean user-facing home and app UI # ===================================================== def get_home_html() -> str: return """ GraphResearcher
Document Chat + GraphRAG

Upload documents. Ask questions. Verify every answer.

GraphResearcher lets users chat with PDFs and reports using citation-grounded retrieval, graph context, and source-backed answers. No document IDs, no Swagger, no developer workflow.

1. Upload
Add a PDF or document from the app sidebar.
2. Chat
Ask natural questions like ChatGPT or Gemini.
3. Verify
See document name, page number, source ID, and evidence preview.

Simple workspace

Users upload and select documents normally. Internal IDs stay hidden.

Grounded answers

Answers are generated from retrieved evidence and source citations.

GraphRAG inside

Graph context and retrieval fusion run behind the scenes for better document reasoning.

""" def get_product_app_html() -> str: return """ GraphResearcher App
No document selected Upload or select a document from the left sidebar.
Ready
Example: “Summarize this”, “Explain step by step”, “What are the key points?”, “Give evidence”.
""" # ===================================================== # Phase 29 override: multi-document compare app UI # ===================================================== def get_product_app_html() -> str: return """ GraphResearcher App
No document selected Upload or select a document from the left sidebar.
Ready
For comparison: choose a second document in the right panel, then ask “Compare the main ideas” or “Which document explains better?”
""" # ===================================================== # Phase 33 override: clean retrieval query + stale cache tools # ===================================================== try: _phase33_previous_get_product_app_html = get_product_app_html except NameError: _phase33_previous_get_product_app_html = None def get_product_app_html() -> str: if _phase33_previous_get_product_app_html is None: return "

GraphResearcher App

App UI is unavailable.

" html = _phase33_previous_get_product_app_html() if "Clear Workspace Cache" not in html: buttons = """ """ html = html.replace("", buttons + "\n ", 1) js = r""" """ if "Phase 33 fix: clean retrieval query" not in html: html = html.replace("", js + "\n") html = html.replace( "Upload documents, select one, and chat. You can also compare two documents.", "Upload documents, select one, and chat. If answers say no sources found after rebuild, clear cache and re-upload." ) html = html.replace( "Upload a PDF/document and start chatting. No document ID needed.", "Upload a PDF/document and start chatting. If Hugging Face rebuilt, old cached documents may need re-upload." ) return html # ===================================================== # Phase 34 override: professional answer rendering # ===================================================== try: _phase34_previous_get_product_app_html = get_product_app_html except NameError: _phase34_previous_get_product_app_html = None def get_product_app_html() -> str: if _phase34_previous_get_product_app_html is None: return "

GraphResearcher App

App UI is unavailable.

" html = _phase34_previous_get_product_app_html() css = """ """ if "answer-card" not in html: html = html.replace("", css + "\n") js = """ """ if "Phase 34:" not in html: html = html.replace("", js + "\n") return html # ===================================================== # Phase 36 override: restore graph actions in user app # ===================================================== try: _phase36_previous_get_product_app_html = get_product_app_html except NameError: _phase36_previous_get_product_app_html = None def get_product_app_html() -> str: if _phase36_previous_get_product_app_html is None: return "

GraphResearcher App

App UI is unavailable.

" html = _phase36_previous_get_product_app_html() graph_section = """

Graph View

Open the entity-relation graph created from the selected document.

""" if "id=\"graphActionsPhase36\"" not in html: if '
' in html and "Advanced Settings" in html: html = html.replace( '
\n

Advanced Settings

', graph_section + '\n
\n

Advanced Settings

', 1 ) elif "" in html: html = html.replace("", graph_section + "\n ", 1) sidebar_buttons = """ """ if "openGraphViewerPhase36" not in html.split("", 1)[0]: if "Clear Workspace Cache" in html: html = html.replace( '', '\n' + sidebar_buttons, 1 ) elif '' in html: html = html.replace( '', '\n' + sidebar_buttons, 1 ) js = """ """ if "Phase 36: restore View Graph" not in html: html = html.replace("", js + "\n") return html # ===================================================== # Phase 37 override: use backend /documents/compare # ===================================================== try: _phase37_previous_get_product_app_html = get_product_app_html except NameError: _phase37_previous_get_product_app_html = None def get_product_app_html() -> str: if _phase37_previous_get_product_app_html is None: return "

GraphResearcher App

App UI is unavailable.

" html = _phase37_previous_get_product_app_html() js = """ """ if "Phase 37:" not in html: html = html.replace("", js + "\n") return html # ===================================================== # Phase 38 final stable UI export # This keeps old helper functions but forces / and /app to use the clean final UI. # ===================================================== from app.product.final_product_ui import get_home_html, get_product_app_html