diff --git a/src/fgai/monitor.py b/src/fgai/monitor.py index 740b5ed..b6f2242 100644 --- a/src/fgai/monitor.py +++ b/src/fgai/monitor.py @@ -141,6 +141,10 @@ def _range_seconds(value: object) -> int: return 300 +def monitor_cycle_timeout_seconds(mcp_poll_timeout: int, mcp_call_timeout: int) -> int: + return max(600, mcp_poll_timeout + max(180, mcp_call_timeout * 8)) + + def _graylog_fields_from_result(result: dict[str, object]) -> list[dict[str, object]]: content = result.get("result", {}).get("content", []) if isinstance(result.get("result"), dict) else [] text = next((item.get("text", "") for item in content if isinstance(item, dict)), "") @@ -743,7 +747,7 @@ def monitor_loop( if runtime.get("log_source") == "graylog_mcp": write_refreshing_status(output, cache_path=status_cache_path, call_timeout_seconds=mcp_call_timeout, poll_timeout_seconds=mcp_poll_timeout, runtime_values=runtime) try: - status_timeout = mcp_poll_timeout + max(90, mcp_call_timeout * 4) + status_timeout = monitor_cycle_timeout_seconds(mcp_poll_timeout, mcp_call_timeout) with _cycle_timeout(status_timeout if runtime.get("log_source") == "graylog_mcp" else 0): status = build_status( log_path, policy_path=policy_path, anomaly_limit=anomaly_limit, diff --git a/tests/test_monitor.py b/tests/test_monitor.py index 1ba091b..73b7ca7 100644 --- a/tests/test_monitor.py +++ b/tests/test_monitor.py @@ -6,10 +6,15 @@ from unittest.mock import patch from fgai.history import StatusSnapshotStore from fgai.history import FieldDiscoveryStore -from fgai.monitor import add_llm_assessment, build_status, cached_status_with_error, write_refreshing_status, write_status +from fgai.monitor import add_llm_assessment, build_status, cached_status_with_error, monitor_cycle_timeout_seconds, write_refreshing_status, write_status class MonitorTests(unittest.TestCase): + def test_monitor_cycle_timeout_keeps_large_buffer(self): + self.assertEqual(monitor_cycle_timeout_seconds(120, 8), 600) + self.assertEqual(monitor_cycle_timeout_seconds(240, 8), 600) + self.assertEqual(monitor_cycle_timeout_seconds(900, 8), 1080) + def test_build_status_from_log_file(self): with tempfile.TemporaryDirectory() as tmp: log_path = Path(tmp) / "fg.log"