Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -266,9 +266,9 @@ documind/

---

## Screenshots
## Demo

> *Screenshots coming soon — upload a PDF, ask questions, see sources cited inline.*
https://github.com/user-attachments/assets/290e7caf-6676-43c2-9f9f-9df63d28c3f9

---

Expand Down
13 changes: 7 additions & 6 deletions rag/agents/graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,13 @@ def retrieve(state: GraphState) -> GraphState:

def direct_response(state: GraphState) -> GraphState:
"""Return a response for general conversation (no retrieval needed)."""
return {
"generation": (
"Hello! I'm a PDF assistant. Please ask me a question about your "
"document and I'll look it up for you."
)
}
question = state.get("question", "").strip().lower()
greetings = {"hi", "hello", "hey", "hiya", "howdy", "sup", "what's up", "whats up"}
if any(question == g or question.startswith(g + " ") for g in greetings):
reply = "Hey! Ask me anything about your document and I'll find the answer for you."
else:
reply = "I can only answer questions about the document you've uploaded. What would you like to know?"
return {"generation": reply}


def fallback(state: GraphState) -> GraphState:
Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,5 @@ streamlit
watchdog

# Evaluation
ragas
ragas==0.0.22
datasets
90 changes: 75 additions & 15 deletions ui/components/chat.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,21 +23,83 @@ def render_chat() -> None:
if not st.session_state.current_doc_id:
# ── Welcome screen ────────────────────────────────────────────────────
st.markdown("""
<div style="
background: linear-gradient(135deg, #1a2035 0%, #1e2d40 100%);
<style>
@keyframes glow-pulse {
0%, 100% { box-shadow: 0 0 18px rgba(126,184,247,0.2), 0 0 40px rgba(167,139,250,0.1); }
50% { box-shadow: 0 0 28px rgba(126,184,247,0.35), 0 0 60px rgba(167,139,250,0.2); }
}
.dm-pill {
background: linear-gradient(135deg, #1a2a40, #1e2d40);
border: 1px solid #2d4a6e;
border-radius: 14px;
padding: 2rem 2.5rem;
max-width: 600px;
margin: 2rem auto;
border-radius: 20px;
padding: 5px 14px;
font-size: 0.83rem;
color: #7eb8f7;
display: inline-block;
}
</style>
<div style="
background: linear-gradient(145deg, #0e1625 0%, #141e35 50%, #111828 100%);
border: 1px solid #253550;
border-radius: 20px;
padding: 2.8rem 2.8rem 2.2rem 2.8rem;
max-width: 640px;
margin: 2.5rem auto 1.5rem auto;
position: relative;
overflow: hidden;
">
<h3 style="color:#7eb8f7; margin-top:0;">Welcome to DocuMind 🧠</h3>
<p style="color:#c0cad8; font-size:0.95rem; line-height:1.7">
Upload a PDF from the sidebar to start a conversation with your document.<br><br>
This assistant uses <b>hybrid search</b> (semantic + keyword),
<b>cross-encoder reranking</b>, and <b>Gemini 2.5 Flash</b> to give you
precise, document-grounded answers.
<div style="
position:absolute; top:-40px; right:-40px;
width:160px; height:160px;
background: radial-gradient(circle, rgba(167,139,250,0.12) 0%, transparent 70%);
pointer-events:none;
"></div>
<div style="display:flex; align-items:center; gap:14px; margin-bottom:1.5rem;">
<div style="
background: linear-gradient(135deg, #1e3a5f 0%, #0f2540 100%);
border: 1px solid #2d5a8e;
border-radius: 14px;
width: 52px; height: 52px;
display: flex; align-items: center; justify-content: center;
font-size: 1.7rem;
animation: glow-pulse 3s ease-in-out infinite;
">🧠</div>
<div>
<div style="
font-size: 1.9rem;
font-weight: 900;
letter-spacing: -0.04em;
line-height: 1.05;
background: linear-gradient(90deg, #7eb8f7 0%, #a78bfa 55%, #f0abfc 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
">DocuMind</div>
<div style="font-size:0.8rem; color:#4a5568; letter-spacing:0.06em; text-transform:uppercase; font-weight:600;">
Agentic Document Intelligence
</div>
</div>
</div>
<div style="font-size:1.15rem; font-weight:700; color:#dde6f5; margin-bottom:0.6rem; line-height:1.4;">
Ask anything about your document.<br>
<span style="
background: linear-gradient(90deg, #a78bfa, #f0abfc);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
">Get answers you can trust.</span>
</div>
<p style="color:#8895aa; font-size:0.93rem; line-height:1.8; margin:0 0 1.6rem 0;">
Upload a PDF from the sidebar. Ask a question and DocuMind will find the relevant parts,
generate an answer based only on your document, and show you exactly where it came from.
</p>
<div style="display:flex; flex-wrap:wrap; gap:8px;">
<span class="dm-pill">⚡ Hybrid Search</span>
<span class="dm-pill">🎯 Cross-Encoder Reranking</span>
<span class="dm-pill">✨ Gemini 2.5 Flash</span>
<span class="dm-pill">🔗 LangGraph Agent</span>
<span class="dm-pill">🛡 Hallucination Guard</span>
</div>
</div>
""", unsafe_allow_html=True)

Expand Down Expand Up @@ -92,14 +154,12 @@ def render_chat() -> None:
st.session_state.chat_history.pop()
return

if sources:
_render_sources(sources)

st.session_state.chat_history.append({
"role": "assistant",
"content": answer,
"sources": sources,
})
st.rerun()


def _stream_query(question: str):
Expand Down
35 changes: 34 additions & 1 deletion ui/components/sidebar.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,40 @@


def render_sidebar() -> None:
st.sidebar.markdown("## 📂 Documents")
st.sidebar.markdown("""
<div style="
display: flex; align-items: center; gap: 10px;
padding: 0.8rem 0 1rem 0;
border-bottom: 1px solid #2a2f3e;
margin-bottom: 1.1rem;
">
<div style="
background: linear-gradient(135deg, #1e3a5f 0%, #0f2540 100%);
border: 1px solid #2d5a8e;
border-radius: 9px;
width: 36px; height: 36px;
display: flex; align-items: center; justify-content: center;
font-size: 1.15rem; flex-shrink: 0;
box-shadow: 0 0 14px rgba(126,184,247,0.2);
">🧠</div>
<div>
<div style="
font-size: 1.25rem;
font-weight: 900;
letter-spacing: -0.03em;
line-height: 1.1;
background: linear-gradient(90deg, #7eb8f7 0%, #a78bfa 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
">DocuMind</div>
<div style="font-size:0.7rem; color:#556070; letter-spacing:0.03em;">v1.0.0</div>
</div>
</div>
<div style="font-size:0.8rem; color:#8892a4; font-weight:600; letter-spacing:0.07em; text-transform:uppercase; margin-bottom:0.6rem;">
📂 Your Documents
</div>
""", unsafe_allow_html=True)

# ── Upload ────────────────────────────────────────────────────────────────
uploaded_file = st.sidebar.file_uploader(
Expand Down
30 changes: 28 additions & 2 deletions ui/streamlit_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,34 @@
# ── Header ─────────────────────────────────────────────────────────────────────
header_left, header_right = st.columns([6, 1])
with header_left:
st.markdown("## 📄 RAG PDF Assistant")
st.caption("Ask questions about your PDF — answers are grounded strictly in your document.")
st.markdown("""
<div style="display:flex; align-items:center; gap:16px; padding: 0.4rem 0 0.6rem 0;">
<div style="
background: linear-gradient(135deg, #1e3a5f 0%, #0f2540 100%);
border: 1px solid #2d5a8e;
border-radius: 14px;
width: 52px; height: 52px;
display: flex; align-items: center; justify-content: center;
font-size: 1.7rem; flex-shrink: 0;
box-shadow: 0 0 20px rgba(126,184,247,0.25), 0 0 40px rgba(167,139,250,0.1);
">🧠</div>
<div>
<div style="
font-size: 2.1rem;
font-weight: 900;
letter-spacing: -0.04em;
line-height: 1.05;
background: linear-gradient(90deg, #7eb8f7 0%, #a78bfa 55%, #f0abfc 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
">DocuMind</div>
<div style="font-size:0.92rem; color:#7a8aa8; letter-spacing:0.01em; margin-top:1px;">
Intelligent answers &nbsp;·&nbsp; grounded in your document
</div>
</div>
</div>
""", unsafe_allow_html=True)
with header_right:
if st.session_state.current_doc_id:
label = "Hide PDF 📕" if st.session_state.show_pdf else "View PDF 📖"
Expand Down
Loading