Commit Graph

522 Commits

Author SHA1 Message Date
Saurav Panda 20e11bcb89 fix: propagate root-frame AX failures, only skip child detaches
Codex flagged that the previous catch-all skipped root-frame failures
too, masking a stale main-frame id as a successful (but empty) AX tree
and breaking interactiveness/form-value serialization that depend on
node.ax_node. Re-raise on the root frame so the retry/empty-DOM path
runs; continue to skip detached child iframes.
2026-05-06 13:35:39 -07:00
Saurav Panda 3a2b93cd05 scope down: drop #4484 step_interval fix, keep AX tree fix only
Codex review noted the original `previous_end - previous_start` formula,
while semantically misnamed, is load-bearing for replay correctness:
rerun_history uses it as a heuristic delay before replaying each step,
giving slow pages time to settle. Switching to the literal "gap" between
steps (~0 because step_start_time is set at the top of step()) silently
regresses replay on slow pages. #4484 needs a more careful redesign.
2026-05-06 12:15:58 -07:00
Saurav Panda 6c57fe75eb fix: correct step_interval gap calc and survive AX tree iframe detach
- StepMetadata.step_interval was computing the previous step's duration
  instead of the gap between steps. Use current_start - previous_end so
  rerun_history's "saved interval includes LLM time" comment actually
  holds (closes #4484). Existing test encoded the bug as expected; updated
  to assert gap semantics.

- _get_ax_tree_for_all_frames called asyncio.gather without
  return_exceptions=True, so a single iframe detaching between
  Page.getFrameTree and Accessibility.getFullAXTree (TOCTOU race common
  with ad/widget iframes) discarded AX data from every other frame
  including the main document, leaving the agent blind. Now skips dead
  frames and merges surviving trees (closes #4778).
2026-05-06 12:08:42 -07:00
Laith Weinberger 9ad4c63cdb fix pagination classifier to prioritize semantic labels over shared glyph symbols 2026-04-11 18:30:46 -04:00
MagMueller e600b70d45 fix: reuse querySelectorAll result to avoid duplicate DOM traversal 2026-04-01 16:55:52 -07:00
MagMueller d2aab6b495 fix: address review comments (StopIteration, isClickable semantics) 2026-04-01 16:45:34 -07:00
MagMueller 163575d9d7 style: fix lint (unused import, redundant parens) 2026-04-01 16:24:17 -07:00
MagMueller 89d82689d8 perf: fix O(n²) bottlenecks in DOM capture for heavy pages
Three targeted fixes for pages with 5k+ elements:

1. build_snapshot_lookup: convert isClickable list to set before loop
   _parse_rare_boolean_data used `index in list` (O(n) per call).
   Called once per node = O(n²). Now O(1) via set lookup.
   20k elements: 14,160ms → 2,973ms. 100k: 356s → 9s.

2. RectUnionPure: add _MAX_RECTS=5000 safety cap
   Paint order rect union fragments exponentially with overlapping
   layers. Uncapped, 20k elements took 372s. Capped: 4.7s.
   Degrades gracefully (less aggressive filtering, same correctness).

3. Skip JS listener detection on pages with >10k elements
   querySelectorAll('*') + per-element DOM.describeNode took 2.3s at 20k.
   Elements still detected via accessibility tree + heuristics.

Combined effect at 20k elements: ~400s → ~16s (25x faster).
Normal pages (<5k elements) are completely unaffected.
2026-04-01 16:21:33 -07:00
MagMueller 6a92780586 perf: fix O(n²) in build_snapshot_lookup — 39x speedup at 100k elements
_parse_rare_boolean_data used `index in list` (O(n) per call) on the
isClickable rare boolean data. Called once per node, this was O(n²)
total — the #1 bottleneck in the entire pipeline.

Fix: convert the list to a set once before the loop. O(1) per lookup.

Before → After:
  5k elements:  1,788ms →   768ms  (2.3x)
  20k elements: 16,819ms → 2,911ms (5.8x)
  100k elements: 356,629ms → 9,224ms (38.7x)

This single fix makes the full pipeline 2-3x faster at every scale:
  5k:  8.0s → ~3.8s
  20k: 29.7s → ~16s
  100k: impossible → ~20s (Chrome-limited, not Python-limited)
2026-04-01 15:53:47 -07:00
MagMueller 5ec5c8d43a perf: hoist CDP session lookup + cap paint order rect explosion
Two additional performance fixes for heavy pages:

1. Hoist get_or_create_cdp_session() outside _construct_enhanced_node
   Previously called once PER DOM NODE inside the recursive tree
   construction. On a 100k-element page, this was 100k+ async
   operations. Now resolved once before recursion starts.

2. Add _MAX_RECTS=5000 safety cap to RectUnionPure
   The paint order rect union can fragment exponentially with many
   overlapping translucent layers (each add() splits up to 4 rects).
   Cap prevents memory/CPU explosion on complex pages.

Also: expanded stress test suite to 15 pages (up to 132k elements)
including shadow DOM + iframe combos, overlapping layers, cross-origin
iframes, and a 100k flat element test. All 15 pass.
2026-04-01 12:25:10 -07:00
MagMueller 683994da8e fix: prevent DOM capture timeout on heavy pages (20k+ elements)
Pages with very large DOMs (e.g. Stimulsoft designer with 20,000+
elements) cause the browser state capture to time out, making the
agent unable to interact with the browser.

Three targeted fixes:

1. Skip JS listener detection on heavy pages (>10k elements)
   The querySelectorAll('*') + getEventListeners() loop followed by
   individual DOM.describeNode CDP calls for each listener element is
   O(n) and can take 10s+ alone on heavy pages.

2. Batch DOM.describeNode calls (chunks of 50)
   Previously all calls fired at once via asyncio.gather, flooding the
   CDP WebSocket and causing timeouts on concurrent operations.

3. Adaptive CDP timeouts based on page complexity
   - >15k elements: 25s initial / 10s retry (was 10s/2s)
   - >5k elements: 15s initial / 5s retry
   - Normal pages: unchanged 10s/2s
2026-04-01 11:25:03 -07:00
Saurav Panda 03de83a069 Merge branch 'main' into iframe-click-issue 2026-03-21 15:57:02 -07:00
Saurav Panda 3b8f2457b1 fix: index elements inside cross-origin iframes reliably 2026-03-21 15:54:35 -07:00
Laith Weinberger 43b5e4ce1d rm code agent 2026-03-21 02:05:42 -04:00
Saurav Panda cc1cf2b1c7 Merge branch 'main' into fix-image-url-stripping 2026-03-19 15:34:27 -07:00
Saurav Panda 9445a9ff9e fix image URLs stripped from extracted markdown 2026-03-19 15:29:06 -07:00
Ahmed Aly 0d0eae16d2 zach/chore: fix ruff 2026-03-17 03:48:54 +00:00
Ahmed Aly e8d1681cd5 zach/chore: strip password field values from DOM snapshots sent to LLM 2026-03-17 03:26:24 +00:00
laithrw a511ba2f1e Merge branch 'main' into 3619 2026-02-03 17:32:46 -05:00
Saurav Panda 48206d62ad fixed code style issues 2026-02-02 16:08:29 -08:00
Saurav Panda 7c05e73bbf improve markdown splitting based on header 2026-02-02 12:37:28 -08:00
Saurav Panda 0b0adfb36c fixed parsing issue with non table data 2026-02-02 10:52:44 -08:00
Saurav Panda e66eac8a37 Improve Markdown Chunker 2026-02-02 00:05:09 -08:00
Saurav Panda 6878bd1ca4 handle autocomplete fields 2026-01-30 11:04:00 -08:00
Laith Weinberger 5b9371ee30 use existing clickable element detector 2026-01-26 17:21:38 -05:00
Laith Weinberger e1c4eeef35 fix(#3538): always index scrollable dropdown containers regardless of interactive descendants 2026-01-25 17:05:10 -05:00
Laith Weinberger f3f82689dd fix docstring incorrectly referencing y_position instead of pages + show generic hint 2026-01-25 13:19:30 -05:00
Laith Weinberger 9027991bae when detecting iframe elements, tell LLM exactly how far to scroll to reach each
Get pixel location of each iframe element that's out of the viewport, convert from pixels to number of page lengths, and provide that to the LLM as context
2026-01-25 13:11:37 -05:00
Laith Weinberger 230a60d6c5 lint 2026-01-25 12:29:29 -05:00
Laith Weinberger eb8e1c1d59 fix(#3619): add hidden content hints for iframes in DOM context
Elements in iframes beyond the 1000px viewport threshold are filtered from selector_map, causing agents to scroll blindly to find them. Add hints to the LLM context indicating hidden content
2026-01-25 12:19:57 -05:00
laithrw 468d149588 Merge branch 'main' into fix/3292-table-row-clickability 2026-01-25 10:48:47 -05:00
laithrw 794b68b448 Merge branch 'main' into fix/label-span-interactive-antd 2026-01-25 10:43:27 -05:00
Laith Weinberger 0b8aa55d54 Merge branch 'main' into fix/label-span-interactive-antd 2026-01-24 17:19:38 -05:00
Laith Weinberger 1794849886 don't mutate page
instead of writing markers to DOM, collect element references in JS, resolve them to internal Chrome node IDs via CDP, and store those IDs in Python
2026-01-24 16:36:14 -05:00
Laith Weinberger 20f51c7fef detect JS event listeners for clickable elements
uses CDP Runtime.evaluate with includeCommandLineAPI to access getEventListeners() and mark elements with click/mousedown/pointerdown listeners before DOM snapshot capture
2026-01-24 14:44:08 -05:00
sudhanshu112233shukla f49fc33f2d Merge remote-tracking branch 'upstream/main' into fix/3292-table-row-clickability 2026-01-11 13:04:41 +00:00
sudhanshu112233shukla d7990721f8 fix(#3292): make table rows and cells with role='row'/'cell' interactive
- Added 'row', 'cell', 'gridcell' to interactive_roles in ClickableElementDetector
- Added 'row', 'cell', 'gridcell' to interactive_ax_roles in ClickableElementDetector
- Verified logic with isolated test case
2026-01-11 12:48:55 +00:00
Magnus Müller 680d2551df Scroll element 2026-01-10 18:20:32 -08:00
ditingdapeng 882ac6471a fix: detect label/span wrappers for AntD-style controls 2026-01-08 04:04:10 +08:00
Saurav Panda 2c06eabf5f Added ax-name fallback for history rerun. 2026-01-06 12:07:10 -08:00
Saurav Panda 07b7a6d8c0 fix: include shadow DOM form elements in selector_map even without snapshot data 2025-12-19 18:32:40 -08:00
mertunsall 1779e9717d improve hashing of elements using cascading hash 2025-12-17 00:55:27 -08:00
Saurav Panda e9c047be92 include ax_name for rerun history element hash 2025-12-16 17:05:48 -08:00
Cursor Agent 24e276d5f4 Refactor markdown preprocessing and add tests
Co-authored-by: mailmertunsal <mailmertunsal@gmail.com>
2025-12-11 00:00:21 +00:00
Mert Unsal fb8994de13 Revert "Fix: Ignore Inert Carousel Elements" 2025-11-15 23:05:21 -08:00
Mert Unsal b11682bfb5 Merge branch 'main' into Invisible-links 2025-11-15 18:59:55 -08:00
kalil0321 1c85a8a688 Fix lint 2025-11-13 15:49:43 +01:00
kalil0321 0988199776 Merge branch 'main' into kalil0321/demo-mode 2025-11-13 15:34:49 +01:00
reformedot 13868aee9b refactor: update all_frames parameter handling in DomService
- Changed the type of the all_frames parameter to allow for None, enabling lazy fetching of cross-origin iframes only when necessary.
- Updated comments to clarify the behavior of all_frames during DOM tree construction.
2025-11-12 20:05:01 -08:00
reformedot 77d7f161fb refactor: enhance session management and error handling in BrowserSession
- Improved the `create_task_with_error_handling` function to allow for better exception logging and retrieval based on the `suppress_exceptions` parameter.
- Updated `SessionManager` to implement event-driven recovery for stale agent focus, replacing polling with efficient event handling.
- Refactored session retrieval methods to ensure focus validation and recovery are handled automatically.
- Enhanced logging for recovery processes and session management to provide clearer insights into state changes and errors.
- Adjusted various watchdogs to utilize the new session management methods, ensuring they correctly handle focus validation and session retrieval.
2025-11-12 19:42:24 -08:00