Skip to content

Commit d1d5c6d

Browse files
committed
return flatten axtree from playwright backend
1 parent 963c999 commit d1d5c6d

File tree

1 file changed

+54
-1
lines changed

1 file changed

+54
-1
lines changed

src/agentlab/backends/browser/playwright.py

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,9 @@ def page_screenshot(self):
101101
return Image.open(BytesIO(scr_bytes))
102102

103103
def page_axtree(self):
104-
return ""
104+
axtree = self._loop.run_until_complete(self._page.accessibility.snapshot())
105+
flat_axtree = flatten_axtree(axtree)
106+
return flat_axtree
105107

106108
def step(self, action: ToolCallAction):
107109
fn = self._actions[action.function.name]
@@ -126,3 +128,54 @@ def actions(self) -> tuple[ToolSpec]:
126128

127129
def close(self):
128130
self._loop.run_until_complete(self._browser.close())
131+
132+
133+
def flatten_axtree(axtree_dict: dict | None) -> str:
134+
"""
135+
Traverses accessibility tree dictionary and returns its markdown view.
136+
137+
Args:
138+
axtree_dict: Accessibility tree from playwright page.accessibility.snapshot()
139+
Structure: dict with 'role', 'name', 'value', 'children' keys
140+
141+
Returns:
142+
String representation of the accessibility tree in markdown format
143+
"""
144+
if axtree_dict is None:
145+
return ""
146+
147+
def traverse_node(node: dict, depth: int = 0) -> list[str]:
148+
"""Recursively traverse the accessibility tree and build markdown lines."""
149+
lines = []
150+
indent = " " * depth # 2 spaces per indent level
151+
152+
# Extract node information
153+
role = node.get("role", "")
154+
name = node.get("name", "")
155+
value = node.get("value", "")
156+
157+
# Build the node representation
158+
parts = []
159+
if role:
160+
parts.append(f"{role}:")
161+
if name.strip():
162+
parts.append(f"{name}")
163+
if value:
164+
parts.append(f"[value: {value}]")
165+
166+
# Only add line if there's meaningful content
167+
if parts:
168+
line = f"{indent}{' '.join(parts)}"
169+
lines.append(line)
170+
171+
# Recursively process children
172+
children = node.get("children", [])
173+
for child in children:
174+
child_lines = traverse_node(child, depth + 1)
175+
lines.extend(child_lines)
176+
177+
return lines
178+
179+
# Start traversal from root
180+
all_lines = traverse_node(axtree_dict, depth=0)
181+
return "\n".join(all_lines)

0 commit comments

Comments
 (0)