From b7bb67fac4dd384448e3a4cd20e64f799ff87bea Mon Sep 17 00:00:00 2001 From: dgtlmoon Date: Mon, 25 May 2026 18:03:11 +0200 Subject: [PATCH] LLM - Smarter reasoning budget logic for gemini models --- changedetectionio/llm/evaluator.py | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/changedetectionio/llm/evaluator.py b/changedetectionio/llm/evaluator.py index f59a07de..0c6b6c94 100644 --- a/changedetectionio/llm/evaluator.py +++ b/changedetectionio/llm/evaluator.py @@ -82,10 +82,23 @@ def _check_input_size(text: str, max_chars: int) -> None: def _thinking_extra_body(model: str, budget: int) -> dict | None: """Return litellm extra_body to control thinking for models that support it. - For Gemini 2.5+: passes thinkingConfig with the given budget (0 = disabled). - For all other models: returns None (no-op). + + The `thinkingConfig.thinkingBudget` payload is Gemini-specific (Anthropic and + OpenAI reasoning models use different parameters), so we gate on the gemini/ + provider prefix first, then defer to litellm's model registry for the actual + "does this model think?" decision. That picks up new Gemini variants and + rolling aliases (`gemini-flash-latest`, etc.) as litellm's registry tracks + them, without us hardcoding model names here. """ - if not model.startswith('gemini/gemini-2.5'): + if not model.startswith('gemini/'): + return None + try: + import litellm + if not litellm.get_model_info(model).get('supports_reasoning'): + return None + except Exception: + # Unknown model or registry lookup failed — skip the thinking config + # rather than guess. Worst case: thinking stays at the provider default. return None return {'generationConfig': {'thinkingConfig': {'thinkingBudget': budget}}}