import requests
import streamlit as st
import textwrap
# ---------------------------
# PAGE CONFIG
# ---------------------------
st.set_page_config(
page_title="CodeSight AI",
page_icon="",
layout="wide",
)
# ---------------------------
# CUSTOM CSS
# ---------------------------
st.markdown(
textwrap.dedent(
"""
"""
).lstrip("\n"),
unsafe_allow_html=True,
)
# ---------------------------
# SIDEBAR
# ---------------------------
with st.sidebar:
st.markdown("## CodeSight AI")
st.caption("AI-Powered Codebase Intelligence")
API_URL = st.text_input(
"Backend URL",
"http://127.0.0.1:8000/api"
)
st.markdown("---")
st.markdown("### 📌 Features")
st.markdown("""
- Hybrid Retrieval (BM25 + Vector)
- Graph RAG with NetworkX
- GitHub Repository Understanding
- Codebase Question Answering
- Dependency Tracing
""")
# ---------------------------
# SESSION STATE
# ---------------------------
if "repo_id" not in st.session_state:
st.session_state.repo_id = ""
# ---------------------------
# ERROR HANDLER
# ---------------------------
def show_api_error(response: requests.Response) -> None:
try:
detail = response.json().get(
"detail",
response.text
)
except ValueError:
detail = response.text
st.error(
f"❌ API request failed "
f"({response.status_code}): {detail}"
)
# ---------------------------
# HERO SECTION
# ---------------------------
# ---------------------------
# HERO SECTION
# ---------------------------
st.markdown(
textwrap.dedent(
"""
CodeSight AI
"""
).lstrip("\n"),
unsafe_allow_html=True,
)
st.text("Chat with any codebase using Graph RAG,Hybrid Retrieval and AI-powered repository reasoning.")
# ---------------------------
# TABS
# ---------------------------
tab_local, tab_github, tab_ask = st.tabs(
[
"📂 Local Repository",
"🌐 GitHub Repository",
"💬 Ask Questions"
]
)
# ---------------------------
# LOCAL REPO TAB
# ---------------------------
with tab_local:
st.markdown("### 📂 Index Local Repository")
path = st.text_input(
"Repository Path",
placeholder=r"G:\Code Base RAG"
)
if st.button(
"🚀 Index Repository",
type="primary"
) and path:
with st.spinner(
"Indexing repository..."
):
response = requests.post(
f"{API_URL}/repos/local",
json={"path": path},
timeout=120
)
if response.ok:
summary = response.json()
st.session_state.repo_id = (
summary["repo_id"]
)
st.success(
f"✅ Indexed "
f"{summary['files_indexed']} "
f"files into "
f"{summary['chunks_indexed']} chunks"
)
st.json(summary)
else:
show_api_error(response)
# ---------------------------
# GITHUB TAB
# ---------------------------
with tab_github:
st.markdown(
"### 🌐 Clone & Index GitHub Repository"
)
url = st.text_input(
"GitHub URL",
placeholder=(
"https://github.com/"
"user/project"
)
)
if st.button(
"🚀 Clone & Index",
type="primary"
) and url:
with st.spinner(
"Cloning and indexing..."
):
response = requests.post(
f"{API_URL}/repos/github",
json={"url": url},
timeout=240
)
if response.ok:
summary = response.json()
st.session_state.repo_id = (
summary["repo_id"]
)
st.success(
f"✅ Indexed "
f"{summary['name']}"
)
st.json(summary)
else:
show_api_error(response)
# ---------------------------
# ASK TAB
# ---------------------------
with tab_ask:
st.markdown(
"### 💬 Ask Questions About Your Codebase"
)
repo_id = st.text_input(
"Repository ID",
value=st.session_state.repo_id
)
question = st.text_area(
"Ask a Question",
placeholder=(
"Explain the authentication "
"flow."
)
)
top_k = st.slider(
"Retrieved Sources",
3,
12,
8
)
if st.button(
"🧠 Ask CodeSight",
type="primary"
) and repo_id and question:
with st.spinner(
"Thinking..."
):
response = requests.post(
f"{API_URL}/repos/"
f"{repo_id}/query",
json={
"question": question,
"top_k": top_k
},
timeout=120,
)
if response.ok:
result = response.json()
st.markdown(
"## 🧠 Answer"
)
st.info(
result["answer"]
)
st.markdown(
"## 📚 Source Citations"
)
for source in (
result["sources"]
):
st.markdown(
textwrap.dedent(
f"""
📄 File:
{source['path']}
📍 Lines:
{source['start_line']}
-
{source['end_line']}
🧩 Type:
{source['kind']}
🔖 Symbol:
{source['symbol']}
⭐ Score:
{round(source['score'], 3)}
"""
).lstrip("\n"),
unsafe_allow_html=True,
)
else:
show_api_error(response)
# ---------------------------
# FOOTER
# ---------------------------
st.markdown(
textwrap.dedent(
"""
"""
).lstrip("\n"),
unsafe_allow_html=True,
)