Skip to content

feat(scroll): support explicit budgets for long target searches - #3837

Open
thymikee wants to merge 8 commits into
mainfrom
perf/android-scroll-latency
Open

thymikee wants to merge 8 commits into
mainfrom
perf/android-scroll-latency

Conversation

@thymikee

@thymikee thymikee commented Oct 19, 2026 •

Copy link
Copy Markdown
Member

Summary

Long lists exceed the default 12-gesture budget and force costly per-page scroll/snapshot requests. Add explicit maxPasses (1–200) to the existing verified search loop through CLI/Node/MCP and recorded .ad scripts. Canceled requests stop before another capture or gesture.

agent-device scroll down --until 'id="row-512"' --max-passes 90

The policy is shared by local and provider bindings with scroll/capture capabilities; each backend retains its gesture timing and reliability checks. Adapter adoption must preserve container scope, momentum and deadlines. Only Android gains are measured.

25 files: production +128/-56; tests +197/-12; docs +430/-1; gate +1. Scope includes request-signal construction and gesture-help extraction. Context: tester-army/e2e#1234.

Validation

  • Head 89ccdad99b11c648e3f98e1833e851ab6e69cc1a: pnpm check:affected --run --head 89ccdad99b passed: 36 checks, exactCommit=true, checkoutChanged=false (receipt run-g3cFRI).
  • Hosted Coverage failed the eager-import budget: flag metadata loaded execution helpers (31 vs 30 modules). Type-only metadata linkage fixes it while compile-time checking the shared maximum. No tests added in this correction. Existing eager-import check: published head 1 failed/852 passed; fix 853 passed.
  • Full Coverage command passed (16,444 main-suite tests and 11 fuzz-worker tests). Changed-line and changed-branch coverage 100%; coverage/complexity gate passed.
  • Android ABBA: 55 gestures each; median 44.510 → 27.581 s (38.0% faster), exact target verified. Recording/replay: 6 steps, zero healing. Our app: correct product and one-pass refusal verified.
  • Independent Opus reviews clean. Measurements and shared applicability.
  • Hosted checks at the new head remain CI obligations.

@github-actions

github-actions Bot commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor
PR Preview Action v1.8.1

QR code for preview link

🚀 View preview at
https://callstack.github.io/agent-device/pr-preview/pr-3837/

Built to branch gh-pages at 2026-10-19 20:02 UTC.
Preview will be ready when the GitHub Pages deployment is complete.

@github-actions

github-actions Bot commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

Size Report

Metric Base Current Diff
Installed (including dependencies) 5.45 MB 5.45 MB +1.3 kB
Package (unpacked) 5.45 MB 5.45 MB +1.3 kB
Package (download) 1.65 MB 1.65 MB +427 B

Startup median (7 runs, lower is better):

Scenario Base Current Diff
CLI --version 42.2 ms 42.3 ms +0.1 ms
CLI --help 83.2 ms 82.7 ms -0.6 ms

@thymikee

Copy link
Copy Markdown
Member Author

This PR is ready at 89ccdad. The code looks right, and the shared scroll loop applies the pass budget and cancellation as intended. CI is green (19 checks, none failing), and the earlier Coverage failure is fixed at this head by the type-only import. There are no conflicts, and nothing else blocks merge.

Not blocking, and you can take or leave these: (1) the cancellation check lives in the executeUntilScroll closures (https://github.com/callstack/agent-device/blob/89ccdad/packages/daemon/src/execution/scroll-runtime.ts#L355), so a canceled scroll bottom still spends more captures and gestures. Could signal go into runScrollPasses instead, so both paths share one rule? (2) contextFromFlags now sets signal on every daemon dispatch context (https://github.com/callstack/agent-device/blob/89ccdad/packages/daemon/src/core/context.ts#L36), so existing context.signal readers now get a live signal. It would help to name those consumers in the PR body. (3) The refusal text says "scroll --max-passes requires --until" (https://github.com/callstack/agent-device/blob/89ccdad/packages/contracts/src/scroll-command.ts#L92), which is CLI wording that Node and MCP callers also see. (4) The help advertises up to 200 passes (https://github.com/callstack/agent-device/blob/89ccdad/src/commands/schema/cli-help-gestures.ts#L23). At about 0.5 s per pass on Android that is around 100 s, above the 90 s default scroll timeout, so a short note that large budgets may need a longer request timeout would help.

On evidence: I did not re-run the tests or the Android benchmark, and the live numbers and replay run come from the PR's evidence doc. Live coverage is the local Android helper only. Apple, Appium, HarmonyOS, web and provider bindings are covered by the shared-loop source trace and the provider-scenarios integration test. I did not check the new context.signal consumers, such as the macOS native interactor and limrun allocation, for cleanup on cancel.

@thymikee thymikee added the ready-for-human Valid work that needs human implementation, judgment, or maintainer merge label Oct 19, 2026
@thymikee

Copy link
Copy Markdown
Member Author

The code verdict for 89ccdad is unchanged: no findings. The branch now conflicts with main, so I removed ready-for-human for now. Please rebase onto main and resolve the conflicts; I will check the resolution on the new head and add the label back if it is clean.

@thymikee thymikee removed the ready-for-human Valid work that needs human implementation, judgment, or maintainer merge label Oct 20, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant