HelioAI's picture
LFM3-1.7B inference modules: experimental release (part 2)
cd61333 verified
Raw History Blame Contribute Delete
5.44 kB
"""Shared render-check-repair logic for visual answers, used by lfm3_deliberate.solve_visual.
(The same rules as scripts/visual_repair.py, which produced the measured numbers.)
problems(rep, animated, src, kind, hints) -> (weighted badness, feedback lines) from a render.py report;
feedback(kind, lines) -> the repair turn text; fix_importmap from vis_autofix (deterministic, no model call).
"""
import re
from vis_autofix import IMPORT_MAP, fix_importmap # noqa: F401 (re-exported for callers)
# browser error -> the fix a web developer would apply (general knowledge, never a solution of a particular task)
HINTS = [
(r'Failed to resolve module specifier "three', "A module imports the bare name 'three' (three.js addons do this "
f"too). Put the import map in <head>, before any module script: {IMPORT_MAP}, then write "
"import * as THREE from 'three'; and import addons like import { OrbitControls } from "
"'three/addons/controls/OrbitControls.js';"),
(r"THREE is not defined", "three.js is not a global variable. Add the import map "
f"{IMPORT_MAP} and, inside <script type=\"module\">, write import * as THREE from 'three';"),
(r"THREE\.(\w+) is not a constructor", "THREE.{0} does not exist in three.js r160. Addons are imported "
"separately, e.g. import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; then "
"new OrbitControls(camera, renderer.domElement). Otherwise check the class name."),
(r"Assignment to constant variable", "A variable declared with const is assigned again: declare variables "
"that change with let."),
(r"ReferenceError: (\w+) is not defined", "'{0}' is used where it is not declared: declare it with const/let "
"at the top level, before the functions that use it run."),
(r"Cannot read properties of (?:undefined|null) \(reading '(\w+)'\)", "Something is undefined or null when "
"its property '{0}' is read: an element id that does not exist, an object used before it is created, or an "
"array index out of range."),
(r"(\S+) is not a function", "{0} is not a function: a property is called like a method or a name is "
"misspelled (canvas.width/height are numbers; drawing methods are ctx.fillRect, ctx.arc, ctx.beginPath, "
"ctx.fill, ctx.stroke; angles in Math are radians, there is no Math.radians)."),
]
BLANK_THREE = ("Add lights for MeshStandardMaterial (AmbientLight and DirectionalLight), put the camera away from "
"the objects with camera.lookAt(0, 0, 0) and render every frame with "
"renderer.setAnimationLoop(() => renderer.render(scene, camera)).")
BLANK_CANVAS = ("Set canvas.width = innerWidth and canvas.height = innerHeight, draw in every frame and use a fill "
"color that differs from the background.")
STATIC_HINT = ("Compute positions from the elapsed time inside a requestAnimationFrame loop (or "
"renderer.setAnimationLoop) and redraw every frame.")
SVG_HINT = "Close every tag, quote every attribute value, write & as &amp; and keep one root <svg> element."
def hints_for(rep, animated, src):
out = []
for e in rep.get("errors", []):
for pat, text in HINTS:
m = re.search(pat, e)
if m:
h = text.replace("{0}", m.group(1)) if m.groups() else text
if h not in out:
out.append(h)
break
if rep.get("parse_error"):
out.append(SVG_HINT)
if rep.get("blank") and not rep.get("parse_error") and not rep.get("errors"):
out.append(BLANK_THREE if "three" in (src or "") else BLANK_CANVAS if "<canvas" in (src or "") else
"Make sure the content is visible: real sizes, colors that differ from the background, nothing "
"hidden by CSS.")
if animated and not rep.get("animated") and not rep.get("blank"):
out.append(STATIC_HINT)
return out
def problems(rep, animated, src, kind, hints=False):
"""(weighted badness, feedback lines); 0 = renders cleanly."""
if not src:
return 10, [f"Your answer does not contain the complete file in a ```{kind} code block."]
bad, lines = 0, []
if rep.get("parse_error"):
bad += 4
lines.append(f"The SVG is not valid XML: {rep['parse_error']}")
if rep["errors"]:
bad += 3
lines += [f"JavaScript error: {e}" for e in rep["errors"][:4]]
if rep["failed"]:
bad += 3
lines += [f"This resource failed to load: {u}" for u in rep["failed"][:3]]
if rep["blank"]:
bad += 3
lines.append("Nothing is visible: the rendered page is blank (a single colour).")
if animated and not rep["animated"]:
bad += 1
lines.append("The animation does not move: two screenshots taken 0.7 seconds apart are identical.")
if rep.get("overflow"):
bad += 1
lines.append("The page is wider than the 1024 px window (there is a horizontal scrollbar).")
if hints and bad:
lines += ["Hint: " + h for h in hints_for(rep, animated, src)]
return bad, lines
def feedback(kind, lines):
what = "SVG" if kind == "svg" else "page"
return (f"I opened your {what} in Chrome (window 1024x768) and found these problems:\n"
+ "\n".join("- " + x for x in lines)
+ f"\n\nFix them and give the complete corrected file in a single ```{kind} code block.")