mirror of
https://github.com/dgtlmoon/changedetection.io.git
synced 2026-07-08 08:21:14 +00:00
LLM: strip sampling params and retry when the model rejects them (#4241)
Build and push containers / metadata (push) Has been cancelled
Build and push containers / build-push-containers (push) Has been cancelled
Publish Python 🐍distribution 📦 to PyPI and TestPyPI / Build distribution 📦 (push) Has been cancelled
ChangeDetection.io App Test / lint-code (push) Has been cancelled
ChangeDetection.io App Test / lint-translations (push) Has been cancelled
ChangeDetection.io App Test / lint-template-i18n (push) Has been cancelled
Publish Python 🐍distribution 📦 to PyPI and TestPyPI / Test the built package works basically. (push) Has been cancelled
Publish Python 🐍distribution 📦 to PyPI and TestPyPI / Publish Python 🐍 distribution 📦 to PyPI (push) Has been cancelled
ChangeDetection.io App Test / test-application-3-10 (push) Has been cancelled
ChangeDetection.io App Test / test-application-3-11 (push) Has been cancelled
ChangeDetection.io App Test / test-application-3-12 (push) Has been cancelled
ChangeDetection.io App Test / test-application-3-13 (push) Has been cancelled
ChangeDetection.io App Test / test-application-3-14 (push) Has been cancelled
Build and push containers / metadata (push) Has been cancelled
Build and push containers / build-push-containers (push) Has been cancelled
Publish Python 🐍distribution 📦 to PyPI and TestPyPI / Build distribution 📦 (push) Has been cancelled
ChangeDetection.io App Test / lint-code (push) Has been cancelled
ChangeDetection.io App Test / lint-translations (push) Has been cancelled
ChangeDetection.io App Test / lint-template-i18n (push) Has been cancelled
Publish Python 🐍distribution 📦 to PyPI and TestPyPI / Test the built package works basically. (push) Has been cancelled
Publish Python 🐍distribution 📦 to PyPI and TestPyPI / Publish Python 🐍 distribution 📦 to PyPI (push) Has been cancelled
ChangeDetection.io App Test / test-application-3-10 (push) Has been cancelled
ChangeDetection.io App Test / test-application-3-11 (push) Has been cancelled
ChangeDetection.io App Test / test-application-3-12 (push) Has been cancelled
ChangeDetection.io App Test / test-application-3-13 (push) Has been cancelled
ChangeDetection.io App Test / test-application-3-14 (push) Has been cancelled
This commit is contained in:
@@ -90,13 +90,24 @@ def completion(model: str, messages: list, api_key: str = None,
|
||||
|
||||
_retryable = (litellm.Timeout, litellm.APIConnectionError)
|
||||
|
||||
# Some models reject sampling params outright: Anthropic Claude Opus 4.7/4.8 and
|
||||
# Fable return HTTP 400 for 'temperature', and OpenAI reasoning models (o1/o3/gpt-5)
|
||||
# only accept the default. litellm's per-model param metadata lags new releases, so
|
||||
# drop_params can't be relied on for freshly released models — instead, if the provider
|
||||
# rejects a sampling param, strip them and retry once. Models that accept them are
|
||||
# unaffected (they still receive temperature=0).
|
||||
_sampling_params = ('temperature', 'top_p', 'top_k')
|
||||
_stripped_sampling = False
|
||||
|
||||
logger.debug(
|
||||
f"LLM client: calling model={model!r} api_base={api_base!r} "
|
||||
f"timeout={_timeout}s max_tokens={kwargs['max_tokens']}"
|
||||
)
|
||||
logger.trace(messages)
|
||||
|
||||
for attempt in range(1, DEFAULT_RETRIES + 1):
|
||||
attempt = 0
|
||||
while attempt < DEFAULT_RETRIES:
|
||||
attempt += 1
|
||||
try:
|
||||
response = litellm.completion(**kwargs)
|
||||
choice = response.choices[0]
|
||||
@@ -157,6 +168,25 @@ def completion(model: str, messages: list, api_key: str = None,
|
||||
)
|
||||
raise
|
||||
|
||||
except litellm.BadRequestError as e:
|
||||
# If the provider rejected an unsupported sampling param (and we haven't
|
||||
# already stripped them), drop them and retry once. attempt-=1 keeps this
|
||||
# off the timeout-retry budget; _stripped_sampling prevents a loop.
|
||||
msg = str(e).lower()
|
||||
if (not _stripped_sampling
|
||||
and any(p in kwargs for p in _sampling_params)
|
||||
and any(p in msg for p in _sampling_params)):
|
||||
dropped = [p for p in _sampling_params if kwargs.pop(p, None) is not None]
|
||||
_stripped_sampling = True
|
||||
attempt -= 1
|
||||
logger.warning(
|
||||
f"LLM client: model={model!r} rejected sampling params {dropped} "
|
||||
f"({e}); retrying without them"
|
||||
)
|
||||
continue
|
||||
logger.warning(f"LLM call failed: model={model!r} error={e}")
|
||||
raise
|
||||
|
||||
except Exception as e:
|
||||
logger.warning(f"LLM call failed: model={model!r} error={e}")
|
||||
raise
|
||||
|
||||
Reference in New Issue
Block a user