c1eef4c6aa
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>
37 lines
1.2 KiB
Python
37 lines
1.2 KiB
Python
"""SiteRecipe interface. Each supported site implements one of these; adding a
|
|
new site is a drop-in module registered in ai/recipes/__init__.py — the core
|
|
capture loop never changes.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
from abc import ABC, abstractmethod
|
|
from typing import Any, Optional
|
|
|
|
from core.models import Lead, PageContext, PageMatch
|
|
|
|
|
|
class SiteRecipe(ABC):
|
|
site_id: str = ""
|
|
display_name: str = ""
|
|
enabled: bool = True
|
|
# Which extracted page_type is a capturable target (e.g. a person's profile).
|
|
target_page_type: str = "profile"
|
|
|
|
@abstractmethod
|
|
def matches(self, ctx: PageContext) -> Optional[PageMatch]:
|
|
"""Return a PageMatch if this recipe recognises the page, else None."""
|
|
|
|
@property
|
|
@abstractmethod
|
|
def extraction_schema(self) -> dict[str, Any]:
|
|
"""JSON schema (structured-output format) for the raw extraction."""
|
|
|
|
@property
|
|
@abstractmethod
|
|
def extraction_prompt(self) -> str:
|
|
"""Instruction given to the vision model alongside the screenshots."""
|
|
|
|
@abstractmethod
|
|
def to_canonical(self, raw: dict[str, Any]) -> Lead:
|
|
"""Map this site's raw extraction to the canonical Lead schema."""
|