cypher-v12-finalized / modules /cypher_empathy_context.py
jescy525's picture
Upload folder using huggingface_hub
076a67c verified
Raw
History Blame Contribute Delete
6.15 kB
"""CYPHER V12 M49 — Empathy + Emotional Context.
Detects emotional tone of prompt + adapts response style accordingly.
"""
from __future__ import annotations
import logging
import re
from typing import Any
logger = logging.getLogger(__name__)
EMOTIONAL_PROFILES = {
"urgent": {
"signals": ("urgent", "asap", "now", "quickly", "immediately",
"right now", "tout de suite", "vite", "rapide",
"emergency", "urgence", "!!", "critical"),
"style": "Be concise, action-first. Skip pleasantries. Numbered steps.",
"max_tokens": 150,
"temperature": 0.25,
},
"frustrated": {
"signals": ("frustrated", "annoyed", "this is dumb", "why doesn't",
"encore", "again?", "still not", "tu te fous",
"this isn't working", "ça marche pas", "WTF", "wtf",
"merde", "putain"),
"style": "Acknowledge frustration briefly. Direct solution. No fluff.",
"max_tokens": 180,
"temperature": 0.30,
},
"exploratory": {
"signals": ("curious", "wondering", "what if", "could you explain",
"je me demande", "et si", "intéressant", "interesting",
"tell me more"),
"style": "Engage curiously. Detail + tangents OK. Suggest follow-ups.",
"max_tokens": 280,
"temperature": 0.45,
},
"casual": {
"signals": ("hey", "hi", "lol", "btw", "salut", "yo",
" :) ", " :( ", " :p "),
"style": "Friendly tone. Brief. Match the casual register.",
"max_tokens": 120,
"temperature": 0.40,
},
"formal": {
"signals": ("please", "kindly", "could you", "would you",
"veuillez", "merci de", "auriez-vous",
"respectfully", "respectueusement"),
"style": "Formal register. Complete sentences. Avoid contractions.",
"max_tokens": 220,
"temperature": 0.30,
},
"technical_deep": {
"signals": ("deep dive", "in detail", "thoroughly", "explain why",
"expliquer pourquoi", "en profondeur", "approfondir"),
"style": "Detailed technical analysis. Cite specifics. Structured.",
"max_tokens": 320,
"temperature": 0.30,
},
"neutral": {
"signals": (),
"style": "Balanced direct response.",
"max_tokens": 200,
"temperature": 0.35,
},
}
def detect_emotional_context(prompt: str) -> dict:
"""Return detected emotional profile + signals."""
if not prompt:
return {"profile": "neutral", "confidence": 0.0, "matched_signals": []}
p_lower = prompt.lower()
# Score each profile by signal hits
scores: dict[str, int] = {}
matched: dict[str, list[str]] = {}
for profile_name, info in EMOTIONAL_PROFILES.items():
signals = info["signals"]
hits = [s for s in signals if s in p_lower]
if hits:
scores[profile_name] = len(hits)
matched[profile_name] = hits
# Punctuation-based boosts
if "!!" in prompt or prompt.count("!") >= 2:
scores["urgent"] = scores.get("urgent", 0) + 1
matched.setdefault("urgent", []).append("multi_exclaim")
if prompt.isupper() and len(prompt) > 10:
scores["frustrated"] = scores.get("frustrated", 0) + 1
matched.setdefault("frustrated", []).append("all_caps")
if not scores:
return {"profile": "neutral", "confidence": 0.0, "matched_signals": []}
top = max(scores, key=lambda k: scores[k])
return {
"profile": top,
"confidence": min(1.0, scores[top] / 3.0),
"matched_signals": matched[top],
"all_scores": scores,
}
class EmpathyAdapter:
"""Adjusts generation params + style based on emotional context."""
@staticmethod
def adapt_params(prompt: str, base_max_tokens: int = 200,
base_temperature: float = 0.35) -> dict:
detected = detect_emotional_context(prompt)
profile_info = EMOTIONAL_PROFILES.get(detected["profile"], EMOTIONAL_PROFILES["neutral"])
return {
"profile": detected["profile"],
"confidence": detected["confidence"],
"matched_signals": detected.get("matched_signals", []),
"max_tokens": profile_info["max_tokens"],
"temperature": profile_info["temperature"],
"style_hint": profile_info["style"],
}
@staticmethod
def style_prefix(profile: str) -> str:
"""Optional style prefix injected before User: prompt."""
info = EMOTIONAL_PROFILES.get(profile, EMOTIONAL_PROFILES["neutral"])
return f"[STYLE: {info['style']}]"
@staticmethod
def acknowledge_emotion(profile: str, lang: str = "en") -> str | None:
"""Optional brief emotional acknowledgment to prepend response."""
if profile == "frustrated":
return "Compris." if lang == "fr" else "Got it."
if profile == "urgent":
return "Immédiat:" if lang == "fr" else "Right away:"
return None
__all__ = ["EMOTIONAL_PROFILES", "detect_emotional_context", "EmpathyAdapter"]
if __name__ == "__main__":
logging.basicConfig(level=logging.INFO)
print("=== M49 cypher_empathy_context SMOKE ===")
tests = [
"URGENT! patch CVE-2024-3400 maintenant!!",
"Hey, quick question about SMC.",
"Could you kindly explain MITRE T1059?",
"wtf this doesn't work again",
"I'm curious about how Hopfield networks function in working memory.",
"Tell me about Log4Shell in detail and thoroughly.",
"What is a firewall?",
]
for p in tests:
info = EmpathyAdapter.adapt_params(p)
print(f"\n'{p[:50]}'")
print(f" → profile={info['profile']} conf={info['confidence']:.2f} signals={info['matched_signals']}")
print(f" → max_tok={info['max_tokens']} temp={info['temperature']}")
ack = EmpathyAdapter.acknowledge_emotion(info["profile"], lang="fr")
if ack:
print(f" → ack: {ack}")
print("\n=== SMOKE PASS ===")