banao-tech commited on
Commit
342895e
Β·
verified Β·
1 Parent(s): 8336a48

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +231 -0
app.py ADDED
@@ -0,0 +1,231 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import gradio as gr
3
+ import anthropic
4
+ from pypdf import PdfReader
5
+
6
+ # ── Anthropic client ──────────────────────────────────────────────────────────
7
+ # Set ANTHROPIC_API_KEY in your HuggingFace Space β†’ Settings β†’ Repository secrets
8
+ client = anthropic.Anthropic(api_key=os.environ.get("ANTHROPIC_API_KEY"))
9
+
10
+ SYSTEM_PROMPT = """You are an expert problem analyst and innovation coach helping interns understand real-world problems and brainstorm creative solutions.
11
+
12
+ When given a transcription or document, you will:
13
+
14
+ 1. **PROBLEM UNDERSTANDING**
15
+ - Identify and clearly articulate the core problem being discussed
16
+ - Highlight key pain points, stakeholders, and context
17
+ - Summarize what is known vs unknown about the problem
18
+
19
+ 2. **ROOT CAUSE ANALYSIS**
20
+ - Break down WHY this problem exists
21
+ - Identify underlying causes (technical, organizational, process-related)
22
+
23
+ 3. **BRAINSTORMING IDEAS**
24
+ - Generate 5–8 diverse, creative solution directions
25
+ - Include both quick wins and long-term strategic ideas
26
+ - Think across technology, process, and people dimensions
27
+
28
+ 4. **NEXT STEPS FOR INTERNS**
29
+ - Suggest 3 concrete actions the intern can take immediately to explore this further
30
+
31
+ Keep your tone encouraging, clear, and structured. Use headers and bullet points for readability."""
32
+
33
+
34
+ def extract_text_from_pdf(pdf_file) -> str:
35
+ """Extract all text from an uploaded PDF file."""
36
+ reader = PdfReader(pdf_file)
37
+ pages_text = []
38
+ for page in reader.pages:
39
+ text = page.extract_text()
40
+ if text:
41
+ pages_text.append(text.strip())
42
+ return "\n\n".join(pages_text)
43
+
44
+
45
+ def run_agent(text_input: str, pdf_file, progress=gr.Progress()):
46
+ """
47
+ Core agent function.
48
+ Accepts either pasted text or a PDF upload, then streams the analysis.
49
+ """
50
+ # ── Determine input source ────────────────────────────────────────────────
51
+ content = ""
52
+
53
+ if pdf_file is not None:
54
+ progress(0.1, desc="Reading PDF...")
55
+ try:
56
+ content = extract_text_from_pdf(pdf_file)
57
+ if not content.strip():
58
+ yield "⚠️ Could not extract text from this PDF. It may be scanned/image-based. Please paste the text manually."
59
+ return
60
+ except Exception as e:
61
+ yield f"⚠️ Error reading PDF: {str(e)}"
62
+ return
63
+
64
+ elif text_input and text_input.strip():
65
+ content = text_input.strip()
66
+
67
+ else:
68
+ yield "⚠️ Please paste a transcription or upload a PDF file to get started."
69
+ return
70
+
71
+ if len(content) < 50:
72
+ yield "⚠️ The input seems too short. Please provide more context for a meaningful analysis."
73
+ return
74
+
75
+ # ── Truncate very long inputs to stay within token limits ─────────────────
76
+ MAX_CHARS = 12000
77
+ if len(content) > MAX_CHARS:
78
+ content = content[:MAX_CHARS] + "\n\n[... content truncated for length ...]"
79
+
80
+ progress(0.3, desc="Analyzing problem...")
81
+
82
+ user_message = f"""Here is the transcription / document content to analyze:
83
+
84
+ ---
85
+ {content}
86
+ ---
87
+
88
+ Please provide a full problem analysis and brainstorming session based on this content."""
89
+
90
+ # ── Stream from Anthropic API ─────────────────────────────────────────────
91
+ output = ""
92
+ try:
93
+ with client.messages.stream(
94
+ model="claude-sonnet-4-20250514",
95
+ max_tokens=2048,
96
+ system=SYSTEM_PROMPT,
97
+ messages=[{"role": "user", "content": user_message}],
98
+ ) as stream:
99
+ progress(0.5, desc="Generating insights...")
100
+ for text_chunk in stream.text_stream:
101
+ output += text_chunk
102
+ yield output
103
+
104
+ except anthropic.AuthenticationError:
105
+ yield "⚠️ Invalid API key. Please set your ANTHROPIC_API_KEY in the Space secrets."
106
+ except anthropic.RateLimitError:
107
+ yield "⚠️ Rate limit hit. Please wait a moment and try again."
108
+ except Exception as e:
109
+ yield f"⚠️ Unexpected error: {str(e)}"
110
+
111
+
112
+ # ── Gradio UI ─────────────────────────────────────────────────────────────────
113
+ with gr.Blocks(
114
+ title="Intern Problem Brainstormer",
115
+ theme=gr.themes.Soft(
116
+ primary_hue="violet",
117
+ secondary_hue="slate",
118
+ font=[gr.themes.GoogleFont("Inter"), "sans-serif"],
119
+ ),
120
+ css="""
121
+ #header { text-align: center; padding: 1.5rem 0 0.5rem; }
122
+ #header h1 { font-size: 2rem; font-weight: 700; margin-bottom: 0.25rem; }
123
+ #header p { color: #6b7280; font-size: 0.95rem; }
124
+ .input-box textarea { font-size: 14px !important; line-height: 1.6 !important; }
125
+ #run-btn { font-size: 1rem !important; padding: 0.65rem 2rem !important; }
126
+ #output-box { font-size: 14px; line-height: 1.75; }
127
+ .gr-tab-item { font-weight: 500; }
128
+ """,
129
+ ) as demo:
130
+
131
+ # Header
132
+ gr.HTML("""
133
+ <div id="header">
134
+ <h1>🧠 Intern Problem Brainstormer</h1>
135
+ <p>Paste a meeting transcription or upload a PDF β€” get instant problem analysis & brainstormed solutions.</p>
136
+ </div>
137
+ """)
138
+
139
+ gr.Markdown("---")
140
+
141
+ with gr.Row(equal_height=False):
142
+ # ── Left column: Input ────────────────────────────────────────────────
143
+ with gr.Column(scale=1):
144
+ gr.Markdown("### πŸ“₯ Input")
145
+
146
+ with gr.Tabs():
147
+ with gr.Tab("πŸ“ Paste Text"):
148
+ text_input = gr.Textbox(
149
+ label="Transcription or problem description",
150
+ placeholder="Paste your meeting notes, transcription, or problem statement here...",
151
+ lines=14,
152
+ max_lines=30,
153
+ elem_classes=["input-box"],
154
+ )
155
+
156
+ with gr.Tab("πŸ“„ Upload PDF"):
157
+ pdf_input = gr.File(
158
+ label="Upload a PDF document",
159
+ file_types=[".pdf"],
160
+ file_count="single",
161
+ )
162
+ gr.Markdown(
163
+ "<small style='color:#6b7280'>Text-based PDFs only. Scanned PDFs won't work.</small>"
164
+ )
165
+
166
+ run_btn = gr.Button(
167
+ "⚑ Analyse & Brainstorm",
168
+ variant="primary",
169
+ elem_id="run-btn",
170
+ )
171
+
172
+ with gr.Accordion("ℹ️ How to use", open=False):
173
+ gr.Markdown("""
174
+ **Option 1 – Paste Text**
175
+ Copy-paste any transcription, meeting notes, or problem description into the text box.
176
+
177
+ **Option 2 – Upload PDF**
178
+ Upload a text-based PDF (e.g. a research doc, spec, or report).
179
+
180
+ **Then click ⚑ Analyse & Brainstorm** to get:
181
+ - A clear articulation of the core problem
182
+ - Root cause analysis
183
+ - 5–8 creative brainstormed ideas
184
+ - Concrete next steps for you as an intern
185
+ """)
186
+
187
+ # ── Right column: Output ──────────────────────────────────────────────
188
+ with gr.Column(scale=1):
189
+ gr.Markdown("### πŸ’‘ Analysis & Ideas")
190
+ output = gr.Markdown(
191
+ value="*Your analysis will appear here...*",
192
+ elem_id="output-box",
193
+ )
194
+
195
+ # ── Examples ──────────────────────────────────────────────────────────────
196
+ gr.Markdown("---")
197
+ gr.Markdown("### πŸ§ͺ Try an example")
198
+ gr.Examples(
199
+ examples=[
200
+ [
201
+ "In today's standup, the team discussed that customers are complaining that the onboarding flow takes too long. New users drop off after the third step in the sign-up process. We don't have clear data on exactly which step causes the most drop-off. The product team thinks it might be the email verification step but engineering says it could be the profile setup form. We have about 2 weeks before the next release and the CEO wants this fixed before the investor demo.",
202
+ None,
203
+ ],
204
+ [
205
+ "Meeting transcript: So the main issue we're facing is that our data pipeline fails every Friday evening when batch jobs run. The on-call engineer has to manually restart it each time. It's been happening for three months. We've tried looking at the logs but they're not detailed enough. The infrastructure team is overwhelmed and can't prioritize it. Meanwhile the analytics team can't get their Monday morning reports on time which is affecting business decisions.",
206
+ None,
207
+ ],
208
+ ],
209
+ inputs=[text_input, pdf_input],
210
+ label="Click an example to load it, then hit Analyse & Brainstorm",
211
+ )
212
+
213
+ # ── Wire up ───────────────────────────────────────────────────────────────
214
+ run_btn.click(
215
+ fn=run_agent,
216
+ inputs=[text_input, pdf_input],
217
+ outputs=output,
218
+ show_progress="full",
219
+ )
220
+
221
+ # Also allow Ctrl+Enter from the text box
222
+ text_input.submit(
223
+ fn=run_agent,
224
+ inputs=[text_input, pdf_input],
225
+ outputs=output,
226
+ show_progress="full",
227
+ )
228
+
229
+
230
+ if __name__ == "__main__":
231
+ demo.launch()