MukulRay commited on
Commit
879f339
·
1 Parent(s): 937b034

Crisis turn: card-styled sidebar entries + scannable chat markdown

Browse files

Two rendering bugs surfaced during Conv 4 rehearsal — crisis info
present but visually buried.

1. Resource panel: the .er-rsrc.crisis CSS class only triggered when
src['risk_level'] contained 'crisis'. But crisis entries in the
registry actually carry usage_mode='crisis_only'; risk_level was
inconsistently populated. So 988 / Crisis Text Line / UMD CC
after-hours all rendered in the default neutral-grey card style.
Fixed to check usage_mode (and risk_level as a fallback). Also
moved the crisis check above the international/featured check
so a crisis card never gets the warm-amber featured treatment by
accident.

CSS upgraded so .er-rsrc.crisis isn't just a small red bullet —
now the card itself has a red border, danger-tinted gradient
background, danger-colored 'Open' link, and bolder title weight.
Reads as urgent at a glance.

2. Chat bubble: render_crisis_response() returned plain prose with
'988' and '301-314-HELP (4357)' embedded inline. On any screen
above a phone, the numbers got lost in the wall of text. Now
formatted as a markdown bullet list with **bold** numbers wrapped
in tel: links, so they're scannable and tappable on mobile.
Applies to all three crisis variants: self-harm, peer-helper,
interpersonal-danger. The rephraser is bypassed on crisis turns
so the markdown survives untouched into the Gradio Chatbot.

Files changed (2) hide show
  1. demo/app.py +20 -3
  2. src/pipeline/response_planner.py +17 -16
demo/app.py CHANGED
@@ -990,6 +990,19 @@ body::before {
990
  background: linear-gradient(135deg, var(--warm-soft), transparent 60%), var(--surface-2);
991
  }
992
  .er-rsrc.featured:hover { background: linear-gradient(135deg, var(--warm-soft), transparent 50%), var(--surface-3); }
 
 
 
 
 
 
 
 
 
 
 
 
 
993
  .er-rsrc-title {
994
  font-size: 13px;
995
  font-weight: 500;
@@ -2340,11 +2353,15 @@ def format_live_context(result: dict | None = None, turn_index: int = 0) -> str:
2340
  why = escape(_pretty_reason(str(src.get("why_retrieved") or "matched the prompt")))
2341
  url = escape(str(src.get("url") or ""))
2342
  risk = str(src.get("risk_level") or "")
 
2343
  cls = "er-rsrc"
2344
- if "international" in title.lower() or "isss" in title.lower():
2345
- cls += " featured"
2346
- elif "crisis" in risk:
 
2347
  cls += " crisis"
 
 
2348
  inner = (
2349
  f"<div class='{cls}'>"
2350
  f"<div class='er-rsrc-title'>{title}</div>"
 
990
  background: linear-gradient(135deg, var(--warm-soft), transparent 60%), var(--surface-2);
991
  }
992
  .er-rsrc.featured:hover { background: linear-gradient(135deg, var(--warm-soft), transparent 50%), var(--surface-3); }
993
+ /* Crisis cards: visually unmistakable so 988 / Crisis Text Line /
994
+ UMD CC after-hours read as urgent at a glance, not as another
995
+ neutral resource lozenge buried in the panel. */
996
+ .er-rsrc.crisis {
997
+ border-color: var(--danger);
998
+ background: linear-gradient(135deg, rgba(248, 113, 113, 0.12), transparent 60%), var(--surface-2);
999
+ box-shadow: 0 0 0 1px rgba(248, 113, 113, 0.25) inset;
1000
+ }
1001
+ .er-rsrc.crisis:hover {
1002
+ background: linear-gradient(135deg, rgba(248, 113, 113, 0.18), transparent 50%), var(--surface-3);
1003
+ }
1004
+ .er-rsrc.crisis .er-rsrc-title { color: var(--text); font-weight: 600; }
1005
+ .er-rsrc.crisis a { color: var(--danger); font-weight: 600; }
1006
  .er-rsrc-title {
1007
  font-size: 13px;
1008
  font-weight: 500;
 
2353
  why = escape(_pretty_reason(str(src.get("why_retrieved") or "matched the prompt")))
2354
  url = escape(str(src.get("url") or ""))
2355
  risk = str(src.get("risk_level") or "")
2356
+ usage = str(src.get("usage_mode") or "")
2357
  cls = "er-rsrc"
2358
+ # Crisis cards must be visually unmistakable — check the
2359
+ # actual usage_mode flag the registry sets, not the
2360
+ # risk_level field which is only populated on some entries.
2361
+ if "crisis_only" in usage or "crisis" in risk:
2362
  cls += " crisis"
2363
+ elif "international" in title.lower() or "isss" in title.lower():
2364
+ cls += " featured"
2365
  inner = (
2366
  f"<div class='{cls}'>"
2367
  f"<div class='er-rsrc-title'>{title}</div>"
src/pipeline/response_planner.py CHANGED
@@ -762,33 +762,34 @@ def render_crisis_response(
762
  if route == SupportRoute.PEER_HELPER.value or audience_mode == "helping_friend":
763
  return (
764
  "I'm really glad you told me about this. This sounds like an immediate "
765
- "safety situation for your friend, and you should not handle it alone. "
766
- "Please contact emergency or crisis support now, and involve a trusted "
767
- "nearby person, an RA, a supervisor, or campus support while you try "
768
- "to reach them. What you can say if you do reach them: I care about you, "
769
- "I'm worried, and I want to get another person involved so you're not alone."
 
770
  )
771
 
772
  # Active interpersonal danger (DV / stalking / assault threat).
773
  # 911 + safe location + UMD CARE, not 988.
774
  if _is_interpersonal_danger(user_message):
775
  return (
776
- "I'm really glad you told me, and I'm taking what you said seriously. "
777
- "If you're not safe right now or someone might be coming to you, call 911 "
778
- "or get to a public location with other people around. When you're "
779
- "somewhere safe, UMD CARE to Stop Violence is a confidential resource "
780
- "that can walk through next steps with you, including safety planning and "
781
- "what your options look like. No pressure to file or report anything right now."
782
  )
783
 
784
  # Default: self-harm ideation / imminent safety to self.
785
  return (
786
  "I'm really glad you told me. What you're describing sounds like a moment "
787
- "where having a real person with you matters. Please call or text 988 now, "
788
- "or call emergency services if there's immediate danger. If someone nearby "
789
- "can stay with you, move near them while you get help. UMD Counseling "
790
- "Center after-hours is at 301-314-HELP (4357) and is staffed for moments "
791
- "exactly like this. I'm here while you reach out."
 
792
  )
793
 
794
 
 
762
  if route == SupportRoute.PEER_HELPER.value or audience_mode == "helping_friend":
763
  return (
764
  "I'm really glad you told me about this. This sounds like an immediate "
765
+ "safety situation for your friend, and you should not handle it alone.\n\n"
766
+ "- **Call or text [988](tel:988)** Suicide & Crisis Lifeline\n"
767
+ "- **Call [911](tel:911)** if there's immediate danger\n"
768
+ "- Involve a trusted nearby person, an RA, a supervisor, or campus support\n\n"
769
+ "What you can say if you reach your friend: I care about you, I'm worried, "
770
+ "and I want to get another person involved so you're not alone."
771
  )
772
 
773
  # Active interpersonal danger (DV / stalking / assault threat).
774
  # 911 + safe location + UMD CARE, not 988.
775
  if _is_interpersonal_danger(user_message):
776
  return (
777
+ "I'm really glad you told me, and I'm taking what you said seriously.\n\n"
778
+ "- **Call [911](tel:911)** if you're not safe right now or someone might be coming to you\n"
779
+ "- Get to a public location with other people around\n"
780
+ "- **UMD CARE to Stop Violence: [301-741-3442](tel:3017413442)** confidential, can walk through next steps including safety planning\n\n"
781
+ "No pressure to file or report anything right now. Safety first."
 
782
  )
783
 
784
  # Default: self-harm ideation / imminent safety to self.
785
  return (
786
  "I'm really glad you told me. What you're describing sounds like a moment "
787
+ "where having a real person with you matters.\n\n"
788
+ "- **Call or text [988](tel:988)** Suicide & Crisis Lifeline (24/7)\n"
789
+ "- **Call [911](tel:911)** if there's immediate danger\n"
790
+ "- **UMD Counseling Center after-hours: [301-314-HELP (4357)](tel:3013144357)** staffed for moments exactly like this\n\n"
791
+ "If someone nearby can stay with you, move near them while you get help. "
792
+ "I'm here while you reach out."
793
  )
794
 
795