CoolFace
Apppublic

build-small-hackathon/hackathon-advisor

sourceHugging Facemitupdated 3mo agoView on Hugging Face
16likes
test_agent.py337 linesDownload Raw Back to tests
1from tests.helpers import load_test_index2 3from hackathon_advisor.agent import AdvisorEngine4from hackathon_advisor.tool_contracts import ToolCall, ToolResolution5 6 7class StaticPlanner:8    backend = "test"9    model_id = "static"10 11    def __init__(self, call: ToolCall) -> None:12        self.call = call13 14    def plan(self, message: str, state: dict) -> ToolResolution:15        return ToolResolution(status="valid", call=self.call, errors=())16 17 18def test_agent_scores_and_persists_idea() -> None:19    index = load_test_index()20    engine = AdvisorEngine(index)21 22    result = engine.turn("A local-first archive cartographer for family photos", {})23 24    assert result.score is not None25    assert result.state["ideas"]26    assert result.state["ideas"][0]["score"] is not None27    assert "goal_fit" in result.state["ideas"][0]["score"]28    assert "prize_fit" not in result.state["ideas"][0]["score"]29    assert "goal_fit" in result.artifact["seal"]30    assert "prize_fit" not in result.artifact["seal"]31    assert result.state["trace"]32    assert result.state["last_tool_resolution"]["call"]["name"] == "save_idea"33    assert result.state["trace"][0]["tool_resolution"]["call"]["name"] == "save_idea"34    assert result.state["last_artifact"]["title"] == result.artifact["title"]35    assert result.state["ideas"][0]["artifact"]["title"] == result.artifact["title"]36    assert result.artifact["wood_map"]["caption"]37    assert {dot["kind"] for dot in result.artifact["wood_map"]["dots"]} >= {"idea", "echo", "inked"}38    assert result.score.to_dict()["echoes"][0]["page_number"] >= 139    assert "page " in result.response40    assert result.response41 42 43def test_agent_finds_whitespace() -> None:44    index = load_test_index()45    engine = AdvisorEngine(index)46 47    result = engine.turn("write bolder and find whitespace", {})48 49    assert result.whitespace50    assert result.score is not None51    assert result.artifact["verdict"] == "UNWRITTEN"52    assert result.state["ideas"][0]["title"] == result.whitespace[0].label53 54 55def test_gap_command_explores_unused_whitespace() -> None:56    index = load_test_index()57    engine = AdvisorEngine(index)58 59    first = engine.turn("write bolder and find whitespace", {})60    second = engine.turn("write bolder and find whitespace", first.state)61 62    assert len(second.state["ideas"]) == 263    assert first.whitespace[0].label != second.whitespace[0].label64    assert second.state["ideas"][-1]["title"] == second.whitespace[0].label65    assert second.state["current_whitespace"]["label"] == second.whitespace[0].label66 67 68def test_agent_preserves_canonical_jargon_case() -> None:69    index = load_test_index()70    engine = AdvisorEngine(index)71 72    result = engine.turn("use neutron and mini cpm on zero gpu", {})73 74    assert "MiniCPM5" in result.artifact["title"]75    assert "ZeroGPU" in result.artifact["title"]76 77 78def test_plan_command_uses_current_idea() -> None:79    index = load_test_index()80    engine = AdvisorEngine(index)81 82    first = engine.turn("A local-first archive cartographer for family photos", {})83    planned = engine.turn("make a build plan", first.state)84 85    assert planned.plan86    assert planned.artifact["title"] == first.artifact["title"]87    assert planned.state["ideas"][0]["title"] == first.artifact["title"]88    assert all("Record the trace" not in step for step in planned.plan)89    assert all("session trace" not in step for step in planned.plan)90 91 92def test_non_plan_turns_clear_stale_build_plan() -> None:93    index = load_test_index()94    engine = AdvisorEngine(index)95 96    first = engine.turn("A local-first archive cartographer for family photos", {})97    planned = engine.turn("make a build plan", first.state)98    project = engine.turn("read project lolaby", planned.state)99    second = engine.turn("A hands-on science coach for kitchen experiments", planned.state)100 101    assert planned.state["last_plan"]102    assert "last_plan" not in project.state103    assert "last_plan" not in second.state104 105 106def test_plan_and_rank_do_not_create_placeholder_ideas() -> None:107    index = load_test_index()108    engine = AdvisorEngine(index)109 110    planned = engine.turn("make a build plan", {})111    ranked = engine.turn("compare ideas", planned.state)112 113    assert planned.state["ideas"] == []114    assert ranked.state["ideas"] == []115    assert "Write one project instinct first" in planned.response116    assert "No idea pages" in ranked.response117    assert planned.tool_events[0].name == "make_plan"118    assert ranked.tool_events[0].name == "compare_ideas"119 120 121def test_plan_uses_profile_context() -> None:122    index = load_test_index()123    engine = AdvisorEngine(index)124    state = {125        "profile": {126            "skills": "frontend prototyping",127            "time": "one evening",128            "preferences": "quiet dashboards",129            "constraints": "CPU-only Space",130        }131    }132 133    first = engine.turn("A local-first archive cartographer for family photos", state)134    planned = engine.turn("make a build plan", first.state)135 136    assert any("one evening" in step for step in planned.plan)137    assert any("frontend prototyping" in step for step in planned.plan)138    assert any("CPU-only Space" in step for step in planned.plan)139    assert any("quiet dashboards" in step for step in planned.plan)140 141 142def test_distinct_idea_turns_append_to_board() -> None:143    index = load_test_index()144    engine = AdvisorEngine(index)145 146    first = engine.turn("A local-first archive cartographer for family photos", {})147    second = engine.turn("write bolder and find whitespace", first.state)148 149    assert len(second.state["ideas"]) == 2150    assert second.state["ideas"][0]["title"] == first.artifact["title"]151    assert second.state["ideas"][1]["title"] == second.artifact["title"]152    assert second.state["ideas"][0]["artifact"]["title"] == first.artifact["title"]153    assert second.state["ideas"][1]["artifact"]["title"] == second.artifact["title"]154 155 156def test_compare_ideas_reranks_board_and_selects_winner() -> None:157    index = load_test_index()158    engine = AdvisorEngine(index)159 160    first = engine.turn("A local-first archive cartographer for family photos", {})161    second = engine.turn("write bolder and find whitespace", first.state)162    ranked = engine.turn("compare ideas", second.state)163 164    assert ranked.score is not None165    assert ranked.artifact["title"] == ranked.state["ideas"][0]["title"]166    assert ranked.state["current_idea_id"] == ranked.state["ideas"][0]["id"]167    assert ranked.state["ideas"][0]["score"]["overall"] >= ranked.state["ideas"][1]["score"]["overall"]168    assert all(idea["artifact"]["title"] == idea["title"] for idea in ranked.state["ideas"])169    assert ranked.plan170    assert "Ranked pages:" in ranked.response171    assert ranked.tool_events[0].name == "compare_ideas"172 173 174def test_plan_preserves_unwritten_whitespace_verdict() -> None:175    index = load_test_index()176    engine = AdvisorEngine(index)177 178    whitespace = engine.turn("write bolder and find whitespace", {})179    planned = engine.turn("make a build plan", whitespace.state)180 181    assert whitespace.artifact["verdict"] == "UNWRITTEN"182    assert planned.artifact["title"] == whitespace.artifact["title"]183    assert planned.artifact["verdict"] == "UNWRITTEN"184 185 186def test_planner_get_project_drives_project_response() -> None:187    index = load_test_index()188    engine = AdvisorEngine(index, planner=StaticPlanner(ToolCall("get_project", {"id": "lolaby"})))189 190    result = engine.turn("read lolaby", {})191 192    assert result.projects193    assert result.projects[0].slug == "lolaby"194    assert result.tool_events[0].name == "get_project"195 196 197def test_rule_project_reference_does_not_create_or_score_idea() -> None:198    index = load_test_index()199    engine = AdvisorEngine(index)200    first = engine.turn("A local-first archive cartographer for family photos", {})201 202    result = engine.turn("read project lolaby", first.state)203 204    assert result.projects205    assert result.projects[0].slug == "lolaby"206    assert result.score is None207    assert result.artifact == {}208    assert len(result.state["ideas"]) == 1209    assert result.state["ideas"][0]["title"] == first.artifact["title"]210    assert result.state["last_artifact"]["title"] == first.artifact["title"]211    assert result.state["last_tool_resolution"]["call"]["name"] == "get_project"212 213 214def test_planner_profile_and_goals_update_state() -> None:215    index = load_test_index()216    planned = AdvisorEngine(index).turn("A local-first archive cartographer for family photos", {})217    planned = AdvisorEngine(index).turn("make a build plan", planned.state)218    assert planned.state["last_plan"]219    profile_engine = AdvisorEngine(220        index,221        planner=StaticPlanner(ToolCall("update_profile", {"field": "skills", "value": "frontend"})),222    )223    profile = profile_engine.turn("remember this", planned.state)224    target_engine = AdvisorEngine(225        index,226        planner=StaticPlanner(ToolCall("set_goals", {"goals": ["Off the Grid", "Field Notes"]})),227    )228    targeted = target_engine.turn("set goals", profile.state)229 230    assert targeted.state["profile"]["skills"] == "frontend"231    assert targeted.state["goals"] == ["Off the Grid", "Field Notes"]232    assert "last_plan" not in profile.state233    assert "last_plan" not in targeted.state234    assert "Local-first, Build notes" in targeted.response235 236 237def test_goal_update_invalidates_current_idea_artifact() -> None:238    index = load_test_index()239    first = AdvisorEngine(index).turn("A local-first archive cartographer for family photos", {})240    first = AdvisorEngine(index).turn("make a build plan", first.state)241    assert first.state["last_plan"]242    target_engine = AdvisorEngine(243        index,244        planner=StaticPlanner(ToolCall("set_goals", {"goals": ["Field Notes"]})),245    )246 247    targeted = target_engine.turn("set goals", first.state)248 249    idea = targeted.state["ideas"][0]250    assert idea["score"] is None251    assert idea["artifact"] is None252    assert "last_artifact" not in targeted.state253    assert "last_plan" not in targeted.state254 255 256def test_session_goals_apply_to_new_and_current_ideas() -> None:257    index = load_test_index()258    engine = AdvisorEngine(index)259    state = {"goals": ["Field Notes"]}260 261    first = engine.turn("A local-first archive cartographer for family photos", state)262    first_idea = first.state["ideas"][0]263    planned = engine.turn("make a build plan", first.state)264 265    assert first_idea["goals"] == ["Field Notes"]266    assert all("LoRA" not in step for step in planned.plan)267 268 269def test_well_tuned_goal_adds_training_step_to_plan() -> None:270    index = load_test_index()271    engine = AdvisorEngine(index)272    state = {"goals": ["Well-Tuned"]}273 274    first = engine.turn("A local-first archive cartographer for family photos", state)275    planned = engine.turn("make a build plan", first.state)276 277    assert first.state["ideas"][0]["goals"] == ["Well-Tuned"]278    assert any("LoRA" in step for step in planned.plan)279    assert all("advisor turns" not in step for step in planned.plan)280 281 282def test_planner_score_idea_scores_current_idea() -> None:283    index = load_test_index()284    first = AdvisorEngine(index).turn("A local-first archive cartographer for family photos", {})285    engine = AdvisorEngine(index, planner=StaticPlanner(ToolCall("score_idea", {})))286 287    scored = engine.turn("score it", first.state)288 289    assert scored.score is not None290    assert scored.artifact["title"] == first.artifact["title"]291 292 293def test_turn_stream_emits_ordered_progress_events() -> None:294    index = load_test_index()295    engine = AdvisorEngine(index)296 297    events = list(engine.turn_stream("A local-first archive cartographer for family photos", {}))298    types = [event["type"] for event in events]299 300    assert types[0] == "start"301    assert types[-1] == "done"302    assert "token" in types303    # the planning stage is announced before any tool runs, and tools stream as they execute304    assert types.index("stage") < types.index("tool_event")305    tool_events = [event for event in events if event["type"] == "tool_event"]306    assert [event["name"] for event in tool_events] == ["save_idea", "search_projects", "score_idea"]307    assert events[-1]["state"]["ideas"]308 309 310def test_turn_stream_done_matches_blocking_turn() -> None:311    # idea ids are randomly generated, so compare the deterministic surface of the turn.312    index = load_test_index()313    streamed = list(AdvisorEngine(index).turn_stream("write bolder and find whitespace", {}))314    done = next(event for event in streamed if event["type"] == "done")315    blocking = AdvisorEngine(index).turn("write bolder and find whitespace", {})316 317    assert done["response"] == blocking.response318    assert done["score"] == (blocking.score.to_dict() if blocking.score else None)319    assert done["plan"] == blocking.plan320    assert [item["label"] for item in done["whitespace"]] == [321        item.label for item in blocking.whitespace322    ]323    assert [idea["title"] for idea in done["state"]["ideas"]] == [324        idea["title"] for idea in blocking.state["ideas"]325    ]326 327 328def test_turn_accepts_injected_resolution() -> None:329    index = load_test_index()330    engine = AdvisorEngine(index, planner=StaticPlanner(ToolCall("score_idea", {})))331    injected = ToolResolution(status="valid", call=ToolCall("list_projects", {"sort": "likes"}), errors=())332 333    result = engine.turn("score it", {}, resolution=injected)334 335    # the injected list_projects call wins over the planner's score_idea call336    assert result.state["last_tool_resolution"]["call"]["name"] == "list_projects"337