ai insight rework #3, add root cause to daily ai insight

This commit is contained in:
Alberto-Audrix committed 2026-10-06 14:14:11 +07:00
1 parent c963bb778c
commit d5b0c12c40
8 files changed
+385 -47

No files matched your search

@@ -672,6 +672,88 @@ class RootCauseTests(TestCase):
self.assertEqual(sanitized["perbaikan_siklus_berikutnya"][0]["id"], "pakan_akses")
class DailyAkarMasalahTests(TestCase):
"""Test daily AI insight 3-section format (kesimpulan, akar_masalah, insight)."""
def test_parse_llm_json_with_akar_masalah(self):
payload = json.dumps({
"kesimpulan": "FCR 1.40 pada hari ke-28 berada di atas standar CP 707 (1.315).",
"akar_masalah": "Fluktuasi suhu kandang malam hari dan akses pakan tidak merata.",
"insight": "Lakukan kalibrasi pemanas dan ratakan distribusi pakan di sepanjang brooding area."
})
parsed = insight_service.parse_llm_json(payload)
self.assertIsNotNone(parsed)
self.assertEqual(parsed["kesimpulan"], "FCR 1.40 pada hari ke-28 berada di atas standar CP 707 (1.315).")
self.assertEqual(parsed["akar_masalah"], "Fluktuasi suhu kandang malam hari dan akses pakan tidak merata.")
self.assertIn("kalibrasi pemanas", parsed["insight"])
def test_parse_llm_json_variants(self):
payload = json.dumps({
"summary": "Kondisi pakan normal.",
"root_cause": "Kondisi operasional optimal, tidak terdeteksi indikasi deviasi.",
"rekomendasi": "Pertahankan SOP saat ini."
})
parsed = insight_service.parse_llm_json(payload)
self.assertIsNotNone(parsed)
self.assertEqual(parsed["kesimpulan"], "Kondisi pakan normal.")
self.assertEqual(parsed["akar_masalah"], "Kondisi operasional optimal, tidak terdeteksi indikasi deviasi.")
self.assertEqual(parsed["insight"], "Pertahankan SOP saat ini.")
def test_parse_llm_json_legacy_fallback(self):
payload = json.dumps({
"kesimpulan": "Data normal.",
"insight": "Lanjutkan pemantauan harian."
})
parsed = insight_service.parse_llm_json(payload)
self.assertIsNotNone(parsed)
self.assertEqual(parsed["kesimpulan"], "Data normal.")
self.assertEqual(parsed["akar_masalah"], "")
self.assertEqual(parsed["insight"], "Lanjutkan pemantauan harian.")
def test_embedded_daily_serialization(self):
clean_insight = "Lakukan penyesuaian tirai kandang dan ventilasi minimal."
akar_masalah = "Suhu brooding terlalu dingin di malam hari (26C vs 32C)."
daily_json = json.dumps({"akar_masalah": akar_masalah, "insight": clean_insight}, ensure_ascii=False)
stored_text = f"{clean_insight}\n\n{insight_service.DAILY_JSON_MARKER}\n{daily_json}"
mock_row = MagicMock()
mock_row.pk = 1
mock_row.cycle_id = 10
mock_row.kandang_id = 2
mock_row.topic = "fcr"
mock_row.report_type = "page"
mock_row.report_period = "current"
mock_row.summary = "FCR tinggi pada hari ke-7."
mock_row.insight_text = stored_text
mock_row.alert = "warning"
mock_row.citations = "[]"
mock_row.date = None
mock_row.created_at = None
mock_row.updated_at = None
serialized = insight_service.serialize_insight(mock_row)
self.assertTrue(serialized["success"])
self.assertEqual(serialized["summary"], "FCR tinggi pada hari ke-7.")
self.assertEqual(serialized["akar_masalah"], akar_masalah)
self.assertEqual(serialized["insight"], clean_insight)
self.assertIn(akar_masalah, serialized["insight_text"])
self.assertIn(clean_insight, serialized["insight_text"])
def test_daily_prompt_structure(self):
prompt = insight_service.build_insight_user_prompt(
topic="fcr",
kandang_name="Kandang 01",
report_type="page",
report_period="current",
context={"fcr_terakhir": 1.4},
graded={"analyses": {"fcr": {"status": "warning", "message": "FCR tinggi"}}},
is_end_cycle=False,
)
self.assertIn("akar_masalah", prompt)
self.assertIn("ANALISIS AKAR PENYEBAB", prompt)
self.assertIn('"akar_masalah":"<analisis faktor pemicu', prompt)
class TraceLintTests(TestCase):
"""Test rag_trace.jsonl linting logic."""