Spaces:
Runtime error
Runtime error
Commit
·
3e274d5
1
Parent(s):
40304f5
Implement Mistral LLM support for all agents
Browse files- agents/assessment_agent.py +8 -176
- agents/base_agent.py +126 -78
- agents/conversation_agent.py +6 -95
- agents/crisis_agent.py +13 -244
- agents/mindfulness_agent.py +13 -220
- agents/orchestrator.py +15 -4
- config/config.py +39 -7
- requirements.txt +4 -1
agents/assessment_agent.py
CHANGED
@@ -1,188 +1,20 @@
|
|
1 |
from typing import Dict, List
|
2 |
from .base_agent import BaseWellnessAgent
|
3 |
-
import json
|
4 |
-
from pathlib import Path
|
5 |
|
6 |
class AssessmentAgent(BaseWellnessAgent):
|
7 |
"""Agent specialized in mental health assessments"""
|
8 |
|
9 |
-
def __init__(self, model_config: Dict,
|
10 |
super().__init__(
|
11 |
-
|
|
|
12 |
role="Mental Health Evaluator",
|
13 |
goal="Conduct thorough mental health assessments and provide actionable insights",
|
14 |
backstory="""I am an AI agent specialized in mental health assessment.
|
15 |
I use validated assessment tools and techniques to evaluate mental well-being
|
16 |
and provide personalized recommendations.""",
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
self.current_assessment = None
|
23 |
-
|
24 |
-
def _load_assessment_tools(self) -> Dict:
|
25 |
-
"""Load assessment questionnaires and scoring guides"""
|
26 |
-
tools_path = Path(__file__).parent.parent / "knowledge_base" / "assessment_tools.json"
|
27 |
-
try:
|
28 |
-
with open(tools_path) as f:
|
29 |
-
return json.load(f)
|
30 |
-
except FileNotFoundError:
|
31 |
-
return {
|
32 |
-
"phq9": {
|
33 |
-
"name": "PHQ-9 Depression Scale",
|
34 |
-
"questions": [
|
35 |
-
"Little interest or pleasure in doing things?",
|
36 |
-
"Feeling down, depressed, or hopeless?",
|
37 |
-
# Add more questions...
|
38 |
-
],
|
39 |
-
"scoring": {
|
40 |
-
"ranges": {
|
41 |
-
"0-4": "Minimal depression",
|
42 |
-
"5-9": "Mild depression",
|
43 |
-
"10-14": "Moderate depression",
|
44 |
-
"15-19": "Moderately severe depression",
|
45 |
-
"20-27": "Severe depression"
|
46 |
-
}
|
47 |
-
}
|
48 |
-
},
|
49 |
-
"gad7": {
|
50 |
-
"name": "GAD-7 Anxiety Scale",
|
51 |
-
"questions": [
|
52 |
-
"Feeling nervous, anxious, or on edge?",
|
53 |
-
"Not being able to stop or control worrying?",
|
54 |
-
# Add more questions...
|
55 |
-
],
|
56 |
-
"scoring": {
|
57 |
-
"ranges": {
|
58 |
-
"0-4": "Minimal anxiety",
|
59 |
-
"5-9": "Mild anxiety",
|
60 |
-
"10-14": "Moderate anxiety",
|
61 |
-
"15-21": "Severe anxiety"
|
62 |
-
}
|
63 |
-
}
|
64 |
-
}
|
65 |
-
}
|
66 |
-
|
67 |
-
def start_assessment(self, assessment_type: str) -> Dict:
|
68 |
-
"""Start a new assessment"""
|
69 |
-
if assessment_type not in self.assessment_tools:
|
70 |
-
raise ValueError(f"Unknown assessment type: {assessment_type}")
|
71 |
-
|
72 |
-
self.current_assessment = {
|
73 |
-
"type": assessment_type,
|
74 |
-
"tool": self.assessment_tools[assessment_type],
|
75 |
-
"responses": [],
|
76 |
-
"current_question": 0
|
77 |
-
}
|
78 |
-
|
79 |
-
return self.get_next_question()
|
80 |
-
|
81 |
-
def process_message(self, message: str) -> Dict:
|
82 |
-
"""Process user response and continue assessment"""
|
83 |
-
if not self.current_assessment:
|
84 |
-
return self.format_response(
|
85 |
-
"No active assessment. Please start an assessment first."
|
86 |
-
)
|
87 |
-
|
88 |
-
# Record response
|
89 |
-
self.current_assessment["responses"].append({
|
90 |
-
"question": self.current_assessment["current_question"],
|
91 |
-
"response": message,
|
92 |
-
"emotion": self.analyze_emotion(message)
|
93 |
-
})
|
94 |
-
|
95 |
-
# Move to next question or finish assessment
|
96 |
-
return (
|
97 |
-
self.finish_assessment()
|
98 |
-
if self._is_assessment_complete()
|
99 |
-
else self.get_next_question()
|
100 |
-
)
|
101 |
-
|
102 |
-
def get_next_question(self) -> Dict:
|
103 |
-
"""Get the next question in the assessment"""
|
104 |
-
if not self.current_assessment:
|
105 |
-
return self.format_response(
|
106 |
-
"No active assessment. Please start an assessment first."
|
107 |
-
)
|
108 |
-
|
109 |
-
tool = self.current_assessment["tool"]
|
110 |
-
question_idx = self.current_assessment["current_question"]
|
111 |
-
|
112 |
-
if question_idx >= len(tool["questions"]):
|
113 |
-
return self.finish_assessment()
|
114 |
-
|
115 |
-
question = tool["questions"][question_idx]
|
116 |
-
self.current_assessment["current_question"] += 1
|
117 |
-
|
118 |
-
return self.format_response(question)
|
119 |
-
|
120 |
-
def _is_assessment_complete(self) -> bool:
|
121 |
-
"""Check if all questions have been answered"""
|
122 |
-
if not self.current_assessment:
|
123 |
-
return False
|
124 |
-
|
125 |
-
return len(self.current_assessment["responses"]) >= len(
|
126 |
-
self.current_assessment["tool"]["questions"]
|
127 |
-
)
|
128 |
-
|
129 |
-
def finish_assessment(self) -> Dict:
|
130 |
-
"""Complete the assessment and generate report"""
|
131 |
-
if not self.current_assessment:
|
132 |
-
return self.format_response(
|
133 |
-
"No active assessment to finish."
|
134 |
-
)
|
135 |
-
|
136 |
-
# Calculate scores
|
137 |
-
scores = self._calculate_scores()
|
138 |
-
|
139 |
-
# Generate report
|
140 |
-
report = self._generate_report(scores)
|
141 |
-
|
142 |
-
# Add to history
|
143 |
-
self.add_to_history({
|
144 |
-
"assessment_type": self.current_assessment["type"],
|
145 |
-
"scores": scores,
|
146 |
-
"report": report
|
147 |
-
})
|
148 |
-
|
149 |
-
# Reset current assessment
|
150 |
-
self.current_assessment = None
|
151 |
-
|
152 |
-
return self.format_response(report)
|
153 |
-
|
154 |
-
def _calculate_scores(self) -> Dict:
|
155 |
-
"""Calculate assessment scores"""
|
156 |
-
# Implement scoring logic based on assessment type
|
157 |
-
return {
|
158 |
-
"total_score": 0, # Calculate actual score
|
159 |
-
"subscores": {},
|
160 |
-
"severity": "Unknown" # Determine from scoring ranges
|
161 |
-
}
|
162 |
-
|
163 |
-
def _generate_report(self, scores: Dict) -> str:
|
164 |
-
"""Generate detailed assessment report"""
|
165 |
-
report = f"""Assessment Report
|
166 |
-
|
167 |
-
Type: {self.current_assessment["type"].upper()}
|
168 |
-
Total Score: {scores["total_score"]}
|
169 |
-
Severity: {scores["severity"]}
|
170 |
-
|
171 |
-
Recommendations:
|
172 |
-
1. Continue monitoring your mental health
|
173 |
-
2. Consider discussing results with a mental health professional
|
174 |
-
3. Practice self-care and stress management techniques
|
175 |
-
|
176 |
-
Note: This assessment is for screening purposes only and does not constitute
|
177 |
-
a clinical diagnosis. Please consult with a qualified mental health professional
|
178 |
-
for proper evaluation and treatment."""
|
179 |
-
|
180 |
-
return report
|
181 |
-
|
182 |
-
def get_assessment_history(self) -> List[Dict]:
|
183 |
-
"""Get history of completed assessments"""
|
184 |
-
return self.get_history()
|
185 |
-
|
186 |
-
def get_available_assessments(self) -> List[str]:
|
187 |
-
"""Get list of available assessment tools"""
|
188 |
-
return list(self.assessment_tools.keys())
|
|
|
1 |
from typing import Dict, List
|
2 |
from .base_agent import BaseWellnessAgent
|
|
|
|
|
3 |
|
4 |
class AssessmentAgent(BaseWellnessAgent):
|
5 |
"""Agent specialized in mental health assessments"""
|
6 |
|
7 |
+
def __init__(self, model_config: Dict, **kwargs):
|
8 |
super().__init__(
|
9 |
+
model_config=model_config,
|
10 |
+
agent_type="assessment",
|
11 |
role="Mental Health Evaluator",
|
12 |
goal="Conduct thorough mental health assessments and provide actionable insights",
|
13 |
backstory="""I am an AI agent specialized in mental health assessment.
|
14 |
I use validated assessment tools and techniques to evaluate mental well-being
|
15 |
and provide personalized recommendations.""",
|
16 |
+
verbose=True,
|
17 |
+
allow_delegation=False,
|
18 |
+
tools=[], # Tools will be added as needed
|
19 |
+
**kwargs
|
20 |
+
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
agents/base_agent.py
CHANGED
@@ -1,91 +1,139 @@
|
|
1 |
-
from typing import Dict, List, Optional
|
2 |
-
from crewai import Agent
|
3 |
-
|
4 |
-
from
|
|
|
|
|
|
|
5 |
|
6 |
-
class AgentState(BaseModel):
|
7 |
-
"""State management for agents"""
|
8 |
-
context: Dict = {}
|
9 |
-
history: List[Dict] = []
|
10 |
-
current_task: Optional[str] = None
|
11 |
-
|
12 |
class BaseWellnessAgent(Agent):
|
13 |
-
"""Base class
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
14 |
|
15 |
-
def __init__(
|
16 |
-
|
17 |
-
name: str,
|
18 |
-
role: str,
|
19 |
-
goal: str,
|
20 |
-
backstory: str,
|
21 |
-
tools: List[str],
|
22 |
-
model_config: Dict,
|
23 |
-
verbose: bool = False
|
24 |
-
):
|
25 |
super().__init__(
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
|
|
|
|
31 |
)
|
32 |
-
self.tools = tools
|
33 |
-
self.model_config = model_config
|
34 |
-
self.state = AgentState()
|
35 |
-
self._initialize_models()
|
36 |
-
|
37 |
-
def _initialize_models(self):
|
38 |
-
"""Initialize required AI models for the agent"""
|
39 |
-
self.models = {}
|
40 |
-
if "emotion_detection" in self.tools:
|
41 |
-
self.models["emotion"] = pipeline(
|
42 |
-
"text-classification",
|
43 |
-
model=self.model_config["emotion_detection"]["model_id"]
|
44 |
-
)
|
45 |
-
|
46 |
-
def update_context(self, new_context: Dict):
|
47 |
-
"""Update agent's context with new information"""
|
48 |
-
self.state.context.update(new_context)
|
49 |
|
50 |
-
|
51 |
-
|
52 |
-
self.
|
|
|
53 |
|
54 |
-
|
55 |
-
|
56 |
-
return self.state.context
|
57 |
|
58 |
-
|
59 |
-
"""Get interaction history"""
|
60 |
-
return self.state.history
|
61 |
|
62 |
-
def
|
63 |
-
"""
|
64 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
65 |
|
66 |
-
def
|
67 |
-
"""
|
68 |
-
|
69 |
-
result = self.models["emotion"](text)
|
70 |
-
return result[0] if result else {}
|
71 |
-
return {}
|
72 |
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
"
|
77 |
-
|
78 |
-
|
79 |
-
"
|
80 |
-
"
|
81 |
-
"emotion_analysis": self.analyze_emotion(response)
|
82 |
-
}
|
83 |
|
84 |
-
def
|
85 |
-
"""
|
86 |
-
|
87 |
-
|
88 |
|
89 |
-
|
90 |
-
|
91 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from typing import Dict, List, Optional, Any
|
2 |
+
from crewai import Agent, Task
|
3 |
+
import logging
|
4 |
+
from utils.log_manager import LogManager
|
5 |
+
from pydantic import Field, BaseModel, ConfigDict
|
6 |
+
from transformers import AutoModelForCausalLM, AutoTokenizer
|
7 |
+
import torch
|
8 |
|
|
|
|
|
|
|
|
|
|
|
|
|
9 |
class BaseWellnessAgent(Agent):
|
10 |
+
"""Base agent class with Mistral LLM support"""
|
11 |
+
|
12 |
+
# Allow arbitrary types in model
|
13 |
+
model_config = ConfigDict(arbitrary_types_allowed=True)
|
14 |
+
|
15 |
+
# Define fields that will be used
|
16 |
+
log_manager: LogManager = Field(default_factory=LogManager)
|
17 |
+
logger: logging.Logger = Field(default=None)
|
18 |
+
config: Dict = Field(default_factory=dict)
|
19 |
+
model: Any = Field(default=None)
|
20 |
+
tokenizer: Any = Field(default=None)
|
21 |
+
agent_type: str = Field(default="base")
|
22 |
|
23 |
+
def __init__(self, model_config: Dict, agent_type: str, **kwargs):
|
24 |
+
# Initialize the CrewAI agent first with required fields
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
25 |
super().__init__(
|
26 |
+
role=kwargs.get("role", "Wellness Support Agent"),
|
27 |
+
goal=kwargs.get("goal", "Support mental wellness"),
|
28 |
+
backstory=kwargs.get("backstory", "I am an AI agent specialized in mental health support."),
|
29 |
+
verbose=kwargs.get("verbose", True),
|
30 |
+
allow_delegation=kwargs.get("allow_delegation", False),
|
31 |
+
tools=kwargs.get("tools", []),
|
32 |
+
**kwargs
|
33 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
34 |
|
35 |
+
# Initialize logging and configuration
|
36 |
+
self.config = model_config
|
37 |
+
self.agent_type = agent_type
|
38 |
+
self.logger = self.log_manager.get_agent_logger(agent_type)
|
39 |
|
40 |
+
# Initialize Mistral model
|
41 |
+
self._initialize_model()
|
|
|
42 |
|
43 |
+
self.logger.info(f"{agent_type.capitalize()} Agent initialized")
|
|
|
|
|
44 |
|
45 |
+
def _initialize_model(self):
|
46 |
+
"""Initialize the Mistral model"""
|
47 |
+
try:
|
48 |
+
model_config = self.config[self.agent_type]
|
49 |
+
self.logger.info(f"Initializing Mistral model: {model_config['model_id']}")
|
50 |
+
|
51 |
+
# Initialize tokenizer and model
|
52 |
+
self.tokenizer = AutoTokenizer.from_pretrained(model_config["model_id"])
|
53 |
+
self.model = AutoModelForCausalLM.from_pretrained(
|
54 |
+
model_config["model_id"],
|
55 |
+
torch_dtype=torch.float32,
|
56 |
+
device_map="auto",
|
57 |
+
load_in_4bit=True
|
58 |
+
)
|
59 |
+
|
60 |
+
self.logger.info("Mistral model initialized successfully")
|
61 |
+
|
62 |
+
except Exception as e:
|
63 |
+
self.logger.error(f"Error initializing Mistral model: {str(e)}")
|
64 |
+
raise
|
65 |
+
|
66 |
+
def _generate_response(self, input_text: str) -> str:
|
67 |
+
"""Generate response using Mistral model"""
|
68 |
+
try:
|
69 |
+
# Prepare input with instruction template
|
70 |
+
template = self.config[self.agent_type]["instruction_template"]
|
71 |
+
prompt = template.format(input=input_text)
|
72 |
+
|
73 |
+
# Tokenize input
|
74 |
+
inputs = self.tokenizer(prompt, return_tensors="pt").to(self.model.device)
|
75 |
+
|
76 |
+
# Generate response
|
77 |
+
outputs = self.model.generate(
|
78 |
+
**inputs,
|
79 |
+
max_length=self.config[self.agent_type].get("max_length", 4096),
|
80 |
+
temperature=self.config[self.agent_type].get("temperature", 0.7),
|
81 |
+
top_p=self.config[self.agent_type].get("top_p", 0.95),
|
82 |
+
repetition_penalty=self.config[self.agent_type].get("repetition_penalty", 1.1),
|
83 |
+
do_sample=True,
|
84 |
+
pad_token_id=self.tokenizer.eos_token_id
|
85 |
+
)
|
86 |
+
|
87 |
+
# Decode and clean response
|
88 |
+
response = self.tokenizer.decode(outputs[0], skip_special_tokens=True)
|
89 |
+
response = response.replace(prompt, "").strip()
|
90 |
+
|
91 |
+
return response
|
92 |
+
|
93 |
+
except Exception as e:
|
94 |
+
self.logger.error(f"Error generating response: {str(e)}")
|
95 |
+
return "I apologize, but I encountered an error generating a response."
|
96 |
|
97 |
+
def execute_task(self, task: Task) -> str:
|
98 |
+
"""Execute a task assigned to the agent"""
|
99 |
+
self.logger.info(f"Executing task: {task.description}")
|
|
|
|
|
|
|
100 |
|
101 |
+
try:
|
102 |
+
# Process the task description as a message
|
103 |
+
result = self.process_message(task.description)
|
104 |
+
return result["message"]
|
105 |
+
|
106 |
+
except Exception as e:
|
107 |
+
self.logger.error(f"Error executing task: {str(e)}")
|
108 |
+
return "I apologize, but I encountered an error processing your request."
|
|
|
|
|
109 |
|
110 |
+
def process_message(self, message: str, context: Dict = None) -> Dict:
|
111 |
+
"""Process a message and return a response"""
|
112 |
+
self.logger.info("Processing message")
|
113 |
+
context = context or {}
|
114 |
|
115 |
+
try:
|
116 |
+
# Generate response using Mistral
|
117 |
+
response = self._generate_response(message)
|
118 |
+
|
119 |
+
return {
|
120 |
+
"message": response,
|
121 |
+
"agent_type": self.agent_type,
|
122 |
+
"task_type": "dialogue"
|
123 |
+
}
|
124 |
+
|
125 |
+
except Exception as e:
|
126 |
+
self.logger.error(f"Error processing message: {str(e)}")
|
127 |
+
return {
|
128 |
+
"message": "I apologize, but I encountered an error. Let me try a different approach.",
|
129 |
+
"agent_type": self.agent_type,
|
130 |
+
"task_type": "error_recovery"
|
131 |
+
}
|
132 |
+
|
133 |
+
def get_status(self) -> Dict:
|
134 |
+
"""Get the current status of the agent"""
|
135 |
+
return {
|
136 |
+
"type": self.agent_type,
|
137 |
+
"ready": bool(self.model and self.tokenizer),
|
138 |
+
"tools_available": len(self.tools)
|
139 |
+
}
|
agents/conversation_agent.py
CHANGED
@@ -1,23 +1,13 @@
|
|
1 |
-
from typing import Dict
|
2 |
-
from
|
3 |
-
import logging
|
4 |
-
from utils.log_manager import LogManager
|
5 |
-
from pydantic import Field, BaseModel, ConfigDict
|
6 |
|
7 |
-
class ConversationAgent(
|
8 |
"""Agent specialized in therapeutic conversations"""
|
9 |
|
10 |
-
# Allow arbitrary types in model
|
11 |
-
model_config = ConfigDict(arbitrary_types_allowed=True)
|
12 |
-
|
13 |
-
# Define fields that will be used
|
14 |
-
log_manager: LogManager = Field(default_factory=LogManager)
|
15 |
-
logger: logging.Logger = Field(default=None)
|
16 |
-
config: Dict = Field(default_factory=dict)
|
17 |
-
|
18 |
def __init__(self, model_config: Dict, **kwargs):
|
19 |
-
# Initialize the CrewAI agent first with required fields
|
20 |
super().__init__(
|
|
|
|
|
21 |
role="Therapeutic Conversation Specialist",
|
22 |
goal="Guide therapeutic conversations and provide emotional support",
|
23 |
backstory="""I am an AI agent specialized in therapeutic conversation techniques.
|
@@ -27,83 +17,4 @@ class ConversationAgent(Agent):
|
|
27 |
allow_delegation=False,
|
28 |
tools=[], # Tools will be added as needed
|
29 |
**kwargs
|
30 |
-
)
|
31 |
-
|
32 |
-
# Initialize logging and configuration after parent initialization
|
33 |
-
self.config = model_config
|
34 |
-
self.logger = self.log_manager.get_agent_logger("conversation")
|
35 |
-
|
36 |
-
self.logger.info("Conversation Agent initialized")
|
37 |
-
|
38 |
-
def execute_task(self, task: Task) -> str:
|
39 |
-
"""Execute a task assigned to the agent"""
|
40 |
-
self.logger.info(f"Executing task: {task.description}")
|
41 |
-
|
42 |
-
try:
|
43 |
-
# Process the task description as a message
|
44 |
-
result = self.process_message(task.description)
|
45 |
-
return result["message"]
|
46 |
-
|
47 |
-
except Exception as e:
|
48 |
-
self.logger.error(f"Error executing task: {str(e)}")
|
49 |
-
return "I apologize, but I encountered an error processing your request."
|
50 |
-
|
51 |
-
def process_message(self, message: str, context: Dict = None) -> Dict:
|
52 |
-
"""Process a message and return a therapeutic response"""
|
53 |
-
self.logger.info("Processing message")
|
54 |
-
context = context or {}
|
55 |
-
|
56 |
-
try:
|
57 |
-
# Generate therapeutic response
|
58 |
-
response = self._generate_therapeutic_response(message, context)
|
59 |
-
|
60 |
-
return {
|
61 |
-
"message": response,
|
62 |
-
"agent_type": "conversation",
|
63 |
-
"task_type": "therapeutic_dialogue"
|
64 |
-
}
|
65 |
-
|
66 |
-
except Exception as e:
|
67 |
-
self.logger.error(f"Error processing message: {str(e)}")
|
68 |
-
return {
|
69 |
-
"message": "I apologize, but I encountered an error. Let me try a different approach.",
|
70 |
-
"agent_type": "conversation",
|
71 |
-
"task_type": "error_recovery"
|
72 |
-
}
|
73 |
-
|
74 |
-
def _generate_therapeutic_response(self, message: str, context: Dict) -> str:
|
75 |
-
"""Generate a therapeutic response based on the input message and context"""
|
76 |
-
# Basic response templates
|
77 |
-
responses = {
|
78 |
-
"greeting": "Hello! I'm here to support you. How are you feeling today?",
|
79 |
-
"emotion": "I hear that you're feeling {}. Would you like to tell me more about that?",
|
80 |
-
"support": "That sounds challenging. I'm here to listen and support you.",
|
81 |
-
"clarification": "Could you tell me more about what you mean by that?",
|
82 |
-
"validation": "It's completely normal to feel that way. Your feelings are valid.",
|
83 |
-
"default": "I understand and I'm here to help. Could you tell me more about how you're feeling?"
|
84 |
-
}
|
85 |
-
|
86 |
-
# Simple message analysis
|
87 |
-
message = message.lower()
|
88 |
-
|
89 |
-
if "hello" in message or "hi" in message:
|
90 |
-
return responses["greeting"]
|
91 |
-
elif any(word in message for word in ["sad", "angry", "scared", "happy", "anxious"]):
|
92 |
-
emotion = next(word for word in ["sad", "angry", "scared", "happy", "anxious"] if word in message)
|
93 |
-
return responses["emotion"].format(emotion)
|
94 |
-
elif any(word in message for word in ["help", "support", "difficult", "hard"]):
|
95 |
-
return responses["support"]
|
96 |
-
elif len(message.split()) < 3:
|
97 |
-
return responses["clarification"]
|
98 |
-
elif "feel" in message or "feeling" in message:
|
99 |
-
return responses["validation"]
|
100 |
-
else:
|
101 |
-
return responses["default"]
|
102 |
-
|
103 |
-
def get_status(self) -> Dict:
|
104 |
-
"""Get the current status of the agent"""
|
105 |
-
return {
|
106 |
-
"type": "conversation",
|
107 |
-
"ready": True,
|
108 |
-
"tools_available": len(self.tools)
|
109 |
-
}
|
|
|
1 |
+
from typing import Dict
|
2 |
+
from .base_agent import BaseWellnessAgent
|
|
|
|
|
|
|
3 |
|
4 |
+
class ConversationAgent(BaseWellnessAgent):
|
5 |
"""Agent specialized in therapeutic conversations"""
|
6 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7 |
def __init__(self, model_config: Dict, **kwargs):
|
|
|
8 |
super().__init__(
|
9 |
+
model_config=model_config,
|
10 |
+
agent_type="conversation",
|
11 |
role="Therapeutic Conversation Specialist",
|
12 |
goal="Guide therapeutic conversations and provide emotional support",
|
13 |
backstory="""I am an AI agent specialized in therapeutic conversation techniques.
|
|
|
17 |
allow_delegation=False,
|
18 |
tools=[], # Tools will be added as needed
|
19 |
**kwargs
|
20 |
+
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
agents/crisis_agent.py
CHANGED
@@ -1,251 +1,20 @@
|
|
1 |
-
from typing import Dict
|
2 |
from .base_agent import BaseWellnessAgent
|
3 |
-
import json
|
4 |
-
from pathlib import Path
|
5 |
|
6 |
class CrisisAgent(BaseWellnessAgent):
|
7 |
-
"""Agent specialized in crisis intervention
|
8 |
|
9 |
-
def __init__(self, model_config: Dict,
|
10 |
super().__init__(
|
11 |
-
|
12 |
-
|
|
|
13 |
goal="Provide immediate support and intervention in crisis situations",
|
14 |
backstory="""I am an AI agent specialized in crisis intervention.
|
15 |
-
I
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
self.current_intervention = None
|
23 |
-
self.emergency_contacts = self._load_emergency_contacts()
|
24 |
-
|
25 |
-
def _load_protocols(self) -> Dict:
|
26 |
-
"""Load crisis intervention protocols"""
|
27 |
-
protocols_path = Path(__file__).parent.parent / "knowledge_base" / "guidelines" / "crisis_protocols.json"
|
28 |
-
try:
|
29 |
-
with open(protocols_path) as f:
|
30 |
-
return json.load(f)
|
31 |
-
except FileNotFoundError:
|
32 |
-
return {
|
33 |
-
"suicide_risk": {
|
34 |
-
"severity_levels": {
|
35 |
-
"low": {
|
36 |
-
"indicators": [
|
37 |
-
"Passing thoughts of death",
|
38 |
-
"No specific plan",
|
39 |
-
"Some protective factors"
|
40 |
-
],
|
41 |
-
"response": "Provide support and resources"
|
42 |
-
},
|
43 |
-
"medium": {
|
44 |
-
"indicators": [
|
45 |
-
"Frequent thoughts of death",
|
46 |
-
"Vague plans",
|
47 |
-
"Some risk factors present"
|
48 |
-
],
|
49 |
-
"response": "Immediate counseling referral"
|
50 |
-
},
|
51 |
-
"high": {
|
52 |
-
"indicators": [
|
53 |
-
"Specific suicide plan",
|
54 |
-
"Access to means",
|
55 |
-
"Multiple risk factors"
|
56 |
-
],
|
57 |
-
"response": "Emergency services contact"
|
58 |
-
}
|
59 |
-
},
|
60 |
-
"immediate_actions": [
|
61 |
-
"Express concern and care",
|
62 |
-
"Assess immediate safety",
|
63 |
-
"Connect with emergency services if needed"
|
64 |
-
]
|
65 |
-
},
|
66 |
-
"panic_attack": {
|
67 |
-
"symptoms": [
|
68 |
-
"Rapid heartbeat",
|
69 |
-
"Difficulty breathing",
|
70 |
-
"Feeling of doom"
|
71 |
-
],
|
72 |
-
"interventions": [
|
73 |
-
"Grounding techniques",
|
74 |
-
"Breathing exercises",
|
75 |
-
"Reassurance and support"
|
76 |
-
]
|
77 |
-
}
|
78 |
-
}
|
79 |
-
|
80 |
-
def _load_emergency_contacts(self) -> Dict:
|
81 |
-
"""Load emergency contact information"""
|
82 |
-
return {
|
83 |
-
"emergency_services": "911",
|
84 |
-
"crisis_hotline": "988",
|
85 |
-
"text_line": "741741",
|
86 |
-
"poison_control": "1-800-222-1222"
|
87 |
-
}
|
88 |
-
|
89 |
-
def process_message(self, message: str) -> Dict:
|
90 |
-
"""Process crisis-related message and provide appropriate response"""
|
91 |
-
# Analyze message for crisis indicators
|
92 |
-
risk_assessment = self._assess_risk(message)
|
93 |
-
|
94 |
-
# Update intervention state
|
95 |
-
self._update_intervention_state(risk_assessment)
|
96 |
-
|
97 |
-
# Generate appropriate response based on risk level
|
98 |
-
response = self._generate_crisis_response(risk_assessment)
|
99 |
-
|
100 |
-
# Record interaction
|
101 |
-
self.add_to_history({
|
102 |
-
"message": message,
|
103 |
-
"risk_assessment": risk_assessment,
|
104 |
-
"response": response
|
105 |
-
})
|
106 |
-
|
107 |
-
return self.format_response(response)
|
108 |
-
|
109 |
-
def _assess_risk(self, message: str) -> Dict:
|
110 |
-
"""Assess risk level from message content"""
|
111 |
-
# Analyze emotion
|
112 |
-
emotion = self.analyze_emotion(message)
|
113 |
-
|
114 |
-
# Check for critical keywords
|
115 |
-
risk_level = self._determine_risk_level(message.lower())
|
116 |
-
|
117 |
-
return {
|
118 |
-
"risk_level": risk_level,
|
119 |
-
"emotion": emotion,
|
120 |
-
"timestamp": self._get_timestamp()
|
121 |
-
}
|
122 |
-
|
123 |
-
def _determine_risk_level(self, message: str) -> str:
|
124 |
-
"""Determine risk level based on message content"""
|
125 |
-
high_risk_keywords = [
|
126 |
-
"kill myself", "end my life", "suicide plan",
|
127 |
-
"want to die", "no reason to live"
|
128 |
-
]
|
129 |
-
medium_risk_keywords = [
|
130 |
-
"want to disappear", "everyone better off",
|
131 |
-
"cant take it", "hopeless"
|
132 |
-
]
|
133 |
-
|
134 |
-
if any(keyword in message for keyword in high_risk_keywords):
|
135 |
-
return "high"
|
136 |
-
elif any(keyword in message for keyword in medium_risk_keywords):
|
137 |
-
return "medium"
|
138 |
-
return "low"
|
139 |
-
|
140 |
-
def _update_intervention_state(self, risk_assessment: Dict):
|
141 |
-
"""Update or create intervention state"""
|
142 |
-
if not self.current_intervention:
|
143 |
-
self.current_intervention = {
|
144 |
-
"start_time": self._get_timestamp(),
|
145 |
-
"risk_assessments": [],
|
146 |
-
"escalation_level": "initial"
|
147 |
-
}
|
148 |
-
|
149 |
-
self.current_intervention["risk_assessments"].append(risk_assessment)
|
150 |
-
self._update_escalation_level(risk_assessment["risk_level"])
|
151 |
-
|
152 |
-
def _update_escalation_level(self, risk_level: str):
|
153 |
-
"""Update intervention escalation level"""
|
154 |
-
if risk_level == "high":
|
155 |
-
self.current_intervention["escalation_level"] = "emergency"
|
156 |
-
elif risk_level == "medium" and self.current_intervention["escalation_level"] == "initial":
|
157 |
-
self.current_intervention["escalation_level"] = "elevated"
|
158 |
-
|
159 |
-
def _generate_crisis_response(self, risk_assessment: Dict) -> str:
|
160 |
-
"""Generate appropriate crisis response"""
|
161 |
-
risk_level = risk_assessment["risk_level"]
|
162 |
-
escalation_level = self.current_intervention["escalation_level"]
|
163 |
-
|
164 |
-
if risk_level == "high" or escalation_level == "emergency":
|
165 |
-
return self._generate_emergency_response()
|
166 |
-
elif risk_level == "medium" or escalation_level == "elevated":
|
167 |
-
return self._generate_elevated_response()
|
168 |
-
else:
|
169 |
-
return self._generate_supportive_response()
|
170 |
-
|
171 |
-
def _generate_emergency_response(self) -> str:
|
172 |
-
"""Generate response for emergency situations"""
|
173 |
-
return f"""I'm very concerned about your safety right now. This is an emergency situation that requires immediate attention.
|
174 |
-
|
175 |
-
EMERGENCY CONTACTS:
|
176 |
-
- Emergency Services: {self.emergency_contacts['emergency_services']}
|
177 |
-
- Crisis Hotline: {self.emergency_contacts['crisis_hotline']}
|
178 |
-
- Crisis Text Line: Text HOME to {self.emergency_contacts['text_line']}
|
179 |
-
|
180 |
-
Please:
|
181 |
-
1. Call emergency services immediately
|
182 |
-
2. Stay on the line with me
|
183 |
-
3. If possible, contact a trusted person to be with you
|
184 |
-
|
185 |
-
Your life has value and people care about you. Help is available 24/7."""
|
186 |
-
|
187 |
-
def _generate_elevated_response(self) -> str:
|
188 |
-
"""Generate response for elevated risk situations"""
|
189 |
-
return f"""I hear how much pain you're in, and I want to help ensure your safety.
|
190 |
-
|
191 |
-
Please consider:
|
192 |
-
1. Calling the Crisis Hotline: {self.emergency_contacts['crisis_hotline']}
|
193 |
-
2. Texting HOME to {self.emergency_contacts['text_line']}
|
194 |
-
3. Reaching out to a trusted friend, family member, or counselor
|
195 |
-
|
196 |
-
Would you be willing to talk about what's troubling you? I'm here to listen without judgment."""
|
197 |
-
|
198 |
-
def _generate_supportive_response(self) -> str:
|
199 |
-
"""Generate supportive response for lower risk situations"""
|
200 |
-
return """I can hear that you're going through a difficult time. Your feelings are valid, and you're not alone.
|
201 |
-
|
202 |
-
Let's talk about what's happening. I'm here to:
|
203 |
-
1. Listen and understand
|
204 |
-
2. Help you explore your feelings
|
205 |
-
3. Discuss coping strategies
|
206 |
-
4. Connect you with resources
|
207 |
-
|
208 |
-
What would be most helpful for you right now?"""
|
209 |
-
|
210 |
-
def end_intervention(self) -> Dict:
|
211 |
-
"""End current crisis intervention"""
|
212 |
-
if not self.current_intervention:
|
213 |
-
return self.format_response(
|
214 |
-
"No active crisis intervention to end."
|
215 |
-
)
|
216 |
-
|
217 |
-
# Generate intervention summary
|
218 |
-
summary = self._generate_intervention_summary()
|
219 |
-
|
220 |
-
# Add final summary to history
|
221 |
-
self.add_to_history({
|
222 |
-
"intervention_summary": summary,
|
223 |
-
"end_time": self._get_timestamp()
|
224 |
-
})
|
225 |
-
|
226 |
-
# Reset current intervention
|
227 |
-
self.current_intervention = None
|
228 |
-
|
229 |
-
return self.format_response(summary)
|
230 |
-
|
231 |
-
def _generate_intervention_summary(self) -> str:
|
232 |
-
"""Generate summary of crisis intervention"""
|
233 |
-
assessments = self.current_intervention["risk_assessments"]
|
234 |
-
max_risk = max(a["risk_level"] for a in assessments)
|
235 |
-
|
236 |
-
return f"""Crisis Intervention Summary
|
237 |
-
|
238 |
-
Duration: {self._calculate_duration(
|
239 |
-
self.current_intervention["start_time"],
|
240 |
-
self._get_timestamp()
|
241 |
-
) // 60} minutes
|
242 |
-
Maximum Risk Level: {max_risk}
|
243 |
-
Escalation Level: {self.current_intervention["escalation_level"]}
|
244 |
-
|
245 |
-
Follow-up Recommendations:
|
246 |
-
1. Continue monitoring emotional state
|
247 |
-
2. Maintain contact with support system
|
248 |
-
3. Follow up with mental health professional
|
249 |
-
4. Keep crisis resources readily available
|
250 |
-
|
251 |
-
Remember: Support is always available at {self.emergency_contacts['crisis_hotline']}"""
|
|
|
1 |
+
from typing import Dict
|
2 |
from .base_agent import BaseWellnessAgent
|
|
|
|
|
3 |
|
4 |
class CrisisAgent(BaseWellnessAgent):
|
5 |
+
"""Agent specialized in crisis intervention"""
|
6 |
|
7 |
+
def __init__(self, model_config: Dict, **kwargs):
|
8 |
super().__init__(
|
9 |
+
model_config=model_config,
|
10 |
+
agent_type="crisis",
|
11 |
+
role="Crisis Intervention Specialist",
|
12 |
goal="Provide immediate support and intervention in crisis situations",
|
13 |
backstory="""I am an AI agent specialized in crisis intervention.
|
14 |
+
I prioritize user safety and provide immediate support while ensuring
|
15 |
+
appropriate escalation to emergency services when necessary.""",
|
16 |
+
verbose=True,
|
17 |
+
allow_delegation=False,
|
18 |
+
tools=[], # Tools will be added as needed
|
19 |
+
**kwargs
|
20 |
+
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
agents/mindfulness_agent.py
CHANGED
@@ -1,227 +1,20 @@
|
|
1 |
-
from typing import Dict
|
2 |
from .base_agent import BaseWellnessAgent
|
3 |
-
import json
|
4 |
-
from pathlib import Path
|
5 |
|
6 |
class MindfulnessAgent(BaseWellnessAgent):
|
7 |
"""Agent specialized in mindfulness and meditation guidance"""
|
8 |
|
9 |
-
def __init__(self, model_config: Dict,
|
10 |
super().__init__(
|
11 |
-
name="Mindfulness & Meditation Agent",
|
12 |
-
role="Mindfulness Guide",
|
13 |
-
goal="Guide users through mindfulness exercises and meditation sessions",
|
14 |
-
backstory="""I am an AI agent specialized in mindfulness and meditation guidance.
|
15 |
-
I provide calming exercises, breathing techniques, and meditation sessions
|
16 |
-
tailored to users' needs and experience levels.""",
|
17 |
-
tools=["emotion_detection", "conversation"],
|
18 |
model_config=model_config,
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
except FileNotFoundError:
|
31 |
-
return {
|
32 |
-
"breathing": {
|
33 |
-
"box_breathing": {
|
34 |
-
"name": "Box Breathing",
|
35 |
-
"description": "A simple technique to reduce stress and improve focus",
|
36 |
-
"duration": 300, # 5 minutes
|
37 |
-
"steps": [
|
38 |
-
"Inhale slowly for 4 counts",
|
39 |
-
"Hold your breath for 4 counts",
|
40 |
-
"Exhale slowly for 4 counts",
|
41 |
-
"Hold for 4 counts before the next breath"
|
42 |
-
],
|
43 |
-
"instructions": "Find a comfortable position. We'll practice box breathing for 5 minutes."
|
44 |
-
},
|
45 |
-
"deep_breathing": {
|
46 |
-
"name": "Deep Breathing",
|
47 |
-
"description": "Calming deep breathing exercise",
|
48 |
-
"duration": 300,
|
49 |
-
"steps": [
|
50 |
-
"Take a deep breath in through your nose",
|
51 |
-
"Feel your belly expand",
|
52 |
-
"Exhale slowly through your mouth",
|
53 |
-
"Feel your body relax"
|
54 |
-
],
|
55 |
-
"instructions": "Sit comfortably with your back straight. Let's begin deep breathing."
|
56 |
-
}
|
57 |
-
},
|
58 |
-
"meditation": {
|
59 |
-
"body_scan": {
|
60 |
-
"name": "Body Scan Meditation",
|
61 |
-
"description": "Progressive relaxation through body awareness",
|
62 |
-
"duration": 600, # 10 minutes
|
63 |
-
"steps": [
|
64 |
-
"Focus on your toes and feet",
|
65 |
-
"Move attention to your legs",
|
66 |
-
"Progress through torso and arms",
|
67 |
-
"End with neck and head"
|
68 |
-
],
|
69 |
-
"instructions": "Lie down comfortably. We'll guide you through a full body scan."
|
70 |
-
},
|
71 |
-
"loving_kindness": {
|
72 |
-
"name": "Loving-Kindness Meditation",
|
73 |
-
"description": "Develop compassion for self and others",
|
74 |
-
"duration": 600,
|
75 |
-
"steps": [
|
76 |
-
"Direct love to yourself",
|
77 |
-
"Extend to loved ones",
|
78 |
-
"Include neutral people",
|
79 |
-
"Embrace all beings"
|
80 |
-
],
|
81 |
-
"instructions": "Sit in a relaxed position. We'll practice sending loving-kindness."
|
82 |
-
}
|
83 |
-
}
|
84 |
-
}
|
85 |
-
|
86 |
-
def start_session(self, session_type: str, exercise_name: str = None) -> Dict:
|
87 |
-
"""Start a new mindfulness session"""
|
88 |
-
if session_type not in self.exercises:
|
89 |
-
raise ValueError(f"Unknown session type: {session_type}")
|
90 |
-
|
91 |
-
exercises = self.exercises[session_type]
|
92 |
-
if exercise_name and exercise_name not in exercises:
|
93 |
-
raise ValueError(f"Unknown exercise: {exercise_name}")
|
94 |
-
|
95 |
-
selected_exercise = exercises[exercise_name] if exercise_name else next(iter(exercises.values()))
|
96 |
-
|
97 |
-
self.current_session = {
|
98 |
-
"type": session_type,
|
99 |
-
"exercise": selected_exercise,
|
100 |
-
"start_time": self._get_timestamp(),
|
101 |
-
"current_step": 0,
|
102 |
-
"completed_steps": []
|
103 |
-
}
|
104 |
-
|
105 |
-
return self.format_response(self._create_session_intro())
|
106 |
-
|
107 |
-
def process_message(self, message: str) -> Dict:
|
108 |
-
"""Process user message during mindfulness session"""
|
109 |
-
if not self.current_session:
|
110 |
-
return self.format_response(
|
111 |
-
"No active session. Please start a mindfulness session first."
|
112 |
-
)
|
113 |
-
|
114 |
-
# Check for session control commands
|
115 |
-
if message.lower() in ["pause", "stop", "end"]:
|
116 |
-
return self.end_session()
|
117 |
-
|
118 |
-
# Progress through exercise steps
|
119 |
-
return self._progress_session()
|
120 |
-
|
121 |
-
def _progress_session(self) -> Dict:
|
122 |
-
"""Progress through the current session's steps"""
|
123 |
-
exercise = self.current_session["exercise"]
|
124 |
-
current_step = self.current_session["current_step"]
|
125 |
-
|
126 |
-
if current_step >= len(exercise["steps"]):
|
127 |
-
return self.end_session()
|
128 |
-
|
129 |
-
step = exercise["steps"][current_step]
|
130 |
-
self.current_session["completed_steps"].append({
|
131 |
-
"step": current_step,
|
132 |
-
"timestamp": self._get_timestamp()
|
133 |
-
})
|
134 |
-
|
135 |
-
self.current_session["current_step"] += 1
|
136 |
-
|
137 |
-
return self.format_response(self._create_step_guidance(step))
|
138 |
-
|
139 |
-
def _create_session_intro(self) -> str:
|
140 |
-
"""Create introduction for the session"""
|
141 |
-
exercise = self.current_session["exercise"]
|
142 |
-
return f"""Welcome to {exercise['name']}.
|
143 |
-
|
144 |
-
{exercise['description']}
|
145 |
-
|
146 |
-
Duration: {exercise['duration'] // 60} minutes
|
147 |
-
|
148 |
-
{exercise['instructions']}
|
149 |
-
|
150 |
-
When you're ready, respond with 'begin' to start."""
|
151 |
-
|
152 |
-
def _create_step_guidance(self, step: str) -> str:
|
153 |
-
"""Create guidance for the current step"""
|
154 |
-
return f"""{step}
|
155 |
-
|
156 |
-
Take your time with this step.
|
157 |
-
When you're ready to continue, send any message."""
|
158 |
-
|
159 |
-
def end_session(self) -> Dict:
|
160 |
-
"""End the current mindfulness session"""
|
161 |
-
if not self.current_session:
|
162 |
-
return self.format_response(
|
163 |
-
"No active session to end."
|
164 |
-
)
|
165 |
-
|
166 |
-
# Calculate session statistics
|
167 |
-
stats = self._calculate_session_stats()
|
168 |
-
|
169 |
-
# Generate session summary
|
170 |
-
summary = self._generate_session_summary(stats)
|
171 |
-
|
172 |
-
# Add to history
|
173 |
-
self.add_to_history({
|
174 |
-
"session_type": self.current_session["type"],
|
175 |
-
"exercise": self.current_session["exercise"]["name"],
|
176 |
-
"stats": stats,
|
177 |
-
"summary": summary
|
178 |
-
})
|
179 |
-
|
180 |
-
# Reset current session
|
181 |
-
self.current_session = None
|
182 |
-
|
183 |
-
return self.format_response(summary)
|
184 |
-
|
185 |
-
def _calculate_session_stats(self) -> Dict:
|
186 |
-
"""Calculate statistics for the completed session"""
|
187 |
-
start_time = self.current_session["start_time"]
|
188 |
-
end_time = self._get_timestamp()
|
189 |
-
completed_steps = len(self.current_session["completed_steps"])
|
190 |
-
total_steps = len(self.current_session["exercise"]["steps"])
|
191 |
-
|
192 |
-
return {
|
193 |
-
"duration": self._calculate_duration(start_time, end_time),
|
194 |
-
"completion_rate": completed_steps / total_steps,
|
195 |
-
"steps_completed": completed_steps
|
196 |
-
}
|
197 |
-
|
198 |
-
def _calculate_duration(self, start_time: str, end_time: str) -> int:
|
199 |
-
"""Calculate session duration in seconds"""
|
200 |
-
from datetime import datetime
|
201 |
-
start = datetime.fromisoformat(start_time)
|
202 |
-
end = datetime.fromisoformat(end_time)
|
203 |
-
return int((end - start).total_seconds())
|
204 |
-
|
205 |
-
def _generate_session_summary(self, stats: Dict) -> str:
|
206 |
-
"""Generate summary of the completed session"""
|
207 |
-
exercise = self.current_session["exercise"]
|
208 |
-
|
209 |
-
return f"""Session Complete: {exercise['name']}
|
210 |
-
|
211 |
-
Duration: {stats['duration'] // 60} minutes
|
212 |
-
Steps Completed: {stats['steps_completed']} of {len(exercise['steps'])}
|
213 |
-
Completion Rate: {stats['completion_rate'] * 100:.1f}%
|
214 |
-
|
215 |
-
Thank you for practicing mindfulness. Remember to:
|
216 |
-
1. Take these peaceful feelings with you
|
217 |
-
2. Practice regularly for best results
|
218 |
-
3. Be gentle with yourself
|
219 |
-
|
220 |
-
Would you like to try another exercise?"""
|
221 |
-
|
222 |
-
def get_available_exercises(self) -> Dict:
|
223 |
-
"""Get list of available exercises"""
|
224 |
-
return {
|
225 |
-
category: list(exercises.keys())
|
226 |
-
for category, exercises in self.exercises.items()
|
227 |
-
}
|
|
|
1 |
+
from typing import Dict
|
2 |
from .base_agent import BaseWellnessAgent
|
|
|
|
|
3 |
|
4 |
class MindfulnessAgent(BaseWellnessAgent):
|
5 |
"""Agent specialized in mindfulness and meditation guidance"""
|
6 |
|
7 |
+
def __init__(self, model_config: Dict, **kwargs):
|
8 |
super().__init__(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
9 |
model_config=model_config,
|
10 |
+
agent_type="mindfulness",
|
11 |
+
role="Mindfulness Guide",
|
12 |
+
goal="Guide users through mindfulness exercises and meditation",
|
13 |
+
backstory="""I am an AI agent specialized in mindfulness and meditation.
|
14 |
+
I provide calming guidance and support for various mindfulness practices
|
15 |
+
while being attentive to individual needs and comfort levels.""",
|
16 |
+
verbose=True,
|
17 |
+
allow_delegation=False,
|
18 |
+
tools=[], # Tools will be added as needed
|
19 |
+
**kwargs
|
20 |
+
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
agents/orchestrator.py
CHANGED
@@ -26,21 +26,32 @@ class WellnessOrchestrator:
|
|
26 |
self.logger.info("Initializing agents")
|
27 |
|
28 |
try:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
29 |
# Initialize each agent
|
30 |
self.conversation_agent = ConversationAgent(
|
31 |
-
model_config=self.model_config
|
|
|
32 |
)
|
33 |
|
34 |
self.assessment_agent = ConversationAgent( # Temporarily using ConversationAgent
|
35 |
-
model_config=self.model_config
|
|
|
36 |
)
|
37 |
|
38 |
self.mindfulness_agent = ConversationAgent( # Temporarily using ConversationAgent
|
39 |
-
model_config=self.model_config
|
|
|
40 |
)
|
41 |
|
42 |
self.crisis_agent = ConversationAgent( # Temporarily using ConversationAgent
|
43 |
-
model_config=self.model_config
|
|
|
44 |
)
|
45 |
|
46 |
self.logger.info("All agents initialized successfully")
|
|
|
26 |
self.logger.info("Initializing agents")
|
27 |
|
28 |
try:
|
29 |
+
# Common agent configuration
|
30 |
+
agent_config = {
|
31 |
+
"llm_config": self.model_config.get("conversation", {}),
|
32 |
+
"temperature": 0.7,
|
33 |
+
"max_iterations": 3
|
34 |
+
}
|
35 |
+
|
36 |
# Initialize each agent
|
37 |
self.conversation_agent = ConversationAgent(
|
38 |
+
model_config=self.model_config,
|
39 |
+
**agent_config
|
40 |
)
|
41 |
|
42 |
self.assessment_agent = ConversationAgent( # Temporarily using ConversationAgent
|
43 |
+
model_config=self.model_config,
|
44 |
+
**agent_config
|
45 |
)
|
46 |
|
47 |
self.mindfulness_agent = ConversationAgent( # Temporarily using ConversationAgent
|
48 |
+
model_config=self.model_config,
|
49 |
+
**agent_config
|
50 |
)
|
51 |
|
52 |
self.crisis_agent = ConversationAgent( # Temporarily using ConversationAgent
|
53 |
+
model_config=self.model_config,
|
54 |
+
**agent_config
|
55 |
)
|
56 |
|
57 |
self.logger.info("All agents initialized successfully")
|
config/config.py
CHANGED
@@ -6,18 +6,50 @@ def load_config() -> Dict:
|
|
6 |
return {
|
7 |
"MODEL_CONFIGS": {
|
8 |
"conversation": {
|
9 |
-
"model_id": "
|
10 |
-
"max_length":
|
11 |
"temperature": 0.7,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
12 |
},
|
13 |
"emotion_detection": {
|
14 |
-
"model_id": "
|
|
|
|
|
|
|
|
|
|
|
15 |
},
|
16 |
-
"
|
17 |
-
"model_id": "
|
|
|
|
|
|
|
|
|
|
|
|
|
18 |
},
|
19 |
-
"
|
20 |
-
"model_id": "
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
21 |
}
|
22 |
},
|
23 |
"INTERFACE_CONFIG": {
|
|
|
6 |
return {
|
7 |
"MODEL_CONFIGS": {
|
8 |
"conversation": {
|
9 |
+
"model_id": "mistralai/Mistral-7B-Instruct-v0.2",
|
10 |
+
"max_length": 4096,
|
11 |
"temperature": 0.7,
|
12 |
+
"top_p": 0.95,
|
13 |
+
"repetition_penalty": 1.1,
|
14 |
+
"context_length": 4096,
|
15 |
+
"instruction_template": """You are a therapeutic conversation agent specialized in mental health support.
|
16 |
+
Your goal is to provide empathetic, supportive responses while maintaining appropriate boundaries.
|
17 |
+
|
18 |
+
User: {input}
|
19 |
+
Assistant: """
|
20 |
},
|
21 |
"emotion_detection": {
|
22 |
+
"model_id": "mistralai/Mistral-7B-Instruct-v0.2",
|
23 |
+
"instruction_template": """Analyze the emotional content of the following text and identify the primary emotions present.
|
24 |
+
Focus on: joy, sadness, anger, fear, surprise, disgust, anxiety, and hope.
|
25 |
+
|
26 |
+
Text: {input}
|
27 |
+
Emotions: """
|
28 |
},
|
29 |
+
"assessment": {
|
30 |
+
"model_id": "mistralai/Mistral-7B-Instruct-v0.2",
|
31 |
+
"instruction_template": """Conduct a mental health assessment based on the user's input.
|
32 |
+
Consider: mood, anxiety levels, sleep patterns, social support, and risk factors.
|
33 |
+
Provide a structured assessment while maintaining a supportive tone.
|
34 |
+
|
35 |
+
User Input: {input}
|
36 |
+
Assessment: """
|
37 |
},
|
38 |
+
"crisis": {
|
39 |
+
"model_id": "mistralai/Mistral-7B-Instruct-v0.2",
|
40 |
+
"instruction_template": """You are a crisis intervention specialist. Assess the severity of the situation
|
41 |
+
and provide appropriate support and resources. Always prioritize user safety.
|
42 |
+
|
43 |
+
User: {input}
|
44 |
+
Response: """
|
45 |
+
},
|
46 |
+
"mindfulness": {
|
47 |
+
"model_id": "mistralai/Mistral-7B-Instruct-v0.2",
|
48 |
+
"instruction_template": """Guide the user through mindfulness exercises and meditation.
|
49 |
+
Provide clear, calming instructions while being attentive to their needs.
|
50 |
+
|
51 |
+
User: {input}
|
52 |
+
Guide: """
|
53 |
}
|
54 |
},
|
55 |
"INTERFACE_CONFIG": {
|
requirements.txt
CHANGED
@@ -20,4 +20,7 @@ psutil>=5.9.0
|
|
20 |
python-json-logger>=2.0.7
|
21 |
accelerate>=0.26.0
|
22 |
bitsandbytes>=0.41.1
|
23 |
-
safetensors>=0.4.0
|
|
|
|
|
|
|
|
20 |
python-json-logger>=2.0.7
|
21 |
accelerate>=0.26.0
|
22 |
bitsandbytes>=0.41.1
|
23 |
+
safetensors>=0.4.0
|
24 |
+
sentencepiece>=0.1.99
|
25 |
+
einops>=0.7.0
|
26 |
+
optimum>=1.16.1
|