Spaces:
Configuration error
Configuration error
Commit ·
bd8d357
1
Parent(s): 082c2a7
CRITICAL FIX: Remove audio insertion logic causing syntax errors
Browse files- backend/compiler.py +34 -53
backend/compiler.py
CHANGED
|
@@ -25,6 +25,8 @@ No markdown
|
|
| 25 |
No explanations
|
| 26 |
No comments
|
| 27 |
No triple quotes
|
|
|
|
|
|
|
| 28 |
|
| 29 |
Exactly 1 Scene class:
|
| 30 |
|
|
@@ -224,65 +226,44 @@ async def generate_manim_code(outline: dict, step_audio_paths=None):
|
|
| 224 |
}
|
| 225 |
for pattern, replacement in replacements.items():
|
| 226 |
code = code.replace(pattern, replacement)
|
| 227 |
-
# Remove any model-generated self.add_sound calls
|
| 228 |
lines = code.split('\n')
|
| 229 |
-
code = '\n'.join([line for line in lines if "self.add_sound" not in line])
|
|
|
|
| 230 |
# Fix .center usage (replace .center with .get_center() only when used as an argument)
|
| 231 |
code = re.sub(r'([\w\)\]]+)\.center(\s*\))', r'\1.get_center()\2', code)
|
| 232 |
code = re.sub(r'class\s+\w+\(Scene\):', 'class GenScene(Scene):', code)
|
| 233 |
|
| 234 |
-
#
|
| 235 |
-
|
| 236 |
-
|
| 237 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 238 |
try:
|
| 239 |
-
|
| 240 |
-
|
| 241 |
-
|
| 242 |
-
|
| 243 |
-
def visit_FunctionDef(self, node):
|
| 244 |
-
if node.name == "construct":
|
| 245 |
-
self.construct_node = node
|
| 246 |
-
|
| 247 |
-
tree = ast.parse(code)
|
| 248 |
-
visitor = ConstructVisitor()
|
| 249 |
-
visitor.visit(tree)
|
| 250 |
-
if visitor.construct_node:
|
| 251 |
-
# Get the lines of the code
|
| 252 |
-
code_lines = code.split('\n')
|
| 253 |
-
func = visitor.construct_node
|
| 254 |
-
# Find the start and end of the construct() method
|
| 255 |
-
start = func.lineno - 1
|
| 256 |
-
end = func.end_lineno if hasattr(func, 'end_lineno') else None
|
| 257 |
-
if end is None:
|
| 258 |
-
# Fallback: find the next function/class or end of file
|
| 259 |
-
for i in range(start+1, len(code_lines)):
|
| 260 |
-
if code_lines[i].startswith(' def ') or code_lines[i].startswith('class '):
|
| 261 |
-
end = i
|
| 262 |
-
break
|
| 263 |
-
if end is None:
|
| 264 |
-
end = len(code_lines)
|
| 265 |
-
# Insert self.add_sound and self.wait after each animation step
|
| 266 |
-
new_func_lines = []
|
| 267 |
-
step_idx = 0
|
| 268 |
-
for line in code_lines[start:end]:
|
| 269 |
-
new_func_lines.append(line)
|
| 270 |
-
# Heuristic: insert after self.play( or self.wait( lines
|
| 271 |
-
if ("self.play(" in line or "self.wait(" in line) and step_idx < len(step_audio_paths):
|
| 272 |
-
audio_path = step_audio_paths[step_idx]
|
| 273 |
-
if audio_path:
|
| 274 |
-
# Indent matches the line
|
| 275 |
-
indent = ' ' * (len(line) - len(line.lstrip()))
|
| 276 |
-
new_func_lines.append(f'{indent}self.add_sound(r"{audio_path}")')
|
| 277 |
-
# Optionally, add a wait (e.g., 1.5s)
|
| 278 |
-
new_func_lines.append(f'{indent}self.wait(1.5)')
|
| 279 |
-
step_idx += 1
|
| 280 |
-
# Replace the function in the code
|
| 281 |
-
code_lines[start:end] = new_func_lines
|
| 282 |
-
code = '\n'.join(code_lines)
|
| 283 |
-
except Exception as e:
|
| 284 |
-
print(f"Error inserting per-step audio: {e}")
|
| 285 |
-
# Fallback: do nothing
|
| 286 |
|
| 287 |
return code
|
| 288 |
except Exception as e:
|
|
|
|
| 25 |
No explanations
|
| 26 |
No comments
|
| 27 |
No triple quotes
|
| 28 |
+
NEVER include self.add_sound() calls
|
| 29 |
+
NEVER include audio or sound methods
|
| 30 |
|
| 31 |
Exactly 1 Scene class:
|
| 32 |
|
|
|
|
| 226 |
}
|
| 227 |
for pattern, replacement in replacements.items():
|
| 228 |
code = code.replace(pattern, replacement)
|
| 229 |
+
# Remove any model-generated self.add_sound calls and self.wait calls
|
| 230 |
lines = code.split('\n')
|
| 231 |
+
code = '\n'.join([line for line in lines if "self.add_sound" not in line and not line.strip().startswith("self.wait(")])
|
| 232 |
+
|
| 233 |
# Fix .center usage (replace .center with .get_center() only when used as an argument)
|
| 234 |
code = re.sub(r'([\w\)\]]+)\.center(\s*\))', r'\1.get_center()\2', code)
|
| 235 |
code = re.sub(r'class\s+\w+\(Scene\):', 'class GenScene(Scene):', code)
|
| 236 |
|
| 237 |
+
# DISABLE audio insertion - it causes syntax errors
|
| 238 |
+
# Audio feature is disabled to prevent malformed code
|
| 239 |
+
|
| 240 |
+
# Validate Python syntax
|
| 241 |
+
try:
|
| 242 |
+
compile(code, '<string>', 'exec')
|
| 243 |
+
print("✓ Generated code validated successfully")
|
| 244 |
+
except SyntaxError as se:
|
| 245 |
+
print(f"⚠ Syntax error in generated code: {se}")
|
| 246 |
+
print(f" Line {se.lineno}: {se.text}")
|
| 247 |
+
# Try to fix by removing problematic lines
|
| 248 |
+
lines = code.split('\n')
|
| 249 |
+
fixed_lines = []
|
| 250 |
+
error_line = se.lineno - 1 if se.lineno else -1
|
| 251 |
+
|
| 252 |
+
for i, line in enumerate(lines):
|
| 253 |
+
skip = False
|
| 254 |
+
if i == error_line or "self.add_sound" in line or (line.strip().startswith("self.wait(") and "self.play" not in lines[i-1] if i > 0 else False):
|
| 255 |
+
print(f" ✗ Removing problematic line {i+1}: {line.strip()}")
|
| 256 |
+
skip = True
|
| 257 |
+
if not skip:
|
| 258 |
+
fixed_lines.append(line)
|
| 259 |
+
|
| 260 |
+
code = '\n'.join(fixed_lines)
|
| 261 |
+
# Try compiling again
|
| 262 |
try:
|
| 263 |
+
compile(code, '<string>', 'exec')
|
| 264 |
+
print("✓ Fixed syntax errors")
|
| 265 |
+
except SyntaxError as se2:
|
| 266 |
+
print(f"⚠ Still has syntax errors: {se2}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 267 |
|
| 268 |
return code
|
| 269 |
except Exception as e:
|