Spaces:
Running
Running
| import unittest | |
| from unittest.mock import patch | |
| from ai_prof.agent import AgentAction, TeachingBeat | |
| from ai_prof.pdf_utils import Deck, Slide | |
| import app | |
| def _state() -> dict: | |
| state = app._new_state() | |
| state["deck"] = Deck( | |
| slides=[ | |
| Slide(index=0, image_path="/tmp/slide-1.png", text="One"), | |
| Slide(index=1, image_path="/tmp/slide-2.png", text="Two"), | |
| Slide(index=2, image_path="/tmp/slide-3.png", text="Three"), | |
| ] | |
| ) | |
| state["readings"] = { | |
| 0: "TITLE: One\nCONCEPTS: first", | |
| 1: "TITLE: Two\nCONCEPTS: second", | |
| 2: "TITLE: Three\nCONCEPTS: third", | |
| } | |
| state["deck_index"] = "1. One\n2. Two\n3. Three" | |
| return state | |
| class OrchestratorTests(unittest.TestCase): | |
| def test_execute_actions_navigates_and_updates_whiteboard(self): | |
| state = _state() | |
| navigated = app._execute_actions( | |
| state, | |
| ( | |
| AgentAction("goto_slide", {"index": 3}), | |
| AgentAction( | |
| "write_note", | |
| {"title": "Remember", "body": "Use the third slide."}, | |
| ), | |
| ), | |
| ) | |
| self.assertTrue(navigated) | |
| self.assertEqual(state["index"], 2) | |
| self.assertEqual(state["whiteboard"][0]["title"], "Remember") | |
| def test_question_can_move_to_supporting_slide(self, plan, _tts): | |
| plan.return_value = TeachingBeat( | |
| narration="Let’s revisit the definition.", | |
| actions=(AgentAction("goto_slide", {"index": 2}),), | |
| continue_lecture=False, | |
| ) | |
| outputs = list(app.on_ask("What was the definition?", _state(), [])) | |
| final = outputs[-1] | |
| self.assertEqual(final[0]["index"], 1) | |
| self.assertEqual(final[2], "Slide 2 / 3") | |
| self.assertEqual(final[3][-1]["content"], "Let’s revisit the definition.") | |
| def test_lecture_advances_when_agent_does_not_navigate(self, plan, _tts): | |
| plan.side_effect = [ | |
| TeachingBeat("First beat.", continue_lecture=True), | |
| TeachingBeat("Second beat.", continue_lecture=False), | |
| ] | |
| outputs = list(app.on_teach_deck(_state(), [])) | |
| final = outputs[-1] | |
| self.assertEqual(final[0]["index"], 1) | |
| self.assertEqual( | |
| [message["content"] for message in final[3]], | |
| ["First beat.", "Second beat."], | |
| ) | |
| def test_lecture_ignores_agent_navigation_and_stays_sequential(self, plan, _tts): | |
| plan.side_effect = [ | |
| TeachingBeat( | |
| "First beat.", | |
| actions=(AgentAction("goto_slide", {"index": 3}),), | |
| continue_lecture=True, | |
| ), | |
| TeachingBeat("Second beat.", continue_lecture=False), | |
| ] | |
| outputs = list(app.on_teach_deck(_state(), [])) | |
| final = outputs[-1] | |
| self.assertEqual(final[0]["index"], 1) | |
| self.assertEqual(final[2], "Slide 2 / 3") | |
| def test_index_select_moves_to_requested_slide(self): | |
| state, _img, caption, _board = app.on_index_select(2, _state()) | |
| self.assertEqual(state["index"], 2) | |
| self.assertEqual(caption, "Slide 3 / 3") | |
| def test_whiteboard_emits_math_block_for_latex(self): | |
| state = _state() | |
| state["whiteboard"] = [{"type": "latex", "expression": r"x^2 + y^2"}] | |
| board = app._whiteboard_view(state) | |
| self.assertIn("$$\nx^2 + y^2\n$$", board) | |
| if __name__ == "__main__": | |
| unittest.main() | |