diff --git a/src/task_scheduler.py b/src/task_scheduler.py index 7b3c6e765..50613ae72 100644 --- a/src/task_scheduler.py +++ b/src/task_scheduler.py @@ -368,19 +368,19 @@ def _resolve_research_settings(get_setting_fn): """ try: max_tokens = int(get_setting_fn("research_max_tokens", 8192)) - except (TypeError, ValueError): + except (TypeError, ValueError, OverflowError): max_tokens = 8192 try: extraction_timeout = int( get_setting_fn("research_extraction_timeout_seconds", 90) or 90 ) - except (TypeError, ValueError): + except (TypeError, ValueError, OverflowError): extraction_timeout = 90 try: extraction_concurrency = int( get_setting_fn("research_extraction_concurrency", 3) or 3 ) - except (TypeError, ValueError): + except (TypeError, ValueError, OverflowError): extraction_concurrency = 3 return max_tokens, extraction_timeout, extraction_concurrency diff --git a/tests/test_scheduler_research_settings_guard.py b/tests/test_scheduler_research_settings_guard.py index 0cdfa2b87..a6448fc9c 100644 --- a/tests/test_scheduler_research_settings_guard.py +++ b/tests/test_scheduler_research_settings_guard.py @@ -15,6 +15,8 @@ same reads defensively; this is the scheduler's equivalent. from __future__ import annotations +import json + from src.task_scheduler import _resolve_research_settings @@ -77,3 +79,24 @@ def test_valid_ints_pass_through(): ) assert _resolve_research_settings(get) == (2048, 120, 6) + + +def test_non_finite_json_numbers_fall_back_individually(): + """JSON exponent overflow produces infinity, which int() cannot convert.""" + keys = ( + "research_max_tokens", + "research_extraction_timeout_seconds", + "research_extraction_concurrency", + ) + valid = (4096, 45, 2) + defaults = (8192, 90, 3) + + for non_finite in (json.loads("1e309"), json.loads("-1e309")): + for index, key in enumerate(keys): + values = dict(zip(keys, valid)) + values[key] = non_finite + expected = list(valid) + expected[index] = defaults[index] + assert _resolve_research_settings( + _fake_get_setting(values) + ) == tuple(expected)