Spaces:
Sleeping
Sleeping
Commit
Β·
2353c7d
1
Parent(s):
d8d0be0
New VERY Conservative Limits:
Browse filesAI Debug Retries: Maximum 1 attempt (down from 2)
Code Regeneration: Maximum 1 attempt per scene
Total per scene: 1 AI fix + 1 code regen = 2 total attempts maximum
Immediate Skip Logic:
β
Quick exit checks at the start of error handling
β
Immediate skip if AI debugger fails
β
Clear "SKIPPING" messages so users know what's happening
β
User notification in Gradio that scenes get max 2 attempts
- app.py +1 -0
- src/rendering/scene_renderer.py +17 -12
app.py
CHANGED
|
@@ -160,6 +160,7 @@ class GradioVideoEngine:
|
|
| 160 |
|
| 161 |
# Step 4: Render scenes
|
| 162 |
self.log_message("π¨ Step 4/5: Rendering video scenes...")
|
|
|
|
| 163 |
progress(0.8, desc="Rendering video scenes...")
|
| 164 |
self.engine.step_4_render_scenes()
|
| 165 |
self.log_message("β
Scene rendering completed")
|
|
|
|
| 160 |
|
| 161 |
# Step 4: Render scenes
|
| 162 |
self.log_message("π¨ Step 4/5: Rendering video scenes...")
|
| 163 |
+
self.log_message("βΉοΈ Note: Each scene gets max 2 attempts to avoid excessive costs")
|
| 164 |
progress(0.8, desc="Rendering video scenes...")
|
| 165 |
self.engine.step_4_render_scenes()
|
| 166 |
self.log_message("β
Scene rendering completed")
|
src/rendering/scene_renderer.py
CHANGED
|
@@ -116,18 +116,25 @@ def render_and_combine_scene(project_config: dict, scene_name: str, code_file: s
|
|
| 116 |
except subprocess.CalledProcessError as e:
|
| 117 |
logger.error_with_context(f"Manim subprocess failed for {scene_name}", f"Code: {e.returncode}")
|
| 118 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 119 |
if "error" in e.stderr.lower() and retry_count < max_retries:
|
| 120 |
# Try AI debugging first (up to max_retries times)
|
| 121 |
-
logger.quick_log("info", "Attempting AI auto-debug")
|
| 122 |
if debugger.debug_and_fix(code_file, e.stderr, scene_name):
|
| 123 |
logger.quick_log("success", "AI fix applied, retrying")
|
| 124 |
return render_and_combine_scene(project_config, scene_name, code_file, manim_executable, renders_cache, debugger, retry_count + 1, max_retries, regen_count, max_regens)
|
| 125 |
else:
|
| 126 |
-
logger.quick_log("error", "AI debugger could not fix issue")
|
|
|
|
| 127 |
|
| 128 |
# If AI debugging failed or we've reached max retries, try code regeneration ONCE
|
| 129 |
if retry_count >= max_retries and regen_count < max_regens:
|
| 130 |
-
logger.quick_log("info", f"
|
| 131 |
from src.generation.code_generator import regenerate_single_scene_code
|
| 132 |
|
| 133 |
# Get the gemini client from the environment
|
|
@@ -141,19 +148,17 @@ def render_and_combine_scene(project_config: dict, scene_name: str, code_file: s
|
|
| 141 |
temp_dir = Path(code_file).parent
|
| 142 |
|
| 143 |
if regenerate_single_scene_code(project_config, gemini_client, str(temp_dir), scene_name):
|
| 144 |
-
logger.quick_log("success", "Code regenerated
|
| 145 |
new_code_file = project_config["scenes"][scene_name]["code_file"]
|
| 146 |
return render_and_combine_scene(project_config, scene_name, new_code_file, manim_executable, renders_cache, debugger, 0, max_retries, regen_count + 1, max_regens)
|
| 147 |
else:
|
| 148 |
-
logger.quick_log("error", "Code regeneration failed")
|
|
|
|
| 149 |
except Exception as regen_e:
|
| 150 |
-
logger.error_with_context("Code regeneration error", str(regen_e))
|
| 151 |
-
|
| 152 |
-
# If we've exhausted all retries AND regenerations, give up
|
| 153 |
-
if retry_count >= max_retries and regen_count >= max_regens:
|
| 154 |
-
logger.quick_log("error", f"All retry and regeneration attempts exhausted for {scene_name}")
|
| 155 |
|
| 156 |
-
logger.end_operation(operation_id, f"Rendering {scene_name} failed")
|
| 157 |
return None
|
| 158 |
except Exception as e:
|
| 159 |
logger.error_with_context(f"Unexpected rendering error for {scene_name}", str(e))
|
|
@@ -198,7 +203,7 @@ def render_scenes(project_config: dict, manim_executable: str, renders_cache: Pa
|
|
| 198 |
try:
|
| 199 |
video_path = render_and_combine_scene(
|
| 200 |
project_config, scene_name, scene_data.get("code_file"),
|
| 201 |
-
manim_executable, renders_cache, debugger, 0,
|
| 202 |
)
|
| 203 |
if video_path and Path(video_path).exists():
|
| 204 |
project_config["scenes"][scene_name]["final_video_path"] = str(video_path)
|
|
|
|
| 116 |
except subprocess.CalledProcessError as e:
|
| 117 |
logger.error_with_context(f"Manim subprocess failed for {scene_name}", f"Code: {e.returncode}")
|
| 118 |
|
| 119 |
+
# Quick exit - if we've already tried a lot, just skip
|
| 120 |
+
if retry_count >= max_retries or regen_count >= max_regens:
|
| 121 |
+
logger.quick_log("error", f"Scene {scene_name} failed - SKIPPING to save time/money")
|
| 122 |
+
logger.end_operation(operation_id, f"Rendering {scene_name} SKIPPED")
|
| 123 |
+
return None
|
| 124 |
+
|
| 125 |
if "error" in e.stderr.lower() and retry_count < max_retries:
|
| 126 |
# Try AI debugging first (up to max_retries times)
|
| 127 |
+
logger.quick_log("info", f"Attempting AI auto-debug ({retry_count + 1}/{max_retries})")
|
| 128 |
if debugger.debug_and_fix(code_file, e.stderr, scene_name):
|
| 129 |
logger.quick_log("success", "AI fix applied, retrying")
|
| 130 |
return render_and_combine_scene(project_config, scene_name, code_file, manim_executable, renders_cache, debugger, retry_count + 1, max_retries, regen_count, max_regens)
|
| 131 |
else:
|
| 132 |
+
logger.quick_log("error", "AI debugger could not fix issue - SKIPPING")
|
| 133 |
+
return None
|
| 134 |
|
| 135 |
# If AI debugging failed or we've reached max retries, try code regeneration ONCE
|
| 136 |
if retry_count >= max_retries and regen_count < max_regens:
|
| 137 |
+
logger.quick_log("info", f"Trying code regeneration - LAST ATTEMPT")
|
| 138 |
from src.generation.code_generator import regenerate_single_scene_code
|
| 139 |
|
| 140 |
# Get the gemini client from the environment
|
|
|
|
| 148 |
temp_dir = Path(code_file).parent
|
| 149 |
|
| 150 |
if regenerate_single_scene_code(project_config, gemini_client, str(temp_dir), scene_name):
|
| 151 |
+
logger.quick_log("success", "Code regenerated - FINAL ATTEMPT")
|
| 152 |
new_code_file = project_config["scenes"][scene_name]["code_file"]
|
| 153 |
return render_and_combine_scene(project_config, scene_name, new_code_file, manim_executable, renders_cache, debugger, 0, max_retries, regen_count + 1, max_regens)
|
| 154 |
else:
|
| 155 |
+
logger.quick_log("error", "Code regeneration failed - SKIPPING")
|
| 156 |
+
return None
|
| 157 |
except Exception as regen_e:
|
| 158 |
+
logger.error_with_context("Code regeneration error - SKIPPING", str(regen_e))
|
| 159 |
+
return None
|
|
|
|
|
|
|
|
|
|
| 160 |
|
| 161 |
+
logger.end_operation(operation_id, f"Rendering {scene_name} failed - SKIPPED")
|
| 162 |
return None
|
| 163 |
except Exception as e:
|
| 164 |
logger.error_with_context(f"Unexpected rendering error for {scene_name}", str(e))
|
|
|
|
| 203 |
try:
|
| 204 |
video_path = render_and_combine_scene(
|
| 205 |
project_config, scene_name, scene_data.get("code_file"),
|
| 206 |
+
manim_executable, renders_cache, debugger, 0, 1, 0, 1 # VERY CONSERVATIVE: 1 AI retry, 1 code regen max
|
| 207 |
)
|
| 208 |
if video_path and Path(video_path).exists():
|
| 209 |
project_config["scenes"][scene_name]["final_video_path"] = str(video_path)
|