reframe / cbt_knowledge /distortions.py
macayaven's picture
first-features (#1)
c6ce43e verified
"""
Cognitive Distortions Database
Complete taxonomy of cognitive distortions with definitions, examples, and reframing strategies.
"""
from typing import Any
COGNITIVE_DISTORTIONS = {
"mind_reading": {
"code": "MW",
"name": "Mind Reading",
"definition": "Assuming you know what others are thinking without evidence",
"examples": [
"They think I'm incompetent",
"Everyone can see how anxious I am",
"She must think I'm boring",
],
"reframing_strategies": [
"What evidence do I have for what they're thinking?",
"What else might they be thinking?",
"How could I find out what they actually think?",
],
"micro_actions": [
"Ask one person directly about their thoughts",
"Notice when predictions about others' thoughts were wrong",
],
},
"fortune_telling": {
"code": "FT",
"name": "Fortune Telling",
"definition": "Predicting the future negatively as if it's certain",
"examples": [
"I'll definitely fail the interview",
"Things will never get better",
"This relationship is doomed to fail",
],
"reframing_strategies": [
"What are other possible outcomes?",
"What's the most likely outcome based on past experience?",
"How certain am I really about this prediction?",
],
"micro_actions": [
"Write down 3 alternative outcomes",
"Track prediction accuracy for one week",
],
},
"catastrophizing": {
"code": "CT",
"name": "Catastrophizing",
"definition": "Blowing things out of proportion or imagining worst-case scenarios",
"examples": [
"This mistake will ruin my entire career",
"If I panic, I'll completely lose control",
"One bad grade means I'll never succeed",
],
"reframing_strategies": [
"What's the worst, best, and most likely outcome?",
"How have I coped with difficulties before?",
"Will this matter in 5 years?",
],
"micro_actions": [
"List past situations you successfully coped with",
"Rate actual vs predicted severity of one worry",
],
},
"all_or_nothing": {
"code": "AO",
"name": "All-or-Nothing Thinking",
"definition": "Seeing things in black-and-white categories with no middle ground",
"examples": [
"If I'm not perfect, I'm a failure",
"Either they love me or they hate me",
"If I can't do it all, I shouldn't do any of it",
],
"reframing_strategies": [
"What would the middle ground look like?",
"Can I rate this on a scale of 0-100?",
"What are the shades of gray here?",
],
"micro_actions": [
"Rate one achievement on a 0-100 scale",
"Find 3 partial successes in your day",
],
},
"mental_filter": {
"code": "MF",
"name": "Mental Filter",
"definition": "Focusing exclusively on negatives while filtering out positives",
"examples": [
"The whole presentation was terrible (despite mostly positive feedback)",
"My day was ruined (one bad thing among many good)",
"All I can think about is that one criticism",
],
"reframing_strategies": [
"What positive aspects am I overlooking?",
"What would a balanced view include?",
"What went well, even if small?",
],
"micro_actions": [
"Write 3 good things that happened today",
"Ask someone else what went well",
],
},
"personalization": {
"code": "PR",
"name": "Personalization",
"definition": "Blaming yourself for things outside your control",
"examples": [
"It's my fault they're in a bad mood",
"The team failed because of me",
"If I had done better, this wouldn't have happened",
],
"reframing_strategies": [
"What other factors contributed?",
"What was actually within my control?",
"Would I blame a friend this much?",
],
"micro_actions": [
"Create a responsibility pie chart",
"List factors outside your control",
],
},
"labeling": {
"code": "LB",
"name": "Labeling",
"definition": "Attaching global negative labels based on single instances",
"examples": ["I'm a loser", "They're completely selfish", "I'm such an idiot"],
"reframing_strategies": [
"What specific behavior am I reacting to?",
"Does one action define a whole person?",
"What evidence contradicts this label?",
],
"micro_actions": [
"Replace one label with specific behavior description",
"List 3 qualities that contradict the label",
],
},
"should_statements": {
"code": "SH",
"name": "Should Statements",
"definition": "Rigid rules about how things must be, leading to guilt or frustration",
"examples": [
"I should always be productive",
"They should understand without me explaining",
"I must never make mistakes",
],
"reframing_strategies": [
"What would I prefer instead of 'should'?",
"Where did this rule come from?",
"What happens if this 'should' isn't met?",
],
"micro_actions": [
"Replace 'should' with 'would like to'",
"Question one 'should' rule's origin",
],
},
"emotional_reasoning": {
"code": "ER",
"name": "Emotional Reasoning",
"definition": "Believing something is true because it feels true",
"examples": [
"I feel worthless, so I must be worthless",
"I feel anxious, so there must be danger",
"I feel guilty, so I must have done something wrong",
],
"reframing_strategies": [
"What are the facts separate from feelings?",
"Have my feelings been wrong before?",
"What would I tell a friend feeling this way?",
],
"micro_actions": [
"List facts vs feelings about one situation",
"Notice when feelings didn't match reality",
],
},
"discounting_positives": {
"code": "DP",
"name": "Discounting Positives",
"definition": "Dismissing positive experiences or achievements as not counting",
"examples": [
"They only complimented me to be nice",
"I only succeeded because it was easy",
"Anyone could have done what I did",
],
"reframing_strategies": [
"What would it mean to fully accept this positive?",
"How do I explain others' successes?",
"What effort did I actually put in?",
],
"micro_actions": [
"Accept one compliment at face value",
"Write down your role in one success",
],
},
"jumping_to_conclusions": {
"code": "JC",
"name": "Jumping to Conclusions",
"definition": "Making negative assumptions without sufficient evidence",
"examples": [
"They didn't text back, they must hate me",
"I made one mistake, I'll be fired",
"They looked away, they must be bored",
],
"reframing_strategies": [
"What evidence do I have for this conclusion?",
"What are other possible explanations?",
"Am I confusing possibility with probability?",
],
"micro_actions": [
"List 3 alternative explanations",
"Test one assumption by asking directly",
],
},
"magnification_minimization": {
"code": "MM",
"name": "Magnification/Minimization",
"definition": "Exaggerating negatives or minimizing positives disproportionately",
"examples": [
"This tiny mistake ruins everything",
"My achievements don't really count",
"Their small flaw makes them terrible",
],
"reframing_strategies": [
"How would an outside observer rate this?",
"Am I using a double standard?",
"What's the actual size/importance of this?",
],
"micro_actions": [
"Rate importance on 1-10 scale",
"Ask someone else for perspective",
],
},
"overgeneralization": {
"code": "OG",
"name": "Overgeneralization",
"definition": "Making broad conclusions from single events",
"examples": [
"I failed once, I always fail",
"One person rejected me, nobody likes me",
"This always happens to me",
],
"reframing_strategies": [
"Is this always true, or just sometimes?",
"What are the exceptions to this pattern?",
"Am I using words like 'always' or 'never' accurately?",
],
"micro_actions": [
"Find 3 exceptions to the pattern",
"Replace 'always/never' with 'sometimes'",
],
},
}
def get_distortion_by_code(code: str) -> dict[str, Any] | None:
"""Get distortion details by its code."""
for distortion in COGNITIVE_DISTORTIONS.values():
if distortion["code"] == code:
return distortion
return None
def detect_distortions(thought_text: str) -> list:
"""
Analyze text for potential cognitive distortions.
Returns list of likely distortion codes with confidence scores.
"""
thought_lower = thought_text.lower()
detected = []
# All-or-nothing thinking
if any(
word in thought_lower
for word in [
"always",
"never",
"everyone",
"everything",
"none",
"nothing",
"completely",
"totally",
]
):
detected.append(("AO", 0.8))
# Fortune telling
future_words = ["will", "going to", "definitely", "won't", "can't", "surely"]
negative_outcomes = ["fail", "disaster", "terrible", "awful", "ruin", "mess up"]
if any(word in thought_lower for word in future_words) and any(
neg in thought_lower for neg in negative_outcomes
):
detected.append(("FT", 0.7))
# Should statements
if any(word in thought_lower for word in ["should", "must", "have to", "ought", "need to"]):
detected.append(("SH", 0.9))
# Labeling
if "i am" in thought_lower or "i'm" in thought_lower or "im " in thought_lower:
labels = ["stupid", "loser", "failure", "worthless", "idiot", "incompetent", "pathetic"]
if any(label in thought_lower for label in labels):
detected.append(("LB", 0.9))
# Mind reading
if any(
phrase in thought_lower
for phrase in ["they think", "he thinks", "she thinks", "everyone thinks", "people think"]
):
detected.append(("MW", 0.7))
# Catastrophizing
if any(
word in thought_lower
for word in ["disaster", "catastrophe", "ruin", "destroy", "horrible", "terrible", "worst"]
):
detected.append(("CT", 0.8))
# Emotional reasoning
if "i feel" in thought_lower and any(
word in thought_lower for word in ["so i must", "therefore", "that means"]
):
detected.append(("ER", 0.6))
# Sort by confidence and return
detected.sort(key=lambda x: x[1], reverse=True)
return detected