Initial commit: Screen Leads app
Screen-capture lead tool: capture agent, Claude vision extractor with pluggable site recipes (LinkedIn), canonical funnel model, SQLite storage, FastAPI backend, dashboard, and setup/run scripts. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
"""Front-tab detection: decide whether the current page is an enabled site's
|
||||
capturable target (a LinkedIn profile, to start).
|
||||
|
||||
Strategy:
|
||||
1. Try to read the browser URL natively (fast, exact; macOS reliably, others
|
||||
best-effort).
|
||||
2. If no URL, capture one screenshot and let the AI read the address bar /
|
||||
recognise the site visually (portable, screen-only).
|
||||
3. Ask the recipe registry whether any enabled recipe matches.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Optional
|
||||
|
||||
from agent import screenshot
|
||||
from agent.platform import get_active_tab_url
|
||||
from ai import recipes
|
||||
from core.models import DetectionResult, PageContext
|
||||
|
||||
|
||||
def detect(use_ai_fallback: bool = True) -> DetectionResult:
|
||||
url = get_active_tab_url()
|
||||
ctx = PageContext(url=url)
|
||||
method = "url" if url else ""
|
||||
|
||||
hit = recipes.match(ctx)
|
||||
|
||||
if hit is None and url is None and use_ai_fallback:
|
||||
# No native URL and nothing matched — read the screen visually.
|
||||
try:
|
||||
shot = screenshot.capture(prefix="detect")
|
||||
from ai import extractor
|
||||
|
||||
info = extractor.classify_page(shot)
|
||||
ctx.ai_site = info.get("site")
|
||||
ctx.ai_page_type = info.get("page_type")
|
||||
ctx.ai_url_text = info.get("address_bar_url")
|
||||
method = "visual"
|
||||
hit = recipes.match(ctx)
|
||||
except Exception as e:
|
||||
return DetectionResult(ok=False, reason=f"detection failed: {e}")
|
||||
|
||||
if hit is None:
|
||||
where = ctx.best_url or "the current tab"
|
||||
return DetectionResult(
|
||||
ok=False,
|
||||
reason=f"Front tab is not a supported site ({where}).",
|
||||
url=ctx.best_url,
|
||||
method=method,
|
||||
)
|
||||
|
||||
recipe, pm = hit
|
||||
if not pm.is_target:
|
||||
return DetectionResult(
|
||||
ok=False,
|
||||
reason=(f"Front tab is {recipe.display_name} but not a "
|
||||
f"{recipe.target_page_type} page (got '{pm.page_type}')."),
|
||||
recipe_id=recipe.site_id,
|
||||
page_type=pm.page_type,
|
||||
url=ctx.best_url,
|
||||
method=method,
|
||||
)
|
||||
|
||||
return DetectionResult(
|
||||
ok=True,
|
||||
recipe_id=recipe.site_id,
|
||||
page_type=pm.page_type,
|
||||
url=ctx.best_url,
|
||||
method=method,
|
||||
)
|
||||
Reference in New Issue
Block a user