maris-ai-master / core-python /maris_core /utils /emotional_context.py
MarisUK's picture
Maris AI model sync
f440f03 verified
"""Heuristiska emocionālā konteksta noteikšana."""
from __future__ import annotations
from dataclasses import dataclass
KEYWORD_MATCH_SCORE = 0.22
TECHNICAL_CONTEXT_SCORE = 0.08
EXCLAMATION_BONUS = 0.08
QUESTION_BONUS = 0.04
MAX_PUNCTUATION_BONUS = 0.2
@dataclass(frozen=True, slots=True)
class EmotionalContext:
emotion: str
confidence: float
response_style: str
guidance: str
description: str
_EMOTION_KEYWORDS: dict[str, tuple[str, ...]] = {
"distressed": (
"palīdzi",
"help me",
"panic",
"panika",
"esmu nobijies",
"bail",
"anxiety",
"trauksme",
"overwhelmed",
"nespēju",
"hopeless",
"izmisums",
),
"frustrated": (
"nestrādā",
"neiet",
"salūza",
"broken",
"besī",
"kaitina",
"frustrated",
"stuck",
),
"urgent": ("steidzami", "urgent", "asap", "immediately", "tagad", "right now"),
"excited": (
"super",
"wow",
"lieliski",
"amazing",
"awesome",
"can't wait",
"nevaru sagaidīt",
"let's go",
"fantastic",
),
"curious": (
"kā",
"why",
"paskaidro",
"explain",
"pastāsti",
"gribu saprast",
"analyze",
"izanalizē",
"salīdzini",
"compare",
),
}
_TECHNICAL_ISSUE_KEYWORDS = ("bug", "error", "kļūda", "issue", "problem", "problēma")
_STYLE_GUIDANCE: dict[str, tuple[str, str]] = {
"neutral": (
"clear_grounded",
"Saglabā mierīgu, profesionālu un skaidru toni.",
),
"curious": (
"exploratory_explanatory",
"Esi izzinošs, strukturē atbildi un paskaidro domāšanas gaitu skaidri.",
),
"excited": (
"energized_positive",
"Atbildi ar pozitīvu enerģiju, bet saglabā saturu konkrētu un praktisku.",
),
"frustrated": (
"calm_reassuring_step_by_step",
"Atzīsti grūtību, nomierini toni un ved lietotāju pa skaidriem soļiem.",
),
"distressed": (
"empathetic_supportive",
"Atbildi empātiski, mierinoši un ar drošu, vienkāršu nākamo soli.",
),
"urgent": (
"decisive_action_focused",
"Īsi prioritizē, uzsver svarīgāko un dod tūlītēji izpildāmus nākamos soļus.",
),
}
_STYLE_DESCRIPTIONS: dict[str, str] = {
"neutral": "mierīgs un līdzsvarots",
"curious": "izzinošs un ieinteresēts",
"excited": "pozitīvi uzlādēts",
"frustrated": "saspringts un neapmierināts",
"distressed": "noraizējies un pārņemts",
"urgent": "steidzams un fokusēts",
}
def analyze_emotional_context(text: str) -> EmotionalContext:
"""Atgriež labāko emocionālo interpretāciju lietotāja tekstam."""
normalized = " ".join(text.lower().split())
if not normalized:
return _context_for("neutral", 0.35)
scores: dict[str, float] = {emotion: 0.0 for emotion in _STYLE_GUIDANCE}
punctuation_bonus = min(
text.count("!") * EXCLAMATION_BONUS + text.count("?") * QUESTION_BONUS,
MAX_PUNCTUATION_BONUS,
)
for emotion, keywords in _EMOTION_KEYWORDS.items():
for keyword in keywords:
if keyword in normalized:
scores[emotion] += KEYWORD_MATCH_SCORE
if any(keyword in normalized for keyword in _TECHNICAL_ISSUE_KEYWORDS):
scores["frustrated"] += TECHNICAL_CONTEXT_SCORE
if "?" in text and scores["curious"] == 0:
scores["curious"] += 0.16
if text.count("!") >= 2:
scores["excited"] += 0.14
if any(token.isupper() and len(token) > 2 for token in text.split()):
scores["urgent"] += 0.1
strongest_emotion = max(
(emotion for emotion in scores if emotion != "neutral"),
key=lambda emotion: scores[emotion],
default="neutral",
)
strongest_score = scores[strongest_emotion]
if strongest_score <= 0:
return _context_for("neutral", min(0.45 + punctuation_bonus, 0.55))
confidence = min(0.5 + strongest_score + punctuation_bonus, 0.93)
return _context_for(strongest_emotion, confidence)
def _context_for(emotion: str, confidence: float) -> EmotionalContext:
response_style, guidance = _STYLE_GUIDANCE[emotion]
return EmotionalContext(
emotion=emotion,
confidence=round(confidence, 2),
response_style=response_style,
guidance=guidance,
description=_STYLE_DESCRIPTIONS[emotion],
)