File size: 2,558 Bytes
6360ebe
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
"""Classificazione locale del fast path per mini-app HTML a file singolo.

Il classificatore è deliberatamente conservativo: in caso di dubbio restituisce
False. Non usa LLM, rete o stato globale e quindi non aggiunge latenza misurabile.
"""
from __future__ import annotations

from dataclasses import dataclass
import re


@dataclass(frozen=True)
class HtmlFastPathDecision:
    eligible: bool
    reason: str
    path: str = "index.html"


_HTML_RE = re.compile(r"\b(?:html5?|html|pagina\s+web|single[- ]page|landing\s+page)\b", re.I)
_CREATE_RE = re.compile(r"\b(?:crea|genera|scrivi|realizza|implementa|build|create|generate|make)\b", re.I)
_SINGLE_FILE_RE = re.compile(
    r"\b(?:un\s+solo\s+file|singolo\s+file|one\s+file|single\s+file|file\s+unico)\b", re.I
)
_PATH_RE = re.compile(r"(?<![\w./-])([\w./-]+\.html)(?![\w.-])", re.I)
_FORBIDDEN_RE = re.compile(
    r"\b(?:deploy|pubblica|publish|rilascia|release|github|git|npm|pnpm|yarn|install|"
    r"api|backend|server|database|db|auth|login|pagamento|payment|webhook|secret|token|"
    r"shell|bash|terminal|esegui\s+comandi|execute\s+commands|multi[- ]file|pi[uù]\s+file|"
    r"react|vue|angular|next(?:\.js)?|vite|typescript|python|sql)\b",
    re.I,
)
_EXTERNAL_RE = re.compile(r"\b(?:fetch|axios|websocket|stripe|supabase|firebase|oauth)\b|https?://", re.I)


def classify_html_fast_path(goal: str) -> HtmlFastPathDecision:
    """Return an eligible decision only for a safe, self-contained HTML request."""
    text = " ".join(str(goal or "").split())
    if not text:
        return HtmlFastPathDecision(False, "empty_goal")
    if len(text) > 500:
        return HtmlFastPathDecision(False, "goal_too_long")
    if not _HTML_RE.search(text):
        return HtmlFastPathDecision(False, "not_html_goal")
    if not _CREATE_RE.search(text):
        return HtmlFastPathDecision(False, "not_creation_goal")
    if not _SINGLE_FILE_RE.search(text):
        return HtmlFastPathDecision(False, "single_file_not_explicit")
    if _FORBIDDEN_RE.search(text):
        return HtmlFastPathDecision(False, "contains_project_or_sensitive_operation")
    if _EXTERNAL_RE.search(text):
        return HtmlFastPathDecision(False, "external_dependency_or_network")

    paths = _PATH_RE.findall(text)
    path = paths[0] if paths else "index.html"
    if "/" in path or path.startswith("."):
        return HtmlFastPathDecision(False, "nested_path_not_allowed", path)
    return HtmlFastPathDecision(True, "self_contained_single_html", path)


__all__ = ["HtmlFastPathDecision", "classify_html_fast_path"]