diff --git a/backend/src/plugins/llm_analysis/service.py b/backend/src/plugins/llm_analysis/service.py index 5c4ca40a..70bebe54 100644 --- a/backend/src/plugins/llm_analysis/service.py +++ b/backend/src/plugins/llm_analysis/service.py @@ -935,18 +935,15 @@ class LLMClient: # @PRE Client initialized with base_url and default_model. # @POST Returns False for known-incompatible combinations to avoid avoidable 400 errors. def _supports_json_response_format(self) -> bool: - base = (self.base_url or "").lower() model = (self.default_model or "").lower() - # OpenRouter routes to many upstream providers; some models reject json_object mode. - if "openrouter.ai" in base: - incompatible_tokens = ( - "stepfun/", - "step-", - ":free", - ) - if any(token in model for token in incompatible_tokens): - return False + # Free-tier models from ANY gateway often reject json_object mode + # (Nvidia NeMo free via OpenRouter or Kilo, stepfun free, etc.) + if ":free" in model: + return False + # stepfun models (even non-free) don't support json_object mode + if "stepfun/" in model or model.startswith("step-"): + return False return True # endregion LLMClient._supports_json_response_format