"""
Solution: compaction and skills (Lab 07, 03_compaction.py and 05_skills.py).
"""
PLACEHOLDER = "[tool output cleared]"
REFUSALS = ("i don't know", "i do not know")


def clear_tool_output(log: list[dict], keep_recent: int = 4) -> list[dict]:
    cut = len(log) - keep_recent
    return [{**m, "text": PLACEHOLDER} if i < cut and m["role"] == "tool" else dict(m) for i, m in enumerate(log)]


def missing_sections(summary: str, sections: list[str]) -> list[str]:
    return [s for s in sections if f"{s.lower()}:" not in summary.lower()]


def lab_grade(reply: str, expect: list[str]) -> bool:
    return all(e in reply.lower() for e in expect)


def strict_grade(reply: str, expect: list[str]) -> bool:
    text = reply.lower().replace("’", "'")
    return lab_grade(reply, expect) and not text.startswith(REFUSALS)


def listing(skills: list[dict]) -> str:
    return "\n".join(f"- {s['name']}: {s['description']}" for s in skills)


def pick_rate(picks: list[dict], mode: str) -> tuple[int, int]:
    return sum(p[mode] == p["expected"] for p in picks), len(picks)
