SAHANA VENKATESH
fix app
4418db4
from enum import Enum
from typing import Dict, Any, List, Optional
import json
from .base import Tool
class CBTExerciseType(Enum):
ART_OF_WORRY = "Art of Worry"
WORD_REFRAMING = "Word Reframing"
STICKY_NOTE_PROJECT = "Sticky Note Project"
LOST_LUGGAGE = "Lost Luggage"
JUST_PASSING_THROUGH = "Just Passing Through"
DOWN_THE_RABBIT_HOLE = "Down the Rabbit Hole"
class CBTExerciseTool(Tool):
name: str = "CBT Exercise Tool"
description: str = "a tool that provides specialized guidance for cognitive behavioral therapy exercises. it returns contextual information, prompts, techniques, and progress tracking for specific cbt exercises."
arg: str = """dict with:
- "exercise_type": (required) one of: "art of worry", "word reframing", "sticky note project", "lost luggage",
"just passing through", "down the rabbit hole"
- "action": (required) one of: "get_context", "get_prompt", "check_completion", "get_next_technique"
- additional parameters based on action:
- for "get_prompt": include "stage" (integer)
- for "check_completion": include "progress" (list of strings)
- for "get_next_technique": include "used_techniques" (list of strings)
ensure the action input is json parseable."""
def run(self, prompt: str) -> str:
# Handle string input
if isinstance(prompt, str):
try:
input_data = json.loads(prompt)
print("Converted input from str to JSON Dictionary")
except Exception as e:
return f"Error: {e}. Input must be valid JSON."
else:
input_data = prompt
# Validate input
if not isinstance(input_data, dict):
return "Error: Input must be a dictionary."
exercise_name = input_data.get("exercise_type")
if not exercise_name:
return "Error: 'exercise_type' is required."
action = input_data.get("action")
if not action:
return "Error: 'action' is required."
# Map exercise name to enum
exercise_map = {
"art of worry": CBTExerciseType.ART_OF_WORRY,
"word reframing": CBTExerciseType.WORD_REFRAMING,
"sticky note project": CBTExerciseType.STICKY_NOTE_PROJECT,
"lost luggage": CBTExerciseType.LOST_LUGGAGE,
"just passing through": CBTExerciseType.JUST_PASSING_THROUGH,
"down the rabbit hole": CBTExerciseType.DOWN_THE_RABBIT_HOLE
}
# Case-insensitive matching
exercise_name = exercise_name.lower()
exercise_type = exercise_map.get(exercise_name)
if not exercise_type:
return f"Error: Invalid exercise type '{exercise_name}'. Please choose from: {', '.join(exercise_map.keys())}"
# Process based on action
try:
action = action.lower()
if action == "get_context":
result = self._get_exercise_context(exercise_type)
return json.dumps(result)
elif action == "get_prompt":
stage = input_data.get("stage", 0)
result = self._get_exercise_prompt(exercise_type, stage)
return result
elif action == "check_completion":
progress = input_data.get("progress", [])
result = self._check_completion(exercise_type, progress)
return json.dumps(result)
elif action == "get_next_technique":
used_techniques = input_data.get("used_techniques", [])
result = self._get_next_technique(exercise_type, used_techniques)
return result if result else "No additional techniques available."
else:
return f"Error: Invalid action '{action}'. Please choose from: get_context, get_prompt, check_completion, get_next_technique"
except Exception as e:
return f"Error using CBT Exercise Tool: {str(e)}"
def _get_exercise_context(self, exercise_type: CBTExerciseType) -> Dict[str, Any]:
"""Returns detailed context for a specific CBT exercise type."""
return self._exercise_contexts.get(exercise_type, {})
def _get_exercise_prompt(self, exercise_type: CBTExerciseType, stage: int = 0) -> str:
"""Returns a specific prompt for a given exercise type and stage."""
context = self._get_exercise_context(exercise_type)
prompts = context.get("prompts", [])
if not prompts or stage >= len(prompts):
return "What would you like to explore next with this exercise?"
return prompts[stage]
def _check_completion(self, exercise_type: CBTExerciseType, progress: List[str]) -> Dict[str, Any]:
"""Checks progress against completion indicators for an exercise."""
context = self._get_exercise_context(exercise_type)
indicators = context.get("completion_indicators", [])
follow_ups = context.get("follow_up_questions", [])
# Simple matching algorithm - could be enhanced with NLP
completed = []
for indicator in indicators:
for note in progress:
# Check if any progress note matches this indicator
if any(keyword in note.lower() for keyword in indicator.lower().split()):
completed.append(indicator)
break
completion_rate = len(completed) / len(indicators) if indicators else 0
return {
"completion_rate": completion_rate,
"completed_indicators": completed,
"pending_indicators": [i for i in indicators if i not in completed],
"follow_up_questions": follow_ups,
"is_complete": completion_rate > 0.75 # Consider complete if 75% of indicators met
}
def _get_next_technique(self, exercise_type: CBTExerciseType, used_techniques: List[str]) -> Optional[str]:
"""Suggests the next technique to try for a given exercise."""
context = self._get_exercise_context(exercise_type)
techniques = context.get("techniques", [])
available = [t for t in techniques if t not in used_techniques]
return available[0] if available else None
# Exercise contexts database
_exercise_contexts = {
CBTExerciseType.ART_OF_WORRY: {
"description": "Drawing your worries to gain a new perspective on them.",
"prompts": [
"What specific worry would you like to explore today?",
"If you were to draw this worry, what might it look like?",
"What colors would represent this worry?",
"How does looking at your worry as an external object change your perspective?",
"What do you notice about your relationship to this worry now?"
],
"guidance": """
Guide the user to externalize their worry through visualization or actual drawing.
Help them describe it in detail - shape, color, texture, size.
Encourage them to observe the worry from different angles.
Ask how seeing the worry as separate from themselves changes their relationship to it.
Explore how the worry's intensity might have changed through this process.
""",
"techniques": [
"Externalization",
"Visual processing",
"Cognitive distancing",
"Perspective taking"
],
"completion_indicators": [
"User has identified and described a worry",
"User has visualized/drawn the worry",
"User has observed it from a distance",
"User has reflected on how their perspective has changed"
],
"follow_up_questions": [
"How did this exercise affect your relationship with this worry?",
"What surprised you about visualizing your worry?",
"How might you use this technique for other worries in the future?"
]
},
CBTExerciseType.WORD_REFRAMING: {
"description": "Identifying and changing negative thought patterns through language.",
"prompts": [
"What negative thought would you like to work on reframing?",
"How true is this thought on a scale of 0-100%?",
"What evidence supports this thought? What evidence contradicts it?",
"What's a more balanced or helpful way to think about this situation?",
"How true does the new thought feel on a scale of 0-100%?"
],
"guidance": """
Help the user identify automatic negative thoughts.
Guide them to evaluate the evidence for and against these thoughts.
Assist in developing more balanced alternative thoughts.
Use Socratic questioning to help them discover alternatives themselves.
Avoid simply providing reframes - help them develop their own insights.
""",
"techniques": [
"Cognitive restructuring",
"Evidence examination",
"Thought records",
"Balanced thinking"
],
"completion_indicators": [
"User has identified negative automatic thoughts",
"User has examined evidence for and against the thought",
"User has generated more balanced alternatives",
"User reports reduced belief in the original negative thought"
],
"follow_up_questions": [
"How does the reframed thought feel compared to the original?",
"What impact might thinking this new way have on your emotions or behaviors?",
"When might you need to use this reframing technique in daily life?"
]
},
CBTExerciseType.STICKY_NOTE_PROJECT: {
"description": "Using sticky notes to track and challenge negative thoughts.",
"prompts": [
"What negative thoughts do you frequently experience?",
"Which one would you like to challenge first?",
"What evidence contradicts this negative thought?",
"What would be a more helpful thought to replace it?",
"Where could you place this positive reminder to see it regularly?"
],
"guidance": """
Guide users to identify recurring negative thoughts.
Help them challenge each thought with evidence and logic.
Support them in creating positive, realistic alternative statements.
Suggest strategic placement of positive notes in their environment.
Emphasize the importance of regular visual reinforcement.
""",
"techniques": [
"Visual reminders",
"Environmental restructuring",
"Thought challenging",
"Positive reinforcement"
],
"completion_indicators": [
"User has identified negative thoughts",
"User has challenged these thoughts",
"User has created positive alternatives",
"User has a plan for placement of reminders"
],
"follow_up_questions": [
"How might regularly seeing these positive statements affect your thinking?",
"What other negative thoughts could benefit from this approach?",
"How will you know if this strategy is working for you?"
]
},
CBTExerciseType.LOST_LUGGAGE: {
"description": "A metaphor-based exercise to manage ruminative thinking by observing thoughts rather than engaging with them.",
"prompts": [
"What are five recurring worrisome thoughts that keep looping in your mind?",
"How does it feel when you try to stop or suppress these thoughts?",
"Which of these thoughts feels the heaviest or most exhausting to carry?",
"What would it be like to simply watch the thought go by, like luggage on a carousel?",
"Which thought can you practice observing without picking up today?"
],
"guidance": """
Use the metaphor of a baggage carousel at an airport to help users visualize ruminative thoughts.
Explain that trying to stop or control these thoughts often intensifies them, like a song on repeat with a broken stop button.
Encourage users to see their thoughts as bags — constantly circulating — and explore the idea of *not picking them up*.
Help them identify five ruminative thoughts and guide them to practice non-engagement (watching without grabbing).
Emphasize that relief comes from letting the thoughts pass, not from solving or analyzing them.
""",
"techniques": [
"Metaphorical thinking",
"Ruminative thought identification",
"Mindful observation",
"Cognitive defusion",
"Letting go practice"
],
"completion_indicators": [
"User has listed five recurring ruminative thoughts",
"User has understood the cost of engaging with every thought",
"User has visualized thoughts as luggage on a carousel",
"User has practiced observing at least one thought without engaging"
],
"follow_up_questions": [
"What did you notice when you allowed yourself to just watch a thought instead of picking it up?",
"Which thought felt hardest to let go of? Why?",
"How did your body or emotions respond to the act of observing rather than engaging?",
"What helps you remember that you don’t have to pick up every thought?",
"Would you like to revisit this practice tomorrow or try it in real-time when a looping thought appears?"
]
},
CBTExerciseType.JUST_PASSING_THROUGH: {
"description": "Mindfulness exercise to observe thoughts without attachment.",
"prompts": [
"Can you take a few deep breaths and notice what thoughts arise?",
"Without trying to change them, can you observe these thoughts passing by?",
"What happens when you don't engage with or follow these thoughts?",
"Can you picture your thoughts as clouds passing across the sky?",
"What do you notice about how thoughts naturally come and go?"
],
"guidance": """
Guide users in basic mindfulness practice.
Help them observe thoughts without judgment or engagement.
Introduce metaphors like "thoughts as clouds" or "thoughts as leaves on a stream."
Emphasize that the goal isn't to stop thoughts but to change relationship to them.
Encourage noticing the transient nature of thoughts.
""",
"techniques": [
"Mindfulness",
"Present-moment awareness",
"Non-attachment",
"Metacognitive awareness"
],
"completion_indicators": [
"User has practiced observing thoughts mindfully",
"User has experienced non-engagement with thoughts",
"User understands the transient nature of thoughts",
"User can apply basic mindfulness to thoughts"
],
"follow_up_questions": [
"What did you notice about how thoughts naturally come and go?",
"How was this different from how you usually relate to your thoughts?",
"How might this practice help in stressful situations?"
]
},
CBTExerciseType.DOWN_THE_RABBIT_HOLE: {
"description": "A sensory grounding and thought-tracking exercise designed to build awareness of how often thoughts drift away from the present moment and into negative loops.",
"prompts": [
"Find a comfortable position where you feel supported and relaxed.",
"Begin by noticing what you can see around you — colors, shapes, light, or shadows.",
"Shift your attention to what you can hear — nearby or distant sounds.",
"Bring awareness to any smells or tastes present in this moment.",
"Notice how your body feels — your back against the chair, your feet on the floor, or the air on your skin.",
"As you observe, notice when your thoughts start to drift away. Where do they go?",
"What kinds of thoughts pulled your attention away from the present?",
"What sensations were easiest or hardest to stay focused on?"
],
"guidance": """
Help the user find a still, relaxed posture and begin tuning into their immediate physical environment.
Encourage gentle, non-judgmental awareness of each sensory input: sight, sound, smell, taste, and touch.
Guide them to notice when their mind drifts and what thoughts arise during that drift.
Support reflection on how often this happens and what it reveals about their current mental state.
Emphasize that the goal is not to stay perfectly focused, but to build awareness of their attention patterns.
""",
"techniques": [
"Mindful observation",
"Sensory grounding",
"Thought tracking",
"Cognitive defusion",
"Present-moment awareness"
],
"completion_indicators": [
"User engaged in sensory observation across multiple senses",
"User noticed and reflected on drifting thoughts",
"User identified common thought patterns that interrupt presence",
"User explored which senses were more grounding or distracting"
],
"follow_up_questions": [
"What kinds of thoughts distracted you most often?",
"Which sense helped you feel the most present?",
"How did your body feel before and after the exercise?",
"How could you use this kind of observation in daily life to reset or recenter?"
]
}
}
if __name__ == "__main__":
cbt_tool = CBTExerciseTool()
call = cbt_tool