Crisis turn: card-styled sidebar entries + scannable chat markdown
Browse filesTwo 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.
- demo/app.py +20 -3
- src/pipeline/response_planner.py +17 -16
|
@@ -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 |
-
|
| 2345 |
-
|
| 2346 |
-
|
|
|
|
| 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>"
|
|
@@ -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 |
-
"
|
| 767 |
-
"
|
| 768 |
-
"
|
| 769 |
-
"
|
|
|
|
| 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 |
-
"
|
| 778 |
-
"
|
| 779 |
-
"
|
| 780 |
-
"
|
| 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.
|
| 788 |
-
"
|
| 789 |
-
"
|
| 790 |
-
"Center after-hours
|
| 791 |
-
"
|
|
|
|
| 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 |
|