@@ -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