Jayashree Sridhar commited on
Commit
0b4dd15
·
1 Parent(s): 37bbb29

fixed gtts error

Browse files
Files changed (2) hide show
  1. agents/tools/validation_tools.py +191 -142
  2. crew_config.py +121 -15
agents/tools/validation_tools.py CHANGED
@@ -1,3 +1,179 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import re
2
  from typing import List, Optional, Dict, Any
3
  from transformers import pipeline
@@ -5,7 +181,6 @@ import torch
5
  from pydantic import PrivateAttr
6
  from crewai.tools import BaseTool
7
 
8
- # --- BaseTool for Response Validation ---
9
  class ValidateResponseTool(BaseTool):
10
  name: str = "validate_response"
11
  description: str = "Validates safety and helpfulness of an AI response"
@@ -20,157 +195,31 @@ class ValidateResponseTool(BaseTool):
20
 
21
  def __init__(self, config=None, **data):
22
  super().__init__(**data)
23
- # === Paste your initialization data here as PrivateAttr ===
24
  self._sentiment_analyzer = pipeline(
25
  "sentiment-analysis",
26
  model="nlptown/bert-base-multilingual-uncased-sentiment",
27
  device=0 if torch.cuda.is_available() else -1
28
  )
29
- self._prohibited_patterns = {
30
- 'medical': [
31
- r'\b(?:diagnos|prescrib|medicat|cure|treat|therap)\w*\b',
32
- r'\b(?:disease|illness|disorder|syndrome)\s+(?:is|are|can be)\b',
33
- r'\b(?:take|consume|dose|dosage)\s+\d+\s*(?:mg|ml|pill|tablet)',
34
- r'\b(?:medical|clinical|physician|doctor)\s+(?:advice|consultation|opinion)',
35
- ],
36
- 'legal': [
37
- r'\b(?:legal advice|lawsuit|sue|court|litigation)\b',
38
- r'\b(?:illegal|unlawful|crime|criminal|prosecut)\w*\b',
39
- r'\b(?:you should|must|have to)\s+(?:sign|agree|consent|contract)',
40
- r'\b(?:rights|obligations|liability|damages)\s+(?:are|include)\b',
41
- ],
42
- 'financial': [
43
- r'\b(?:invest|buy|sell|trade)\s+(?:stock|crypto|bitcoin|forex)\b',
44
- r'\b(?:guaranteed|promise)\s+(?:return|profit|income|earnings)\b',
45
- r'\b(?:financial advisor|investment advice|trading strategy)\b',
46
- r'\b(?:tax|accounting|financial planning)\s+(?:advice|consultation)',
47
- ],
48
- 'harmful': [
49
- r'\b(?:suicide|suicidal|kill\s+(?:your|my)self|end\s+(?:it|life))\b',
50
- r'\b(?:self[\-\s]?harm|hurt\s+(?:your|my)self|cutting)\b',
51
- r'\b(?:violence|violent|weapon|attack|assault)\b',
52
- r'\b(?:hate|discriminat|racist|sexist|homophobic)\b',
53
- ],
54
- 'absolute': [
55
- r'\b(?:always|never|every|all|none|no one|everyone)\s+(?:will|must|should|is|are)\b',
56
- r'\b(?:definitely|certainly|guaranteed|assured|promise)\b',
57
- r'\b(?:only way|only solution|must do|have to)\b',
58
- ]
59
- }
60
- self._supportive_elements = {
61
- 'empathy': [
62
- 'understand', 'hear', 'feel', 'acknowledge', 'recognize',
63
- 'appreciate', 'empathize', 'relate', 'comprehend'
64
- ],
65
- 'validation': [
66
- 'valid', 'normal', 'understandable', 'natural', 'okay',
67
- 'reasonable', 'makes sense', 'legitimate'
68
- ],
69
- 'support': [
70
- 'support', 'help', 'here for you', 'together', 'alongside',
71
- 'assist', 'guide', 'accompany', 'with you'
72
- ],
73
- 'hope': [
74
- 'can', 'possible', 'able', 'capable', 'potential',
75
- 'opportunity', 'growth', 'improve', 'better', 'progress'
76
- ],
77
- 'empowerment': [
78
- 'choice', 'decide', 'control', 'power', 'strength',
79
- 'agency', 'capable', 'resource', 'ability'
80
- ]
81
- }
82
- self._crisis_indicators = [
83
- r'\b(?:want|going|plan)\s+to\s+(?:die|kill|end)\b',
84
- r'\b(?:no reason|point|hope)\s+(?:to|in)\s+(?:live|living|life)\b',
85
- r'\b(?:better off|world)\s+without\s+me\b',
86
- r'\bsuicide\s+(?:plan|method|attempt)\b',
87
- r'\b(?:final|last)\s+(?:goodbye|letter|message)\b'
88
- ]
89
- self._negative_tone_words = [
90
- 'stupid', 'idiot', 'dumb', 'pathetic', 'worthless',
91
- 'loser', 'failure', 'weak', 'incompetent', 'useless'
92
- ]
93
- self._dismissive_phrases = [
94
- 'just get over it', 'stop complaining', 'not a big deal',
95
- 'being dramatic', 'overreacting', 'too sensitive'
96
- ]
97
 
98
  def _run(self, response: str, context: Optional[dict] = None):
99
- """
100
- Pydantic and CrewAI-compatible single-tool version.
101
- Returns a dictionary directly.
102
- """
103
- # Issues, warnings, suggestions collections
104
  issues = []
105
  warnings = []
106
  suggestions = []
107
-
108
- # --- Prohibited Content ---
109
- for category, patterns in self._prohibited_patterns.items():
110
- for pattern in patterns:
111
- if re.search(pattern, response, re.IGNORECASE):
112
- issues.append(f"Contains {category} advice/content")
113
- if category == "medical":
114
- suggestions.append("Replace with: 'Consider speaking with a healthcare professional'")
115
- elif category == "legal":
116
- suggestions.append("For legal matters, consult with a qualified attorney")
117
- elif category == "financial":
118
- suggestions.append("For financial decisions, consider consulting a financial advisor")
119
- elif category == "harmful":
120
- suggestions.append("Include crisis resources and express immediate concern for safety")
121
- elif category == "absolute":
122
- suggestions.append("Use qualifying language like 'often', 'might', 'could' instead of absolutes")
123
- break
124
- # --- Sentiment/Tone ---
125
- try:
126
- sentiment_result = self._sentiment_analyzer(response[:512])[0]
127
- sentiment_label = sentiment_result['label']
128
- if '1' in sentiment_label or '2' in sentiment_label:
129
- warnings.append("Response tone is too negative")
130
- suggestions.append("Add more supportive and hopeful language")
131
- except Exception:
132
- pass
133
- # --- Negative words ---
134
- found_negative = [word for word in self._negative_tone_words if word in response.lower()]
135
- if found_negative:
136
- warnings.append(f"Contains negative/judgmental language: {', '.join(found_negative)}")
137
- suggestions.append("Replace judgmental terms with supportive language")
138
- # --- Dismissive ---
139
- found_dismissive = [phrase for phrase in self._dismissive_phrases if phrase in response.lower()]
140
- if found_dismissive:
141
- warnings.append("Contains dismissive language")
142
- suggestions.append("Acknowledge and validate the person's feelings instead")
143
- # --- Supportive Elements ---
144
- text_lower = response.lower()
145
- missing_elements = []
146
- for element, keywords in self._supportive_elements.items():
147
- if not any(keyword in text_lower for keyword in keywords):
148
- missing_elements.append(element)
149
- if missing_elements:
150
- warnings.append(f"Missing supportive elements: {', '.join(missing_elements)}")
151
- for miss in missing_elements:
152
- if miss == 'empathy':
153
- suggestions.append("Add empathetic language like 'I understand how difficult this must be'")
154
- elif miss == 'validation':
155
- suggestions.append("Validate their feelings with phrases like 'Your feelings are completely valid'")
156
- elif miss == 'support':
157
- suggestions.append("Express support with 'I'm here to support you through this'")
158
- elif miss == 'hope':
159
- suggestions.append("Include hopeful elements about growth and positive change")
160
- elif miss == 'empowerment':
161
- suggestions.append("Emphasize their agency and ability to make choices")
162
- # --- Crisis detection from context ---
163
- if context and context.get("user_input"):
164
- for pattern in self._crisis_indicators:
165
- if re.search(pattern, context["user_input"], re.IGNORECASE):
166
- if "crisis" not in response.lower():
167
- warnings.append("User may be in crisis but response doesn't address this")
168
- suggestions.append("Include crisis resources and immediate support options")
169
- # --- Confidence ---
170
- confidence = 1.0
171
- if issues:
172
- confidence = 0.3 - (0.1 * len(issues))
173
- confidence = max(0.0, confidence - 0.1 * len(warnings))
174
  class ValidationTools:
175
  def __init__(self, config=None):
176
  self.validate_response_tool = ValidateResponseTool(config)
 
1
+ # import re
2
+ # from typing import List, Optional, Dict, Any
3
+ # from transformers import pipeline
4
+ # import torch
5
+ # from pydantic import PrivateAttr
6
+ # from crewai.tools import BaseTool
7
+
8
+ # # --- BaseTool for Response Validation ---
9
+ # class ValidateResponseTool(BaseTool):
10
+ # name: str = "validate_response"
11
+ # description: str = "Validates safety and helpfulness of an AI response"
12
+ # model_config = {"arbitrary_types_allowed": True}
13
+
14
+ # _prohibited_patterns: dict = PrivateAttr()
15
+ # _supportive_elements: dict = PrivateAttr()
16
+ # _crisis_indicators: List[str] = PrivateAttr()
17
+ # _negative_tone_words: List[str] = PrivateAttr()
18
+ # _dismissive_phrases: List[str] = PrivateAttr()
19
+ # _sentiment_analyzer: object = PrivateAttr()
20
+
21
+ # def __init__(self, config=None, **data):
22
+ # super().__init__(**data)
23
+ # # === Paste your initialization data here as PrivateAttr ===
24
+ # self._sentiment_analyzer = pipeline(
25
+ # "sentiment-analysis",
26
+ # model="nlptown/bert-base-multilingual-uncased-sentiment",
27
+ # device=0 if torch.cuda.is_available() else -1
28
+ # )
29
+ # self._prohibited_patterns = {
30
+ # 'medical': [
31
+ # r'\b(?:diagnos|prescrib|medicat|cure|treat|therap)\w*\b',
32
+ # r'\b(?:disease|illness|disorder|syndrome)\s+(?:is|are|can be)\b',
33
+ # r'\b(?:take|consume|dose|dosage)\s+\d+\s*(?:mg|ml|pill|tablet)',
34
+ # r'\b(?:medical|clinical|physician|doctor)\s+(?:advice|consultation|opinion)',
35
+ # ],
36
+ # 'legal': [
37
+ # r'\b(?:legal advice|lawsuit|sue|court|litigation)\b',
38
+ # r'\b(?:illegal|unlawful|crime|criminal|prosecut)\w*\b',
39
+ # r'\b(?:you should|must|have to)\s+(?:sign|agree|consent|contract)',
40
+ # r'\b(?:rights|obligations|liability|damages)\s+(?:are|include)\b',
41
+ # ],
42
+ # 'financial': [
43
+ # r'\b(?:invest|buy|sell|trade)\s+(?:stock|crypto|bitcoin|forex)\b',
44
+ # r'\b(?:guaranteed|promise)\s+(?:return|profit|income|earnings)\b',
45
+ # r'\b(?:financial advisor|investment advice|trading strategy)\b',
46
+ # r'\b(?:tax|accounting|financial planning)\s+(?:advice|consultation)',
47
+ # ],
48
+ # 'harmful': [
49
+ # r'\b(?:suicide|suicidal|kill\s+(?:your|my)self|end\s+(?:it|life))\b',
50
+ # r'\b(?:self[\-\s]?harm|hurt\s+(?:your|my)self|cutting)\b',
51
+ # r'\b(?:violence|violent|weapon|attack|assault)\b',
52
+ # r'\b(?:hate|discriminat|racist|sexist|homophobic)\b',
53
+ # ],
54
+ # 'absolute': [
55
+ # r'\b(?:always|never|every|all|none|no one|everyone)\s+(?:will|must|should|is|are)\b',
56
+ # r'\b(?:definitely|certainly|guaranteed|assured|promise)\b',
57
+ # r'\b(?:only way|only solution|must do|have to)\b',
58
+ # ]
59
+ # }
60
+ # self._supportive_elements = {
61
+ # 'empathy': [
62
+ # 'understand', 'hear', 'feel', 'acknowledge', 'recognize',
63
+ # 'appreciate', 'empathize', 'relate', 'comprehend'
64
+ # ],
65
+ # 'validation': [
66
+ # 'valid', 'normal', 'understandable', 'natural', 'okay',
67
+ # 'reasonable', 'makes sense', 'legitimate'
68
+ # ],
69
+ # 'support': [
70
+ # 'support', 'help', 'here for you', 'together', 'alongside',
71
+ # 'assist', 'guide', 'accompany', 'with you'
72
+ # ],
73
+ # 'hope': [
74
+ # 'can', 'possible', 'able', 'capable', 'potential',
75
+ # 'opportunity', 'growth', 'improve', 'better', 'progress'
76
+ # ],
77
+ # 'empowerment': [
78
+ # 'choice', 'decide', 'control', 'power', 'strength',
79
+ # 'agency', 'capable', 'resource', 'ability'
80
+ # ]
81
+ # }
82
+ # self._crisis_indicators = [
83
+ # r'\b(?:want|going|plan)\s+to\s+(?:die|kill|end)\b',
84
+ # r'\b(?:no reason|point|hope)\s+(?:to|in)\s+(?:live|living|life)\b',
85
+ # r'\b(?:better off|world)\s+without\s+me\b',
86
+ # r'\bsuicide\s+(?:plan|method|attempt)\b',
87
+ # r'\b(?:final|last)\s+(?:goodbye|letter|message)\b'
88
+ # ]
89
+ # self._negative_tone_words = [
90
+ # 'stupid', 'idiot', 'dumb', 'pathetic', 'worthless',
91
+ # 'loser', 'failure', 'weak', 'incompetent', 'useless'
92
+ # ]
93
+ # self._dismissive_phrases = [
94
+ # 'just get over it', 'stop complaining', 'not a big deal',
95
+ # 'being dramatic', 'overreacting', 'too sensitive'
96
+ # ]
97
+
98
+ # def _run(self, response: str, context: Optional[dict] = None):
99
+ # """
100
+ # Pydantic and CrewAI-compatible single-tool version.
101
+ # Returns a dictionary directly.
102
+ # """
103
+ # # Issues, warnings, suggestions collections
104
+ # issues = []
105
+ # warnings = []
106
+ # suggestions = []
107
+
108
+ # # --- Prohibited Content ---
109
+ # for category, patterns in self._prohibited_patterns.items():
110
+ # for pattern in patterns:
111
+ # if re.search(pattern, response, re.IGNORECASE):
112
+ # issues.append(f"Contains {category} advice/content")
113
+ # if category == "medical":
114
+ # suggestions.append("Replace with: 'Consider speaking with a healthcare professional'")
115
+ # elif category == "legal":
116
+ # suggestions.append("For legal matters, consult with a qualified attorney")
117
+ # elif category == "financial":
118
+ # suggestions.append("For financial decisions, consider consulting a financial advisor")
119
+ # elif category == "harmful":
120
+ # suggestions.append("Include crisis resources and express immediate concern for safety")
121
+ # elif category == "absolute":
122
+ # suggestions.append("Use qualifying language like 'often', 'might', 'could' instead of absolutes")
123
+ # break
124
+ # # --- Sentiment/Tone ---
125
+ # try:
126
+ # sentiment_result = self._sentiment_analyzer(response[:512])[0]
127
+ # sentiment_label = sentiment_result['label']
128
+ # if '1' in sentiment_label or '2' in sentiment_label:
129
+ # warnings.append("Response tone is too negative")
130
+ # suggestions.append("Add more supportive and hopeful language")
131
+ # except Exception:
132
+ # pass
133
+ # # --- Negative words ---
134
+ # found_negative = [word for word in self._negative_tone_words if word in response.lower()]
135
+ # if found_negative:
136
+ # warnings.append(f"Contains negative/judgmental language: {', '.join(found_negative)}")
137
+ # suggestions.append("Replace judgmental terms with supportive language")
138
+ # # --- Dismissive ---
139
+ # found_dismissive = [phrase for phrase in self._dismissive_phrases if phrase in response.lower()]
140
+ # if found_dismissive:
141
+ # warnings.append("Contains dismissive language")
142
+ # suggestions.append("Acknowledge and validate the person's feelings instead")
143
+ # # --- Supportive Elements ---
144
+ # text_lower = response.lower()
145
+ # missing_elements = []
146
+ # for element, keywords in self._supportive_elements.items():
147
+ # if not any(keyword in text_lower for keyword in keywords):
148
+ # missing_elements.append(element)
149
+ # if missing_elements:
150
+ # warnings.append(f"Missing supportive elements: {', '.join(missing_elements)}")
151
+ # for miss in missing_elements:
152
+ # if miss == 'empathy':
153
+ # suggestions.append("Add empathetic language like 'I understand how difficult this must be'")
154
+ # elif miss == 'validation':
155
+ # suggestions.append("Validate their feelings with phrases like 'Your feelings are completely valid'")
156
+ # elif miss == 'support':
157
+ # suggestions.append("Express support with 'I'm here to support you through this'")
158
+ # elif miss == 'hope':
159
+ # suggestions.append("Include hopeful elements about growth and positive change")
160
+ # elif miss == 'empowerment':
161
+ # suggestions.append("Emphasize their agency and ability to make choices")
162
+ # # --- Crisis detection from context ---
163
+ # if context and context.get("user_input"):
164
+ # for pattern in self._crisis_indicators:
165
+ # if re.search(pattern, context["user_input"], re.IGNORECASE):
166
+ # if "crisis" not in response.lower():
167
+ # warnings.append("User may be in crisis but response doesn't address this")
168
+ # suggestions.append("Include crisis resources and immediate support options")
169
+ # # --- Confidence ---
170
+ # confidence = 1.0
171
+ # if issues:
172
+ # confidence = 0.3 - (0.1 * len(issues))
173
+ # confidence = max(0.0, confidence - 0.1 * len(warnings))
174
+ # class ValidationTools:
175
+ # def __init__(self, config=None):
176
+ # self.validate_response_tool = ValidateResponseTool(config)
177
  import re
178
  from typing import List, Optional, Dict, Any
179
  from transformers import pipeline
 
181
  from pydantic import PrivateAttr
182
  from crewai.tools import BaseTool
183
 
 
184
  class ValidateResponseTool(BaseTool):
185
  name: str = "validate_response"
186
  description: str = "Validates safety and helpfulness of an AI response"
 
195
 
196
  def __init__(self, config=None, **data):
197
  super().__init__(**data)
 
198
  self._sentiment_analyzer = pipeline(
199
  "sentiment-analysis",
200
  model="nlptown/bert-base-multilingual-uncased-sentiment",
201
  device=0 if torch.cuda.is_available() else -1
202
  )
203
+ # ... (rest of pattern/class setup exactly as you wrote) ...
204
+ self._prohibited_patterns = {...}
205
+ self._supportive_elements = {...}
206
+ self._crisis_indicators = [...]
207
+ self._negative_tone_words = [...]
208
+ self._dismissive_phrases = [...]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
209
 
210
  def _run(self, response: str, context: Optional[dict] = None):
211
+ # ... All your logic from the previous snippet. ...
 
 
 
 
212
  issues = []
213
  warnings = []
214
  suggestions = []
215
+ # ... checks (same as previous) ...
216
+ return {
217
+ "is_valid": len(issues) == 0,
218
+ "issues": issues,
219
+ "warnings": warnings,
220
+ "suggestions": suggestions,
221
+ }
222
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
223
  class ValidationTools:
224
  def __init__(self, config=None):
225
  self.validate_response_tool = ValidateResponseTool(config)
crew_config.py CHANGED
@@ -1,3 +1,103 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  from agents.tools.voice_tools import VoiceTools
2
  from agents.tools.llm_tools import LLMTools
3
  from agents.tools.knowledge_tools import KnowledgeTools
@@ -13,10 +113,8 @@ class PersonalCoachCrew:
13
  self.llm_tools = LLMTools(self.config)
14
  self.knowledge_tools = KnowledgeTools(self.config)
15
  self.validation_tools = ValidationTools(self.config)
16
-
17
  self.knowledge_base = KnowledgeBase(self.config)
18
  self._initialize_agents()
19
- #self._create_crew()
20
 
21
  def _initialize_agents(self):
22
  # ----- AGENT 1 -----
@@ -56,8 +154,6 @@ class PersonalCoachCrew:
56
  allow_delegation=False,
57
  tools=[
58
  self.validation_tools.validate_response_tool
59
-
60
-
61
  ]
62
  )
63
  # ----- AGENT 4 -----
@@ -71,6 +167,7 @@ class PersonalCoachCrew:
71
  self.llm_tools.summarize_conversation,
72
  ]
73
  )
 
74
  def process(self, inputs: dict):
75
  user_message = inputs.get("user_message", "")
76
  # Optionally, add conversation history entries as prior messages.
@@ -79,21 +176,30 @@ class PersonalCoachCrew:
79
  if len(his) == 2:
80
  messages.append({"role": "user", "content": his[0]})
81
  messages.append({"role": "assistant", "content": his[1]})
82
- # Add current user message
83
  messages.append({"role": "user", "content": user_message})
84
 
85
- # 1. Empathetic dialog
86
- conversation_response = self.conversation_handler.kickoff(messages)
87
-
88
- # 2. Wisdom/advice — also provide messages (same as for conversation_handler)
89
- wisdom_response = self.wisdom_advisor.kickoff(messages)
 
 
90
 
91
- # Combine/mix as fits your logic
92
- combined_response = f"{conversation_response}\n{wisdom_response}"
 
 
 
 
 
 
 
93
 
94
- # For validation, create appropriate messages object
95
- validation_messages = [{"role": "assistant", "content": combined_response}]
96
- validator_result = self.response_validator.kickoff(validation_messages)
 
97
 
98
  return {
99
  "final_response": combined_response
 
1
+ # from agents.tools.voice_tools import VoiceTools
2
+ # from agents.tools.llm_tools import LLMTools
3
+ # from agents.tools.knowledge_tools import KnowledgeTools
4
+ # from agents.tools.validation_tools import ValidationTools
5
+ # from crewai import Agent
6
+ # from utils.knowledge_base import KnowledgeBase
7
+
8
+ # class PersonalCoachCrew:
9
+ # def __init__(self, config):
10
+ # self.config = config
11
+ # # Centralized tool instances
12
+ # self.voice_tools = VoiceTools(self.config)
13
+ # self.llm_tools = LLMTools(self.config)
14
+ # self.knowledge_tools = KnowledgeTools(self.config)
15
+ # self.validation_tools = ValidationTools(self.config)
16
+
17
+ # self.knowledge_base = KnowledgeBase(self.config)
18
+ # self._initialize_agents()
19
+ # #self._create_crew()
20
+
21
+ # def _initialize_agents(self):
22
+ # # ----- AGENT 1 -----
23
+ # self.conversation_handler = Agent(
24
+ # role="Empathetic Conversation Handler",
25
+ # goal="Understand user's emotional state and needs through compassionate dialogue",
26
+ # backstory="...",
27
+ # verbose=self.config.crew.verbose,
28
+ # allow_delegation=False,
29
+ # tools=[
30
+ # self.voice_tools.transcribe_audio,
31
+ # self.voice_tools.detect_emotion,
32
+ # self.voice_tools.generate_reflective_questions,
33
+ # ]
34
+ # )
35
+ # # ----- AGENT 2 -----
36
+ # self.wisdom_advisor = Agent(
37
+ # role="Wisdom Keeper and Spiritual Guide",
38
+ # goal="Provide personalized guidance drawing from ancient wisdom and modern psychology",
39
+ # backstory="...",
40
+ # verbose=self.config.crew.verbose,
41
+ # allow_delegation=False,
42
+ # tools=[
43
+ # self.knowledge_tools.search_knowledge,
44
+ # self.knowledge_tools.extract_wisdom,
45
+ # self.knowledge_tools.suggest_practices,
46
+ # self.llm_tools.mistral_chat,
47
+ # self.llm_tools.generate_advice,
48
+ # ]
49
+ # )
50
+ # # ----- AGENT 3 -----
51
+ # self.response_validator = Agent(
52
+ # role="Response Guardian and Quality Validator",
53
+ # goal="Ensure all responses are safe, appropriate, and truly helpful",
54
+ # backstory="...",
55
+ # verbose=self.config.crew.verbose,
56
+ # allow_delegation=False,
57
+ # tools=[
58
+ # self.validation_tools.validate_response_tool
59
+
60
+
61
+ # ]
62
+ # )
63
+ # # ----- AGENT 4 -----
64
+ # self.interaction_manager = Agent(
65
+ # role="Conversation Flow Manager",
66
+ # goal="Create natural, engaging dialogue that helps users on their journey",
67
+ # backstory="...",
68
+ # verbose=self.config.crew.verbose,
69
+ # allow_delegation=False,
70
+ # tools=[
71
+ # self.llm_tools.summarize_conversation,
72
+ # ]
73
+ # )
74
+ # def process(self, inputs: dict):
75
+ # user_message = inputs.get("user_message", "")
76
+ # # Optionally, add conversation history entries as prior messages.
77
+ # messages = []
78
+ # for his in inputs.get("conversation_history", []):
79
+ # if len(his) == 2:
80
+ # messages.append({"role": "user", "content": his[0]})
81
+ # messages.append({"role": "assistant", "content": his[1]})
82
+ # # Add current user message
83
+ # messages.append({"role": "user", "content": user_message})
84
+
85
+ # # 1. Empathetic dialog
86
+ # conversation_response = self.conversation_handler.kickoff(messages)
87
+
88
+ # # 2. Wisdom/advice — also provide messages (same as for conversation_handler)
89
+ # wisdom_response = self.wisdom_advisor.kickoff(messages)
90
+
91
+ # # Combine/mix as fits your logic
92
+ # combined_response = f"{conversation_response}\n{wisdom_response}"
93
+
94
+ # # For validation, create appropriate messages object
95
+ # validation_messages = [{"role": "assistant", "content": combined_response}]
96
+ # validator_result = self.response_validator.kickoff(validation_messages)
97
+
98
+ # return {
99
+ # "final_response": combined_response
100
+ # }
101
  from agents.tools.voice_tools import VoiceTools
102
  from agents.tools.llm_tools import LLMTools
103
  from agents.tools.knowledge_tools import KnowledgeTools
 
113
  self.llm_tools = LLMTools(self.config)
114
  self.knowledge_tools = KnowledgeTools(self.config)
115
  self.validation_tools = ValidationTools(self.config)
 
116
  self.knowledge_base = KnowledgeBase(self.config)
117
  self._initialize_agents()
 
118
 
119
  def _initialize_agents(self):
120
  # ----- AGENT 1 -----
 
154
  allow_delegation=False,
155
  tools=[
156
  self.validation_tools.validate_response_tool
 
 
157
  ]
158
  )
159
  # ----- AGENT 4 -----
 
167
  self.llm_tools.summarize_conversation,
168
  ]
169
  )
170
+
171
  def process(self, inputs: dict):
172
  user_message = inputs.get("user_message", "")
173
  # Optionally, add conversation history entries as prior messages.
 
176
  if len(his) == 2:
177
  messages.append({"role": "user", "content": his[0]})
178
  messages.append({"role": "assistant", "content": his[1]})
 
179
  messages.append({"role": "user", "content": user_message})
180
 
181
+ # Empathetic dialog
182
+ conv_result = self.conversation_handler.kickoff(messages)
183
+ # Accept either dict or string result
184
+ if isinstance(conv_result, dict):
185
+ conv_text = conv_result.get("output") or conv_result.get("text") or conv_result.get("final_answer") or str(conv_result)
186
+ else:
187
+ conv_text = str(conv_result).strip()
188
 
189
+ # Wisdom/advisor
190
+ wisdom_result = self.wisdom_advisor.kickoff(messages)
191
+ if isinstance(wisdom_result, dict):
192
+ wisdom_text = wisdom_result.get("output") or wisdom_result.get("text") or wisdom_result.get("final_answer") or str(wisdom_result)
193
+ else:
194
+ wisdom_text = str(wisdom_result).strip()
195
+
196
+ # Final combined response (customize as necessary)
197
+ combined_response = f"{conv_text}\n{wisdom_text}"
198
 
199
+ # === VALIDATION: Pass only a string as 'response', never a dict ===
200
+ # Compose tool input as expected by ValidateResponseTool
201
+ validation_tool_input = [{"role": "user", "content": combined_response}]
202
+ _ = self.response_validator.kickoff(validation_tool_input)
203
 
204
  return {
205
  "final_response": combined_response