import json import unittest from ai_daily_report.observability import LlmCallObserver, summarize_observed_calls class ObservabilityTests(unittest.TestCase): def test_records_prompt_and_response_hashes(self): observer = LlmCallObserver(lambda prompt: json.dumps({"ok": True}), stage="stage3") response = observer("prompt") self.assertEqual(response, '{"ok": true}') self.assertEqual(len(observer.records), 1) self.assertEqual(observer.records[0]["stage"], "stage3") self.assertEqual(observer.records[0]["prompt_chars"], 6) self.assertEqual(observer.records[0]["response_chars"], len(response)) self.assertRegex(observer.records[0]["prompt_hash"], r"^[0-9a-f]{64}$") self.assertRegex(observer.records[0]["response_hash"], r"^[0-9a-f]{64}$") def test_summarizes_observed_calls(self): left = LlmCallObserver(lambda prompt: "a", stage="stage3") right = LlmCallObserver(lambda prompt: "b", stage="stage4") left("x") right("y") right("z") report = summarize_observed_calls([left, right]) self.assertEqual(report["total_calls"], 3) self.assertEqual(report["by_stage"], {"stage3": 1, "stage4": 2}) if __name__ == "__main__": unittest.main()