Basementup commited on
Commit
8dcba3e
·
verified ·
1 Parent(s): 1377cde

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +350 -38
app.py CHANGED
@@ -1,39 +1,351 @@
1
  import gradio as gr
2
- from pypdf import PdfReader
3
-
4
- def check_evidence(assertion, file_obj):
5
- if file_obj is None or not assertion:
6
- return "Waiting for file and assertion..."
7
-
8
- try:
9
- # Extract text from PDF
10
- reader = PdfReader(file_obj.name)
11
- evidence_text = ""
12
- for page in reader.pages:
13
- evidence_text += page.extract_text() or ""
14
-
15
- # Simple, clean comparison
16
- if assertion.lower().strip() in evidence_text.lower():
17
- return "VERIFIED: The assertion was found in the document."
18
- else:
19
- return "FAILED: The assertion does not exist in the document."
20
-
21
- except Exception as e:
22
- return f"Error: {str(e)}"
23
-
24
- # Minimalist Interface
25
- with gr.Blocks() as demo:
26
- gr.Markdown("# Universal Evidence Auditor")
27
-
28
- with gr.Row():
29
- with gr.Column():
30
- file_input = gr.File(label="Upload PDF", file_types=[".pdf"])
31
- claim_input = gr.Textbox(label="Assertion to Verify", placeholder="Paste the text you want to check...")
32
- run_btn = gr.Button("Run Audit")
33
-
34
- with gr.Column():
35
- output_text = gr.Textbox(label="Result", lines=5)
36
-
37
- run_btn.click(check_evidence, inputs=[claim_input, file_input], outputs=output_text)
38
-
39
- demo.launch()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import gradio as gr
2
+ import anthropic
3
+ import os
4
+
5
+ # ── Anthropic client (key from HF Space secret) ──────────────────────────────
6
+ def get_client():
7
+ api_key = os.environ.get("ANTHROPIC_API_KEY", "")
8
+ if not api_key:
9
+ raise gr.Error("⚠️ ANTHROPIC_API_KEY secret not set. Add it in Space Settings → Secrets.")
10
+ return anthropic.Anthropic(api_key=api_key)
11
+
12
+
13
+ # ── Technique runners ─────────────────────────────────────────────────────────
14
+
15
+ def run_perspective(persona: str, task: str, metaphor: str) -> str:
16
+ """Technique 1 – Perspective-Shifting Prompts"""
17
+ if not persona.strip() or not task.strip():
18
+ return "⚠️ Please fill in both the Persona and the Task fields."
19
+ prompt = f"Be a {persona} who explains {task}"
20
+ if metaphor.strip():
21
+ prompt += f" using {metaphor} metaphors"
22
+ prompt += ". Give a rich, vivid explanation."
23
+ client = get_client()
24
+ msg = client.messages.create(
25
+ model="claude-sonnet-4-20250514",
26
+ max_tokens=1000,
27
+ messages=[{"role": "user", "content": prompt}],
28
+ )
29
+ return msg.content[0].text
30
+
31
+
32
+ def run_constrained(ingredients: str, count: int) -> str:
33
+ """Technique 2 – Constrained Creativity Boosters"""
34
+ if not ingredients.strip():
35
+ return "⚠️ Please enter at least one ingredient / constraint."
36
+ items = [i.strip() for i in ingredients.split(",") if i.strip()]
37
+ prompt = (
38
+ f"Suggest {int(count)} innovative startup ideas that MUST incorporate ALL of the "
39
+ f"following elements: {', '.join(items)}. "
40
+ "Be wildly creative — find non-obvious connections. "
41
+ "For each idea: name, one-line pitch, and why the combination is powerful."
42
+ )
43
+ client = get_client()
44
+ msg = client.messages.create(
45
+ model="claude-sonnet-4-20250514",
46
+ max_tokens=1000,
47
+ messages=[{"role": "user", "content": prompt}],
48
+ )
49
+ return msg.content[0].text
50
+
51
+
52
+ def run_meta(goal: str, criteria: str) -> str:
53
+ """Technique 3 – Meta-Prompts for Precision"""
54
+ if not goal.strip():
55
+ return "⚠️ Please enter a goal."
56
+ ranking_criteria = criteria if criteria.strip() else "1. Effectiveness 2. Cost 3. Ease of implementation"
57
+ prompt = (
58
+ f"First, suggest 3 concrete ways to: {goal}\n\n"
59
+ f"Then rank them by:\n{ranking_criteria}\n\n"
60
+ "Finally, critically identify 2–3 potential flaws in your own ranking system and "
61
+ "explain how those flaws could be mitigated."
62
+ )
63
+ client = get_client()
64
+ msg = client.messages.create(
65
+ model="claude-sonnet-4-20250514",
66
+ max_tokens=1200,
67
+ messages=[{"role": "user", "content": prompt}],
68
+ )
69
+ return msg.content[0].text
70
+
71
+
72
+ def run_cot(problem: str, domain: str) -> str:
73
+ """Technique 4 – Chain-of-Thought Templates"""
74
+ if not problem.strip():
75
+ return "⚠️ Please describe the problem."
76
+ domain_hint = f" (domain: {domain})" if domain.strip() else ""
77
+ prompt = (
78
+ f"Let's solve this complex problem step by step{domain_hint}: {problem}\n\n"
79
+ "Follow this exact structure:\n"
80
+ "1. Break down the key components of the problem\n"
81
+ "2. Identify 3 potential failure points\n"
82
+ "3. Propose specific countermeasures for each failure point\n"
83
+ "4. Create a phased implementation roadmap\n"
84
+ "5. Predict 2 unexpected side effects (positive or negative) and how to handle them\n\n"
85
+ "Be thorough and specific at every step."
86
+ )
87
+ client = get_client()
88
+ msg = client.messages.create(
89
+ model="claude-sonnet-4-20250514",
90
+ max_tokens=1400,
91
+ messages=[{"role": "user", "content": prompt}],
92
+ )
93
+ return msg.content[0].text
94
+
95
+
96
+ # ── Custom CSS ────────────────────────────────────────────────────────────────
97
+ CSS = """
98
+ @import url('https://fonts.googleapis.com/css2?family=Syne:wght@400;700;800&family=DM+Mono:wght@400;500&display=swap');
99
+
100
+ :root {
101
+ --bg: #0b0c10;
102
+ --surface: #13151a;
103
+ --border: #1e2230;
104
+ --accent: #c8f135;
105
+ --accent2: #35f1c8;
106
+ --text: #e8eaf0;
107
+ --muted: #6b7280;
108
+ --radius: 10px;
109
+ }
110
+
111
+ body, .gradio-container {
112
+ background: var(--bg) !important;
113
+ font-family: 'Syne', sans-serif !important;
114
+ color: var(--text) !important;
115
+ }
116
+
117
+ /* Header */
118
+ .header-wrap {
119
+ text-align: center;
120
+ padding: 2.5rem 1rem 1.5rem;
121
+ border-bottom: 1px solid var(--border);
122
+ margin-bottom: 1.5rem;
123
+ }
124
+ .header-wrap h1 {
125
+ font-size: 2.6rem;
126
+ font-weight: 800;
127
+ letter-spacing: -0.03em;
128
+ background: linear-gradient(135deg, var(--accent) 0%, var(--accent2) 100%);
129
+ -webkit-background-clip: text;
130
+ -webkit-text-fill-color: transparent;
131
+ margin: 0;
132
+ }
133
+ .header-wrap p {
134
+ color: var(--muted);
135
+ font-family: 'DM Mono', monospace;
136
+ font-size: 0.85rem;
137
+ margin-top: 0.5rem;
138
+ }
139
+
140
+ /* Tabs */
141
+ .tab-nav button {
142
+ background: transparent !important;
143
+ color: var(--muted) !important;
144
+ border: 1px solid transparent !important;
145
+ border-radius: var(--radius) !important;
146
+ font-family: 'Syne', sans-serif !important;
147
+ font-weight: 700 !important;
148
+ font-size: 0.9rem !important;
149
+ padding: 0.5rem 1.2rem !important;
150
+ transition: all 0.2s !important;
151
+ }
152
+ .tab-nav button.selected {
153
+ background: var(--surface) !important;
154
+ color: var(--accent) !important;
155
+ border-color: var(--border) !important;
156
+ }
157
+ .tab-nav button:hover {
158
+ color: var(--text) !important;
159
+ }
160
+
161
+ /* Inputs & Textareas */
162
+ input[type="text"], textarea, .gr-textbox textarea {
163
+ background: var(--surface) !important;
164
+ border: 1px solid var(--border) !important;
165
+ border-radius: var(--radius) !important;
166
+ color: var(--text) !important;
167
+ font-family: 'DM Mono', monospace !important;
168
+ font-size: 0.88rem !important;
169
+ padding: 0.65rem 0.9rem !important;
170
+ transition: border-color 0.2s !important;
171
+ }
172
+ input[type="text"]:focus, textarea:focus {
173
+ border-color: var(--accent) !important;
174
+ outline: none !important;
175
+ box-shadow: 0 0 0 2px rgba(200, 241, 53, 0.12) !important;
176
+ }
177
+
178
+ /* Labels */
179
+ label span, .gr-form label {
180
+ color: var(--text) !important;
181
+ font-family: 'Syne', sans-serif !important;
182
+ font-weight: 700 !important;
183
+ font-size: 0.82rem !important;
184
+ letter-spacing: 0.06em !important;
185
+ text-transform: uppercase !important;
186
+ }
187
+
188
+ /* Buttons */
189
+ button.primary {
190
+ background: var(--accent) !important;
191
+ color: #0b0c10 !important;
192
+ border: none !important;
193
+ border-radius: var(--radius) !important;
194
+ font-family: 'Syne', sans-serif !important;
195
+ font-weight: 800 !important;
196
+ font-size: 0.9rem !important;
197
+ letter-spacing: 0.05em !important;
198
+ padding: 0.65rem 1.6rem !important;
199
+ cursor: pointer !important;
200
+ transition: transform 0.15s, opacity 0.15s !important;
201
+ }
202
+ button.primary:hover { opacity: 0.88 !important; transform: translateY(-1px) !important; }
203
+
204
+ /* Output box */
205
+ .output-box textarea {
206
+ background: #0f1117 !important;
207
+ border: 1px solid var(--border) !important;
208
+ border-left: 3px solid var(--accent2) !important;
209
+ font-family: 'DM Mono', monospace !important;
210
+ font-size: 0.86rem !important;
211
+ line-height: 1.65 !important;
212
+ color: var(--text) !important;
213
+ border-radius: 0 var(--radius) var(--radius) 0 !important;
214
+ }
215
+
216
+ /* Technique cards */
217
+ .technique-card {
218
+ background: var(--surface);
219
+ border: 1px solid var(--border);
220
+ border-radius: var(--radius);
221
+ padding: 1rem 1.2rem;
222
+ margin-bottom: 1rem;
223
+ }
224
+ .technique-card .badge {
225
+ display: inline-block;
226
+ font-family: 'DM Mono', monospace;
227
+ font-size: 0.72rem;
228
+ font-weight: 500;
229
+ letter-spacing: 0.08em;
230
+ text-transform: uppercase;
231
+ padding: 0.2rem 0.6rem;
232
+ border-radius: 4px;
233
+ background: rgba(200,241,53,0.12);
234
+ color: var(--accent);
235
+ margin-bottom: 0.4rem;
236
+ }
237
+ .technique-card p {
238
+ color: var(--muted);
239
+ font-size: 0.84rem;
240
+ margin: 0;
241
+ line-height: 1.55;
242
+ }
243
+
244
+ /* Slider */
245
+ input[type="range"] { accent-color: var(--accent) !important; }
246
+
247
+ /* Footer */
248
+ .footer-note {
249
+ text-align: center;
250
+ padding: 1.5rem;
251
+ color: var(--muted);
252
+ font-family: 'DM Mono', monospace;
253
+ font-size: 0.75rem;
254
+ border-top: 1px solid var(--border);
255
+ margin-top: 2rem;
256
+ }
257
+ """
258
+
259
+ # ── UI ────────────────────────────────────────────────────────────────────────
260
+ with gr.Blocks(css=CSS, title="Prompt Engineering Toolkit") as demo:
261
+
262
+ gr.HTML("""
263
+ <div class="header-wrap">
264
+ <h1>⚡ Prompt Engineering Toolkit</h1>
265
+ <p>4 battle-tested techniques for precision AI output</p>
266
+ </div>
267
+ """)
268
+
269
+ with gr.Tabs():
270
+
271
+ # ── Tab 1: Perspective-Shifting ───────────────────────────────────────
272
+ with gr.Tab("01 · Perspective Shift"):
273
+ gr.HTML("""
274
+ <div class="technique-card">
275
+ <div class="badge">Formula: Be X who does Y using Z metaphors</div>
276
+ <p>Forces the AI to adopt a specific expert persona, shaping tone, depth, and vocabulary.
277
+ The metaphor layer bridges complex domains into intuitive language.</p>
278
+ </div>
279
+ """)
280
+ with gr.Row():
281
+ ps_persona = gr.Textbox(label="Persona (X)", placeholder="e.g. neurosurgeon, jazz musician, Viking navigator")
282
+ ps_task = gr.Textbox(label="Explain / Do (Y)", placeholder="e.g. quantum entanglement, blockchain consensus")
283
+ ps_meta = gr.Textbox(label="Metaphor Domain (Z) — optional", placeholder="e.g. cooking, football, carpentry")
284
+ ps_btn = gr.Button("Generate →", variant="primary")
285
+ ps_out = gr.Textbox(label="Output", lines=14, elem_classes=["output-box"])
286
+ ps_btn.click(run_perspective, inputs=[ps_persona, ps_task, ps_meta], outputs=ps_out)
287
+
288
+ # ── Tab 2: Constrained Creativity ────────────────────────────────────
289
+ with gr.Tab("02 · Constrained Creativity"):
290
+ gr.HTML("""
291
+ <div class="technique-card">
292
+ <div class="badge">Concept: Limitations force innovation</div>
293
+ <p>By restricting the solution space to specific ingredients, the AI must find
294
+ non-obvious creative bridges — generating ideas that would never emerge from open-ended prompts.</p>
295
+ </div>
296
+ """)
297
+ cc_items = gr.Textbox(
298
+ label="Ingredients / Constraints (comma-separated)",
299
+ placeholder="e.g. 3D printers, seaweed, TikTok",
300
+ )
301
+ cc_count = gr.Slider(label="Number of Ideas", minimum=2, maximum=8, value=5, step=1)
302
+ cc_btn = gr.Button("Generate →", variant="primary")
303
+ cc_out = gr.Textbox(label="Output", lines=18, elem_classes=["output-box"])
304
+ cc_btn.click(run_constrained, inputs=[cc_items, cc_count], outputs=cc_out)
305
+
306
+ # ── Tab 3: Meta-Prompts ───────────────────────────────────────────────
307
+ with gr.Tab("03 · Meta-Prompts"):
308
+ gr.HTML("""
309
+ <div class="technique-card">
310
+ <div class="badge">Concept: Make the AI critique its own output</div>
311
+ <p>Multi-stage prompting forces the model to suggest, rank, then audit its own
312
+ reasoning — surfacing blind spots and producing genuinely reliable recommendations.</p>
313
+ </div>
314
+ """)
315
+ mp_goal = gr.Textbox(label="Goal / Challenge", placeholder="e.g. improve sleep quality, reduce team meeting time")
316
+ mp_criteria = gr.Textbox(
317
+ label="Ranking Criteria (one per line) — leave blank for defaults",
318
+ placeholder="1. Scientific validity\n2. Cost-effectiveness\n3. Ease of implementation",
319
+ lines=3,
320
+ )
321
+ mp_btn = gr.Button("Generate →", variant="primary")
322
+ mp_out = gr.Textbox(label="Output", lines=18, elem_classes=["output-box"])
323
+ mp_btn.click(run_meta, inputs=[mp_goal, mp_criteria], outputs=mp_out)
324
+
325
+ # ── Tab 4: Chain-of-Thought ───────────────────────────────────────────
326
+ with gr.Tab("04 · Chain of Thought"):
327
+ gr.HTML("""
328
+ <div class="technique-card">
329
+ <div class="badge">Concept: Force systematic reasoning</div>
330
+ <p>Breaks the problem into obligatory reasoning stages: decomposition → failure analysis →
331
+ countermeasures → roadmap → side-effect prediction. Prevents shallow or hand-wavy answers.</p>
332
+ </div>
333
+ """)
334
+ cot_problem = gr.Textbox(
335
+ label="Complex Problem",
336
+ placeholder="e.g. launching a product in a saturated market with zero ad budget",
337
+ lines=3,
338
+ )
339
+ cot_domain = gr.Textbox(label="Domain Hint — optional", placeholder="e.g. B2B SaaS, healthcare, fintech")
340
+ cot_btn = gr.Button("Generate ���", variant="primary")
341
+ cot_out = gr.Textbox(label="Output", lines=22, elem_classes=["output-box"])
342
+ cot_btn.click(run_cot, inputs=[cot_problem, cot_domain], outputs=cot_out)
343
+
344
+ gr.HTML("""
345
+ <div class="footer-note">
346
+ Powered by Claude · claude-sonnet-4-20250514 · Requires ANTHROPIC_API_KEY secret
347
+ </div>
348
+ """)
349
+
350
+ if __name__ == "__main__":
351
+ demo.launch()