mirror of
https://github.com/dgtlmoon/changedetection.io.git
synced 2026-07-08 08:21:14 +00:00
WIP
This commit is contained in:
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user