diff --git a/changedetectionio/blueprint/settings/__init__.py b/changedetectionio/blueprint/settings/__init__.py index 74af6b712..2f027bba6 100644 --- a/changedetectionio/blueprint/settings/__init__.py +++ b/changedetectionio/blueprint/settings/__init__.py @@ -41,6 +41,7 @@ def construct_blueprint(datastore: ChangeDetectionStore): 'llm_change_summary_default': datastore.data['settings']['application'].get('llm_change_summary_default', ''), 'llm_override_diff_with_summary': datastore.data['settings']['application'].get('llm_override_diff_with_summary', True), 'llm_restock_use_fallback_extract': datastore.data['settings']['application'].get('llm_restock_use_fallback_extract', True), + 'llm_debug': datastore.data['settings']['application'].get('llm_debug', False), 'llm_budget_action': datastore.data['settings']['application'].get('llm_budget_action', 'skip_llm'), 'llm_thinking_budget': str(datastore.data['settings']['application'].get('llm_thinking_budget', 0)), 'llm_max_summary_tokens': str(datastore.data['settings']['application'].get('llm_max_summary_tokens', 3000)), @@ -125,6 +126,9 @@ def construct_blueprint(datastore: ChangeDetectionStore): datastore.data['settings']['application']['llm_restock_use_fallback_extract'] = ( bool(llm_data.get('llm_restock_use_fallback_extract', True)) ) + datastore.data['settings']['application']['llm_debug'] = ( + bool(llm_data.get('llm_debug', False)) + ) datastore.data['settings']['application']['llm_budget_action'] = ( llm_data.get('llm_budget_action') or 'skip_llm' ) diff --git a/changedetectionio/blueprint/settings/llm.py b/changedetectionio/blueprint/settings/llm.py index a027d7516..35392d202 100644 --- a/changedetectionio/blueprint/settings/llm.py +++ b/changedetectionio/blueprint/settings/llm.py @@ -113,23 +113,43 @@ def construct_llm_blueprint(datastore: ChangeDetectionStore): @llm_blueprint.route("/test", methods=['GET']) @login_optionally_required def llm_test(): + from flask import request from changedetectionio.llm.client import completion - llm_cfg = datastore.data['settings']['application'].get('llm') or {} - model = llm_cfg.get('model', '').strip() - api_base = llm_cfg.get('api_base', '') or '' + # Pull stored config as the fallback, then override with anything the + # form-driven JS sent as query params. Lets users test config changes + # without first hitting Save (matching how /settings/llm/models works). + stored = datastore.data['settings']['application'].get('llm') or {} + llm_cfg = { + 'model': (request.args.get('model') or stored.get('model', '')).strip(), + 'api_key': (request.args.get('api_key') or stored.get('api_key', '')).strip(), + 'api_base': (request.args.get('api_base') or stored.get('api_base', '')).strip(), + 'provider_kind': (request.args.get('provider_kind') or stored.get('provider_kind', '')).strip(), + 'local_token_multiplier': request.args.get('local_token_multiplier') or stored.get('local_token_multiplier'), + } + model = llm_cfg['model'] + api_base = llm_cfg['api_base'] - logger.debug(f"LLM connection test requested: model={model!r} api_base={api_base!r}") + logger.debug( + f"LLM connection test requested: model={model!r} api_base={api_base!r} " + f"provider_kind={llm_cfg['provider_kind']!r} " + f"source={'form' if request.args.get('model') else 'datastore'}" + ) if not model: - logger.error("LLM connection test failed: no model configured in datastore") + logger.error("LLM connection test failed: no model configured") return jsonify({'ok': False, 'error': 'No model configured.'}), 400 try: logger.debug(f"LLM connection test: sending test prompt to model={model!r}") # Reuse the same multiplier path the production calls use, so cloud providers # stay on a small base cap (matching upstream's pre-existing behavior) and only - # 'openai_compatible' endpoints opt into the reasoning-friendly headroom. + # reasoning-capable endpoints (Ollama, openai_compatible) opt into the extra + # headroom needed for chain-of-thought to complete. + # Timeout: omit the override so the test inherits DEFAULT_TIMEOUT (60s, tunable + # via LLM_TIMEOUT). A shorter test-only timeout falsely fails on cold-starting + # cloud reasoning models (e.g. ollama.com hosting qwen3.5:397b takes ~60s on + # first hit) even though the same call succeeds in production. from changedetectionio.llm.evaluator import apply_local_token_multiplier text, total_tokens, input_tokens, output_tokens = completion( model=model, @@ -137,8 +157,8 @@ def construct_llm_blueprint(datastore: ChangeDetectionStore): 'Respond with just the word: ready'}], api_key=llm_cfg.get('api_key') or None, api_base=api_base or None, - timeout=30, max_tokens=apply_local_token_multiplier(200, llm_cfg), + debug=bool(datastore.data['settings']['application'].get('llm_debug', False)), ) reply = text.strip() if not reply: diff --git a/changedetectionio/blueprint/settings/templates/settings_llm_tab.html b/changedetectionio/blueprint/settings/templates/settings_llm_tab.html index f53097528..38074337e 100644 --- a/changedetectionio/blueprint/settings/templates/settings_llm_tab.html +++ b/changedetectionio/blueprint/settings/templates/settings_llm_tab.html @@ -123,14 +123,15 @@ {# Hidden field carrying the dropdown selection so the backend knows when to apply - reasoning-friendly token caps (only for self-hosted OpenAI-compatible endpoints). #} + reasoning-friendly token caps (Ollama and OpenAI-compatible endpoints, which commonly + serve reasoning models that need headroom for chain-of-thought to complete). #} {{ form.llm.form.llm_provider_kind() }} @@ -201,6 +202,17 @@ {{ _('Removes all cached AI change summaries across all watches. They will be regenerated on the next check.') }} + +
+ + {{ form.llm.form.llm_debug() }} + + + {{ _('Enables litellm verbose output (routed through loguru). Useful when diagnosing provider errors or empty responses. Leave off in production — generates a lot of log volume.') }} + +
{% endif %}{# llm_env_configured #} {% if not llm_env_configured and not (llm_config and llm_config.get('model')) %} @@ -417,13 +429,14 @@ } // Persist the dropdown selection so the backend can branch on provider kind - // (currently only 'openai_compatible' triggers the local-multiplier code path). + // (self-hosted endpoints — 'ollama' and 'openai_compatible' — trigger the + // local-multiplier code path; cloud providers do not). if (kindField) kindField.value = provider || ''; - // Show the local-endpoint advanced settings (token multiplier) only for the - // OpenAI-compatible self-hosted option. Cloud providers and Ollama get the - // original tight caps and don't see this section at all. - if (localAdvGrp) localAdvGrp.style.display = (provider === 'openai_compatible') ? '' : 'none'; + // Show the local-endpoint advanced settings (token multiplier) for self-hosted + // endpoints. Cloud providers get the original tight caps and don't see this + // section at all. + if (localAdvGrp) localAdvGrp.style.display = (provider === 'ollama' || provider === 'openai_compatible') ? '' : 'none'; hint.textContent = KEY_HINTS[provider] || ''; modelSelGrp.style.display = 'none'; @@ -502,8 +515,23 @@ btn.textContent = '⏳ {{ _("Testing…") }}'; result.style.display = 'none'; + // Send the form's current values so the user doesn't have to hit Save before + // testing a config change. Endpoint falls back to the stored datastore values + // for any field we don't send. + const params = new URLSearchParams(); + const model = (document.querySelector('[name="llm-llm_model"]') || {}).value || ''; + const apiKey = (document.querySelector('[name="llm-llm_api_key"]') || {}).value || ''; + const apiBase = (document.querySelector('[name="llm-llm_api_base"]') || {}).value || ''; + const kind = (document.querySelector('[name="llm-llm_provider_kind"]') || {}).value || ''; + const mult = (document.querySelector('[name="llm-llm_local_token_multiplier"]') || {}).value || ''; + if (model.trim()) params.set('model', model.trim()); + if (apiKey.trim()) params.set('api_key', apiKey.trim()); + if (apiBase.trim()) params.set('api_base', apiBase.trim()); + if (kind.trim()) params.set('provider_kind', kind.trim()); + if (mult.trim()) params.set('local_token_multiplier', mult.trim()); + try { - const resp = await fetch('{{ url_for("settings.llm.llm_test") }}'); + const resp = await fetch('{{ url_for("settings.llm.llm_test") }}?' + params); const data = await resp.json(); if (data.ok) { result.style.cssText = 'display:block; background:rgba(39,174,96,0.08); border:1px solid rgba(39,174,96,0.3); border-radius:5px; padding:0.6em 0.85em; font-size:0.88em; line-height:1.45;'; @@ -519,7 +547,7 @@ result.innerHTML = '✗ {{ _("Request failed") }}: ' + e.message.replace(/ tuple[str, int, int, int]: + max_tokens: int = None, extra_body: dict = None, + debug: bool = False) -> tuple[str, int, int, int]: """ Call the LLM and return (response_text, total_tokens, input_tokens, output_tokens). Retries up to DEFAULT_RETRIES times on timeout or connection errors. @@ -31,6 +69,9 @@ def completion(model: str, messages: list, api_key: str = None, except ImportError: raise RuntimeError("litellm is not installed. Add it to requirements.txt.") + if debug: + _install_litellm_debug() + _timeout = timeout if timeout is not None else DEFAULT_TIMEOUT kwargs = { @@ -49,7 +90,10 @@ def completion(model: str, messages: list, api_key: str = None, _retryable = (litellm.Timeout, litellm.APIConnectionError) - logger.trace("Sending payload to LLM.. ") + 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): diff --git a/changedetectionio/llm/evaluator.py b/changedetectionio/llm/evaluator.py index 7502dabe7..618fa9703 100644 --- a/changedetectionio/llm/evaluator.py +++ b/changedetectionio/llm/evaluator.py @@ -120,22 +120,25 @@ def _summary_max_tokens(diff: str, max_cap: int = LLM_DEFAULT_MAX_SUMMARY_TOKENS def apply_local_token_multiplier(base_max_tokens: int, llm_cfg: dict) -> int: """ - Scale max_tokens for self-hosted OpenAI-compatible endpoints (vLLM, LM Studio, llama.cpp). + Scale max_tokens for endpoints that commonly serve reasoning models + (Ollama — self-hosted or ollama.com cloud — and OpenAI-compatible servers like + vLLM, LM Studio, llama.cpp). Reasoning models (Qwen3, DeepSeek-R1, Gemma 3, etc.) emit chain-of-thought into `message.reasoning_content` BEFORE the final answer lands in `message.content`. - Without enough headroom the request truncates mid-thought (`finish_reason='length'`) - and the answer never lands — callers see an empty string and silently fall through - to safe defaults, hiding the problem. + Without enough headroom the request truncates mid-thought (`finish_reason='length'` + or `'stop'` with empty content) and the answer never lands — callers see an empty + string and silently fall through to safe defaults, hiding the problem. - Local self-hosted models cost no per-token money, so headroom is cheap; cloud - providers (OpenAI, Anthropic, Gemini, OpenRouter) keep their original tight caps - so existing users see no cost change. + Cloud providers with stable, non-reasoning defaults (OpenAI, Anthropic, Gemini, + OpenRouter) keep their original tight caps so existing users see no behavior or + cost change. Ollama / OpenAI-compatible users can dial the multiplier down to 1x + in Settings → AI → Provider if they want to keep costs tight on a paid endpoint. - Activated only when `llm_cfg['provider_kind'] == 'openai_compatible'`. + Activated when `llm_cfg['provider_kind']` is `'ollama'` or `'openai_compatible'`. Multiplier defaults to 5x and is user-configurable in Settings → AI → Provider. """ - if (llm_cfg or {}).get('provider_kind') != 'openai_compatible': + if (llm_cfg or {}).get('provider_kind') not in ('ollama', 'openai_compatible'): return base_max_tokens try: multiplier = int(llm_cfg.get('local_token_multiplier') or 5) @@ -399,6 +402,7 @@ def run_setup(watch, datastore, snapshot_text: str) -> None: api_base=cfg.get('api_base'), max_tokens=apply_local_token_multiplier(JSON_RESPONSE_MAX_TOKENS, cfg), extra_body=_thinking_extra_body(cfg['model'], int(datastore.data['settings']['application'].get('llm_thinking_budget', LLM_DEFAULT_THINKING_BUDGET) or 0)), + debug=bool(datastore.data['settings']['application'].get('llm_debug', False)), ) _check_token_budget(watch, cfg, tokens) accumulate_global_tokens(datastore, tokens, model=cfg['model']) @@ -472,7 +476,7 @@ class DiffPrefs: def build_summary_cache_prompt(effective_prompt: str, max_summary_tokens: int, - prefs: DiffPrefs = None) -> str: + prefs: DiffPrefs = None, model: str = '') -> str: """ Compose the full cache-key string passed to save/get_llm_diff_summary. @@ -480,6 +484,10 @@ def build_summary_cache_prompt(effective_prompt: str, max_summary_tokens: int, worker-side pre-cache is hit by an unmodified UI request. Same helper must be used by both the worker pre-cache write and the UI diff route read, otherwise the prompt hashes diverge and the cache file isn't found. + + The active model name is folded into the key so switching models + (e.g. qwen3 → gpt-4o) invalidates stale summaries that were generated + by a different model with potentially different phrasing/quality. """ if prefs is None: prefs = DiffPrefs() @@ -488,6 +496,7 @@ def build_summary_cache_prompt(effective_prompt: str, max_summary_tokens: int, + prefs.cache_key_suffix() + f'\x00sys:{build_change_summary_system_prompt()}' + f'\x00max_tokens:{max_summary_tokens}' + + f'\x00model:{model}' ) @@ -551,6 +560,7 @@ def summarise_change(watch, datastore, diff: str, current_snapshot: str = '') -> cfg, ), extra_body=_extra_body, + debug=bool(datastore.data['settings']['application'].get('llm_debug', False)), ) raw, tokens = _resp[0], _resp[1] input_tokens = _resp[2] if len(_resp) > 2 else 0 @@ -613,6 +623,7 @@ def preview_extract(watch, datastore, content: str) -> dict | None: api_base=cfg.get('api_base'), max_tokens=apply_local_token_multiplier(JSON_RESPONSE_MAX_TOKENS, cfg), extra_body=_thinking_extra_body(cfg['model'], int(datastore.data['settings']['application'].get('llm_thinking_budget', LLM_DEFAULT_THINKING_BUDGET) or 0)), + debug=bool(datastore.data['settings']['application'].get('llm_debug', False)), ) accumulate_global_tokens(datastore, tokens, model=cfg['model']) result = parse_preview_response(raw) @@ -697,6 +708,7 @@ def evaluate_change(watch, datastore, diff: str, current_snapshot: str = '') -> api_base=cfg.get('api_base'), max_tokens=apply_local_token_multiplier(JSON_RESPONSE_MAX_TOKENS, cfg), extra_body=_thinking_extra_body(cfg['model'], int(datastore.data['settings']['application'].get('llm_thinking_budget', LLM_DEFAULT_THINKING_BUDGET) or 0)), + debug=bool(datastore.data['settings']['application'].get('llm_debug', False)), ) raw, tokens = _resp[0], _resp[1] input_tokens = _resp[2] if len(_resp) > 2 else 0 diff --git a/changedetectionio/processors/text_json_diff/difference.py b/changedetectionio/processors/text_json_diff/difference.py index d712e315d..c5e9ee985 100644 --- a/changedetectionio/processors/text_json_diff/difference.py +++ b/changedetectionio/processors/text_json_diff/difference.py @@ -218,9 +218,11 @@ def render(watch, datastore, request, url_for, render_template, flash, redirect, # Must match the cache_prompt the worker writes and the UI ajax route reads — # using UI default diff prefs so the initial render finds the worker's pre-cache. _max_summary_tokens = datastore.data['settings']['application'].get('llm_max_summary_tokens', 3000) + _llm_model = (datastore.data['settings']['application'].get('llm') or {}).get('model', '') _cache_prompt = build_summary_cache_prompt( effective_prompt=_prompt, max_summary_tokens=_max_summary_tokens, + model=_llm_model, ) llm_diff_summary = watch.get_llm_diff_summary(from_version, to_version, prompt=_cache_prompt) except Exception as e: diff --git a/changedetectionio/translations/cs/LC_MESSAGES/messages.po b/changedetectionio/translations/cs/LC_MESSAGES/messages.po index 5222742cd..94ee6229b 100644 --- a/changedetectionio/translations/cs/LC_MESSAGES/messages.po +++ b/changedetectionio/translations/cs/LC_MESSAGES/messages.po @@ -906,10 +906,11 @@ msgstr "" #: changedetectionio/blueprint/settings/templates/settings_llm_tab.html #, python-format msgid "" -"Local reasoning models (Qwen3, DeepSeek-R1, Gemma 3, etc.) emit chain-of-thought before the final answer. This " -"multiplier scales every max_tokens cap for this endpoint to leave reasoning room. Defaults to " -"%(default)s; raise it if responses come back truncated, lower it if you want tighter limits. Only applied to self-" -"hosted OpenAI-compatible endpoints — cloud providers (OpenAI, Anthropic, Gemini) keep their original tight caps." +"Reasoning models (Qwen3, DeepSeek-R1, Gemma 3, etc.) emit chain-of-thought before the final answer. This multiplier " +"scales every max_tokens cap for this endpoint to leave reasoning room. Defaults to %(default)s; raise it" +" if responses come back truncated or empty, lower it (down to 1x) if you want tighter limits on a paid endpoint. " +"Applied to Ollama and OpenAI-compatible endpoints — other cloud providers (OpenAI, Anthropic, Gemini) keep their " +"original tight caps." msgstr "" #: changedetectionio/blueprint/settings/templates/settings_llm_tab.html @@ -983,6 +984,12 @@ msgstr "" msgid "Removes all cached AI change summaries across all watches. They will be regenerated on the next check." msgstr "" +#: changedetectionio/blueprint/settings/templates/settings_llm_tab.html +msgid "" +"Enables litellm verbose output (routed through loguru). Useful when diagnosing provider errors or empty responses. " +"Leave off in production — generates a lot of log volume." +msgstr "" + #: changedetectionio/blueprint/settings/templates/settings_llm_tab.html msgid "Default AI Change Summary" msgstr "" @@ -3173,6 +3180,10 @@ msgstr "" msgid "Use LLM as a fallback for extracting price and restock info" msgstr "" +#: changedetectionio/forms.py +msgid "Enable LLM debug logging" +msgstr "" + #: changedetectionio/forms.py msgid "AI thinking budget (tokens)" msgstr "AI pracovní rozpočet (tokeny)" diff --git a/changedetectionio/translations/de/LC_MESSAGES/messages.po b/changedetectionio/translations/de/LC_MESSAGES/messages.po index 6a7985bd5..56057920a 100644 --- a/changedetectionio/translations/de/LC_MESSAGES/messages.po +++ b/changedetectionio/translations/de/LC_MESSAGES/messages.po @@ -922,10 +922,11 @@ msgstr "" #: changedetectionio/blueprint/settings/templates/settings_llm_tab.html #, python-format msgid "" -"Local reasoning models (Qwen3, DeepSeek-R1, Gemma 3, etc.) emit chain-of-thought before the final answer. This " -"multiplier scales every max_tokens cap for this endpoint to leave reasoning room. Defaults to " -"%(default)s; raise it if responses come back truncated, lower it if you want tighter limits. Only applied to self-" -"hosted OpenAI-compatible endpoints — cloud providers (OpenAI, Anthropic, Gemini) keep their original tight caps." +"Reasoning models (Qwen3, DeepSeek-R1, Gemma 3, etc.) emit chain-of-thought before the final answer. This multiplier " +"scales every max_tokens cap for this endpoint to leave reasoning room. Defaults to %(default)s; raise it" +" if responses come back truncated or empty, lower it (down to 1x) if you want tighter limits on a paid endpoint. " +"Applied to Ollama and OpenAI-compatible endpoints — other cloud providers (OpenAI, Anthropic, Gemini) keep their " +"original tight caps." msgstr "" #: changedetectionio/blueprint/settings/templates/settings_llm_tab.html @@ -999,6 +1000,12 @@ msgstr "" msgid "Removes all cached AI change summaries across all watches. They will be regenerated on the next check." msgstr "" +#: changedetectionio/blueprint/settings/templates/settings_llm_tab.html +msgid "" +"Enables litellm verbose output (routed through loguru). Useful when diagnosing provider errors or empty responses. " +"Leave off in production — generates a lot of log volume." +msgstr "" + #: changedetectionio/blueprint/settings/templates/settings_llm_tab.html msgid "Default AI Change Summary" msgstr "" @@ -3225,6 +3232,10 @@ msgstr "" msgid "Use LLM as a fallback for extracting price and restock info" msgstr "" +#: changedetectionio/forms.py +msgid "Enable LLM debug logging" +msgstr "" + #: changedetectionio/forms.py msgid "AI thinking budget (tokens)" msgstr "" diff --git a/changedetectionio/translations/en_GB/LC_MESSAGES/messages.po b/changedetectionio/translations/en_GB/LC_MESSAGES/messages.po index 8f0fafec4..2d830e9a5 100644 --- a/changedetectionio/translations/en_GB/LC_MESSAGES/messages.po +++ b/changedetectionio/translations/en_GB/LC_MESSAGES/messages.po @@ -904,10 +904,11 @@ msgstr "" #: changedetectionio/blueprint/settings/templates/settings_llm_tab.html #, python-format msgid "" -"Local reasoning models (Qwen3, DeepSeek-R1, Gemma 3, etc.) emit chain-of-thought before the final answer. This " -"multiplier scales every max_tokens cap for this endpoint to leave reasoning room. Defaults to " -"%(default)s; raise it if responses come back truncated, lower it if you want tighter limits. Only applied to self-" -"hosted OpenAI-compatible endpoints — cloud providers (OpenAI, Anthropic, Gemini) keep their original tight caps." +"Reasoning models (Qwen3, DeepSeek-R1, Gemma 3, etc.) emit chain-of-thought before the final answer. This multiplier " +"scales every max_tokens cap for this endpoint to leave reasoning room. Defaults to %(default)s; raise it" +" if responses come back truncated or empty, lower it (down to 1x) if you want tighter limits on a paid endpoint. " +"Applied to Ollama and OpenAI-compatible endpoints — other cloud providers (OpenAI, Anthropic, Gemini) keep their " +"original tight caps." msgstr "" #: changedetectionio/blueprint/settings/templates/settings_llm_tab.html @@ -981,6 +982,12 @@ msgstr "" msgid "Removes all cached AI change summaries across all watches. They will be regenerated on the next check." msgstr "" +#: changedetectionio/blueprint/settings/templates/settings_llm_tab.html +msgid "" +"Enables litellm verbose output (routed through loguru). Useful when diagnosing provider errors or empty responses. " +"Leave off in production — generates a lot of log volume." +msgstr "" + #: changedetectionio/blueprint/settings/templates/settings_llm_tab.html msgid "Default AI Change Summary" msgstr "" @@ -3167,6 +3174,10 @@ msgstr "" msgid "Use LLM as a fallback for extracting price and restock info" msgstr "" +#: changedetectionio/forms.py +msgid "Enable LLM debug logging" +msgstr "" + #: changedetectionio/forms.py msgid "AI thinking budget (tokens)" msgstr "" diff --git a/changedetectionio/translations/en_US/LC_MESSAGES/messages.po b/changedetectionio/translations/en_US/LC_MESSAGES/messages.po index 25fa13542..f3f3a3a8b 100644 --- a/changedetectionio/translations/en_US/LC_MESSAGES/messages.po +++ b/changedetectionio/translations/en_US/LC_MESSAGES/messages.po @@ -904,10 +904,11 @@ msgstr "" #: changedetectionio/blueprint/settings/templates/settings_llm_tab.html #, python-format msgid "" -"Local reasoning models (Qwen3, DeepSeek-R1, Gemma 3, etc.) emit chain-of-thought before the final answer. This " -"multiplier scales every max_tokens cap for this endpoint to leave reasoning room. Defaults to " -"%(default)s; raise it if responses come back truncated, lower it if you want tighter limits. Only applied to self-" -"hosted OpenAI-compatible endpoints — cloud providers (OpenAI, Anthropic, Gemini) keep their original tight caps." +"Reasoning models (Qwen3, DeepSeek-R1, Gemma 3, etc.) emit chain-of-thought before the final answer. This multiplier " +"scales every max_tokens cap for this endpoint to leave reasoning room. Defaults to %(default)s; raise it" +" if responses come back truncated or empty, lower it (down to 1x) if you want tighter limits on a paid endpoint. " +"Applied to Ollama and OpenAI-compatible endpoints — other cloud providers (OpenAI, Anthropic, Gemini) keep their " +"original tight caps." msgstr "" #: changedetectionio/blueprint/settings/templates/settings_llm_tab.html @@ -981,6 +982,12 @@ msgstr "" msgid "Removes all cached AI change summaries across all watches. They will be regenerated on the next check." msgstr "" +#: changedetectionio/blueprint/settings/templates/settings_llm_tab.html +msgid "" +"Enables litellm verbose output (routed through loguru). Useful when diagnosing provider errors or empty responses. " +"Leave off in production — generates a lot of log volume." +msgstr "" + #: changedetectionio/blueprint/settings/templates/settings_llm_tab.html msgid "Default AI Change Summary" msgstr "" @@ -3167,6 +3174,10 @@ msgstr "" msgid "Use LLM as a fallback for extracting price and restock info" msgstr "" +#: changedetectionio/forms.py +msgid "Enable LLM debug logging" +msgstr "" + #: changedetectionio/forms.py msgid "AI thinking budget (tokens)" msgstr "" diff --git a/changedetectionio/translations/es/LC_MESSAGES/messages.po b/changedetectionio/translations/es/LC_MESSAGES/messages.po index dbfd7d70b..d1f14a8ba 100644 --- a/changedetectionio/translations/es/LC_MESSAGES/messages.po +++ b/changedetectionio/translations/es/LC_MESSAGES/messages.po @@ -942,10 +942,11 @@ msgstr "" #: changedetectionio/blueprint/settings/templates/settings_llm_tab.html #, python-format msgid "" -"Local reasoning models (Qwen3, DeepSeek-R1, Gemma 3, etc.) emit chain-of-thought before the final answer. This " -"multiplier scales every max_tokens cap for this endpoint to leave reasoning room. Defaults to " -"%(default)s; raise it if responses come back truncated, lower it if you want tighter limits. Only applied to self-" -"hosted OpenAI-compatible endpoints — cloud providers (OpenAI, Anthropic, Gemini) keep their original tight caps." +"Reasoning models (Qwen3, DeepSeek-R1, Gemma 3, etc.) emit chain-of-thought before the final answer. This multiplier " +"scales every max_tokens cap for this endpoint to leave reasoning room. Defaults to %(default)s; raise it" +" if responses come back truncated or empty, lower it (down to 1x) if you want tighter limits on a paid endpoint. " +"Applied to Ollama and OpenAI-compatible endpoints — other cloud providers (OpenAI, Anthropic, Gemini) keep their " +"original tight caps." msgstr "" #: changedetectionio/blueprint/settings/templates/settings_llm_tab.html @@ -1019,6 +1020,12 @@ msgstr "" msgid "Removes all cached AI change summaries across all watches. They will be regenerated on the next check." msgstr "" +#: changedetectionio/blueprint/settings/templates/settings_llm_tab.html +msgid "" +"Enables litellm verbose output (routed through loguru). Useful when diagnosing provider errors or empty responses. " +"Leave off in production — generates a lot of log volume." +msgstr "" + #: changedetectionio/blueprint/settings/templates/settings_llm_tab.html msgid "Default AI Change Summary" msgstr "" @@ -3240,6 +3247,10 @@ msgstr "" msgid "Use LLM as a fallback for extracting price and restock info" msgstr "" +#: changedetectionio/forms.py +msgid "Enable LLM debug logging" +msgstr "" + #: changedetectionio/forms.py msgid "AI thinking budget (tokens)" msgstr "" diff --git a/changedetectionio/translations/fr/LC_MESSAGES/messages.po b/changedetectionio/translations/fr/LC_MESSAGES/messages.po index 05408acff..1f6d45860 100644 --- a/changedetectionio/translations/fr/LC_MESSAGES/messages.po +++ b/changedetectionio/translations/fr/LC_MESSAGES/messages.po @@ -910,10 +910,11 @@ msgstr "" #: changedetectionio/blueprint/settings/templates/settings_llm_tab.html #, python-format msgid "" -"Local reasoning models (Qwen3, DeepSeek-R1, Gemma 3, etc.) emit chain-of-thought before the final answer. This " -"multiplier scales every max_tokens cap for this endpoint to leave reasoning room. Defaults to " -"%(default)s; raise it if responses come back truncated, lower it if you want tighter limits. Only applied to self-" -"hosted OpenAI-compatible endpoints — cloud providers (OpenAI, Anthropic, Gemini) keep their original tight caps." +"Reasoning models (Qwen3, DeepSeek-R1, Gemma 3, etc.) emit chain-of-thought before the final answer. This multiplier " +"scales every max_tokens cap for this endpoint to leave reasoning room. Defaults to %(default)s; raise it" +" if responses come back truncated or empty, lower it (down to 1x) if you want tighter limits on a paid endpoint. " +"Applied to Ollama and OpenAI-compatible endpoints — other cloud providers (OpenAI, Anthropic, Gemini) keep their " +"original tight caps." msgstr "" #: changedetectionio/blueprint/settings/templates/settings_llm_tab.html @@ -987,6 +988,12 @@ msgstr "" msgid "Removes all cached AI change summaries across all watches. They will be regenerated on the next check." msgstr "" +#: changedetectionio/blueprint/settings/templates/settings_llm_tab.html +msgid "" +"Enables litellm verbose output (routed through loguru). Useful when diagnosing provider errors or empty responses. " +"Leave off in production — generates a lot of log volume." +msgstr "" + #: changedetectionio/blueprint/settings/templates/settings_llm_tab.html msgid "Default AI Change Summary" msgstr "" @@ -3180,6 +3187,10 @@ msgstr "" msgid "Use LLM as a fallback for extracting price and restock info" msgstr "" +#: changedetectionio/forms.py +msgid "Enable LLM debug logging" +msgstr "" + #: changedetectionio/forms.py msgid "AI thinking budget (tokens)" msgstr "" diff --git a/changedetectionio/translations/it/LC_MESSAGES/messages.po b/changedetectionio/translations/it/LC_MESSAGES/messages.po index b7bffe5d2..7ecf8e2a7 100644 --- a/changedetectionio/translations/it/LC_MESSAGES/messages.po +++ b/changedetectionio/translations/it/LC_MESSAGES/messages.po @@ -906,10 +906,11 @@ msgstr "" #: changedetectionio/blueprint/settings/templates/settings_llm_tab.html #, python-format msgid "" -"Local reasoning models (Qwen3, DeepSeek-R1, Gemma 3, etc.) emit chain-of-thought before the final answer. This " -"multiplier scales every max_tokens cap for this endpoint to leave reasoning room. Defaults to " -"%(default)s; raise it if responses come back truncated, lower it if you want tighter limits. Only applied to self-" -"hosted OpenAI-compatible endpoints — cloud providers (OpenAI, Anthropic, Gemini) keep their original tight caps." +"Reasoning models (Qwen3, DeepSeek-R1, Gemma 3, etc.) emit chain-of-thought before the final answer. This multiplier " +"scales every max_tokens cap for this endpoint to leave reasoning room. Defaults to %(default)s; raise it" +" if responses come back truncated or empty, lower it (down to 1x) if you want tighter limits on a paid endpoint. " +"Applied to Ollama and OpenAI-compatible endpoints — other cloud providers (OpenAI, Anthropic, Gemini) keep their " +"original tight caps." msgstr "" #: changedetectionio/blueprint/settings/templates/settings_llm_tab.html @@ -983,6 +984,12 @@ msgstr "" msgid "Removes all cached AI change summaries across all watches. They will be regenerated on the next check." msgstr "" +#: changedetectionio/blueprint/settings/templates/settings_llm_tab.html +msgid "" +"Enables litellm verbose output (routed through loguru). Useful when diagnosing provider errors or empty responses. " +"Leave off in production — generates a lot of log volume." +msgstr "" + #: changedetectionio/blueprint/settings/templates/settings_llm_tab.html msgid "Default AI Change Summary" msgstr "" @@ -3169,6 +3176,10 @@ msgstr "" msgid "Use LLM as a fallback for extracting price and restock info" msgstr "" +#: changedetectionio/forms.py +msgid "Enable LLM debug logging" +msgstr "" + #: changedetectionio/forms.py msgid "AI thinking budget (tokens)" msgstr "" diff --git a/changedetectionio/translations/ja/LC_MESSAGES/messages.po b/changedetectionio/translations/ja/LC_MESSAGES/messages.po index 1bb786d8d..a0f7b8331 100644 --- a/changedetectionio/translations/ja/LC_MESSAGES/messages.po +++ b/changedetectionio/translations/ja/LC_MESSAGES/messages.po @@ -911,10 +911,11 @@ msgstr "" #: changedetectionio/blueprint/settings/templates/settings_llm_tab.html #, python-format msgid "" -"Local reasoning models (Qwen3, DeepSeek-R1, Gemma 3, etc.) emit chain-of-thought before the final answer. This " -"multiplier scales every max_tokens cap for this endpoint to leave reasoning room. Defaults to " -"%(default)s; raise it if responses come back truncated, lower it if you want tighter limits. Only applied to self-" -"hosted OpenAI-compatible endpoints — cloud providers (OpenAI, Anthropic, Gemini) keep their original tight caps." +"Reasoning models (Qwen3, DeepSeek-R1, Gemma 3, etc.) emit chain-of-thought before the final answer. This multiplier " +"scales every max_tokens cap for this endpoint to leave reasoning room. Defaults to %(default)s; raise it" +" if responses come back truncated or empty, lower it (down to 1x) if you want tighter limits on a paid endpoint. " +"Applied to Ollama and OpenAI-compatible endpoints — other cloud providers (OpenAI, Anthropic, Gemini) keep their " +"original tight caps." msgstr "" #: changedetectionio/blueprint/settings/templates/settings_llm_tab.html @@ -988,6 +989,12 @@ msgstr "" msgid "Removes all cached AI change summaries across all watches. They will be regenerated on the next check." msgstr "" +#: changedetectionio/blueprint/settings/templates/settings_llm_tab.html +msgid "" +"Enables litellm verbose output (routed through loguru). Useful when diagnosing provider errors or empty responses. " +"Leave off in production — generates a lot of log volume." +msgstr "" + #: changedetectionio/blueprint/settings/templates/settings_llm_tab.html msgid "Default AI Change Summary" msgstr "" @@ -3186,6 +3193,10 @@ msgstr "" msgid "Use LLM as a fallback for extracting price and restock info" msgstr "" +#: changedetectionio/forms.py +msgid "Enable LLM debug logging" +msgstr "" + #: changedetectionio/forms.py msgid "AI thinking budget (tokens)" msgstr "" diff --git a/changedetectionio/translations/ko/LC_MESSAGES/messages.po b/changedetectionio/translations/ko/LC_MESSAGES/messages.po index d715fd22e..d52c9bf00 100644 --- a/changedetectionio/translations/ko/LC_MESSAGES/messages.po +++ b/changedetectionio/translations/ko/LC_MESSAGES/messages.po @@ -912,10 +912,11 @@ msgstr "Ollama 또는 사용자 지정/자체 호스팅 엔드포인트에만 #: changedetectionio/blueprint/settings/templates/settings_llm_tab.html #, python-format msgid "" -"Local reasoning models (Qwen3, DeepSeek-R1, Gemma 3, etc.) emit chain-of-thought before the final answer. This " -"multiplier scales every max_tokens cap for this endpoint to leave reasoning room. Defaults to " -"%(default)s; raise it if responses come back truncated, lower it if you want tighter limits. Only applied to self-" -"hosted OpenAI-compatible endpoints — cloud providers (OpenAI, Anthropic, Gemini) keep their original tight caps." +"Reasoning models (Qwen3, DeepSeek-R1, Gemma 3, etc.) emit chain-of-thought before the final answer. This multiplier " +"scales every max_tokens cap for this endpoint to leave reasoning room. Defaults to %(default)s; raise it" +" if responses come back truncated or empty, lower it (down to 1x) if you want tighter limits on a paid endpoint. " +"Applied to Ollama and OpenAI-compatible endpoints — other cloud providers (OpenAI, Anthropic, Gemini) keep their " +"original tight caps." msgstr "" #: changedetectionio/blueprint/settings/templates/settings_llm_tab.html @@ -989,6 +990,12 @@ msgstr "모든 요약 캐시 지우기" msgid "Removes all cached AI change summaries across all watches. They will be regenerated on the next check." msgstr "모든 모니터링에 저장된 AI 변경 요약 캐시를 제거합니다. 다음 확인 시 다시 생성됩니다." +#: changedetectionio/blueprint/settings/templates/settings_llm_tab.html +msgid "" +"Enables litellm verbose output (routed through loguru). Useful when diagnosing provider errors or empty responses. " +"Leave off in production — generates a lot of log volume." +msgstr "" + #: changedetectionio/blueprint/settings/templates/settings_llm_tab.html msgid "Default AI Change Summary" msgstr "기본 AI 변경 요약" @@ -3177,6 +3184,10 @@ msgstr "{{diff}} 알림 토큰을 AI 요약으로 대체" msgid "Use LLM as a fallback for extracting price and restock info" msgstr "가격 및 재입고 정보 추출의 대체 수단으로 LLM 사용" +#: changedetectionio/forms.py +msgid "Enable LLM debug logging" +msgstr "" + #: changedetectionio/forms.py msgid "AI thinking budget (tokens)" msgstr "AI 추론 예산 (토큰)" diff --git a/changedetectionio/translations/messages.pot b/changedetectionio/translations/messages.pot index 30bf05a26..fe4c8fbad 100644 --- a/changedetectionio/translations/messages.pot +++ b/changedetectionio/translations/messages.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: changedetection.io 0.55.3\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2026-05-15 15:44+0200\n" +"POT-Creation-Date: 2026-05-15 18:31+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -903,10 +903,11 @@ msgstr "" #: changedetectionio/blueprint/settings/templates/settings_llm_tab.html #, python-format msgid "" -"Local reasoning models (Qwen3, DeepSeek-R1, Gemma 3, etc.) emit chain-of-thought before the final answer. This " -"multiplier scales every max_tokens cap for this endpoint to leave reasoning room. Defaults to " -"%(default)s; raise it if responses come back truncated, lower it if you want tighter limits. Only applied to self-" -"hosted OpenAI-compatible endpoints — cloud providers (OpenAI, Anthropic, Gemini) keep their original tight caps." +"Reasoning models (Qwen3, DeepSeek-R1, Gemma 3, etc.) emit chain-of-thought before the final answer. This multiplier " +"scales every max_tokens cap for this endpoint to leave reasoning room. Defaults to %(default)s; raise it" +" if responses come back truncated or empty, lower it (down to 1x) if you want tighter limits on a paid endpoint. " +"Applied to Ollama and OpenAI-compatible endpoints — other cloud providers (OpenAI, Anthropic, Gemini) keep their " +"original tight caps." msgstr "" #: changedetectionio/blueprint/settings/templates/settings_llm_tab.html @@ -980,6 +981,12 @@ msgstr "" msgid "Removes all cached AI change summaries across all watches. They will be regenerated on the next check." msgstr "" +#: changedetectionio/blueprint/settings/templates/settings_llm_tab.html +msgid "" +"Enables litellm verbose output (routed through loguru). Useful when diagnosing provider errors or empty responses. " +"Leave off in production — generates a lot of log volume." +msgstr "" + #: changedetectionio/blueprint/settings/templates/settings_llm_tab.html msgid "Default AI Change Summary" msgstr "" @@ -3166,6 +3173,10 @@ msgstr "" msgid "Use LLM as a fallback for extracting price and restock info" msgstr "" +#: changedetectionio/forms.py +msgid "Enable LLM debug logging" +msgstr "" + #: changedetectionio/forms.py msgid "AI thinking budget (tokens)" msgstr "" diff --git a/changedetectionio/translations/pt_BR/LC_MESSAGES/messages.po b/changedetectionio/translations/pt_BR/LC_MESSAGES/messages.po index 069b2670f..b5a0ee6a7 100644 --- a/changedetectionio/translations/pt_BR/LC_MESSAGES/messages.po +++ b/changedetectionio/translations/pt_BR/LC_MESSAGES/messages.po @@ -929,10 +929,11 @@ msgstr "" #: changedetectionio/blueprint/settings/templates/settings_llm_tab.html #, python-format msgid "" -"Local reasoning models (Qwen3, DeepSeek-R1, Gemma 3, etc.) emit chain-of-thought before the final answer. This " -"multiplier scales every max_tokens cap for this endpoint to leave reasoning room. Defaults to " -"%(default)s; raise it if responses come back truncated, lower it if you want tighter limits. Only applied to self-" -"hosted OpenAI-compatible endpoints — cloud providers (OpenAI, Anthropic, Gemini) keep their original tight caps." +"Reasoning models (Qwen3, DeepSeek-R1, Gemma 3, etc.) emit chain-of-thought before the final answer. This multiplier " +"scales every max_tokens cap for this endpoint to leave reasoning room. Defaults to %(default)s; raise it" +" if responses come back truncated or empty, lower it (down to 1x) if you want tighter limits on a paid endpoint. " +"Applied to Ollama and OpenAI-compatible endpoints — other cloud providers (OpenAI, Anthropic, Gemini) keep their " +"original tight caps." msgstr "" #: changedetectionio/blueprint/settings/templates/settings_llm_tab.html @@ -1006,6 +1007,12 @@ msgstr "" msgid "Removes all cached AI change summaries across all watches. They will be regenerated on the next check." msgstr "" +#: changedetectionio/blueprint/settings/templates/settings_llm_tab.html +msgid "" +"Enables litellm verbose output (routed through loguru). Useful when diagnosing provider errors or empty responses. " +"Leave off in production — generates a lot of log volume." +msgstr "" + #: changedetectionio/blueprint/settings/templates/settings_llm_tab.html msgid "Default AI Change Summary" msgstr "" @@ -3217,6 +3224,10 @@ msgstr "" msgid "Use LLM as a fallback for extracting price and restock info" msgstr "" +#: changedetectionio/forms.py +msgid "Enable LLM debug logging" +msgstr "" + #: changedetectionio/forms.py msgid "AI thinking budget (tokens)" msgstr "" diff --git a/changedetectionio/translations/tr/LC_MESSAGES/messages.po b/changedetectionio/translations/tr/LC_MESSAGES/messages.po index 4fad07ca7..2b3f9e2fe 100644 --- a/changedetectionio/translations/tr/LC_MESSAGES/messages.po +++ b/changedetectionio/translations/tr/LC_MESSAGES/messages.po @@ -939,10 +939,11 @@ msgstr "" #: changedetectionio/blueprint/settings/templates/settings_llm_tab.html #, python-format msgid "" -"Local reasoning models (Qwen3, DeepSeek-R1, Gemma 3, etc.) emit chain-of-thought before the final answer. This " -"multiplier scales every max_tokens cap for this endpoint to leave reasoning room. Defaults to " -"%(default)s; raise it if responses come back truncated, lower it if you want tighter limits. Only applied to self-" -"hosted OpenAI-compatible endpoints — cloud providers (OpenAI, Anthropic, Gemini) keep their original tight caps." +"Reasoning models (Qwen3, DeepSeek-R1, Gemma 3, etc.) emit chain-of-thought before the final answer. This multiplier " +"scales every max_tokens cap for this endpoint to leave reasoning room. Defaults to %(default)s; raise it" +" if responses come back truncated or empty, lower it (down to 1x) if you want tighter limits on a paid endpoint. " +"Applied to Ollama and OpenAI-compatible endpoints — other cloud providers (OpenAI, Anthropic, Gemini) keep their " +"original tight caps." msgstr "" #: changedetectionio/blueprint/settings/templates/settings_llm_tab.html @@ -1016,6 +1017,12 @@ msgstr "" msgid "Removes all cached AI change summaries across all watches. They will be regenerated on the next check." msgstr "" +#: changedetectionio/blueprint/settings/templates/settings_llm_tab.html +msgid "" +"Enables litellm verbose output (routed through loguru). Useful when diagnosing provider errors or empty responses. " +"Leave off in production — generates a lot of log volume." +msgstr "" + #: changedetectionio/blueprint/settings/templates/settings_llm_tab.html msgid "Default AI Change Summary" msgstr "" @@ -3220,6 +3227,10 @@ msgstr "" msgid "Use LLM as a fallback for extracting price and restock info" msgstr "" +#: changedetectionio/forms.py +msgid "Enable LLM debug logging" +msgstr "" + #: changedetectionio/forms.py msgid "AI thinking budget (tokens)" msgstr "" diff --git a/changedetectionio/translations/uk/LC_MESSAGES/messages.po b/changedetectionio/translations/uk/LC_MESSAGES/messages.po index 5d4684548..e4db96c00 100644 --- a/changedetectionio/translations/uk/LC_MESSAGES/messages.po +++ b/changedetectionio/translations/uk/LC_MESSAGES/messages.po @@ -919,10 +919,11 @@ msgstr "" #: changedetectionio/blueprint/settings/templates/settings_llm_tab.html #, python-format msgid "" -"Local reasoning models (Qwen3, DeepSeek-R1, Gemma 3, etc.) emit chain-of-thought before the final answer. This " -"multiplier scales every max_tokens cap for this endpoint to leave reasoning room. Defaults to " -"%(default)s; raise it if responses come back truncated, lower it if you want tighter limits. Only applied to self-" -"hosted OpenAI-compatible endpoints — cloud providers (OpenAI, Anthropic, Gemini) keep their original tight caps." +"Reasoning models (Qwen3, DeepSeek-R1, Gemma 3, etc.) emit chain-of-thought before the final answer. This multiplier " +"scales every max_tokens cap for this endpoint to leave reasoning room. Defaults to %(default)s; raise it" +" if responses come back truncated or empty, lower it (down to 1x) if you want tighter limits on a paid endpoint. " +"Applied to Ollama and OpenAI-compatible endpoints — other cloud providers (OpenAI, Anthropic, Gemini) keep their " +"original tight caps." msgstr "" #: changedetectionio/blueprint/settings/templates/settings_llm_tab.html @@ -996,6 +997,12 @@ msgstr "" msgid "Removes all cached AI change summaries across all watches. They will be regenerated on the next check." msgstr "" +#: changedetectionio/blueprint/settings/templates/settings_llm_tab.html +msgid "" +"Enables litellm verbose output (routed through loguru). Useful when diagnosing provider errors or empty responses. " +"Leave off in production — generates a lot of log volume." +msgstr "" + #: changedetectionio/blueprint/settings/templates/settings_llm_tab.html msgid "Default AI Change Summary" msgstr "" @@ -3199,6 +3206,10 @@ msgstr "" msgid "Use LLM as a fallback for extracting price and restock info" msgstr "" +#: changedetectionio/forms.py +msgid "Enable LLM debug logging" +msgstr "" + #: changedetectionio/forms.py msgid "AI thinking budget (tokens)" msgstr "" diff --git a/changedetectionio/translations/zh/LC_MESSAGES/messages.po b/changedetectionio/translations/zh/LC_MESSAGES/messages.po index c67adc3e9..f34f9dcbf 100644 --- a/changedetectionio/translations/zh/LC_MESSAGES/messages.po +++ b/changedetectionio/translations/zh/LC_MESSAGES/messages.po @@ -908,10 +908,11 @@ msgstr "" #: changedetectionio/blueprint/settings/templates/settings_llm_tab.html #, python-format msgid "" -"Local reasoning models (Qwen3, DeepSeek-R1, Gemma 3, etc.) emit chain-of-thought before the final answer. This " -"multiplier scales every max_tokens cap for this endpoint to leave reasoning room. Defaults to " -"%(default)s; raise it if responses come back truncated, lower it if you want tighter limits. Only applied to self-" -"hosted OpenAI-compatible endpoints — cloud providers (OpenAI, Anthropic, Gemini) keep their original tight caps." +"Reasoning models (Qwen3, DeepSeek-R1, Gemma 3, etc.) emit chain-of-thought before the final answer. This multiplier " +"scales every max_tokens cap for this endpoint to leave reasoning room. Defaults to %(default)s; raise it" +" if responses come back truncated or empty, lower it (down to 1x) if you want tighter limits on a paid endpoint. " +"Applied to Ollama and OpenAI-compatible endpoints — other cloud providers (OpenAI, Anthropic, Gemini) keep their " +"original tight caps." msgstr "" #: changedetectionio/blueprint/settings/templates/settings_llm_tab.html @@ -985,6 +986,12 @@ msgstr "" msgid "Removes all cached AI change summaries across all watches. They will be regenerated on the next check." msgstr "" +#: changedetectionio/blueprint/settings/templates/settings_llm_tab.html +msgid "" +"Enables litellm verbose output (routed through loguru). Useful when diagnosing provider errors or empty responses. " +"Leave off in production — generates a lot of log volume." +msgstr "" + #: changedetectionio/blueprint/settings/templates/settings_llm_tab.html msgid "Default AI Change Summary" msgstr "" @@ -3172,6 +3179,10 @@ msgstr "" msgid "Use LLM as a fallback for extracting price and restock info" msgstr "" +#: changedetectionio/forms.py +msgid "Enable LLM debug logging" +msgstr "" + #: changedetectionio/forms.py msgid "AI thinking budget (tokens)" msgstr "" diff --git a/changedetectionio/translations/zh_Hant_TW/LC_MESSAGES/messages.po b/changedetectionio/translations/zh_Hant_TW/LC_MESSAGES/messages.po index ddf594832..5734cfc10 100644 --- a/changedetectionio/translations/zh_Hant_TW/LC_MESSAGES/messages.po +++ b/changedetectionio/translations/zh_Hant_TW/LC_MESSAGES/messages.po @@ -907,10 +907,11 @@ msgstr "" #: changedetectionio/blueprint/settings/templates/settings_llm_tab.html #, python-format msgid "" -"Local reasoning models (Qwen3, DeepSeek-R1, Gemma 3, etc.) emit chain-of-thought before the final answer. This " -"multiplier scales every max_tokens cap for this endpoint to leave reasoning room. Defaults to " -"%(default)s; raise it if responses come back truncated, lower it if you want tighter limits. Only applied to self-" -"hosted OpenAI-compatible endpoints — cloud providers (OpenAI, Anthropic, Gemini) keep their original tight caps." +"Reasoning models (Qwen3, DeepSeek-R1, Gemma 3, etc.) emit chain-of-thought before the final answer. This multiplier " +"scales every max_tokens cap for this endpoint to leave reasoning room. Defaults to %(default)s; raise it" +" if responses come back truncated or empty, lower it (down to 1x) if you want tighter limits on a paid endpoint. " +"Applied to Ollama and OpenAI-compatible endpoints — other cloud providers (OpenAI, Anthropic, Gemini) keep their " +"original tight caps." msgstr "" #: changedetectionio/blueprint/settings/templates/settings_llm_tab.html @@ -984,6 +985,12 @@ msgstr "" msgid "Removes all cached AI change summaries across all watches. They will be regenerated on the next check." msgstr "" +#: changedetectionio/blueprint/settings/templates/settings_llm_tab.html +msgid "" +"Enables litellm verbose output (routed through loguru). Useful when diagnosing provider errors or empty responses. " +"Leave off in production — generates a lot of log volume." +msgstr "" + #: changedetectionio/blueprint/settings/templates/settings_llm_tab.html msgid "Default AI Change Summary" msgstr "" @@ -3171,6 +3178,10 @@ msgstr "" msgid "Use LLM as a fallback for extracting price and restock info" msgstr "" +#: changedetectionio/forms.py +msgid "Enable LLM debug logging" +msgstr "" + #: changedetectionio/forms.py msgid "AI thinking budget (tokens)" msgstr "" diff --git a/changedetectionio/worker.py b/changedetectionio/worker.py index d3dd9cb68..eeef24266 100644 --- a/changedetectionio/worker.py +++ b/changedetectionio/worker.py @@ -539,9 +539,11 @@ async def async_update_worker(worker_id, q, notification_q, app, datastore, exec ) _llm_to_version = list(watch.history.keys())[-1] _llm_max_summary_tokens = datastore.data['settings']['application'].get('llm_max_summary_tokens', 3000) + _llm_model = (datastore.data['settings']['application'].get('llm') or {}).get('model', '') _llm_cache_prompt = build_summary_cache_prompt( effective_prompt=get_effective_summary_prompt(watch, datastore), max_summary_tokens=_llm_max_summary_tokens, + model=_llm_model, ) watch.save_llm_diff_summary( update_obj['_llm_change_summary'],