This commit is contained in:
dgtlmoon
2026-05-30 13:35:49 +02:00
parent 1e643b2244
commit 39fa7f9692
4 changed files with 5 additions and 29 deletions
+2 -2
View File
@@ -693,7 +693,7 @@ def summarise_change(watch, datastore, diff: str, current_snapshot: str = '',
# Live-preview extraction (current content, no diff)
# ---------------------------------------------------------------------------
def preview_extract(watch, datastore, content: str, metadata: str = '') -> dict | None:
def preview_extract(watch, datastore, content: str) -> dict | None:
"""
For the live-preview endpoint: extract relevant information from the
*current* page content according to the watch's intent.
@@ -717,7 +717,7 @@ def preview_extract(watch, datastore, content: str, metadata: str = '') -> dict
title = watch.get('page_title') or watch.get('title') or ''
system_prompt = build_preview_system_prompt()
user_prompt = build_preview_prompt(intent, content, url=url, title=title, metadata=metadata)
user_prompt = build_preview_prompt(intent, content, url=url, title=title)
settings = get_llm_settings(datastore)
try:
+1 -8
View File
@@ -102,18 +102,13 @@ def build_eval_system_prompt() -> str:
)
def build_preview_prompt(intent: str, content: str, url: str = '', title: str = '',
metadata: str = '') -> str:
def build_preview_prompt(intent: str, content: str, url: str = '', title: str = '') -> str:
"""
Build the user message for a live-preview extraction call.
Unlike build_eval_prompt (which analyses a diff), this asks the LLM to
extract relevant information from the *current* page content — giving the
user a direct answer to their intent so they can verify it makes sense
before saving.
`metadata` is verbatim current-state structured data (JSON-LD/OpenGraph) appended
so intents about SKUs / IDs / availability can be answered even when the visible
text has dropped them.
"""
parts = []
if url:
@@ -122,8 +117,6 @@ def build_preview_prompt(intent: str, content: str, url: str = '', title: str =
parts.append(f"Page title: {title}")
parts.append(f"Intent / question: {intent}")
parts.append(f"\nPage content:\n{content[:6_000]}")
if metadata:
parts.append(f"\n{metadata}")
return '\n'.join(parts)
@@ -185,13 +185,9 @@ def prepare_filter_prevew(datastore, watch_uuid, form_data):
# Results are NOT cached back to the real watch.
llm_evaluation = None
try:
from changedetectionio.llm.evaluator import preview_extract, compute_llm_enrichment
from changedetectionio.llm.evaluator import preview_extract
if text_after_filter and text_after_filter.strip() not in ('', 'Empty content'):
# Append verbatim structured metadata (JSON-LD/OpenGraph) from the raw HTML so
# preview answers about SKUs/IDs/availability work even when the visible text dropped them.
_llm_raw_html = getattr(getattr(update_handler, 'fetcher', None), 'content', '') or ''
_llm_metadata = compute_llm_enrichment(tmp_watch, datastore, _llm_raw_html, text_after_filter)
llm_evaluation = preview_extract(tmp_watch, datastore, content=text_after_filter, metadata=_llm_metadata)
llm_evaluation = preview_extract(tmp_watch, datastore, content=text_after_filter)
except Exception as e:
logger.warning(f"LLM preview evaluation failed for {watch_uuid}: {e}")
@@ -8,7 +8,6 @@ from changedetectionio.llm.prompt_builder import (
build_eval_prompt,
build_eval_system_prompt,
build_change_summary_prompt,
build_preview_prompt,
build_setup_prompt,
build_setup_system_prompt,
SNAPSHOT_CONTEXT_CHARS,
@@ -109,23 +108,11 @@ class TestMetadataEnrichmentInPrompts:
without = build_change_summary_prompt(diff='- a\n+ b', custom_prompt='x')
assert 'Structured metadata found' not in without
def test_preview_prompt_includes_metadata(self):
prompt = build_preview_prompt(intent='what is the SKU?', content='some page text',
metadata=self.METADATA)
assert self.METADATA in prompt
assert '"sku":"12345"' in prompt
def test_preview_prompt_unchanged_without_metadata(self):
without = build_preview_prompt(intent='q', content='page text')
assert 'Structured metadata found' not in without
def test_empty_metadata_appends_nothing(self):
# Falsy metadata ('') must not add a trailing block/whitespace section
assert build_eval_prompt(intent='i', diff='d', metadata='') == build_eval_prompt(intent='i', diff='d')
assert (build_change_summary_prompt(diff='d', custom_prompt='c', metadata='')
== build_change_summary_prompt(diff='d', custom_prompt='c'))
assert (build_preview_prompt(intent='i', content='c', metadata='')
== build_preview_prompt(intent='i', content='c'))
class TestBuildEvalSystemPrompt: