Your Name commited on
Commit
d0098ba
Β·
1 Parent(s): 708dd4c

Remove Hugging Face sentiment pipeline and ensure Azure creds load

Browse files
Files changed (5) hide show
  1. agents/azure_agent.py +4 -0
  2. agents/sentiment_agent.py +17 -52
  3. app.py +13 -25
  4. models.yaml +4 -3
  5. requirements.txt +1 -0
agents/azure_agent.py CHANGED
@@ -2,6 +2,7 @@
2
  import os
3
  import sys
4
  import logging
 
5
 
6
  # Add parent directory to path for imports
7
  sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
@@ -22,6 +23,9 @@ class AzureTextAnalyticsAgent:
22
  from azure.ai.textanalytics import TextAnalyticsClient
23
  from azure.core.credentials import AzureKeyCredential
24
 
 
 
 
25
  key = os.getenv("AZURE_TEXT_ANALYTICS_KEY")
26
  endpoint = os.getenv("AZURE_TEXT_ANALYTICS_ENDPOINT")
27
 
 
2
  import os
3
  import sys
4
  import logging
5
+ from dotenv import load_dotenv
6
 
7
  # Add parent directory to path for imports
8
  sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
 
23
  from azure.ai.textanalytics import TextAnalyticsClient
24
  from azure.core.credentials import AzureKeyCredential
25
 
26
+ # Load environment variables so Azure credentials from .env are available
27
+ load_dotenv()
28
+
29
  key = os.getenv("AZURE_TEXT_ANALYTICS_KEY")
30
  endpoint = os.getenv("AZURE_TEXT_ANALYTICS_ENDPOINT")
31
 
agents/sentiment_agent.py CHANGED
@@ -1,4 +1,4 @@
1
- """Sentiment Agent - responsible for sentiment analysis (uses Azure, Hugging Face, or NLTK fallback)"""
2
  import os
3
  import sys
4
  import logging
@@ -8,22 +8,14 @@ sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
8
  from config import MODEL_CONFIG
9
  from agents.azure_agent import AzureTextAnalyticsAgent
10
 
11
- # Import transformers with error handling
12
- try:
13
- from transformers import pipeline
14
- transformers_available = True
15
- except ImportError:
16
- logging.warning("Transformers library not available. Using fallback sentiment analysis.")
17
- transformers_available = False
18
-
19
  class SentimentAgent:
20
- """Agent responsible for sentiment analysis (uses Azure, Hugging Face, or NLTK fallback)"""
21
 
22
  def __init__(self, config=None):
23
  self.config = config or MODEL_CONFIG or {}
24
  self.azure_agent = AzureTextAnalyticsAgent(config=self.config)
25
- self.sentiment_analyzer = None
26
  self.ready = False
 
27
  self._initialize()
28
 
29
  def _initialize(self):
@@ -33,56 +25,29 @@ class SentimentAgent:
33
  self.ready = True
34
  logging.info("[SentimentAgent] Using Azure Text Analytics")
35
  return
36
-
37
- # Fallback to Hugging Face
38
- sentiment_model = self.config.get('sentiment', {}).get('primary_model', 'distilbert/distilbert-base-uncased-finetuned-sst-2-english') if self.config else 'distilbert/distilbert-base-uncased-finetuned-sst-2-english'
39
-
40
- if transformers_available:
41
- try:
42
- logging.info("[SentimentAgent] Initializing Hugging Face sentiment analyzer...")
43
- self.sentiment_analyzer = pipeline("sentiment-analysis", model=sentiment_model)
44
- self.ready = True
45
- logging.info("[SentimentAgent] βœ“ Initialized successfully")
46
- except Exception as e:
47
- logging.warning(f"[SentimentAgent] Hugging Face model failed: {e}, using fallback")
48
- self.sentiment_analyzer = None
49
- self.ready = True # Fallback available
50
- else:
51
- self.ready = True # Fallback available
52
-
53
  def analyze(self, text):
54
- """Analyze sentiment of text (tries Azure, then Hugging Face, then NLTK)"""
55
  # Try Azure first
56
  if self.azure_agent.is_ready():
57
  result = self.azure_agent.analyze(text)
58
  if result is not None:
59
  return result
60
-
61
- # Fallback to Hugging Face
62
- if self.sentiment_analyzer:
63
- try:
64
- result = self.sentiment_analyzer(text)[0]
65
- label = result['label'].lower()
66
- score = result['score']
67
-
68
- if 'positive' in label:
69
- return score
70
- elif 'negative' in label:
71
- return -score
72
- else:
73
- return 0.0
74
- except Exception as e:
75
- logging.error(f"[SentimentAgent] Error: {e}")
76
- return self._fallback_analyze(text)
77
- else:
78
- return self._fallback_analyze(text)
79
-
80
  def _fallback_analyze(self, text):
81
  """Fallback sentiment analysis using NLTK VADER"""
82
  try:
83
- from nltk.sentiment import SentimentIntensityAnalyzer
84
- analyzer = SentimentIntensityAnalyzer()
85
- scores = analyzer.polarity_scores(text)
 
 
86
  return scores['compound'] # Returns value between -1 and 1
87
  except Exception as e:
88
  logging.error(f"[SentimentAgent] Fallback failed: {e}")
 
1
+ """Sentiment Agent - responsible for sentiment analysis (uses Azure with NLTK fallback)"""
2
  import os
3
  import sys
4
  import logging
 
8
  from config import MODEL_CONFIG
9
  from agents.azure_agent import AzureTextAnalyticsAgent
10
 
 
 
 
 
 
 
 
 
11
  class SentimentAgent:
12
+ """Agent responsible for sentiment analysis (uses Azure with NLTK fallback)"""
13
 
14
  def __init__(self, config=None):
15
  self.config = config or MODEL_CONFIG or {}
16
  self.azure_agent = AzureTextAnalyticsAgent(config=self.config)
 
17
  self.ready = False
18
+ self._fallback_analyzer = None
19
  self._initialize()
20
 
21
  def _initialize(self):
 
25
  self.ready = True
26
  logging.info("[SentimentAgent] Using Azure Text Analytics")
27
  return
28
+
29
+ # Azure not available – rely on fallback
30
+ logging.info("[SentimentAgent] Using NLTK VADER fallback for sentiment analysis")
31
+ self.ready = True # Fallback available
32
+
 
 
 
 
 
 
 
 
 
 
 
 
33
  def analyze(self, text):
34
+ """Analyze sentiment of text (tries Azure first, falls back to NLTK)"""
35
  # Try Azure first
36
  if self.azure_agent.is_ready():
37
  result = self.azure_agent.analyze(text)
38
  if result is not None:
39
  return result
40
+
41
+ return self._fallback_analyze(text)
42
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43
  def _fallback_analyze(self, text):
44
  """Fallback sentiment analysis using NLTK VADER"""
45
  try:
46
+ if self._fallback_analyzer is None:
47
+ from nltk.sentiment import SentimentIntensityAnalyzer
48
+ self._fallback_analyzer = SentimentIntensityAnalyzer()
49
+
50
+ scores = self._fallback_analyzer.polarity_scores(text)
51
  return scores['compound'] # Returns value between -1 and 1
52
  except Exception as e:
53
  logging.error(f"[SentimentAgent] Fallback failed: {e}")
app.py CHANGED
@@ -165,31 +165,19 @@ def initialize_sentiment_analyzer():
165
  try:
166
  logging.info("πŸ”„ [Sentiment Analyzer] Starting initialization...")
167
  print("πŸ”„ [Sentiment Analyzer] Starting initialization...")
168
- try:
169
- from transformers import pipeline
170
- analyzer = pipeline(
171
- "sentiment-analysis",
172
- model="distilbert/distilbert-base-uncased-finetuned-sst-2-english"
173
- )
174
- result = analyzer("test")
175
- logging.info("βœ“ [Sentiment Analyzer] Hugging Face model loaded")
176
- print("βœ“ [Sentiment Analyzer] Hugging Face model loaded")
177
- init_status['sentiment_analyzer']['ready'] = True
178
- return True
179
- except ImportError:
180
  logging.info("βœ“ [Sentiment Analyzer] Using fallback (NLTK VADER)")
181
  print("βœ“ [Sentiment Analyzer] Using fallback (NLTK VADER)")
182
- init_status['sentiment_analyzer']['ready'] = True
183
- return True
184
- except Exception as e:
185
- error_msg = str(e)
186
- if 'np.float_' in error_msg or 'NumPy 2' in error_msg or '_ARRAY_API' in error_msg:
187
- logging.warning(f"⚠ [Sentiment Analyzer] NumPy compatibility issue - using fallback")
188
- print("⚠ [Sentiment Analyzer] NumPy compatibility issue - using fallback")
189
- init_status['sentiment_analyzer']['ready'] = True
190
- return True
191
- else:
192
- raise
193
  except Exception as e:
194
  error_msg = f"Sentiment analyzer initialization failed: {e}"
195
  logging.warning(f"⚠ [Sentiment Analyzer] {error_msg} - using fallback")
@@ -506,9 +494,9 @@ def initialize_components():
506
  # CRITICAL: Only mark as initialized if ALL components are ready
507
  # If any component fails, EXIT the application immediately
508
  if init_status['fully_initialized']:
509
- is_initialized = True
510
  logging.info("βœ“ Galatea AI system fully initialized and ready")
511
- logging.info(f"Emotions initialized: {galatea_ai.emotional_state}")
512
  else:
513
  logging.error("=" * 60)
514
  logging.error("❌ INITIALIZATION FAILED - EXITING APPLICATION")
 
165
  try:
166
  logging.info("πŸ”„ [Sentiment Analyzer] Starting initialization...")
167
  print("πŸ”„ [Sentiment Analyzer] Starting initialization...")
168
+ from agents.sentiment_agent import SentimentAgent
169
+
170
+ agent = SentimentAgent()
171
+
172
+ if agent.azure_agent.is_ready():
173
+ logging.info("βœ“ [Sentiment Analyzer] Azure Text Analytics ready")
174
+ print("βœ“ [Sentiment Analyzer] Azure Text Analytics ready")
175
+ else:
 
 
 
 
176
  logging.info("βœ“ [Sentiment Analyzer] Using fallback (NLTK VADER)")
177
  print("βœ“ [Sentiment Analyzer] Using fallback (NLTK VADER)")
178
+
179
+ init_status['sentiment_analyzer']['ready'] = True
180
+ return True
 
 
 
 
 
 
 
 
181
  except Exception as e:
182
  error_msg = f"Sentiment analyzer initialization failed: {e}"
183
  logging.warning(f"⚠ [Sentiment Analyzer] {error_msg} - using fallback")
 
494
  # CRITICAL: Only mark as initialized if ALL components are ready
495
  # If any component fails, EXIT the application immediately
496
  if init_status['fully_initialized']:
497
+ is_initialized = True
498
  logging.info("βœ“ Galatea AI system fully initialized and ready")
499
+ logging.info(f"Emotions initialized: {galatea_ai.emotional_state}")
500
  else:
501
  logging.error("=" * 60)
502
  logging.error("❌ INITIALIZATION FAILED - EXITING APPLICATION")
models.yaml CHANGED
@@ -28,9 +28,10 @@ inflection_ai:
28
 
29
  # Sentiment Analysis Configuration
30
  sentiment:
31
- # Primary model (Hugging Face)
32
- primary_model: "distilbert/distilbert-base-uncased-finetuned-sst-2-english"
33
- # Fallback: NLTK VADER (automatic if primary fails)
 
34
 
35
  # Memory System Configuration (JSON only)
36
  memory:
 
28
 
29
  # Sentiment Analysis Configuration
30
  sentiment:
31
+ # Uses Azure Text Analytics when credentials are provided
32
+ preferred: "azure_text_analytics"
33
+ # Automatically falls back to NLTK VADER if Azure is unavailable
34
+ fallback: "nltk_vader"
35
 
36
  # Memory System Configuration (JSON only)
37
  memory:
requirements.txt CHANGED
@@ -4,3 +4,4 @@ python-dotenv==1.0.0
4
  requests==2.31.0
5
  pyyaml==6.0.1
6
  openai>=1.0.0
 
 
4
  requests==2.31.0
5
  pyyaml==6.0.1
6
  openai>=1.0.0
7
+ azure-ai-textanalytics==5.3.0