@@ -47,17 +47,8 @@ async def bfs(self, websocket=None):
47
47
for _ in range (level_size ):
48
48
current_node = queue .popleft ()
49
49
queue_set .remove (current_node ) # Remove from queue tracking
50
-
51
- # Skip if we've already visited this node
52
- if current_node in visited :
53
- continue
54
-
55
50
visited .add (current_node )
56
51
57
- # Skip terminal nodes
58
- if current_node .is_terminal :
59
- continue
60
-
61
52
# Expand current node if it hasn't been expanded yet and hasn't reached max_depth
62
53
# node expansion for the next level
63
54
if not current_node .children and current_node .depth < self .config .max_depth :
@@ -78,7 +69,7 @@ async def bfs(self, websocket=None):
78
69
79
70
# Add non-terminal children to queue for next level if they haven't reached max_depth
80
71
for child in current_node .children :
81
- if not child . is_terminal and child not in visited and child not in queue_set and child .depth < self .config .max_depth :
72
+ if child not in visited and child not in queue_set and child .depth <= self .config .max_depth :
82
73
queue .append (child )
83
74
queue_set .add (child ) # Add to queue tracking
84
75
@@ -134,76 +125,50 @@ async def bfs(self, websocket=None):
134
125
135
126
return None
136
127
137
- # TODO: first evaluate, then expansion
138
- async def dfs (self , websocket = None ) -> List [Dict [str , Any ]]:
139
- stack = [self .root_node ]
128
+ async def dfs (self , websocket = None ):
129
+ stack = [self .root_node ] # Use a list as a stack
140
130
stack_set = {self .root_node } # Track nodes in stack
141
131
best_score = float ('-inf' )
142
132
best_path = None
143
133
best_node = None
144
134
visited = set () # Track visited nodes to avoid cycles
145
- current_path = [] # Track current path for DFS
146
-
147
- # # Get the live browser URL during initial setup
148
- # live_browser_url, session_id = await self._reset_browser(websocket)
149
-
150
135
151
136
while stack :
152
- current_node = stack [- 1 ] # Peek at the top node without removing it
153
-
154
- # Skip if we've already visited this node
155
- if current_node in visited :
156
- stack .pop ()
157
- stack_set .remove (current_node )
158
- if current_path :
159
- current_path .pop () # Remove from current path
160
- continue
161
-
137
+ # Get the top node from the stack
138
+ current_node = stack .pop ()
139
+ stack_set .remove (current_node ) # Remove from stack tracking
162
140
visited .add (current_node )
163
- current_path .append (current_node ) # Add to current path
164
141
165
- # Skip terminal nodes
166
- if current_node .is_terminal :
167
- print (f"Node { id (current_node )} is terminal" )
168
- stack .pop ()
169
- stack_set .remove (current_node )
170
- current_path .pop () # Remove from current path
171
- continue
172
-
173
142
# Expand current node if it hasn't been expanded yet and hasn't reached max_depth
174
- # stage 1: node expansion
175
143
if not current_node .children and current_node .depth < self .config .max_depth :
176
- ## during the node expansion process, reset browser for each node
144
+ # Reset browser for each node expansion
177
145
live_browser_url , session_id = await self ._reset_browser (websocket )
178
- # await self.websocket_step_start(step=1, step_name="node_expansion", websocket=websocket)
179
146
await self .websocket_node_selection (current_node , websocket = websocket )
180
147
await self .node_expansion (current_node , websocket )
181
148
tree_data = self ._get_tree_data ()
149
+
182
150
if websocket :
183
151
await self .websocket_tree_update (type = "tree_update_node_expansion" , websocket = websocket , tree_data = tree_data )
184
152
else :
185
153
print_entire_tree (self .root_node )
186
154
187
- # Get the path from root to this node
188
- path = self .get_path_to_root (current_node )
155
+ # Node evaluation
189
156
await self .node_evaluation (current_node )
190
157
tree_data = self ._get_tree_data ()
191
158
if websocket :
192
159
await self .websocket_tree_update (type = "tree_update_node_evaluation" , websocket = websocket , tree_data = tree_data )
193
160
else :
194
161
print ("after evaluation" )
195
162
print_entire_tree (self .root_node )
196
- path = self .get_path_to_root (current_node )
197
163
198
-
164
+ path = self . get_path_to_root ( current_node )
199
165
score = current_node .value
200
166
201
167
# Update best path if this score is better
202
168
if score > best_score :
203
169
best_score = score
204
170
best_path = path
205
171
best_node = current_node
206
-
207
172
208
173
print (f"Node { id (current_node )} score: { score } " )
209
174
@@ -213,23 +178,16 @@ async def dfs(self, websocket=None) -> List[Dict[str, Any]]:
213
178
214
179
# Send completion update if websocket is provided
215
180
await self .websocket_search_complete ("success" , score , current_node .get_trajectory (), websocket = websocket )
216
- await self .playwright_manager .close ()
181
+ await self .playwright_manager .close ()
182
+
217
183
return current_node
218
-
219
- # Add non-terminal children to stack in reverse order
220
- has_unvisited_children = False
184
+
185
+ # Add children to stack in reverse order so that the first child is processed first
186
+ # This maintains the left-to-right exploration order similar to BFS
221
187
for child in reversed (current_node .children ):
222
- if not child . is_terminal and child not in visited and child not in stack_set :
188
+ if child not in visited and child not in stack_set and child . depth <= self . config . max_depth :
223
189
stack .append (child )
224
190
stack_set .add (child ) # Add to stack tracking
225
- has_unvisited_children = True
226
- break # Only add one child at a time for DFS
227
-
228
- # If no unvisited children, remove current node from stack
229
- if not has_unvisited_children :
230
- stack .pop ()
231
- stack_set .remove (current_node )
232
- current_path .pop () # Remove from current path
233
191
234
192
# If we've exhausted all nodes and haven't found a perfect solution,
235
193
# return the best path we found
@@ -249,5 +207,4 @@ async def dfs(self, websocket=None) -> List[Dict[str, Any]]:
249
207
await self .websocket_search_complete ("failure" , 0 , None , websocket = websocket )
250
208
await self .playwright_manager .close ()
251
209
252
- return None
253
-
210
+ return None
0 commit comments