Commit Graph

15 Commits

Author SHA1 Message Date
525e555884 test(lib): add golden regression suite for mouse + scroll
64 parametrised cases (8 routes/scrolls x 4 seeds each) compare the
rewritten ORT/NumPy pipeline against captures from the pre-migration
PyTorch implementation.

The pre-migration captures used torch.manual_seed + torch.randn for the
flow-ODE noise; the rewrite uses np.random.default_rng. These RNGs
produce different random numbers for the same seed, so the per-point
trajectories cannot match bit-for-bit. The suite therefore guards
*structural* equivalence:

  * mouse: identical shape, start/end snapping, xy diff within
    max(30 px, 20% of move distance), timestamp diff within 700 ms
  * scroll: identical shape (skip with reason on quantum boundary
    drift), identical deltaMode, identical total signed scroll
    distance, per-event delta within 2 wheel quanta, timestamp diff
    within 700 ms

Observed worst-case in this run: ~170 px xy diff on a 1681 px move
(~10% of distance, well under the 20% envelope) and ~600 ms timestamp
drift. All 64 cases pass; 0 skipped.

Goldens stored as compressed .npz under tests/unit/data/ and tracked
via Git LFS-free vanilla blobs (each file is ~kB).
2026-05-12 01:19:58 +08:00
d39db46170 feat(lib): switch __init__ to ONNX-backed generate/generate_scroll 2026-05-12 01:16:03 +08:00
4e69ecc963 feat(lib): add ScrollModel (numpy + ONNX Runtime); rename legacy scroll module 2026-05-12 01:14:37 +08:00
bae9a93ffa feat(lib): add MouseModel (numpy + ONNX Runtime) 2026-05-12 01:13:06 +08:00
2231e4e24b feat(lib): add sample_duration, truncnorm_sample (no scipy) 2026-05-12 01:09:22 +08:00
b93d240641 feat(lib): add resample_arc, build_timestamps 2026-05-12 01:08:39 +08:00
6cfcb6d1a4 feat(lib): add smooth_start, enforce_forward_monotonic 2026-05-12 01:07:58 +08:00
09e8ebee4a feat(lib): add snap_endpoints to _postprocess 2026-05-12 01:07:19 +08:00
6d848dc23d feat(lib): add gaussian_smooth to _postprocess 2026-05-12 01:06:42 +08:00
3c1cf171a7 feat(lib): add _assets module for bundled-weight resolution
Provide bundled_path() and resolve() helpers that locate ONNX
weights and JSON metadata via importlib.resources, falling back to
a user-supplied directory. Missing assets raise ModelLoadError.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-12 01:04:37 +08:00
8182bb1a01 feat(lib): add errors module
Introduce AiMouseError base class plus ModelLoadError and
GenerationError subclasses so downstream consumers can catch the
umbrella or specific failure modes.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-12 01:02:57 +08:00
17b406c28b feat(lib): add private _coord.py with numpy transforms
Copy of coord.py (which is already pure numpy) into the private
underscored module to be consumed by upcoming mouse.py rewrite.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-12 01:02:25 +08:00
fc7b2bd236 refactor(tests): split into tests/unit and tests/tools 2026-05-12 00:47:00 +08:00
e3d4626031 test: capture scroll generate() golden output (pre-migration) 2026-05-12 00:20:13 +08:00
98daef54ca test: capture mouse generate() golden output (pre-migration) 2026-05-12 00:19:39 +08:00