p = 'backend/app/tasks/quiz_tasks.py'
s = open(p).read()

s = s.replace(
    "        from app.services import article_service, illustrate, storage_service",
    "        from app.services import article_service, diagram, illustrate, storage_service")

old = '''            answer = illustrate.read_reply(raw)
            if answer is None:
                _push_step(r, job_id, "ai", f"{section.get('title')}: unusable reply")
                continue
            if not answer.get("useful"):
                continue
            svg = illustrate.check(answer.get("svg", ""))
            if not svg:
                _push_step(r, job_id, "ai", f"{section.get('title')}: the drawing was refused")
                continue

            alt = " ".join(str(answer.get("alt") or "").split())[:300] or section.get("title")'''
new = '''            answer = illustrate.read_spec(raw)
            if answer is None:
                _push_step(r, job_id, "ai", f"{section.get('title')}: unusable reply")
                continue
            if not answer.get("useful"):
                continue
            # The model chose the content; the geometry is ours. A spec that
            # will not fit — a label that needs four lines, nine nodes in a
            # cycle — yields no figure rather than a squeezed one.
            try:
                svg = diagram.render(answer["spec"])
            except diagram.BadSpec as bad:
                _push_step(r, job_id, "ai", f"{section.get('title')}: {bad}")
                continue
            except Exception as exc:
                _push_step(r, job_id, "ai", f"{section.get('title')}: could not draw it. {_why(exc)}")
                continue
            if not illustrate.check(svg):
                # Our own output, so this should never fire. It stays because
                # the day it does fire is the day something upstream changed.
                _push_step(r, job_id, "ai", f"{section.get('title')}: the drawing was refused")
                continue

            spec = answer["spec"]
            alt = " ".join(str(spec.get("caption") or "").split())[:300] or section.get("title")'''
assert old in s
s = s.replace(old, new)

s = s.replace('''                raw = chat(model=ai_model_id, messages=[{"role": "user", "content": prompt}],
                           max_tokens=6000, temperature=0.2, api_key=ai_api_key).strip()''',
'''                # A spec is a few hundred tokens of JSON. The old ask was a
                # whole SVG, which is where the empty completions came from.
                raw = chat(model=ai_model_id, messages=[{"role": "user", "content": prompt}],
                           max_tokens=1600, temperature=0.2, api_key=ai_api_key).strip()''')

s = s.replace('''                path=key, title=str(answer.get("title") or section.get("title"))[:300],''',
'''                path=key, title=str(spec.get("title") or section.get("title"))[:300],''')

open(p, 'w').write(s)
print('written')
