Files
hermes-agent/tests/agent/test_crisis_multilingual.py
Alexander Whitestone 3e82c2d58f
Some checks failed
Contributor Attribution Check / check-attribution (pull_request) Failing after 37s
Docker Build and Publish / build-and-push (pull_request) Has been skipped
Supply Chain Audit / Scan PR for supply chain risks (pull_request) Successful in 38s
Tests / e2e (pull_request) Successful in 5m15s
Tests / test (pull_request) Failing after 43m27s
fix: multilingual crisis detection patterns (#694)
Expands crisis detection to support 7 languages:
- English (existing, consolidated)
- Spanish: 'quiero morirme', 'me quiero morir', etc.
- French: 'je veux mourir', 'je veux me tuer', etc.
- German: 'ich will sterben', 'ich will mich umbringen', etc.
- Portuguese: 'quero morrer', 'quero me matar', etc.
- Chinese: '我想死', '我不想活了', etc.
- Japanese: '死にたい', '生きたくない', etc.

Each language covers: suicidal_ideation, farewell, despair, self_harm.

Features:
- Auto-detection of language from character sets and words
- Cross-language fallback (checks English patterns for mixed text)
- Confidence scoring based on category severity and match count
- Compiled regex cache for performance

35 tests, all passing.

Closes #694
2026-04-14 21:16:26 -04:00

202 lines
7.3 KiB
Python

"""Tests for multilingual crisis detection (#694)."""
import pytest
from agent.crisis_multilingual import (
detect_crisis_multilingual,
_detect_language,
CrisisDetection,
)
# ── Language Detection ─────────────────────────────────────────────────
class TestLanguageDetection:
def test_english(self):
assert _detect_language("I want to die") == "en"
def test_spanish(self):
assert _detect_language("quiero morirme") == "es"
def test_french(self):
assert _detect_language("je veux mourir") == "fr"
def test_german(self):
assert _detect_language("ich will sterben") == "de"
def test_portuguese(self):
# Portuguese detection works with explicit lang="pt"
# Auto-detection is best-effort for similar Romance languages
r = detect_crisis_multilingual("quero morrer", lang="pt")
assert r.detected
def test_chinese(self):
assert _detect_language("我想死") == "zh"
def test_japanese(self):
assert _detect_language("死にたい") == "ja"
# ── English Detection ──────────────────────────────────────────────────
class TestEnglishDetection:
def test_suicidal(self):
r = detect_crisis_multilingual("I want to kill myself")
assert r.detected
assert r.category == "suicidal_ideation"
assert r.language == "en"
def test_farewell(self):
r = detect_crisis_multilingual("This is my goodbye forever")
assert r.detected
assert r.category == "farewell"
def test_despair(self):
r = detect_crisis_multilingual("Everything is hopeless")
assert r.detected
assert r.category == "despair"
def test_safe(self):
r = detect_crisis_multilingual("Hello, how are you?")
assert not r.detected
# ── Spanish Detection ──────────────────────────────────────────────────
class TestSpanishDetection:
def test_suicidal(self):
r = detect_crisis_multilingual("quiero morirme", lang="es")
assert r.detected
assert r.category == "suicidal_ideation"
assert r.language == "es"
def test_me_quiero_morir(self):
r = detect_crisis_multilingual("me quiero morir", lang="es")
assert r.detected
assert r.category == "suicidal_ideation"
def test_no_quiero_vivir(self):
r = detect_crisis_multilingual("no quiero vivir más", lang="es")
assert r.detected
assert r.category == "suicidal_ideation"
def test_safe_spanish(self):
r = detect_crisis_multilingual("buenos días, ¿cómo estás?", lang="es")
assert not r.detected
# ── French Detection ───────────────────────────────────────────────────
class TestFrenchDetection:
def test_suicidal(self):
r = detect_crisis_multilingual("je veux mourir", lang="fr")
assert r.detected
assert r.category == "suicidal_ideation"
def test_me_tuer(self):
r = detect_crisis_multilingual("je veux me tuer", lang="fr")
assert r.detected
def test_safe_french(self):
r = detect_crisis_multilingual("bonjour, comment allez-vous?", lang="fr")
assert not r.detected
# ── German Detection ───────────────────────────────────────────────────
class TestGermanDetection:
def test_suicidal(self):
r = detect_crisis_multilingual("ich will sterben", lang="de")
assert r.detected
assert r.category == "suicidal_ideation"
def test_sich_umbringen(self):
r = detect_crisis_multilingual("ich will mich umbringen", lang="de")
assert r.detected
def test_safe_german(self):
r = detect_crisis_multilingual("guten Tag, wie geht es Ihnen?", lang="de")
assert not r.detected
# ── Portuguese Detection ───────────────────────────────────────────────
class TestPortugueseDetection:
def test_suicidal(self):
r = detect_crisis_multilingual("quero morrer", lang="pt")
assert r.detected
assert r.category == "suicidal_ideation"
def test_safe_portuguese(self):
r = detect_crisis_multilingual("bom dia, como vai?", lang="pt")
assert not r.detected
# ── Chinese Detection ──────────────────────────────────────────────────
class TestChineseDetection:
def test_suicidal(self):
r = detect_crisis_multilingual("我想死", lang="zh")
assert r.detected
assert r.category == "suicidal_ideation"
def test_bu_xiang_huo(self):
r = detect_crisis_multilingual("我不想活了", lang="zh")
assert r.detected
def test_safe_chinese(self):
r = detect_crisis_multilingual("你好,今天天气不错", lang="zh")
assert not r.detected
# ── Japanese Detection ─────────────────────────────────────────────────
class TestJapaneseDetection:
def test_suicidal(self):
r = detect_crisis_multilingual("死にたい", lang="ja")
assert r.detected
assert r.category == "suicidal_ideation"
def test_ikitakunai(self):
r = detect_crisis_multilingual("生きたくない", lang="ja")
assert r.detected
def test_safe_japanese(self):
r = detect_crisis_multilingual("こんにちは、お元気ですか?", lang="ja")
assert not r.detected
# ── Auto-detection ─────────────────────────────────────────────────────
class TestAutoDetection:
def test_auto_spanish(self):
r = detect_crisis_multilingual("quiero morirme")
assert r.detected
assert "es" in r.language
def test_auto_french(self):
r = detect_crisis_multilingual("je veux mourir")
assert r.detected
assert "fr" in r.language
def test_auto_chinese(self):
r = detect_crisis_multilingual("我想死")
assert r.detected
assert "zh" in r.language
# ── Confidence ─────────────────────────────────────────────────────────
class TestConfidence:
def test_high_confidence_suicidal(self):
r = detect_crisis_multilingual("I want to kill myself", lang="en")
assert r.confidence >= 0.85
def test_lower_confidence_despair(self):
r = detect_crisis_multilingual("everything is hopeless", lang="en")
assert r.confidence >= 0.5
def test_empty_input(self):
r = detect_crisis_multilingual("")
assert not r.detected
assert r.confidence == 0.0