ismdrobiul489 commited on
Commit
1b10369
·
1 Parent(s): 795b7e9

Fix: Groq API key check both GROQ_API and GROQ_API_KEY, improve fallback with varied poses

Browse files
modules/art_reels/services/professional_stick_figure.py CHANGED
@@ -130,12 +130,14 @@ class ProfessionalStickFigure:
130
  CHARACTER_Y = 1100
131
 
132
  def __init__(self, groq_api_key: str = None):
133
- self.groq_api_key = groq_api_key or os.environ.get("GROQ_API_KEY")
 
134
  if self.groq_api_key:
135
  self.groq = Groq(api_key=self.groq_api_key)
 
136
  else:
137
  self.groq = None
138
- logger.warning("Groq API key not found - AI scene generation disabled")
139
 
140
  # Load fonts
141
  self._load_fonts()
@@ -203,11 +205,62 @@ Generate exactly {len(chunks)} scenes. Return ONLY valid JSON array."""
203
  return self._generate_fallback_scenes(chunks)
204
 
205
  def _generate_fallback_scenes(self, chunks: List[Dict]) -> List[Dict]:
206
- """Fallback scene generation"""
207
  scenes = []
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
208
  for i, chunk in enumerate(chunks):
209
  text = chunk.get("text", "").lower()
210
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
211
  # Detect scene type
212
  scene_type = "single"
213
  if any(word in text for word in ["vs", "versus", "compare", "between", "both", "two"]):
@@ -215,16 +268,25 @@ Generate exactly {len(chunks)} scenes. Return ONLY valid JSON array."""
215
  elif any(word in text for word in ["introduce", "what is", "explained", "definition"]):
216
  scene_type = "title"
217
 
218
- scenes.append({
 
219
  "chunk_id": i,
220
  "scene_type": scene_type,
221
  "background": "white",
222
  "title_text": text[:30].upper() if scene_type == "title" else None,
223
  "characters": [
224
- {"position": "center", "pose": "standing", "emotion": "happy", "props": []}
 
 
 
 
 
225
  ] if scene_type != "title" else [],
226
  "caption": text[:50] + "..." if len(text) > 50 else text
227
- })
 
 
 
228
 
229
  return scenes
230
 
 
130
  CHARACTER_Y = 1100
131
 
132
  def __init__(self, groq_api_key: str = None):
133
+ # Try both GROQ_API (config) and GROQ_API_KEY env vars
134
+ self.groq_api_key = groq_api_key or os.environ.get("GROQ_API") or os.environ.get("GROQ_API_KEY")
135
  if self.groq_api_key:
136
  self.groq = Groq(api_key=self.groq_api_key)
137
+ logger.info("Groq API initialized for AI scene generation")
138
  else:
139
  self.groq = None
140
+ logger.warning("Groq API key not found (GROQ_API or GROQ_API_KEY) - AI scene generation disabled")
141
 
142
  # Load fonts
143
  self._load_fonts()
 
205
  return self._generate_fallback_scenes(chunks)
206
 
207
  def _generate_fallback_scenes(self, chunks: List[Dict]) -> List[Dict]:
208
+ """Fallback scene generation with varied poses and emotions"""
209
  scenes = []
210
+
211
+ # Pose keywords for text detection
212
+ pose_keywords = {
213
+ "walking": ["walk", "walked", "forward", "step", "move", "journey"],
214
+ "running": ["run", "ran", "fast", "quick", "rush", "hurry"],
215
+ "sitting": ["sit", "sat", "rest", "relax", "seat", "chair"],
216
+ "sleeping": ["sleep", "slept", "tired", "exhausted", "rest", "night"],
217
+ "thinking": ["think", "thought", "wonder", "consider", "decide", "choice"],
218
+ "jumping": ["jump", "leap", "excited", "joy", "success", "win"],
219
+ "celebrating": ["celebrate", "success", "victory", "won", "achieve", "happy"],
220
+ "pointing": ["point", "show", "look", "direction", "this", "that"],
221
+ "talking": ["said", "told", "speak", "talk", "explain", "teach"],
222
+ "waving": ["hello", "hi", "bye", "goodbye", "wave", "greeting"]
223
+ }
224
+
225
+ # Emotion keywords
226
+ emotion_keywords = {
227
+ "happy": ["happy", "joy", "success", "win", "good", "great", "smile"],
228
+ "sad": ["sad", "fail", "failed", "lost", "wrong", "bad", "sorry"],
229
+ "thinking": ["think", "wonder", "decide", "choose", "question"],
230
+ "excited": ["excited", "wow", "amazing", "incredible", "jump", "celebrate"],
231
+ "surprised": ["surprise", "shock", "unexpected", "suddenly"],
232
+ "confused": ["confused", "wonder", "how", "why", "what"]
233
+ }
234
+
235
+ # Default poses for variety cycling
236
+ default_poses = ["standing", "walking", "pointing", "thinking", "talking", "waving"]
237
+ default_emotions = ["happy", "thinking", "excited", "happy"]
238
+
239
  for i, chunk in enumerate(chunks):
240
  text = chunk.get("text", "").lower()
241
 
242
+ # Detect pose from text
243
+ detected_pose = None
244
+ for pose, keywords in pose_keywords.items():
245
+ if any(kw in text for kw in keywords):
246
+ detected_pose = pose
247
+ break
248
+
249
+ # If no pose detected, cycle through defaults
250
+ if not detected_pose:
251
+ detected_pose = default_poses[i % len(default_poses)]
252
+
253
+ # Detect emotion from text
254
+ detected_emotion = None
255
+ for emotion, keywords in emotion_keywords.items():
256
+ if any(kw in text for kw in keywords):
257
+ detected_emotion = emotion
258
+ break
259
+
260
+ # If no emotion detected, cycle through defaults
261
+ if not detected_emotion:
262
+ detected_emotion = default_emotions[i % len(default_emotions)]
263
+
264
  # Detect scene type
265
  scene_type = "single"
266
  if any(word in text for word in ["vs", "versus", "compare", "between", "both", "two"]):
 
268
  elif any(word in text for word in ["introduce", "what is", "explained", "definition"]):
269
  scene_type = "title"
270
 
271
+ # Build scene
272
+ scene = {
273
  "chunk_id": i,
274
  "scene_type": scene_type,
275
  "background": "white",
276
  "title_text": text[:30].upper() if scene_type == "title" else None,
277
  "characters": [
278
+ {
279
+ "position": "center",
280
+ "pose": detected_pose,
281
+ "emotion": detected_emotion,
282
+ "props": []
283
+ }
284
  ] if scene_type != "title" else [],
285
  "caption": text[:50] + "..." if len(text) > 50 else text
286
+ }
287
+
288
+ scenes.append(scene)
289
+ logger.info(f"Fallback scene {i}: pose={detected_pose}, emotion={detected_emotion}")
290
 
291
  return scenes
292