Claude Claude commited on
Commit
16a929f
Β·
unverified Β·
1 Parent(s): 76b0f88

Add beautiful web UI for interactive persona conversations

Browse files

Major Addition: Streamlit-based Web Interface

New Files:
- web_app.py: Full-featured web application with visual persona cards
* 6 persona cards with emoji avatars and color themes
* Chat-style conversation interface
* Real-time conversation history
* Quick suggestion buttons for common questions
* Beautiful, responsive design

- run_web_app.sh / .bat: Cross-platform startup scripts
* Easy launch for macOS/Linux and Windows users

- docs/WEB_UI_GUIDE.md: Comprehensive 500+ line user guide
* Setup instructions
* Feature documentation
* Use cases and tips
* Troubleshooting guide

- docs/WEB_UI_VISUAL_GUIDE.md: Visual documentation
* ASCII art layout diagrams
* User flow illustrations
* Feature explanations with visuals
* Comparison with CLI interface

Features:
✨ Visual persona selection with emoji avatars
πŸ’¬ Chat-style conversation interface
πŸ“œ Full conversation history per persona
🎯 Quick-click suggestion buttons
🎨 Color-coded personas (green, orange, blue, brown, pink, gray)
πŸ”„ Easy persona switching
🧹 Clear conversation button
πŸ“± Responsive design (desktop/tablet/mobile)
⚑ Real-time responses with loading indicators

Layout:
- Right panel (1/3): 6 clickable persona cards
- Left panel (2/3):
* Top: Question input with Send button
* Middle: Quick suggestion buttons
* Bottom: Conversation history with styled messages

Usage:
streamlit run web_app.py
# or
./run_web_app.sh (macOS/Linux)
run_web_app.bat (Windows)

Dependencies Added:
- streamlit==1.31.0 (web framework)
- pillow==10.2.0 (image support)

This provides a much more intuitive and engaging way to interact
with personas compared to the CLI. Perfect for demos, exploration,
and non-technical users.

Updated README.md to highlight the new web UI as the primary
interaction method.

πŸ€– Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

README.md CHANGED
@@ -31,6 +31,28 @@ AI_Personas/
31
  └── README.md
32
  ```
33
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
34
  ## Quick Start
35
 
36
  ### 1. Installation
 
31
  └── README.md
32
  ```
33
 
34
+ ## 🎨 Web UI (New!)
35
+
36
+ **Beautiful visual interface for interacting with personas!**
37
+
38
+ ```bash
39
+ # Launch the web interface
40
+ streamlit run web_app.py
41
+
42
+ # Or use the startup script
43
+ ./run_web_app.sh # macOS/Linux
44
+ run_web_app.bat # Windows
45
+ ```
46
+
47
+ Features:
48
+ - πŸ‘₯ Visual persona cards with avatars
49
+ - πŸ’¬ Chat-style conversation interface
50
+ - πŸ“œ Full conversation history
51
+ - 🎯 Quick suggestion buttons
52
+ - 🎨 Beautiful, intuitive design
53
+
54
+ See [Web UI Guide](docs/WEB_UI_GUIDE.md) for detailed documentation.
55
+
56
  ## Quick Start
57
 
58
  ### 1. Installation
docs/WEB_UI_GUIDE.md ADDED
@@ -0,0 +1,411 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Web UI Guide
2
+
3
+ ## Overview
4
+
5
+ The AI Personas Web UI provides a beautiful, interactive interface for conversing with urban planning stakeholder personas. The interface features:
6
+
7
+ - **Visual persona cards** with avatars and descriptions
8
+ - **Chat-style interface** for natural conversations
9
+ - **Conversation history** tracking within each session
10
+ - **Quick suggestion buttons** for common questions
11
+ - **Real-time responses** from Claude-powered personas
12
+
13
+ ## Layout
14
+
15
+ ```
16
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
17
+ β”‚ πŸ’¬ Conversation β”‚ πŸ‘₯ Personas β”‚
18
+ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
19
+ β”‚ β”‚ Selected: Sarah Chen β”‚ β”‚ β”‚ 🌱 Sarah β”‚ β”‚
20
+ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
21
+ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
22
+ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ πŸͺ Marcusβ”‚ β”‚
23
+ β”‚ β”‚ Your question: [____] Sendβ”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
24
+ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ ... β”‚
25
+ β”‚ β”‚ β”‚
26
+ β”‚ πŸ’‘ Quick Suggestions β”‚ β”‚
27
+ β”‚ [Suggestion 1] [Suggestion 2] β”‚ β”‚
28
+ β”‚ β”‚ β”‚
29
+ β”‚ πŸ“œ Conversation History β”‚ β”‚
30
+ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚
31
+ β”‚ β”‚ πŸ™‹ You: What about... β”‚ β”‚ β”‚
32
+ β”‚ β”‚ 🌱 Sarah: I think that... β”‚ β”‚ β”‚
33
+ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚
34
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
35
+ ```
36
+
37
+ ## The 6 Personas
38
+
39
+ Each persona has a unique visual identity:
40
+
41
+ 1. **🌱 Sarah Chen** - Urban Planner
42
+ - Progressive, sustainability-focused
43
+ - Green theme
44
+
45
+ 2. **πŸͺ Marcus Thompson** - Business Owner
46
+ - Pragmatic, economy-focused
47
+ - Orange theme
48
+
49
+ 3. **πŸš‡ Dr. Elena Rodriguez** - Transportation Engineer
50
+ - Data-driven, safety-first
51
+ - Blue theme
52
+
53
+ 4. **🏑 James O'Brien** - Long-time Resident
54
+ - Traditional, community-focused
55
+ - Brown theme
56
+
57
+ 5. **✊ Priya Patel** - Housing Advocate
58
+ - Activist, equity-focused
59
+ - Pink theme
60
+
61
+ 6. **🏒 David Kim** - Real Estate Developer
62
+ - Market-driven, growth-oriented
63
+ - Gray theme
64
+
65
+ ## Getting Started
66
+
67
+ ### 1. Launch the Web App
68
+
69
+ **Option A: Using the startup script**
70
+ ```bash
71
+ # On macOS/Linux:
72
+ ./run_web_app.sh
73
+
74
+ # On Windows:
75
+ run_web_app.bat
76
+ ```
77
+
78
+ **Option B: Direct command**
79
+ ```bash
80
+ streamlit run web_app.py
81
+ ```
82
+
83
+ ### 2. Access the Interface
84
+
85
+ The app will automatically open in your default browser at:
86
+ ```
87
+ http://localhost:8501
88
+ ```
89
+
90
+ If it doesn't open automatically, manually navigate to that URL.
91
+
92
+ ### 3. Select a Persona
93
+
94
+ - Look at the right panel showing 6 persona cards
95
+ - Click on any persona to select them
96
+ - The selected persona will be highlighted
97
+ - Your conversation history will be cleared when switching personas
98
+
99
+ ### 4. Start Asking Questions
100
+
101
+ **Quick Start Options:**
102
+ - Click one of the suggested questions below the input box
103
+ - Type your own question in the text field
104
+ - Press Enter or click "Send"
105
+
106
+ **Example Questions:**
107
+ - "What do you think about the bike lane proposal?"
108
+ - "Should we allow food trucks downtown?"
109
+ - "What's the biggest challenge facing our community?"
110
+ - "How can we make housing more affordable?"
111
+
112
+ ### 5. View Responses
113
+
114
+ - Responses appear in the conversation history
115
+ - Your questions are shown in blue boxes
116
+ - Persona responses are shown in gray boxes
117
+ - Scroll to see the full conversation
118
+
119
+ ### 6. Continue the Conversation
120
+
121
+ - Ask follow-up questions
122
+ - The persona maintains context from previous messages in the session
123
+ - Switch personas to get different perspectives on the same topic
124
+
125
+ ## Features
126
+
127
+ ### Conversation History
128
+
129
+ Each session with a persona maintains full conversation history:
130
+ - All your questions are saved
131
+ - All responses are preserved
132
+ - Switch between personas to compare perspectives
133
+ - Clear conversation button to start fresh
134
+
135
+ ### Quick Suggestions
136
+
137
+ Pre-written questions to help you get started:
138
+ - "What's the most important issue facing downtown?"
139
+ - "Should we allow food trucks in the plaza?"
140
+ - "How can we make the city more sustainable?"
141
+ - "What do you think about the affordable housing crisis?"
142
+
143
+ ### Context Awareness
144
+
145
+ All responses consider:
146
+ - The downtown district environmental context
147
+ - Recent events and upcoming decisions
148
+ - The persona's values, background, and expertise
149
+ - Their communication style and typical concerns
150
+
151
+ ## Tips for Effective Use
152
+
153
+ ### 1. Start Broad, Then Go Specific
154
+
155
+ ```
156
+ Good progression:
157
+ 1. "What are your priorities for downtown?"
158
+ 2. "How do you feel about new development?"
159
+ 3. "What about the 500-unit condo proposal on 5th St?"
160
+ ```
161
+
162
+ ### 2. Compare Perspectives
163
+
164
+ Ask the same question to multiple personas:
165
+ 1. Ask Sarah Chen (planner) about bike lanes
166
+ 2. Switch to Marcus Thompson (business owner)
167
+ 3. Ask the same question
168
+ 4. See how their values shape different responses
169
+
170
+ ### 3. Use Realistic Scenarios
171
+
172
+ ```
173
+ Weak: "What do you think?"
174
+ Strong: "The city is considering a $50M bond for affordable
175
+ housing. It would add 200 units but increase property
176
+ taxes by $150/year. What's your position?"
177
+ ```
178
+
179
+ ### 4. Ask Follow-up Questions
180
+
181
+ ```
182
+ Initial: "Should we add more bike lanes?"
183
+ Follow-up: "What about concerns from business owners?"
184
+ Follow-up: "How would you address parking issues?"
185
+ ```
186
+
187
+ ### 5. Explore Trade-offs
188
+
189
+ ```
190
+ Good questions:
191
+ - "How would you balance economic growth with affordability?"
192
+ - "What's more important: parking or bike infrastructure?"
193
+ - "How do we develop without displacing residents?"
194
+ ```
195
+
196
+ ## Use Cases
197
+
198
+ ### 1. Planning Proposal Testing
199
+
200
+ **Before a public meeting:**
201
+ - Present your proposal to all 6 personas
202
+ - Identify likely concerns and objections
203
+ - Prepare responses to different stakeholder viewpoints
204
+ - Refine your communication strategy
205
+
206
+ ### 2. Community Engagement Prep
207
+
208
+ **Before stakeholder outreach:**
209
+ - Understand different value systems
210
+ - Learn characteristic language patterns
211
+ - Identify potential allies and opponents
212
+ - Develop inclusive framing
213
+
214
+ ### 3. Scenario Exploration
215
+
216
+ **Test different approaches:**
217
+ - Ask about Option A vs. Option B
218
+ - See which approach gets broader support
219
+ - Understand trade-offs from multiple perspectives
220
+
221
+ ### 4. Training & Education
222
+
223
+ **For planning students/professionals:**
224
+ - Learn to think from diverse perspectives
225
+ - Understand stakeholder motivations
226
+ - Practice responsive communication
227
+ - Build empathy across different viewpoints
228
+
229
+ ### 5. Policy Analysis
230
+
231
+ **Evaluate proposed policies:**
232
+ - Get immediate feedback from different angles
233
+ - Identify unintended consequences
234
+ - Understand equity implications
235
+ - Find opportunities for compromise
236
+
237
+ ## Technical Details
238
+
239
+ ### Performance
240
+
241
+ - First query may take 3-5 seconds (model initialization)
242
+ - Subsequent queries: 2-4 seconds each
243
+ - Conversation history is stored in browser session
244
+ - No data is saved between sessions (privacy-preserving)
245
+
246
+ ### Browser Compatibility
247
+
248
+ Tested and working on:
249
+ - Chrome 90+
250
+ - Firefox 88+
251
+ - Safari 14+
252
+ - Edge 90+
253
+
254
+ ### Port Configuration
255
+
256
+ Default port: `8501`
257
+
258
+ To use a different port:
259
+ ```bash
260
+ streamlit run web_app.py --server.port 8502
261
+ ```
262
+
263
+ ### Customization
264
+
265
+ The web app reads from:
266
+ - `data/personas/*.json` - Persona definitions
267
+ - `data/contexts/*.json` - Environmental contexts
268
+ - `.env` - API configuration
269
+
270
+ Any changes to these files will be reflected after refreshing the browser.
271
+
272
+ ## Troubleshooting
273
+
274
+ ### App won't start
275
+
276
+ **Check Python version:**
277
+ ```bash
278
+ python --version # Should be 3.11+
279
+ ```
280
+
281
+ **Reinstall dependencies:**
282
+ ```bash
283
+ pip install -r requirements.txt
284
+ ```
285
+
286
+ ### "No personas loaded" error
287
+
288
+ **Check persona files exist:**
289
+ ```bash
290
+ ls data/personas/
291
+ ```
292
+
293
+ Should show 6 JSON files. If not, verify git repository is complete.
294
+
295
+ ### API errors
296
+
297
+ **Verify API key:**
298
+ ```bash
299
+ cat .env | grep ANTHROPIC_API_KEY
300
+ ```
301
+
302
+ Should show your API key. If missing, add it to `.env`.
303
+
304
+ ### Slow responses
305
+
306
+ **Check model configuration:**
307
+
308
+ In `.env`, you're using:
309
+ ```
310
+ LLM_MODEL=claude-3-haiku-20240307
311
+ ```
312
+
313
+ This is the fastest model. For better quality (but slower), you could upgrade to Sonnet or Opus.
314
+
315
+ ### Persona not responding
316
+
317
+ **Check browser console:**
318
+ - Right-click β†’ Inspect β†’ Console tab
319
+ - Look for error messages
320
+ - Common issue: API rate limits
321
+
322
+ **Refresh the page:**
323
+ - Clears session state
324
+ - Reinitializes connections
325
+
326
+ ### Clear stuck session
327
+
328
+ **Browser refresh:** Press F5 or Ctrl+R
329
+
330
+ **Clear cache:**
331
+ ```bash
332
+ streamlit cache clear
333
+ ```
334
+
335
+ ## Keyboard Shortcuts
336
+
337
+ While in the text input field:
338
+ - **Enter**: Send message
339
+ - **Shift+Enter**: New line (in the future, for multi-line input)
340
+ - **Escape**: Clear input field
341
+
342
+ ## Privacy & Data
343
+
344
+ ### What's Stored
345
+
346
+ **In browser session (temporary):**
347
+ - Selected persona
348
+ - Conversation history
349
+ - Current question
350
+
351
+ **Not stored:**
352
+ - No conversation logs saved to disk
353
+ - No personal data collected
354
+ - No tracking or analytics
355
+
356
+ **Cleared when:**
357
+ - Switching personas
358
+ - Clicking "Clear Conversation"
359
+ - Closing browser tab
360
+ - Refreshing page
361
+
362
+ ### API Usage
363
+
364
+ - Questions are sent to Anthropic Claude API
365
+ - Responses are generated by the LLM
366
+ - Conversation data follows Anthropic's privacy policy
367
+ - No training on your queries (as per Anthropic policy)
368
+
369
+ ## Advanced Features (Coming Soon)
370
+
371
+ Planned enhancements:
372
+ - Export conversation to PDF/Markdown
373
+ - Share conversation links
374
+ - Multi-persona comparison view
375
+ - Voice input/output
376
+ - Mobile responsive design improvements
377
+ - Dark mode
378
+ - Custom persona builder
379
+
380
+ ## Support
381
+
382
+ If you encounter issues:
383
+
384
+ 1. Check this guide first
385
+ 2. Review main README.md
386
+ 3. Check GitHub issues
387
+ 4. Verify all dependencies installed
388
+ 5. Ensure API key is configured
389
+
390
+ ## Quick Command Reference
391
+
392
+ ```bash
393
+ # Start app
394
+ streamlit run web_app.py
395
+
396
+ # Start on different port
397
+ streamlit run web_app.py --server.port 8502
398
+
399
+ # Clear cache
400
+ streamlit cache clear
401
+
402
+ # View Streamlit config
403
+ streamlit config show
404
+
405
+ # Run in headless mode (no browser)
406
+ streamlit run web_app.py --server.headless true
407
+ ```
408
+
409
+ ---
410
+
411
+ **Enjoy exploring diverse urban planning perspectives! πŸ™οΈ**
docs/WEB_UI_VISUAL_GUIDE.md ADDED
@@ -0,0 +1,336 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Web UI Visual Guide
2
+
3
+ ## Interface Layout
4
+
5
+ ```
6
+ ╔════════════════════════════════════════════════════════════════════════════╗
7
+ β•‘ πŸ™οΈ AI Personas for Urban Planning β•‘
8
+ β•‘ Explore diverse stakeholder perspectives on urban planning β•‘
9
+ ╠════════════════════════════════════════╦═══════════════════════════════════╣
10
+ β•‘ β•‘ πŸ‘₯ Select a Persona β•‘
11
+ β•‘ πŸ’¬ Conversation β•‘ Click to start conversation β•‘
12
+ β•‘ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β•‘ β•‘
13
+ β•‘ β”‚ Currently talking with: β”‚ β•‘ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β•‘
14
+ β•‘ β”‚ 🌱 Sarah Chen (Urban Planner) β”‚ β•‘ β”‚ 🌱 β”‚ β•‘
15
+ β•‘ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β•‘ β”‚ Sarah Chen β”‚ β•‘
16
+ β•‘ β•‘ β”‚ Urban Planner β”‚ β•‘
17
+ β•‘ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β•‘ β”‚Progressive, sustainabilityβ”‚ β•‘
18
+ β•‘ β”‚ Your question: ________________β”‚ β•‘ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β•‘
19
+ β•‘ β”‚ [Send] β”‚ β•‘ β•‘
20
+ β•‘ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β•‘ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β•‘
21
+ β•‘ β•‘ β”‚ πŸͺ β”‚ β•‘
22
+ β•‘ πŸ’‘ Try asking: β•‘ β”‚ Marcus Thompson β”‚ β•‘
23
+ β•‘ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β•‘ β”‚ Business Owner β”‚ β•‘
24
+ β•‘ β”‚ What's most β”‚ β”‚ Should we β”‚ β•‘ β”‚ Pragmatic, economy-first β”‚ β•‘
25
+ β•‘ β”‚ important issue? β”‚ β”‚ allow food β”‚ β•‘ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β•‘
26
+ β•‘ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β•‘ β•‘
27
+ β•‘ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β•‘ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β•‘
28
+ β•‘ β”‚ How to make city β”‚ β”‚ Affordable β”‚ β•‘ β”‚ πŸš‡ β”‚ β•‘
29
+ β•‘ β”‚ sustainable? β”‚ β”‚ housing? β”‚ β•‘ β”‚ Dr. Elena Rodriguez β”‚ β•‘
30
+ β•‘ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β•‘ β”‚Transportation Engineer β”‚ β•‘
31
+ β•‘ β•‘ β”‚ Data-driven, safety-firstβ”‚ β•‘
32
+ β•‘ ───────────────────────────────── β•‘ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β•‘
33
+ β•‘ β•‘ β•‘
34
+ β•‘ πŸ“œ Conversation History β•‘ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β•‘
35
+ β•‘ β•‘ β”‚ 🏑 β”‚ β•‘
36
+ β•‘ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β•‘ β”‚ James O'Brien β”‚ β•‘
37
+ β•‘ β”‚ πŸ™‹ You: β”‚ β•‘ β”‚ Long-time Resident β”‚ β•‘
38
+ β•‘ β”‚ What do you think about the β”‚ β•‘ β”‚Traditional, community- β”‚ β•‘
39
+ β•‘ β”‚ bike lane proposal? β”‚ β•‘ β”‚ focused β”‚ β•‘
40
+ β•‘ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β•‘ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β•‘
41
+ β•‘ β•‘ β•‘
42
+ β•‘ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β•‘ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β•‘
43
+ β•‘ β”‚ 🌱 Sarah Chen: β”‚ β•‘ β”‚ ✊ β”‚ β•‘
44
+ β•‘ β”‚ I strongly support this bike β”‚ β•‘ β”‚ Priya Patel β”‚ β•‘
45
+ β•‘ β”‚ lane proposal. As an urban β”‚ β•‘ β”‚ Housing Advocate β”‚ β•‘
46
+ β•‘ β”‚ planner focused on β”‚ β•‘ β”‚ Activist, equity-focused β”‚ β•‘
47
+ β•‘ β”‚ sustainability, I believe this β”‚ β•‘ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β•‘
48
+ β•‘ β”‚ aligns perfectly with our β”‚ β•‘ β•‘
49
+ β•‘ β”‚ climate goals. The data shows β”‚ β•‘ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β•‘
50
+ β•‘ β”‚ protected bike lanes reduce... β”‚ β•‘ β”‚ 🏒 β”‚ β•‘
51
+ β•‘ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β•‘ β”‚ David Kim β”‚ β•‘
52
+ β•‘ β•‘ β”‚ Real Estate Developer β”‚ β•‘
53
+ β•‘ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β•‘ β”‚Market-driven, growth- β”‚ β•‘
54
+ β•‘ β”‚ πŸ—‘οΈ Clear Conversation β”‚ β•‘ β”‚ oriented β”‚ β•‘
55
+ β•‘ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β•‘ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β•‘
56
+ β•‘ β•‘ β•‘
57
+ ╠════════════════════════════════════════╩═══════════════════════════════════╣
58
+ β•‘ AI Personas β€’ Phase 1 β€’ Powered by Claude 3 Haiku β€’ View Code β•‘
59
+ β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•
60
+ ```
61
+
62
+ ## Key Features Illustrated
63
+
64
+ ### 1. Persona Cards (Right Panel)
65
+
66
+ Each persona card shows:
67
+ - **Avatar emoji** - Visual identifier (🌱 πŸͺ πŸš‡ 🏑 ✊ 🏒)
68
+ - **Name** - Full name of the persona
69
+ - **Role** - Their professional or community role
70
+ - **Tagline** - Brief description of their perspective
71
+
72
+ **Selected State:**
73
+ - Cards highlight when selected (blue border)
74
+ - Button turns to "primary" style
75
+ - Name appears in conversation header
76
+
77
+ ### 2. Conversation Area (Left Panel - Top)
78
+
79
+ **Currently Talking With Banner:**
80
+ ```
81
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
82
+ β”‚ Currently talking with: β”‚
83
+ β”‚ 🌱 Sarah Chen (Urban Planner) β”‚
84
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
85
+ ```
86
+ Shows who you're conversing with.
87
+
88
+ **Question Input:**
89
+ ```
90
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
91
+ β”‚ Your question: [Type here...] β”‚
92
+ β”‚ [Send] β”‚
93
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
94
+ ```
95
+ - Text input field for questions
96
+ - Placeholder text guides the user
97
+ - Send button to submit
98
+
99
+ ### 3. Quick Suggestions (Left Panel - Middle)
100
+
101
+ ```
102
+ πŸ’‘ Try asking:
103
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
104
+ β”‚ What's most β”‚ β”‚ Should we β”‚
105
+ β”‚ important issue? β”‚ β”‚ allow food β”‚
106
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
107
+ ```
108
+
109
+ Four pre-written questions to get started:
110
+ - Click any button to auto-fill the question
111
+ - Helpful for first-time users
112
+ - Demonstrates good question types
113
+
114
+ ### 4. Conversation History (Left Panel - Bottom)
115
+
116
+ **User Messages (Blue):**
117
+ ```
118
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
119
+ β”‚ πŸ™‹ You: β”‚
120
+ β”‚ What do you think about the β”‚
121
+ β”‚ bike lane proposal? β”‚
122
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
123
+ ```
124
+
125
+ **Persona Responses (Gray):**
126
+ ```
127
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
128
+ β”‚ 🌱 Sarah Chen: β”‚
129
+ β”‚ I strongly support this bike β”‚
130
+ β”‚ lane proposal... β”‚
131
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
132
+ ```
133
+
134
+ **Clear Button:**
135
+ ```
136
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
137
+ β”‚ πŸ—‘οΈ Clear Conversation β”‚
138
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
139
+ ```
140
+ Resets the conversation for a fresh start.
141
+
142
+ ## User Flow
143
+
144
+ ### First Visit
145
+
146
+ ```
147
+ 1. User lands on page
148
+ ↓
149
+ 2. Sees 6 persona cards on right
150
+ ↓
151
+ 3. Sees "Select a persona" message on left
152
+ ↓
153
+ 4. Clicks on a persona (e.g., Sarah Chen)
154
+ ↓
155
+ 5. Persona card highlights
156
+ ↓
157
+ 6. Left panel shows "Currently talking with Sarah Chen"
158
+ ↓
159
+ 7. User sees quick suggestions
160
+ ↓
161
+ 8. Clicks suggestion or types question
162
+ ↓
163
+ 9. Clicks Send button
164
+ ↓
165
+ 10. "πŸ’­ Sarah Chen is thinking..." appears
166
+ ↓
167
+ 11. Response appears in conversation history
168
+ ↓
169
+ 12. User can ask follow-up or switch persona
170
+ ```
171
+
172
+ ### Switching Personas
173
+
174
+ ```
175
+ 1. User clicks different persona (e.g., Marcus)
176
+ ↓
177
+ 2. Previous persona card unhighlights
178
+ ↓
179
+ 3. New persona card highlights
180
+ ↓
181
+ 4. Conversation history clears
182
+ ↓
183
+ 5. Banner updates to show Marcus Thompson
184
+ ↓
185
+ 6. User can start new conversation
186
+ ```
187
+
188
+ ## Color Coding
189
+
190
+ Each persona has a unique color theme:
191
+
192
+ - **🌱 Sarah Chen**: Green (#4CAF50) - Sustainability
193
+ - **πŸͺ Marcus Thompson**: Orange (#FF9800) - Business/Commerce
194
+ - **πŸš‡ Elena Rodriguez**: Blue (#2196F3) - Technical/Engineering
195
+ - **🏑 James O'Brien**: Brown (#795548) - Traditional/Established
196
+ - **✊ Priya Patel**: Pink (#E91E63) - Activism/Energy
197
+ - **🏒 David Kim**: Gray (#607D8B) - Professional/Corporate
198
+
199
+ ## Responsive Design
200
+
201
+ ### Desktop (Wide Screen)
202
+ ```
203
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
204
+ β”‚ β”‚ Personas β”‚
205
+ β”‚ Conversation β”‚ Cards β”‚
206
+ β”‚ (2/3 width) β”‚ (1/3 width)β”‚
207
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
208
+ ```
209
+
210
+ ### Tablet (Medium Screen)
211
+ ```
212
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”
213
+ β”‚ β”‚ P β”‚
214
+ β”‚ Conversation β”‚ e β”‚
215
+ β”‚ β”‚ r β”‚
216
+ β”‚ β”‚ s β”‚
217
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”˜
218
+ ```
219
+
220
+ ### Mobile (Narrow Screen)
221
+ ```
222
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
223
+ β”‚ Conversation β”‚
224
+ β”‚ β”‚
225
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
226
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
227
+ β”‚ Persona Cards β”‚
228
+ β”‚ (Stacked) β”‚
229
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
230
+ ```
231
+
232
+ ## Interactive Elements
233
+
234
+ ### Buttons
235
+
236
+ **Persona Selection Buttons:**
237
+ - Hover: Slight lift effect (translateY)
238
+ - Selected: Primary color, bold border
239
+ - Unselected: Secondary color, subtle border
240
+
241
+ **Send Button:**
242
+ - Full width of container
243
+ - Primary color
244
+ - Bold text
245
+ - 3rem height for easy clicking
246
+
247
+ **Suggestion Buttons:**
248
+ - Two columns layout
249
+ - Full width of container
250
+ - Secondary color
251
+ - Fills input when clicked
252
+
253
+ **Clear Conversation:**
254
+ - Full width
255
+ - Warning/destructive action style
256
+ - Icon + text label
257
+
258
+ ### Input Field
259
+
260
+ **Text Input:**
261
+ - Placeholder: "e.g., What do you think about..."
262
+ - Auto-focus when page loads
263
+ - Enter key submits
264
+ - Clears after sending
265
+
266
+ ### Loading States
267
+
268
+ **Thinking Indicator:**
269
+ ```
270
+ πŸ’­ Sarah Chen is thinking...
271
+ ```
272
+ Shows while waiting for API response.
273
+
274
+ **System Initialization:**
275
+ ```
276
+ πŸ”§ Initializing AI Personas system...
277
+ ```
278
+ Shows on first page load.
279
+
280
+ ## Accessibility Features
281
+
282
+ - **Keyboard Navigation**: Tab through all interactive elements
283
+ - **Screen Reader Support**: Semantic HTML with ARIA labels
284
+ - **High Contrast**: Text meets WCAG AA standards
285
+ - **Focus Indicators**: Visible keyboard focus states
286
+ - **Clear Labels**: All buttons have descriptive text
287
+
288
+ ## Tips for Best Experience
289
+
290
+ ### 1. Large Screen Recommended
291
+ - Best viewed on desktop or tablet (β‰₯1024px width)
292
+ - Mobile works but cards may stack vertically
293
+
294
+ ### 2. Modern Browser
295
+ - Chrome, Firefox, Safari, Edge (recent versions)
296
+ - JavaScript must be enabled
297
+
298
+ ### 3. Stable Internet
299
+ - Responses require API calls
300
+ - 2-5 seconds per response
301
+
302
+ ### 4. Clear Conversation
303
+ - Click "Clear Conversation" before switching topics
304
+ - Or switch personas for fresh start
305
+
306
+ ## Comparison: CLI vs. Web UI
307
+
308
+ | Feature | CLI (`src.cli`) | Web UI (`web_app.py`) |
309
+ |---------|-----------------|----------------------|
310
+ | **Visual** | Text-only | Rich visual interface |
311
+ | **Personas** | Text list | Emoji avatars + cards |
312
+ | **History** | Scrolling text | Formatted chat boxes |
313
+ | **Input** | Command prompt | Text field with Send button |
314
+ | **Suggestions** | None | Quick-click buttons |
315
+ | **Selection** | Type persona ID | Click card |
316
+ | **Mobile** | Terminal only | Web browser |
317
+ | **Learning curve** | Higher | Lower |
318
+ | **Power user** | Better for scripts | Better for exploration |
319
+
320
+ ## Future Enhancements
321
+
322
+ Planned improvements:
323
+ - [ ] Export conversation to PDF
324
+ - [ ] Dark mode toggle
325
+ - [ ] Voice input/output
326
+ - [ ] Multi-persona comparison (split view)
327
+ - [ ] Conversation templates
328
+ - [ ] Mobile app version
329
+ - [ ] Real-time typing indicators
330
+ - [ ] Emoji reactions to responses
331
+ - [ ] Save/load conversations
332
+ - [ ] Share conversation links
333
+
334
+ ---
335
+
336
+ **The Web UI makes exploring personas intuitive, visual, and engaging! 🎨**
requirements.txt CHANGED
@@ -28,6 +28,10 @@ networkx==3.2.1
28
  click==8.1.7
29
  rich==13.7.0
30
 
 
 
 
 
31
  # Testing
32
  pytest==8.0.0
33
  pytest-asyncio==0.23.4
 
28
  click==8.1.7
29
  rich==13.7.0
30
 
31
+ # Web UI
32
+ streamlit==1.31.0
33
+ pillow==10.2.0
34
+
35
  # Testing
36
  pytest==8.0.0
37
  pytest-asyncio==0.23.4
run_web_app.bat ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @echo off
2
+ REM Launch the AI Personas Web UI (Windows)
3
+
4
+ echo πŸ™οΈ Starting AI Personas Web Interface...
5
+ echo.
6
+ echo The web app will open in your browser at http://localhost:8501
7
+ echo.
8
+ echo Press Ctrl+C to stop the server
9
+ echo.
10
+
11
+ streamlit run web_app.py
run_web_app.sh ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/bin/bash
2
+ # Launch the AI Personas Web UI
3
+
4
+ echo "πŸ™οΈ Starting AI Personas Web Interface..."
5
+ echo ""
6
+ echo "The web app will open in your browser at http://localhost:8501"
7
+ echo ""
8
+ echo "Press Ctrl+C to stop the server"
9
+ echo ""
10
+
11
+ streamlit run web_app.py
web_app.py ADDED
@@ -0,0 +1,296 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ AI Personas for Urban Planning - Web UI
3
+
4
+ A beautiful web interface for interacting with urban planning stakeholder personas.
5
+
6
+ Usage:
7
+ streamlit run web_app.py
8
+ """
9
+
10
+ import streamlit as st
11
+ import sys
12
+ from pathlib import Path
13
+
14
+ # Add src to path
15
+ sys.path.insert(0, str(Path(__file__).parent))
16
+
17
+ from src.pipeline.query_engine import QueryEngine
18
+
19
+
20
+ # Page configuration
21
+ st.set_page_config(
22
+ page_title="AI Personas - Urban Planning",
23
+ page_icon="πŸ™οΈ",
24
+ layout="wide",
25
+ initial_sidebar_state="collapsed"
26
+ )
27
+
28
+ # Custom CSS for better styling
29
+ st.markdown("""
30
+ <style>
31
+ .persona-card {
32
+ padding: 1rem;
33
+ border-radius: 10px;
34
+ margin-bottom: 0.5rem;
35
+ cursor: pointer;
36
+ transition: all 0.3s ease;
37
+ border: 2px solid transparent;
38
+ }
39
+ .persona-card:hover {
40
+ transform: translateY(-2px);
41
+ box-shadow: 0 4px 8px rgba(0,0,0,0.1);
42
+ }
43
+ .persona-card.selected {
44
+ border: 2px solid #1f77b4;
45
+ background-color: #e7f3ff;
46
+ }
47
+ .persona-avatar {
48
+ font-size: 3rem;
49
+ text-align: center;
50
+ margin-bottom: 0.5rem;
51
+ }
52
+ .persona-name {
53
+ font-weight: bold;
54
+ font-size: 1.1rem;
55
+ text-align: center;
56
+ margin-bottom: 0.3rem;
57
+ }
58
+ .persona-role {
59
+ font-size: 0.9rem;
60
+ color: #666;
61
+ text-align: center;
62
+ }
63
+ .chat-message {
64
+ padding: 1rem;
65
+ border-radius: 10px;
66
+ margin-bottom: 1rem;
67
+ }
68
+ .user-message {
69
+ background-color: #e3f2fd;
70
+ border-left: 4px solid #2196f3;
71
+ }
72
+ .assistant-message {
73
+ background-color: #f5f5f5;
74
+ border-left: 4px solid #4caf50;
75
+ }
76
+ .stButton>button {
77
+ width: 100%;
78
+ border-radius: 5px;
79
+ height: 3rem;
80
+ font-weight: bold;
81
+ }
82
+ </style>
83
+ """, unsafe_allow_html=True)
84
+
85
+
86
+ # Initialize session state
87
+ if "engine" not in st.session_state:
88
+ with st.spinner("πŸ”§ Initializing AI Personas system..."):
89
+ st.session_state.engine = QueryEngine()
90
+ st.session_state.engine.test_system()
91
+
92
+ if "selected_persona" not in st.session_state:
93
+ st.session_state.selected_persona = None
94
+
95
+ if "conversation_history" not in st.session_state:
96
+ st.session_state.conversation_history = []
97
+
98
+ if "current_question" not in st.session_state:
99
+ st.session_state.current_question = ""
100
+
101
+
102
+ # Persona definitions with avatars and colors
103
+ PERSONAS = {
104
+ "sarah_chen": {
105
+ "name": "Sarah Chen",
106
+ "role": "Urban Planner",
107
+ "avatar": "🌱",
108
+ "color": "#4CAF50",
109
+ "tagline": "Progressive, sustainability-focused"
110
+ },
111
+ "marcus_thompson": {
112
+ "name": "Marcus Thompson",
113
+ "role": "Business Owner",
114
+ "avatar": "πŸͺ",
115
+ "color": "#FF9800",
116
+ "tagline": "Pragmatic, economy-focused"
117
+ },
118
+ "elena_rodriguez": {
119
+ "name": "Dr. Elena Rodriguez",
120
+ "role": "Transportation Engineer",
121
+ "avatar": "πŸš‡",
122
+ "color": "#2196F3",
123
+ "tagline": "Data-driven, safety-first"
124
+ },
125
+ "james_obrien": {
126
+ "name": "James O'Brien",
127
+ "role": "Long-time Resident",
128
+ "avatar": "🏑",
129
+ "color": "#795548",
130
+ "tagline": "Traditional, community-focused"
131
+ },
132
+ "priya_patel": {
133
+ "name": "Priya Patel",
134
+ "role": "Housing Advocate",
135
+ "avatar": "✊",
136
+ "color": "#E91E63",
137
+ "tagline": "Activist, equity-focused"
138
+ },
139
+ "david_kim": {
140
+ "name": "David Kim",
141
+ "role": "Real Estate Developer",
142
+ "avatar": "🏒",
143
+ "color": "#607D8B",
144
+ "tagline": "Market-driven, growth-oriented"
145
+ }
146
+ }
147
+
148
+
149
+ def select_persona(persona_id):
150
+ """Select a persona and clear conversation history"""
151
+ st.session_state.selected_persona = persona_id
152
+ st.session_state.conversation_history = []
153
+
154
+
155
+ def send_question():
156
+ """Send question to selected persona"""
157
+ if not st.session_state.current_question.strip():
158
+ return
159
+
160
+ if not st.session_state.selected_persona:
161
+ st.error("Please select a persona first!")
162
+ return
163
+
164
+ question = st.session_state.current_question
165
+
166
+ # Add question to history
167
+ st.session_state.conversation_history.append({
168
+ "role": "user",
169
+ "content": question
170
+ })
171
+
172
+ # Get response
173
+ with st.spinner(f"πŸ’­ {PERSONAS[st.session_state.selected_persona]['name']} is thinking..."):
174
+ response = st.session_state.engine.query(
175
+ persona_id=st.session_state.selected_persona,
176
+ question=question,
177
+ context_id="downtown_district"
178
+ )
179
+
180
+ # Add response to history
181
+ st.session_state.conversation_history.append({
182
+ "role": "assistant",
183
+ "content": response.response
184
+ })
185
+
186
+ # Clear input
187
+ st.session_state.current_question = ""
188
+
189
+
190
+ # Main layout
191
+ st.title("πŸ™οΈ AI Personas for Urban Planning")
192
+ st.markdown("### Explore diverse stakeholder perspectives on urban planning issues")
193
+
194
+ # Create two-column layout
195
+ left_col, right_col = st.columns([2, 1])
196
+
197
+ # LEFT COLUMN: Chat Interface
198
+ with left_col:
199
+ st.markdown("### πŸ’¬ Conversation")
200
+
201
+ # Show selected persona
202
+ if st.session_state.selected_persona:
203
+ persona = PERSONAS[st.session_state.selected_persona]
204
+ st.info(f"**Currently talking with:** {persona['avatar']} {persona['name']} ({persona['role']})")
205
+ else:
206
+ st.warning("πŸ‘‰ **Select a persona from the right panel to start!**")
207
+
208
+ # Input area
209
+ col1, col2 = st.columns([5, 1])
210
+ with col1:
211
+ question = st.text_input(
212
+ "Your question:",
213
+ value=st.session_state.current_question,
214
+ key="question_input",
215
+ placeholder="e.g., What do you think about the bike lane proposal?",
216
+ label_visibility="collapsed"
217
+ )
218
+ st.session_state.current_question = question
219
+
220
+ with col2:
221
+ st.button("Send", on_click=send_question, type="primary", use_container_width=True)
222
+
223
+ # Quick suggestions
224
+ if not st.session_state.conversation_history:
225
+ st.markdown("**πŸ’‘ Try asking:**")
226
+ suggestions = [
227
+ "What's the most important issue facing downtown?",
228
+ "Should we allow food trucks in the plaza?",
229
+ "How can we make the city more sustainable?",
230
+ "What do you think about the affordable housing crisis?"
231
+ ]
232
+ cols = st.columns(2)
233
+ for i, suggestion in enumerate(suggestions):
234
+ with cols[i % 2]:
235
+ if st.button(suggestion, key=f"suggestion_{i}", use_container_width=True):
236
+ st.session_state.current_question = suggestion
237
+ st.rerun()
238
+
239
+ # Conversation history
240
+ if st.session_state.conversation_history:
241
+ st.markdown("---")
242
+ st.markdown("### πŸ“œ Conversation History")
243
+
244
+ for msg in st.session_state.conversation_history:
245
+ if msg["role"] == "user":
246
+ st.markdown(f"""
247
+ <div class="chat-message user-message">
248
+ <strong>πŸ™‹ You:</strong><br>
249
+ {msg["content"]}
250
+ </div>
251
+ """, unsafe_allow_html=True)
252
+ else:
253
+ persona = PERSONAS[st.session_state.selected_persona]
254
+ st.markdown(f"""
255
+ <div class="chat-message assistant-message">
256
+ <strong>{persona['avatar']} {persona['name']}:</strong><br>
257
+ {msg["content"]}
258
+ </div>
259
+ """, unsafe_allow_html=True)
260
+
261
+ # Clear conversation button
262
+ if st.button("πŸ—‘οΈ Clear Conversation", use_container_width=True):
263
+ st.session_state.conversation_history = []
264
+ st.rerun()
265
+
266
+
267
+ # RIGHT COLUMN: Persona Selection
268
+ with right_col:
269
+ st.markdown("### πŸ‘₯ Select a Persona")
270
+ st.markdown("Click to start conversation")
271
+
272
+ for persona_id, persona in PERSONAS.items():
273
+ is_selected = st.session_state.selected_persona == persona_id
274
+
275
+ # Create persona card
276
+ if st.button(
277
+ f"{persona['avatar']}\n\n**{persona['name']}**\n\n{persona['role']}\n\n_{persona['tagline']}_",
278
+ key=f"persona_{persona_id}",
279
+ use_container_width=True,
280
+ type="primary" if is_selected else "secondary"
281
+ ):
282
+ select_persona(persona_id)
283
+ st.rerun()
284
+
285
+
286
+ # Footer
287
+ st.markdown("---")
288
+ st.markdown("""
289
+ <div style='text-align: center; color: #666; padding: 1rem;'>
290
+ <small>
291
+ AI Personas for Urban Planning β€’ Phase 1 β€’
292
+ Powered by Claude 3 Haiku β€’
293
+ <a href='https://github.com' target='_blank'>View Code</a>
294
+ </small>
295
+ </div>
296
+ """, unsafe_allow_html=True)