-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathelement_filter.py
More file actions
134 lines (108 loc) · 3.65 KB
/
element_filter.py
File metadata and controls
134 lines (108 loc) · 3.65 KB
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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
"""
Element filtering utilities for agent-based element selection.
This module provides centralized element filtering logic to reduce duplication
across agent implementations.
"""
from typing import Optional
from .models import Element, Snapshot
class ElementFilter:
"""
Centralized element filtering logic for agent-based element selection.
Provides static methods for filtering elements based on:
- Importance scores
- Goal-based keyword matching
- Role and visual properties
"""
# Common stopwords for keyword extraction
STOPWORDS = {
"the",
"a",
"an",
"and",
"or",
"but",
"in",
"on",
"at",
"to",
"for",
"of",
"with",
"by",
"from",
"as",
"is",
"was",
}
@staticmethod
def filter_by_importance(
snapshot: Snapshot,
max_elements: int = 50,
) -> list[Element]:
"""
Filter elements by importance score (simple top-N selection).
Args:
snapshot: Current page snapshot
max_elements: Maximum number of elements to return
Returns:
Top N elements sorted by importance score
"""
elements = snapshot.elements
# Elements are already sorted by importance in snapshot
return elements[:max_elements]
@staticmethod
def filter_by_goal(
snapshot: Snapshot,
goal: str | None,
max_elements: int = 100,
) -> list[Element]:
"""
Filter elements from snapshot based on goal context.
Applies goal-based keyword matching to boost relevant elements
and filters out irrelevant ones.
Args:
snapshot: Current page snapshot
goal: User's goal (can inform filtering)
max_elements: Maximum number of elements to return
Returns:
Filtered list of elements sorted by boosted importance score
"""
elements = snapshot.elements
# If no goal provided, return all elements (up to limit)
if not goal:
return elements[:max_elements]
goal_lower = goal.lower()
# Extract keywords from goal
keywords = ElementFilter._extract_keywords(goal_lower)
# Boost elements matching goal keywords
scored_elements = []
for el in elements:
score = el.importance
# Boost if element text matches goal
if el.text and any(kw in el.text.lower() for kw in keywords):
score += 0.3
# Boost if role matches goal intent
if "click" in goal_lower and el.visual_cues.is_clickable:
score += 0.2
if "type" in goal_lower and el.role in ["textbox", "searchbox"]:
score += 0.2
if "search" in goal_lower:
# Filter out non-interactive elements for search tasks
if el.role in ["link", "img"] and not el.visual_cues.is_primary:
score -= 0.5
scored_elements.append((score, el))
# Re-sort by boosted score
scored_elements.sort(key=lambda x: x[0], reverse=True)
elements = [el for _, el in scored_elements]
return elements[:max_elements]
@staticmethod
def _extract_keywords(text: str) -> list[str]:
"""
Extract meaningful keywords from goal text.
Args:
text: Text to extract keywords from
Returns:
List of keywords (non-stopwords, length > 2)
"""
words = text.split()
return [w for w in words if w not in ElementFilter.STOPWORDS and len(w) > 2]