From 8bbd1ff10d220f839b635426bf39e7b1f9d507ce Mon Sep 17 00:00:00 2001 From: jerry Date: Thu, 2 Jul 2026 15:29:46 -0400 Subject: [PATCH 1/2] remove temperature from kwargs if a related error is raised --- forecasting_tools/ai_models/general_llm.py | 59 +++++++++++++++++----- 1 file changed, 46 insertions(+), 13 deletions(-) diff --git a/forecasting_tools/ai_models/general_llm.py b/forecasting_tools/ai_models/general_llm.py index d6e8d44f..e4800af5 100644 --- a/forecasting_tools/ai_models/general_llm.py +++ b/forecasting_tools/ai_models/general_llm.py @@ -269,19 +269,7 @@ async def _mockable_direct_call_to_model( litellm.drop_params = True with MonetaryCostManager(1) as cost_manager: - if self.responses_api: - original_response = await aresponses( - input=self.model_input_to_message(prompt), # type: ignore # NOTE: This might only accept the last message in the list? - **self.litellm_kwargs, - ) - assert isinstance(original_response, ResponsesAPIResponse) - response = self._normalize_response(original_response, ModelResponse()) - # Simpler method might be just grabbing last message in choices `response.output[-1].content[0].text` - else: - response = await acompletion( - messages=self.model_input_to_message(prompt), - **self.litellm_kwargs, - ) + response = await self._call_litellm_dropping_deprecated_temperature(prompt) call_back_cost = cost_manager.current_usage assert isinstance(response, ModelResponse) @@ -357,6 +345,51 @@ async def _mockable_direct_call_to_model( return response + async def _call_litellm_dropping_deprecated_temperature( + self, prompt: ModelInputType + ) -> ModelResponse: + try: + return await self._call_litellm(prompt) + except litellm.BadRequestError as error: + if not self._is_deprecated_temperature_error(error): + raise + if "temperature" not in self.litellm_kwargs: + raise + logger.warning( + f"Model {self.model} rejected the 'temperature' parameter as deprecated/unsupported. " + f"Dropping it and retrying (this llm will no longer send temperature)." + ) + self.litellm_kwargs.pop("temperature", None) + return await self._call_litellm(prompt) + + async def _call_litellm(self, prompt: ModelInputType) -> ModelResponse: + if self.responses_api: + original_response = await aresponses( + input=self.model_input_to_message(prompt), # type: ignore # NOTE: This might only accept the last message in the list? + **self.litellm_kwargs, + ) + assert isinstance(original_response, ResponsesAPIResponse) + # Simpler method might be just grabbing last message in choices `response.output[-1].content[0].text` + return self._normalize_response(original_response, ModelResponse()) + response = await acompletion( + messages=self.model_input_to_message(prompt), + **self.litellm_kwargs, + ) + assert isinstance(response, ModelResponse) + return response + + @staticmethod + def _is_deprecated_temperature_error(error: Exception) -> bool: + message = str(error).lower() + mentions_temperature = "temperature" in message + is_unsupported = ( + "deprecated" in message + or "not supported" in message + or "unsupported" in message + or "does not support" in message + ) + return mentions_temperature and is_unsupported + def _answer_from_reasoning_content(self, message: Message) -> str | None: reasoning_content = getattr(message, "reasoning_content", None) if isinstance(reasoning_content, str) and reasoning_content: From 8aecca28daf0915c51867efa2a616d8303eeac57 Mon Sep 17 00:00:00 2001 From: jerry Date: Thu, 2 Jul 2026 16:27:03 -0400 Subject: [PATCH 2/2] remove temp kwarg for sonnet 5 and fable --- run_bots.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/run_bots.py b/run_bots.py index 36a94e02..e735cbfd 100644 --- a/run_bots.py +++ b/run_bots.py @@ -624,7 +624,7 @@ def get_default_bot_dict() -> dict[str, RunBotConfig]: # NOSONAR "bot": create_bot( llm=GeneralLlm( model="anthropic/claude-sonnet-5", - temperature=default_temperature, + temperature=None, ), ), "tournaments": TournConfig.aib_and_site, @@ -659,7 +659,7 @@ def get_default_bot_dict() -> dict[str, RunBotConfig]: # NOSONAR "bot": create_bot( llm=GeneralLlm( model="anthropic/claude-fable-5", - temperature=default_temperature, + temperature=None, ), bot_type="no_research_one_shot", ), @@ -713,7 +713,11 @@ def get_default_bot_dict() -> dict[str, RunBotConfig]: # NOSONAR "bot": create_bot( llm=GeneralLlm( model="anthropic/claude-fable-5", - **claude_adaptive_thinking_settings_high, + **{ + k: v + for k, v in claude_adaptive_thinking_settings_high.items() + if k != "temperature" + }, ), ), "tournaments": TournConfig.aib_and_site + [AllowedTourn.METACULUS_CUP],