ciaochris commited on
Commit
c0559f8
·
verified ·
1 Parent(s): a1f72bb

Update rhythma.py

Browse files
Files changed (1) hide show
  1. rhythma.py +138 -49
rhythma.py CHANGED
@@ -6,6 +6,22 @@ from PIL import Image
6
  import io
7
  from sklearn.metrics.pairwise import cosine_similarity
8
  import soundfile as sf
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
 
10
  class RhythmaModulationEngine:
11
  """
@@ -334,7 +350,7 @@ class RhythmaSymphAICore:
334
  SymphAI Core - The intelligent symbolic engine that interprets rhythm and state
335
  """
336
 
337
- def __init__(self, rhythm_analyzer=None, pattern_matcher=None):
338
  """Initialize the SymphAI Core"""
339
  # Default emotional states that can be detected
340
  self.emotional_states = [
@@ -347,46 +363,101 @@ class RhythmaSymphAICore:
347
  "calm", "active", "focused", "relaxed"
348
  ]
349
 
350
- # Create embeddings for rhythm states if using semantic matching
351
- try:
352
- from sentence_transformers import SentenceTransformer
353
- self.embedding_model = SentenceTransformer('all-MiniLM-L6-v2')
354
- self.emotional_embeddings = {
355
- emotion: self.embedding_model.encode([emotion])
356
- for emotion in self.emotional_states
357
- }
358
- self.rhythm_embeddings = {
359
- pattern: self.embedding_model.encode([pattern])
360
- for pattern in self.rhythm_patterns
361
- }
362
- except ImportError:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
363
  self.embedding_model = None
364
  self.emotional_embeddings = {}
365
  self.rhythm_embeddings = {}
366
- print("SentenceTransformer not installed. Semantic matching disabled.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
367
 
368
  def get_closest_emotional_state(self, input_text):
369
  """Map input text to the closest emotional state"""
370
- if not self.embedding_model:
371
- # Fallback to simple word matching if no embedding model
372
- for emotion in self.emotional_states:
373
- if emotion in input_text.lower():
374
- return emotion
375
- return "calm" # Default
 
 
 
 
 
 
 
376
 
377
- # Use semantic similarity to find the closest emotion
378
- input_embedding = self.embedding_model.encode([input_text])
379
- similarities = {
380
- emotion: cosine_similarity(input_embedding, embedding)[0][0]
381
- for emotion, embedding in self.emotional_embeddings.items()
382
- }
383
- return max(similarities, key=similarities.get)
384
 
385
- def get_closest_rhythm_pattern(self, input_text):
386
- """Map input text to the closest rhythm pattern"""
387
- if not self.embedding_model:
388
- # Fallback to simple mapping based on emotional state
389
- emotional_state = self.get_closest_emotional_state(input_text)
390
  # Map emotional states to rhythm patterns
391
  mapping = {
392
  "anxious": "active",
@@ -400,20 +471,38 @@ class RhythmaSymphAICore:
400
  }
401
  return mapping.get(emotional_state, "calm")
402
 
403
- # Use semantic similarity to find the closest rhythm pattern
404
- input_embedding = self.embedding_model.encode([input_text])
405
- similarities = {
406
- pattern: cosine_similarity(input_embedding, embedding)[0][0]
407
- for pattern, embedding in self.rhythm_embeddings.items()
408
- }
409
- return max(similarities, key=similarities.get)
410
-
411
- def analyze_input(self, input_text):
412
- """Analyze input text and return appropriate emotional state and rhythm pattern"""
413
- emotional_state = self.get_closest_emotional_state(input_text)
414
- rhythm_pattern = self.get_closest_rhythm_pattern(input_text)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
415
 
416
- return {
417
- "emotional_state": emotional_state,
418
- "rhythm_pattern": rhythm_pattern
419
- }
 
6
  import io
7
  from sklearn.metrics.pairwise import cosine_similarity
8
  import soundfile as sf
9
+ import os
10
+
11
+ # Try to import optional dependencies
12
+ try:
13
+ from groq import Groq
14
+ GROQ_AVAILABLE = True
15
+ except ImportError:
16
+ GROQ_AVAILABLE = False
17
+ print("Groq package not installed. Falling back to local analysis.")
18
+
19
+ try:
20
+ from sentence_transformers import SentenceTransformer
21
+ SENTENCE_TRANSFORMER_AVAILABLE = True
22
+ except ImportError:
23
+ SENTENCE_TRANSFORMER_AVAILABLE = False
24
+ print("SentenceTransformer not installed. Simple text matching will be used.")
25
 
26
  class RhythmaModulationEngine:
27
  """
 
350
  SymphAI Core - The intelligent symbolic engine that interprets rhythm and state
351
  """
352
 
353
+ def __init__(self, use_groq=True):
354
  """Initialize the SymphAI Core"""
355
  # Default emotional states that can be detected
356
  self.emotional_states = [
 
363
  "calm", "active", "focused", "relaxed"
364
  ]
365
 
366
+ # Initialize Groq client if available and requested
367
+ self.use_groq = use_groq and GROQ_AVAILABLE
368
+ if self.use_groq:
369
+ try:
370
+ self.groq_client = Groq(
371
+ api_key=os.environ.get("GROQ_API_KEY"),
372
+ )
373
+ print("Groq client initialized successfully.")
374
+ except Exception as e:
375
+ print(f"Failed to initialize Groq client: {str(e)}")
376
+ self.use_groq = False
377
+
378
+ # Initialize sentence transformer for semantic matching if available
379
+ if SENTENCE_TRANSFORMER_AVAILABLE:
380
+ try:
381
+ self.embedding_model = SentenceTransformer('all-MiniLM-L6-v2')
382
+ self.emotional_embeddings = {
383
+ emotion: self.embedding_model.encode([emotion])
384
+ for emotion in self.emotional_states
385
+ }
386
+ self.rhythm_embeddings = {
387
+ pattern: self.embedding_model.encode([pattern])
388
+ for pattern in self.rhythm_patterns
389
+ }
390
+ print("SentenceTransformer initialized successfully.")
391
+ except Exception as e:
392
+ print(f"Failed to initialize SentenceTransformer: {str(e)}")
393
+ self.embedding_model = None
394
+ self.emotional_embeddings = {}
395
+ self.rhythm_embeddings = {}
396
+ else:
397
  self.embedding_model = None
398
  self.emotional_embeddings = {}
399
  self.rhythm_embeddings = {}
400
+
401
+ def detect_emotion_with_groq(self, input_text):
402
+ """Use Groq LLM to detect emotion in text"""
403
+ if not self.use_groq:
404
+ return None
405
+
406
+ prompt = f"""Analyze the following text and determine the primary emotion expressed.
407
+ Choose the most appropriate emotion from this list: anxious, stressed, calm, sad, angry, fearful, confused, happy.
408
+ Provide your answer as a single word that best describes the emotional state.
409
+
410
+ Text: {input_text}
411
+ Emotion:"""
412
+
413
+ try:
414
+ chat_completion = self.groq_client.chat.completions.create(
415
+ messages=[
416
+ {
417
+ "role": "user",
418
+ "content": prompt,
419
+ }
420
+ ],
421
+ model="llama-3.3-70b-versatile",
422
+ max_tokens=10,
423
+ )
424
+
425
+ detected_emotion = chat_completion.choices[0].message.content.strip().lower()
426
+
427
+ # Validate the detected emotion
428
+ if detected_emotion in self.emotional_states:
429
+ return detected_emotion
430
+ else:
431
+ # If LLM returns something not in our list, find closest match
432
+ return self.get_closest_emotional_state(detected_emotion)
433
+
434
+ except Exception as e:
435
+ print(f"Error using Groq for emotion detection: {str(e)}")
436
+ return None
437
 
438
  def get_closest_emotional_state(self, input_text):
439
  """Map input text to the closest emotional state"""
440
+ # First try simple word matching
441
+ for emotion in self.emotional_states:
442
+ if emotion in input_text.lower():
443
+ return emotion
444
+
445
+ # If sentence transformer is available, use semantic similarity
446
+ if self.embedding_model:
447
+ input_embedding = self.embedding_model.encode([input_text])
448
+ similarities = {
449
+ emotion: cosine_similarity(input_embedding, embedding)[0][0]
450
+ for emotion, embedding in self.emotional_embeddings.items()
451
+ }
452
+ return max(similarities, key=similarities.get)
453
 
454
+ # Default fallback
455
+ return "calm"
 
 
 
 
 
456
 
457
+ def get_closest_rhythm_pattern(self, input_text=None, emotional_state=None):
458
+ """Map input text or emotional state to the closest rhythm pattern"""
459
+ # If emotional state is provided, use direct mapping
460
+ if emotional_state:
 
461
  # Map emotional states to rhythm patterns
462
  mapping = {
463
  "anxious": "active",
 
471
  }
472
  return mapping.get(emotional_state, "calm")
473
 
474
+ # If input text is provided and sentence transformer is available
475
+ if input_text and self.embedding_model:
476
+ input_embedding = self.embedding_model.encode([input_text])
477
+ similarities = {
478
+ pattern: cosine_similarity(input_embedding, embedding)[0][0]
479
+ for pattern, embedding in self.rhythm_embeddings.items()
480
+ }
481
+ return max(similarities, key=similarities.get)
482
+
483
+ # Default fallback
484
+ return "calm"
485
+
486
+ def transcribe_audio(self, audio_path):
487
+ """Transcribe audio using Groq if available"""
488
+ if not self.use_groq:
489
+ return "Audio transcription requires Groq API. Please enter text instead."
490
+
491
+ try:
492
+ # Open and read the audio file
493
+ with open(audio_path, "rb") as audio_file:
494
+ audio_data = audio_file.read()
495
+
496
+ # Transcribe the audio using Distil-Whisper
497
+ transcription = self.groq_client.audio.transcriptions.create(
498
+ file=(os.path.basename(audio_path), audio_data),
499
+ model="distil-whisper-large-v3-en",
500
+ response_format="verbose_json",
501
+ )
502
+
503
+ return transcription.text
504
+ except Exception as e:
505
+ return f"Error in transcription: {str(e)}"
506
 
507
+ def analyze_input(self, input_text, audio_path=None):
508
+ """Analyze input text and return appropriate emotional s