Commit Graph
14 Commits
Author SHA1 Message Date
dgtlmoonandClaude Opus 5.5 be09f73c3a Restock: let a plugin do LLM price/stock extraction without litellm (HTML + text hook, reusable helpers) (#4545)
Build and push containers / metadata (push) Canceled after 0s
Build and push containers / build-push-containers (push) Canceled after 0s
Publish Python 🐍distribution 📦 to PyPI and TestPyPI / Build distribution 📦 (push) Canceled after 0s
Publish Python 🐍distribution 📦 to PyPI and TestPyPI / Test the built package works basically. (push) Canceled after 0s
Publish Python 🐍distribution 📦 to PyPI and TestPyPI / Publish Python 🐍 distribution 📦 to PyPI (push) Canceled after 0s
ChangeDetection.io App Test / lint-code (push) Canceled after 0s
ChangeDetection.io App Test / lint-translations (push) Canceled after 0s
ChangeDetection.io App Test / lint-template-i18n (push) Canceled after 0s
ChangeDetection.io App Test / test-application-3-11 (push) Canceled after 0s
ChangeDetection.io App Test / test-application-3-12 (push) Canceled after 0s
ChangeDetection.io App Test / test-application-3-13 (push) Canceled after 0s
ChangeDetection.io App Test / test-application-3-14 (push) Canceled after 0s
* LLM restock: parse string prices with price_parser instead of stripping separators

If the model returns the price as page text, e.g. "1.299,95 €", stripping
everything but digits and dots gave 1.29995. price_parser (already a
dependency) handles the locale formats the prompt lists.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* LLM restock: use Restock.parse_currency() like the other price extractors

Same parser c8afea1b (#4494) moved the structured-data extractors to, so
there's one place price text becomes a number. parse_currency() now lists
every caller, and the call sites point back to it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* LLM restock: expose prompt/cache/parsing helpers so other LLM backends can reuse them

Split the hook body into build_restock_messages(), restock_cache_key/get/put()
and parse_restock_reply(), so a plugin talking to a provider without litellm
only has to supply the HTTP call. accumulate_global_tokens() takes an optional
cost_usd, since the default estimate imports litellm's pricing (~200MB that's
never released). The built-in plugin behaves exactly as before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Test: give the no-litellm subprocess check a PYTHONPATH

CI runs pytest from inside the package dir without installing it, so the
child interpreter couldn't import changedetectionio.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Restock plugins: pass html_to_text() output to the restock hook, let third-party backends go first

get_itemprop_availability_override now also gets `text` (the fetched page through
html_to_text()), only computed when an implementation declares it. The hook is
firstresult and the built-in litellm plugin is trylast, so a plugin that talks to an
LLM with plain requests answers first and the built-in one is never billed as well.

Also fixes the built-in plugin never receiving llm_intent: pluggy silently doesn't
pass hookimpl arguments that have a default value, and it declared llm_intent=None.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 12:32:32 +02:00
dgtlmoonandClaude Opus 5.5 7ec79fc231 LLM restock: fix locale-formatted string prices (1.299,95 read as 1.29995) (#4544)
* LLM restock: parse string prices with price_parser instead of stripping separators

If the model returns the price as page text, e.g. "1.299,95 €", stripping
everything but digits and dots gave 1.29995. price_parser (already a
dependency) handles the locale formats the prompt lists.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* LLM restock: use Restock.parse_currency() like the other price extractors

Same parser c8afea1b (#4494) moved the structured-data extractors to, so
there's one place price text becomes a number. parse_currency() now lists
every caller, and the call sites point back to it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 11:21:06 +02:00
dgtlmoon a165df2da9 LLM UI - When LLM is disabled, hide it from the groups settings also (#4471) 2026-09-20 15:54:41 +02:00
dgtlmoon 97317398ac LLM - Per watch/group settings and UI tidyup (#4354)
* UI - LLM section tidyup

* Rebuild translatiosn

* UI - Fixing language for prompt adjustement to be more clear

* UI - clarify field action

* UI - clarify layout for sections

* WIP

* test tweaks
2026-09-02 10:07:34 +02:00
dgtlmoonandClaude Opus 5 143a0f116f fix(llm): handle reasoning blocks that aren't a well-formed <think>...</think> pair (#4349)
Build and push containers / metadata (push) Canceled after 0s
Build and push containers / build-push-containers (push) Canceled after 0s
Publish Python 🐍distribution 📦 to PyPI and TestPyPI / Build distribution 📦 (push) Canceled after 0s
ChangeDetection.io App Test / lint-code (push) Canceled after 0s
ChangeDetection.io App Test / lint-translations (push) Canceled after 0s
ChangeDetection.io App Test / lint-template-i18n (push) Canceled after 0s
Publish Python 🐍distribution 📦 to PyPI and TestPyPI / Test the built package works basically. (push) Canceled after 0s
Publish Python 🐍distribution 📦 to PyPI and TestPyPI / Publish Python 🐍 distribution 📦 to PyPI (push) Canceled after 0s
ChangeDetection.io App Test / test-application-3-11 (push) Canceled after 0s
ChangeDetection.io App Test / test-application-3-12 (push) Canceled after 0s
ChangeDetection.io App Test / test-application-3-13 (push) Canceled after 0s
ChangeDetection.io App Test / test-application-3-14 (push) Canceled after 0s
Follow-up to #4340. The <think> stripper added there only matches a closed pair, but a
reasoning scratchpad routinely contains JSON of its own ("initially I thought
{"important": false}, but..."), so any leftover scratchpad lets _extract_json lock onto
a discarded intermediate answer. Three shapes slipped through, all of which inverted the
verdict to important=false and therefore silently suppressed the notification:

- opener stripped by the provider/chat template, only </think> comes back over the wire
- <thinking> spelled out in full
- unterminated block, i.e. the response was cut off mid-thought by max_tokens

The first two are now stripped. The third raises ValueError, because a truncated response
holds no answer at all - only the abandoned guess. Raising routes it to the existing
handler in evaluator.py, which passes the change through as important rather than dropping
it; parse_eval_response deliberately does not catch ValueError, since its own fallback
(important=False) would suppress the notification instead.

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-01 12:42:16 +02:00
Andrew Peabody 9e54ed3adb fix(llm): string boolean parsing, reasoning model <think> stripping, and timestamp diff annotation (#4340)
- Simplify _to_bool using changedetectionio.strtobool.strtobool
- Strip <think>...</think> reasoning blocks in _extract_json for reasoning models
- Fix _annotate_moved_lines short-circuit so standalone relative timestamps are always annotated
- Add comprehensive unit tests in test_response_parser and test_prompt_builder
2026-09-01 11:52:40 +02:00
dgtlmoon c24f338f95 Add watch UI - Tidying up logic around browser selection/visibility
Build and push containers / metadata (push) Canceled after 0s
Build and push containers / build-push-containers (push) Canceled after 0s
Publish Python 🐍distribution 📦 to PyPI and TestPyPI / Build distribution 📦 (push) Canceled after 0s
ChangeDetection.io App Test / lint-code (push) Canceled after 0s
ChangeDetection.io App Test / lint-translations (push) Canceled after 0s
ChangeDetection.io App Test / lint-template-i18n (push) Canceled after 0s
Publish Python 🐍distribution 📦 to PyPI and TestPyPI / Test the built package works basically. (push) Canceled after 0s
Publish Python 🐍distribution 📦 to PyPI and TestPyPI / Publish Python 🐍 distribution 📦 to PyPI (push) Canceled after 0s
ChangeDetection.io App Test / test-application-3-10 (push) Canceled after 0s
ChangeDetection.io App Test / test-application-3-11 (push) Canceled after 0s
ChangeDetection.io App Test / test-application-3-12 (push) Canceled after 0s
ChangeDetection.io App Test / test-application-3-13 (push) Canceled after 0s
ChangeDetection.io App Test / test-application-3-14 (push) Canceled after 0s
2026-08-26 12:29:55 +02:00
dgtlmoon bb2e6adece Add watch UI should show which browser(s) are available and set default browser (#4334) 2026-08-25 20:15:59 +02:00
01cf56c8fb feature: allow a watch or group to append to the inherited AI Change Summary prompt (#4294)
Build and push containers / metadata (push) Canceled after 0s
Build and push containers / build-push-containers (push) Canceled after 0s
Publish Python 🐍distribution 📦 to PyPI and TestPyPI / Build distribution 📦 (push) Canceled after 0s
ChangeDetection.io Container Build Test / Build linux/amd64 (alpine) (push) Canceled after 0s
ChangeDetection.io Container Build Test / Build linux/arm64 (alpine) (push) Canceled after 0s
ChangeDetection.io Container Build Test / Build linux/amd64 (main) (push) Canceled after 0s
ChangeDetection.io Container Build Test / Build linux/arm/v7 (main) (push) Canceled after 0s
ChangeDetection.io Container Build Test / Build linux/arm/v8 (main) (push) Canceled after 0s
ChangeDetection.io Container Build Test / Build linux/arm64 (main) (push) Canceled after 0s
ChangeDetection.io App Test / lint-code (push) Canceled after 0s
ChangeDetection.io App Test / lint-translations (push) Canceled after 0s
ChangeDetection.io App Test / lint-template-i18n (push) Canceled after 0s
Publish Python 🐍distribution 📦 to PyPI and TestPyPI / Test the built package works basically. (push) Canceled after 0s
Publish Python 🐍distribution 📦 to PyPI and TestPyPI / Publish Python 🐍 distribution 📦 to PyPI (push) Canceled after 0s
ChangeDetection.io App Test / test-application-3-10 (push) Canceled after 0s
ChangeDetection.io App Test / test-application-3-11 (push) Canceled after 0s
ChangeDetection.io App Test / test-application-3-12 (push) Canceled after 0s
ChangeDetection.io App Test / test-application-3-13 (push) Canceled after 0s
ChangeDetection.io App Test / test-application-3-14 (push) Canceled after 0s
Co-authored-by: snowyukitty <270071858+snowyukitty@users.noreply.github.com>
Co-authored-by: dgtlmoon <dgtlmoon@gmail.com>
2026-08-20 15:14:59 +02:00
dgtlmoon 71d332d5a0 UI full refactor / upgrade (#4183)
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
2026-07-16 15:08:29 +02:00
dgtlmoon a69ddbd787 LLM - Raise or remove LLM timeout when local endpoint detected #4225 (#4254) 2026-07-13 09:50:35 +02:00
dgtlmoon 0e3f1941b3 Code - LLM settings pydantic refactor (#4181)
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 Container Build Test / Build linux/amd64 (alpine) (push) Has been cancelled
ChangeDetection.io Container Build Test / Build linux/arm64 (alpine) (push) Has been cancelled
ChangeDetection.io Container Build Test / Build linux/amd64 (main) (push) Has been cancelled
ChangeDetection.io Container Build Test / Build linux/arm/v7 (main) (push) Has been cancelled
ChangeDetection.io Container Build Test / Build linux/arm/v8 (main) (push) Has been cancelled
ChangeDetection.io Container Build Test / Build linux/arm64 (main) (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
2026-05-25 10:43:52 +02:00
dgtlmoon 701833b6ed UI - LLM - Flag LLM_FEATURES_DISABLED to disable all LLM from the UI/system (#4171)
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
2026-05-21 12:51:56 +02:00
dgtlmoon e9e8c8d218 LLM / AI Change detection rules and Summaries
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 Container Build Test / Build linux/amd64 (alpine) (push) Has been cancelled
ChangeDetection.io Container Build Test / Build linux/arm64 (alpine) (push) Has been cancelled
ChangeDetection.io Container Build Test / Build linux/amd64 (main) (push) Has been cancelled
ChangeDetection.io Container Build Test / Build linux/arm/v7 (main) (push) Has been cancelled
ChangeDetection.io Container Build Test / Build linux/arm/v8 (main) (push) Has been cancelled
ChangeDetection.io Container Build Test / Build linux/arm64 (main) (push) Has been cancelled
ChangeDetection.io App Test / lint-code (push) Has been cancelled
ChangeDetection.io App Test / lint-translations (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
2026-04-24 15:21:09 +02:00