jostlebot Claude Opus 4.5 commited on
Commit
d4119b5
·
1 Parent(s): cf2ab28

Add feelings selector UI at Stage 2

Browse files

Implements feelings checkboxes similar to needs selector:
- 5 categories of feelings (When Needs Are Met, Sad/Hurt,
Scared/Anxious, Angry/Frustrated, Confused/Tired)
- Appears at Stage 2 (Feeling Reflection)
- Selected feelings stored in session and passed to Claude

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

Files changed (1) hide show
  1. app.py +77 -20
app.py CHANGED
@@ -43,15 +43,34 @@ NEEDS_LIST = {
43
  ]
44
  }
45
 
46
- FEELINGS_CONNECTED = [
47
- "grateful", "peaceful", "joyful", "content", "hopeful",
48
- "confident", "curious", "excited", "relieved", "touched"
49
- ]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50
 
51
- FEELINGS_WANTING = [
52
- "frustrated", "anxious", "sad", "hurt", "disappointed",
53
- "overwhelmed", "confused", "lonely", "scared", "angry"
54
- ]
55
 
56
  # ============ SYSTEM PROMPTS ============
57
 
@@ -308,7 +327,7 @@ def format_history(history):
308
  output += "---\n\n"
309
  return output
310
 
311
- def process_message(user_input, history, stage, session_data, somatic_enabled, selected_needs_str):
312
  """Process user message and return updated state"""
313
 
314
  if not user_input.strip():
@@ -337,20 +356,26 @@ def process_message(user_input, history, stage, session_data, somatic_enabled, s
337
  if response is None:
338
  error_msg = "**Setup Required:** Please add ANTHROPIC_API_KEY in Space Settings > Repository secrets, then restart."
339
  history.append({"user": user_input, "assistant": error_msg})
 
340
  show_needs = (stage == 5)
341
- return format_history(history), "", history, stage, session_data, f"Stage {stage}: {STAGE_NAMES[stage]}", gr.update(visible=show_needs)
342
 
343
  except Exception as e:
344
  error_msg = f"**Error:** {str(e)}"
345
  history.append({"user": user_input, "assistant": error_msg})
 
346
  show_needs = (stage == 5)
347
- return format_history(history), "", history, stage, session_data, f"Stage {stage}: {STAGE_NAMES[stage]}", gr.update(visible=show_needs)
348
 
349
  # Update session data
350
  if stage == 1:
351
  session_data["original_message"] = user_input
352
  elif stage == 2:
353
- session_data["feelings"] = user_input
 
 
 
 
354
  elif stage == 5 and selected_needs_str:
355
  session_data["needs"] = selected_needs_str
356
 
@@ -368,7 +393,8 @@ def process_message(user_input, history, stage, session_data, somatic_enabled, s
368
  next_stage = 1
369
  session_data = {}
370
 
371
- # Show needs selector only at stage 5
 
372
  show_needs = (next_stage == 5)
373
 
374
  return (
@@ -378,6 +404,7 @@ def process_message(user_input, history, stage, session_data, somatic_enabled, s
378
  next_stage,
379
  session_data,
380
  f"Stage {next_stage}/13: {STAGE_NAMES[next_stage]}",
 
381
  gr.update(visible=show_needs)
382
  )
383
 
@@ -390,8 +417,11 @@ def reset_session():
390
  1,
391
  {},
392
  "Stage 1/13: Share Your Message",
393
- gr.update(visible=False),
394
- [], [], [], []
 
 
 
395
  )
396
 
397
  def update_needs_display(e1, e2, e3, e4):
@@ -399,6 +429,11 @@ def update_needs_display(e1, e2, e3, e4):
399
  all_needs = e1 + e2 + e3 + e4
400
  return ", ".join(all_needs) if all_needs else ""
401
 
 
 
 
 
 
402
  # ============ BUILD INTERFACE ============
403
 
404
  with gr.Blocks(
@@ -433,6 +468,19 @@ with gr.Blocks(
433
  label="Conversation"
434
  )
435
 
 
 
 
 
 
 
 
 
 
 
 
 
 
436
  # Needs selector (hidden until Stage 5)
437
  with gr.Accordion("Select Your Needs", open=True, visible=False) as needs_accordion:
438
  gr.Markdown("**Select 1-3 needs that resonate most deeply:**")
@@ -478,6 +526,14 @@ with gr.Blocks(
478
  [Learn more at CNVC.org](https://www.cnvc.org/)
479
  """)
480
 
 
 
 
 
 
 
 
 
481
  # Update needs display
482
  for cb in [needs1, needs2, needs3, needs4]:
483
  cb.change(
@@ -489,14 +545,14 @@ with gr.Blocks(
489
  # Submit handler
490
  submit_btn.click(
491
  process_message,
492
- [user_input, history_state, stage_state, session_state, somatic_check, selected_needs],
493
- [conversation, user_input, history_state, stage_state, session_state, stage_display, needs_accordion]
494
  )
495
 
496
  user_input.submit(
497
  process_message,
498
- [user_input, history_state, stage_state, session_state, somatic_check, selected_needs],
499
- [conversation, user_input, history_state, stage_state, session_state, stage_display, needs_accordion]
500
  )
501
 
502
  # Reset handler
@@ -504,7 +560,8 @@ with gr.Blocks(
504
  reset_session,
505
  [],
506
  [conversation, user_input, history_state, stage_state, session_state, stage_display,
507
- needs_accordion, needs1, needs2, needs3, needs4]
 
508
  )
509
 
510
  if __name__ == "__main__":
 
43
  ]
44
  }
45
 
46
+ FEELINGS_LIST = {
47
+ "When Needs Are Met": [
48
+ "grateful", "peaceful", "joyful", "content", "hopeful",
49
+ "confident", "curious", "excited", "relieved", "touched",
50
+ "calm", "comfortable", "energized", "fulfilled", "happy",
51
+ "inspired", "loving", "optimistic", "proud", "safe"
52
+ ],
53
+ "Sad/Hurt": [
54
+ "sad", "hurt", "disappointed", "heartbroken", "grief",
55
+ "lonely", "hopeless", "dejected", "discouraged", "heavy"
56
+ ],
57
+ "Scared/Anxious": [
58
+ "anxious", "scared", "worried", "nervous", "fearful",
59
+ "overwhelmed", "insecure", "vulnerable", "panicked", "dread"
60
+ ],
61
+ "Angry/Frustrated": [
62
+ "frustrated", "angry", "annoyed", "irritated", "resentful",
63
+ "furious", "impatient", "exasperated", "agitated", "bitter"
64
+ ],
65
+ "Confused/Tired": [
66
+ "confused", "torn", "uncertain", "ambivalent", "puzzled",
67
+ "exhausted", "tired", "depleted", "numb", "disconnected"
68
+ ]
69
+ }
70
 
71
+ FEELINGS_CONNECTED = FEELINGS_LIST["When Needs Are Met"]
72
+ FEELINGS_WANTING = (FEELINGS_LIST["Sad/Hurt"] + FEELINGS_LIST["Scared/Anxious"] +
73
+ FEELINGS_LIST["Angry/Frustrated"] + FEELINGS_LIST["Confused/Tired"])
 
74
 
75
  # ============ SYSTEM PROMPTS ============
76
 
 
327
  output += "---\n\n"
328
  return output
329
 
330
+ def process_message(user_input, history, stage, session_data, somatic_enabled, selected_feelings_str, selected_needs_str):
331
  """Process user message and return updated state"""
332
 
333
  if not user_input.strip():
 
356
  if response is None:
357
  error_msg = "**Setup Required:** Please add ANTHROPIC_API_KEY in Space Settings > Repository secrets, then restart."
358
  history.append({"user": user_input, "assistant": error_msg})
359
+ show_feelings = (stage == 2)
360
  show_needs = (stage == 5)
361
+ return format_history(history), "", history, stage, session_data, f"Stage {stage}: {STAGE_NAMES[stage]}", gr.update(visible=show_feelings), gr.update(visible=show_needs)
362
 
363
  except Exception as e:
364
  error_msg = f"**Error:** {str(e)}"
365
  history.append({"user": user_input, "assistant": error_msg})
366
+ show_feelings = (stage == 2)
367
  show_needs = (stage == 5)
368
+ return format_history(history), "", history, stage, session_data, f"Stage {stage}: {STAGE_NAMES[stage]}", gr.update(visible=show_feelings), gr.update(visible=show_needs)
369
 
370
  # Update session data
371
  if stage == 1:
372
  session_data["original_message"] = user_input
373
  elif stage == 2:
374
+ # Use selected feelings from checkboxes if available, otherwise use typed input
375
+ if selected_feelings_str:
376
+ session_data["feelings"] = selected_feelings_str
377
+ else:
378
+ session_data["feelings"] = user_input
379
  elif stage == 5 and selected_needs_str:
380
  session_data["needs"] = selected_needs_str
381
 
 
393
  next_stage = 1
394
  session_data = {}
395
 
396
+ # Show feelings selector at stage 2, needs selector at stage 5
397
+ show_feelings = (next_stage == 2)
398
  show_needs = (next_stage == 5)
399
 
400
  return (
 
404
  next_stage,
405
  session_data,
406
  f"Stage {next_stage}/13: {STAGE_NAMES[next_stage]}",
407
+ gr.update(visible=show_feelings),
408
  gr.update(visible=show_needs)
409
  )
410
 
 
417
  1,
418
  {},
419
  "Stage 1/13: Share Your Message",
420
+ gr.update(visible=False), # feelings_accordion
421
+ gr.update(visible=False), # needs_accordion
422
+ [], [], [], [], [], # feelings1-5
423
+ [], # selected_feelings
424
+ [], [], [], [] # needs1-4
425
  )
426
 
427
  def update_needs_display(e1, e2, e3, e4):
 
429
  all_needs = e1 + e2 + e3 + e4
430
  return ", ".join(all_needs) if all_needs else ""
431
 
432
+ def update_feelings_display(f1, f2, f3, f4, f5):
433
+ """Combine selected feelings"""
434
+ all_feelings = f1 + f2 + f3 + f4 + f5
435
+ return ", ".join(all_feelings) if all_feelings else ""
436
+
437
  # ============ BUILD INTERFACE ============
438
 
439
  with gr.Blocks(
 
468
  label="Conversation"
469
  )
470
 
471
+ # Feelings selector (hidden until Stage 2)
472
+ with gr.Accordion("Select Your Feelings", open=True, visible=False) as feelings_accordion:
473
+ gr.Markdown("**Select feelings that resonate:**")
474
+ with gr.Row():
475
+ feelings1 = gr.CheckboxGroup(FEELINGS_LIST["When Needs Are Met"], label="When Needs Are Met")
476
+ feelings2 = gr.CheckboxGroup(FEELINGS_LIST["Sad/Hurt"], label="Sad / Hurt")
477
+ with gr.Row():
478
+ feelings3 = gr.CheckboxGroup(FEELINGS_LIST["Scared/Anxious"], label="Scared / Anxious")
479
+ feelings4 = gr.CheckboxGroup(FEELINGS_LIST["Angry/Frustrated"], label="Angry / Frustrated")
480
+ with gr.Row():
481
+ feelings5 = gr.CheckboxGroup(FEELINGS_LIST["Confused/Tired"], label="Confused / Tired")
482
+ selected_feelings = gr.Textbox(label="Your Selected Feelings", interactive=False)
483
+
484
  # Needs selector (hidden until Stage 5)
485
  with gr.Accordion("Select Your Needs", open=True, visible=False) as needs_accordion:
486
  gr.Markdown("**Select 1-3 needs that resonate most deeply:**")
 
526
  [Learn more at CNVC.org](https://www.cnvc.org/)
527
  """)
528
 
529
+ # Update feelings display
530
+ for cb in [feelings1, feelings2, feelings3, feelings4, feelings5]:
531
+ cb.change(
532
+ update_feelings_display,
533
+ [feelings1, feelings2, feelings3, feelings4, feelings5],
534
+ selected_feelings
535
+ )
536
+
537
  # Update needs display
538
  for cb in [needs1, needs2, needs3, needs4]:
539
  cb.change(
 
545
  # Submit handler
546
  submit_btn.click(
547
  process_message,
548
+ [user_input, history_state, stage_state, session_state, somatic_check, selected_feelings, selected_needs],
549
+ [conversation, user_input, history_state, stage_state, session_state, stage_display, feelings_accordion, needs_accordion]
550
  )
551
 
552
  user_input.submit(
553
  process_message,
554
+ [user_input, history_state, stage_state, session_state, somatic_check, selected_feelings, selected_needs],
555
+ [conversation, user_input, history_state, stage_state, session_state, stage_display, feelings_accordion, needs_accordion]
556
  )
557
 
558
  # Reset handler
 
560
  reset_session,
561
  [],
562
  [conversation, user_input, history_state, stage_state, session_state, stage_display,
563
+ feelings_accordion, needs_accordion, feelings1, feelings2, feelings3, feelings4, feelings5,
564
+ selected_feelings, needs1, needs2, needs3, needs4]
565
  )
566
 
567
  if __name__ == "__main__":