lesson-agent-dev / libs /agent /tests /test_runner.py
MSG
Feat/fixing stuff (#11)
8c6b423
Raw
History Blame Contribute Delete
5.78 kB
from agent.models import EducationPptxInput, SlideOutline, SlideSpec
from agent.preview import outline_to_html, render_slide_images
from agent.prompts import fallback_outline, outline_looks_like_schema_echo, outline_max_tokens
from agent.runner import AgentRunner
from agent.tools.docx import create_docx, create_html_export
from agent.tools.pptx import create_pptx
def test_outline_max_tokens_scales_with_slide_count():
assert outline_max_tokens(5) == 750
assert outline_max_tokens(1) == 230
assert outline_max_tokens(20) == 1024
runner = AgentRunner()
raw = (
'{"title": "AI Agents", "slides": ['
'{"title": "Intro", "bullets": ["What is an agent?"]},'
'{"title": "Uses", "bullets": ["Automation"]}'
"]}"
)
outline = runner._parse_outline(raw, expected_slides=5)
assert len(outline.slides) == 5
assert outline.title == "AI Agents"
def test_parse_outline_trims_when_model_returns_too_many():
runner = AgentRunner()
raw = (
'{"title": "Topic", "slides": ['
'{"title": "A", "bullets": ["a"]},'
'{"title": "B", "bullets": ["b"]},'
'{"title": "C", "bullets": ["c"]},'
'{"title": "D", "bullets": ["d"]}'
"]}"
)
outline = runner._parse_outline(raw, expected_slides=3)
assert len(outline.slides) == 3
def test_extract_json_from_fenced_block():
raw = '```json\n{"title": "T", "slides": [{"title": "S", "bullets": ["a"]}]}\n```'
data = AgentRunner._extract_json(raw)
assert data["title"] == "T"
def test_extract_json_ignores_trailing_text():
raw = (
'{"title": "AI Agents", "slides": [{"title": "Intro", "bullets": ["a"]}]}\n'
"Here is a short explanation of the lesson outline."
)
data = AgentRunner._extract_json(raw)
assert data["title"] == "AI Agents"
def test_extract_json_ignores_duplicate_object():
first = '{"title": "First", "slides": [{"title": "A", "bullets": ["a"]}]}'
second = '{"title": "Second", "slides": [{"title": "B", "bullets": ["b"]}]}'
data = AgentRunner._extract_json(f"{first}\n{second}")
assert data["title"] == "First"
def test_extract_json_empty_raises():
import pytest
with pytest.raises(ValueError, match="empty output"):
AgentRunner._extract_json(" ")
def test_extract_json_after_thinking_block():
raw = (
"planning the lesson\n"
'{"title": "Agents", "slides": [{"title": "Intro", "bullets": ["What is an agent?"]}]}'
)
from inference.response_clean import strip_thinking_blocks
cleaned = strip_thinking_blocks(raw)
data = AgentRunner._extract_json(cleaned)
assert data["title"] == "Agents"
def test_parse_outline_or_error_empty():
runner = AgentRunner()
outline, err = runner._parse_outline_or_error("", 5, None)
assert outline is None
assert "empty" in err.lower()
def test_parse_outline_rejects_schema_echo():
runner = AgentRunner()
raw = (
'{"title": "string β€” presentation title", "slides": ['
'{"title": "string β€” slide heading", "bullets": ["string", "..."], '
'"speaker_note": "string β€” one sentence for the teacher"}'
"]}"
)
import pytest
with pytest.raises(ValueError, match="schema placeholders"):
runner._parse_outline(raw, expected_slides=5)
def test_outline_looks_like_schema_echo():
echo = SlideOutline(
title="string β€” presentation title",
slides=[SlideSpec(title="string β€” slide heading", bullets=["string", "..."])],
)
assert outline_looks_like_schema_echo(echo) is True
real = SlideOutline(
title="Small model finetuning",
slides=[SlideSpec(title="What is finetuning?", bullets=["Adapting a base model"])],
)
assert outline_looks_like_schema_echo(real) is False
def test_fallback_outline_slide_count():
req = EducationPptxInput(topic="ai agent", grade="6", slide_count=5)
outline = fallback_outline(req)
assert len(outline.slides) == 5
assert "ai agent" in outline.title.lower()
def test_create_pptx_writes_file(tmp_path, monkeypatch):
monkeypatch.setenv("AGENT_OUTPUTS_DIR", str(tmp_path))
outline = SlideOutline(
title="Photosynthesis",
slides=[
SlideSpec(title="What is it?", bullets=["Plants make food", "Uses sunlight"]),
SlideSpec(title="Why it matters", bullets=["Oxygen", "Food chain"]),
],
)
path = create_pptx(outline, run_id="test")
assert path.exists()
assert path.suffix == ".pptx"
def test_create_docx_writes_file(tmp_path, monkeypatch):
monkeypatch.setenv("AGENT_OUTPUTS_DIR", str(tmp_path))
outline = SlideOutline(
title="Photosynthesis",
slides=[SlideSpec(title="Intro", bullets=["Sunlight", "Chlorophyll"])],
)
path = create_docx(outline, run_id="test")
assert path.exists()
assert path.suffix == ".docx"
def test_outline_preview_and_images(tmp_path, monkeypatch):
monkeypatch.setenv("AGENT_OUTPUTS_DIR", str(tmp_path))
outline = SlideOutline(
title="Water Cycle",
slides=[SlideSpec(title="Evaporation", bullets=["Heat", "Vapor"])],
)
html = outline_to_html(outline)
assert "Water Cycle" in html
assert "Evaporation" in html
images = render_slide_images(outline, run_id="prev")
assert len(images) == 2
assert all(p.exists() for p in images)
def test_create_html_export(tmp_path, monkeypatch):
monkeypatch.setenv("AGENT_OUTPUTS_DIR", str(tmp_path))
outline = SlideOutline(
title="Fractions",
slides=[SlideSpec(title="Parts", bullets=["Half", "Quarter"])],
)
path = create_html_export(outline, run_id="html")
assert path.exists()
assert "Fractions" in path.read_text()