NatalieMonged commited on
Commit
1a7d6c6
Β·
verified Β·
1 Parent(s): d92d96e

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +174 -0
app.py ADDED
@@ -0,0 +1,174 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import os
3
+ import tempfile
4
+ from langchain_google_genai import ChatGoogleGenerativeAI
5
+ from langchain_text_splitters import RecursiveCharacterTextSplitter
6
+ from langchain_community.document_loaders import PyPDFLoader
7
+ from langchain_core.prompts import PromptTemplate
8
+
9
+ # GLOBAL UI & STYLING CONFIGURATION
10
+ #===================================
11
+
12
+ st.set_page_config(page_title="MindFlow AI", layout="wide" , page_icon="πŸ’‘")
13
+
14
+ # Injecting specialized CSS to enhance User Experience (UX)
15
+ st.markdown("""
16
+ <style>
17
+ div.stButton > button:first-child {
18
+ background-color: #5DADE2;
19
+ color: white;
20
+ transition: all 0.3s ease;
21
+ }
22
+ div.stButton > button:first-child:hover {
23
+ background-color: #2E86C1;
24
+ border-color: #2E86C1;
25
+ color: #FFFFFF;
26
+ }
27
+ </style>
28
+ """, unsafe_allow_html=True)
29
+
30
+ # Custom Branding Header: Using HTML/CSS for advanced typography and branding alignment
31
+ st.markdown("""
32
+ <style>
33
+ @import url('https://fonts.googleapis.com/css2?family=Fredoka+One&family=Montserrat:wght@400;700&display=swap');
34
+ </style>
35
+ <div style='text-align: center; margin-bottom: 20px;'>
36
+ <h1 style='font-family: "Fredoka One", cursive; font-size: 60px; color: #5D6D7E; letter-spacing: 2px; margin-bottom: 0px;'>
37
+ MindFlow <span style='color: #85C1E9;'>AI</span> <br>
38
+ <span style='text-align: center; font-family: "Segoe UI";font-size: 30px; color: #666;'>Driven Assistant Summarization</span>
39
+ </h1>
40
+ </div>
41
+ """, unsafe_allow_html=True)
42
+
43
+ # BACKEND & MODEL INITIALIZATION
44
+ #====================================
45
+
46
+
47
+ # Setting the GOOGLE_API_KEY
48
+ os.environ["GOOGLE_API_KEY"] = "AIzaSyA0rDJF-58ffKHiuVvUpd5HHc4_1NfvrOM"
49
+
50
+ # Initialize Google Gemini Model
51
+ # Temperature 0.01 is utilized to minimize variance and ensure factual consistency
52
+ llm = ChatGoogleGenerativeAI(model="gemini-2.5-flash", temperature=0.01)
53
+
54
+
55
+ # SIDEBAR: Audience Type Controls
56
+ with st.sidebar:
57
+ st.title("User Settings")
58
+ st.markdown("### **Target Audience:**")
59
+ audience_type = st.radio("", ["Beginner", "Expert"])
60
+ st.info(f"Targeting: {audience_type} level.")
61
+
62
+ # Data Ingestion Layer
63
+ # Drag and drop a pdf OR paste a text manually
64
+ st.header("Input Source")
65
+ tab1, tab2 = st.tabs(["πŸ“„ Upload PDF", "✍️ Paste Text"])
66
+
67
+ full_text = ""
68
+
69
+ # Handling PDF uploads using LangChain loaders and temporary disk storage
70
+ with tab1:
71
+ uploaded_file = st.file_uploader("Upload PDF Document", type="pdf")
72
+ if uploaded_file:
73
+ with tempfile.NamedTemporaryFile(delete=False) as tmp_file:
74
+ tmp_file.write(uploaded_file.getvalue())
75
+ tmp_path = tmp_file.name
76
+
77
+ # Extracting semantic content from PDF
78
+ loader = PyPDFLoader(tmp_path)
79
+ pages = loader.load()
80
+ # Merging PDF pages
81
+ full_text = " ".join([page.page_content for page in pages])
82
+ # Ensuring local storage cleanup
83
+ os.remove(tmp_path)
84
+
85
+ # Handling direct text input
86
+ with tab2:
87
+ manual_text = st.text_area("Paste your article or text here:", height=300)
88
+ if manual_text:
89
+ full_text = manual_text
90
+
91
+ # PROCESSING PIPELINE: Summarization & Evaluation
92
+ if st.button("Generate & Evaluate"):
93
+ if full_text.strip():
94
+ with st.spinner("Processing..."):
95
+ # SEMANTIC CHUNKING PHASE
96
+ # Recursive splitting ensures text segments stay within LLM context windows
97
+ text_splitter = RecursiveCharacterTextSplitter(chunk_size=4000, chunk_overlap=300)
98
+ chunks = text_splitter.split_text(full_text)
99
+ text_to_process = " ".join(chunks[:2])
100
+
101
+ # TAILORED SUMMARIZATION PHASE
102
+ #Utilizing a persona-driven Prompt Template for audience-specific output
103
+ summary_prompt = PromptTemplate.from_template("""
104
+ [STRICT AUDIT MODE: ZERO HALLUCINATION TOLERANCE]
105
+ You are an elite expert. Your ONLY source of truth is the provided text.
106
+ CRITICAL RESTRICTION:
107
+ If a concept (like 'Regularization', 'Overfitting', or 'Lasso') is NOT explicitly mentioned in the source text,
108
+ you are FORBIDDEN from mentioning it, even if it is factually related to the topic.
109
+ Failure to follow this will result in an inaccurate evaluation.
110
+
111
+ Act as an elite educational consultant and technical expert. Your goal is to transform complex information into a high-quality summary perfectly tailored for a {audience} audience.
112
+
113
+ Target Persona:
114
+ - If Audience is "Beginner": You are a supportive teacher. Use simple analogies, avoid technical jargon unless explained, and focus on the "Big Picture" and "Why it matters." Use friendly, encouraging tone and clear bullet points.
115
+ - If Audience is "Expert": You are a senior researcher. Use precise academic terminology, focus on methodology, data results, and nuanced conclusions. Maintain high information density and professional tone.
116
+
117
+ Task Instructions:
118
+ 1. Core Essence**: Extract the most critical information without losing the original context.
119
+ 2. Structural Integrity: Organize the output with clear headers (e.g., "Overview", "Key Findings", "Implications").
120
+ 3. Contextual Adaptation:
121
+ - For Beginners: Include a "Simple Definition" section for complex terms.
122
+ - For Experts: Include a "Technical Highlights" section focusing on metrics or logic.
123
+ 4. Faithfulness: Ensure ( 100% ) accuracy to the source text; do not hallucinate or add external information[cite: 56].
124
+ CONSTRAINTS:
125
+ - STRICT ADHERENCE: Do NOT include any information, concepts, or terms that are NOT present in the source text.
126
+ - NO OUTSIDE KNOWLEDGE: Even if you know more about the topic, ignore it.
127
+ - FORBIDDEN TOPICS: If the source text does not mention things like 'Regularization' or 'Overfitting', you MUST NOT mention them.
128
+ - AUDIENCE ADAPTATION:
129
+ - If {audience} is Beginner: Explain ONLY the concepts in the text using simple analogies.
130
+ - If {audience} is Expert: Focus ONLY on the technical details provided in the text.
131
+ Source Text:
132
+ {text}
133
+ Final Output Requirements:
134
+ - Format: Professional Markdown.
135
+ - Language: Clear and Concise English[cite: 6].
136
+ - Accuracy: Maintain strict adherence to the facts provided in the document[cite: 56].
137
+ """)
138
+
139
+ summary_chain = summary_prompt | llm
140
+ summary_output = summary_chain.invoke({"audience": audience_type, "text": text_to_process})
141
+
142
+ st.subheader(f"πŸ“ Summary for {audience_type}")
143
+ st.markdown(summary_output.content)
144
+
145
+ st.divider()
146
+
147
+ # AUTOMATED AI-AS-A-JUDGE EVALUATION PHASE
148
+ # Implementing a secondary LLM chain to audit the quality of the generated summary
149
+ eval_prompt = PromptTemplate.from_template("""
150
+ As an AI Auditor, evaluate the summary against the source text.
151
+ Return a Markdown table with scores (1-5) and justifications.
152
+
153
+ | Criterion | Score | Justification |
154
+ | :--- | :--- | :--- |
155
+ | Faithfulness | | |
156
+ | Coherence | | |
157
+ | Audience Alignment | | |
158
+
159
+ Level: {level}
160
+ Source: {source}
161
+ Summary: {summary}
162
+ """)
163
+
164
+ eval_chain = eval_prompt | llm
165
+ eval_output = eval_chain.invoke({
166
+ "level": audience_type,
167
+ "source": text_to_process[:4000],
168
+ "summary": summary_output.content
169
+ })
170
+
171
+ st.subheader("πŸ“Š Automated Quality Evaluation")
172
+ st.markdown(eval_output.content)
173
+ else:
174
+ st.warning("Please upload a PDF or paste some text first!")