Commit graph

93 commits

Author SHA1 Message Date
1fa5b9e2b0 feat(avocet): add cancel buttons for benchmark and fine-tune runs 2026-03-15 18:15:35 -07:00
8e016d7fe6 fix(avocet): narrow cancel except clause, clear stale cancel flags on new run
- except clause in cancel_benchmark/cancel_finetune narrowed from Exception
  to _subprocess.TimeoutExpired (C1)
- _cancelled_jobs.discard() called after registering new proc to prevent
  a stale flag from a prior run masking errors (I2)
- local `import subprocess` removed from run_benchmark and
  run_finetune_endpoint; all Popen calls updated to _subprocess.Popen (I1)
- test patch targets updated from subprocess.Popen to app.api._subprocess.Popen;
  cancelled-event tests updated to set flag in proc.wait() side-effect so
  the discard-on-new-run logic is exercised correctly
2026-03-15 18:13:01 -07:00
30f19711ec feat(avocet): add cancel endpoints for benchmark and finetune jobs
Adds POST /api/benchmark/cancel and POST /api/finetune/cancel endpoints
that terminate the running subprocess (kill on 3s timeout), and updates
the run generators to emit a cancelled SSE event instead of error when
the job was intentionally stopped.
2026-03-15 18:09:20 -07:00
753f8f5def fix(avocet): use_reentrant=False for gradient checkpointing
Reentrant gradient checkpointing (the default) conflicts with Accelerate's
gradient accumulation context manager -- causes 'backward through graph a
second time' on the first training step. use_reentrant=False uses the
non-reentrant autograd hook path which is compatible with Accelerate >= 0.27.
2026-03-15 17:23:40 -07:00
5dee23f53c fix(avocet): reduce deberta-small VRAM + auto-select freest GPU for training
- deberta-small: batch_size 16→8 + grad_accum 1→2 (same effective batch),
  gradient_checkpointing=True (fp16 stays off: DeBERTa v3 disentangled
  attention overflows fp16 at the gather step)
- api: _best_cuda_device() picks highest free-VRAM GPU via nvidia-smi;
  sets CUDA_VISIBLE_DEVICES in subprocess env to prevent DataParallel
  replication across both GPUs; adds PYTORCH_ALLOC_CONF=expandable_segments
- SSE log now reports which GPU was selected
2026-03-15 17:09:06 -07:00
606917f90f feat(avocet): add restart-api command to manage.sh 2026-03-15 17:04:00 -07:00
74ba9103cd fix(avocet): use startsWith for error class in ft-log (consistent with benchmark log) 2026-03-15 16:14:47 -07:00
95eb238add feat(avocet): add fine-tune section and trained models badge row to BenchmarkView 2026-03-15 16:09:51 -07:00
60fe1231ce fix(avocet): _MODELS_DIR overridable in tests; sanitize score paths against path traversal 2026-03-15 16:07:27 -07:00
ef8adfb035 feat(avocet): add /api/finetune/status and /api/finetune/run endpoints 2026-03-15 16:04:34 -07:00
64fd19a7b6 fix(avocet): move TorchDataset import to top; split sample_count into total+train 2026-03-15 16:02:43 -07:00
8ba34bb2d1 feat(avocet): run_finetune, CLI, multi-score-file merge with last-write-wins dedup
- load_and_prepare_data() now accepts Path | list[Path]; single-Path callers unchanged
- Dedup by MD5(subject + body[:100]); last file/row wins (lets later runs correct labels)
- Prints summary line when duplicates are dropped
- Added _EmailDataset (TorchDataset wrapper), run_finetune(), and argparse CLI
- run_finetune() saves model + tokenizer + training_info.json with score_files provenance
- Stratified split guard: val set size clamped to at least n_classes (handles tiny example data)
- 3 new unit tests (merge, last-write-wins dedup, single-Path compat) + 1 integration test
- All 16 tests pass (15 unit + 1 integration)
2026-03-15 15:52:41 -07:00
f262b23cf5 fix(avocet): tighten body truncation test to exact 400-char assertion 2026-03-15 15:44:19 -07:00
5eb593569d feat(avocet): add finetune data pipeline, class weights, WeightedTrainer
Implements load_and_prepare_data (JSONL ingestion with class filtering),
compute_class_weights (inverse-frequency, div-by-zero safe), compute_metrics_for_trainer
(macro F1 + accuracy), and WeightedTrainer.compute_loss (**kwargs-safe for
Transformers 4.38+ num_items_in_batch). All 12 tests pass.
2026-03-15 15:38:45 -07:00
2d795b9573 fix(avocet): guard discover_finetuned_models against malformed/incomplete training_info.json 2026-03-15 15:18:13 -07:00
36117b35c4 feat(avocet): auto-discover fine-tuned models in benchmark harness 2026-03-15 11:59:13 -07:00
da8478082e fix(avocet): FineTunedAdapter GPU device routing + precise body truncation test 2026-03-15 10:56:47 -07:00
7a4ca422ca feat(avocet): add FineTunedAdapter for local checkpoint inference 2026-03-15 10:54:38 -07:00
71d0bfafe6 chore(avocet): add scikit-learn to classifier env 2026-03-15 09:44:04 -07:00
8c22dd62de feat(avocet): benchmark UI, label fixes, BenchmarkView with charts and SSE run 2026-03-15 09:39:37 -07:00
d3ae5b576a docs: finalize fine-tune classifier design spec (3 review passes) 2026-03-15 06:47:17 -07:00
8c26cbe597 docs: add fine-tune classifier design spec 2026-03-15 06:41:38 -07:00
fb1ce89244 fix(avocet): reset card element state when new item loads to clear previous animation inline styles 2026-03-08 07:44:02 -07:00
e01f743c39 feat(avocet): badge pop via Anime.js spring transition hook 2026-03-08 07:35:49 -07:00
6829bebdd4 fix(avocet): constrain grid-active to 640px on wide viewports using left/right offsets 2026-03-08 07:26:46 -07:00
ddb6025c89 feat(avocet): animate bucket grid rise with Anime.js spring 2026-03-08 07:17:56 -07:00
d410fa5c80 fix(avocet): restore drag aura color feedback via updateAura in useCardAnimation 2026-03-08 07:14:24 -07:00
6c98ee6d69 feat(avocet): wire Anime.js card animation into EmailCardStack
Replace CSS keyframe dismiss classes and inline cardStyle/deltaX/deltaY
with useCardAnimation composable — pickup/setDragPosition/snapBack/animateDismiss
are now called from pointer event handlers and a dismissType watcher.
2026-03-08 07:07:58 -07:00
3197252c31 docs: fix animejs v4 API examples in animation plan (spring object form, 2-arg animate) 2026-03-08 07:00:10 -07:00
4bea1b6812 feat(avocet): add useCardAnimation composable with Anime.js
TDD: 8 tests written first (red), then composable implemented (green).
Adapts to Anime.js v4 API: 2-arg animate(), object-param spring(),
utils.set() for instant drag-position updates without cache desync.
2026-03-08 06:52:27 -07:00
d418a719f0 feat(avocet): add animejs v4 dependency 2026-03-08 06:47:50 -07:00
144a9b29b3 docs: add Anime.js animation implementation plan 2026-03-08 06:38:16 -07:00
8af63d959b docs: add Anime.js animation integration design 2026-03-08 06:33:46 -07:00
cfa5ed2194 docs: add privacy policy reference 2026-03-05 20:59:37 -08:00
e03d91ece9 fix(avocet): ball escapes overflow clip, floats above header/footer with z-index + transparency 2026-03-05 15:14:24 -08:00
be3b52f150 fix(avocet): grid pinned to viewport with height 100dvh + card ball floats above finger at scale 0.55 2026-03-05 15:07:58 -08:00
1ccac024a4 feat(avocet): add velocity-based fling detection to toss gesture (option B: speed + alignment) 2026-03-05 14:55:10 -08:00
f8e911c48f feat(avocet): add toss-zone overlays and grid-rise animation to LabelView 2026-03-05 13:41:52 -08:00
2bbd925c41 feat(avocet): replace swipe+HTML5-drag with unified pointer-events toss gesture 2026-03-05 10:38:52 -08:00
a8b1c89c62 feat(avocet): replace HTML5 drag events on LabelBucketGrid with hoveredBucket prop 2026-03-05 10:10:48 -08:00
f8aafb2974 feat: card crumples to small ball on drag pickup so buckets expand fully 2026-03-04 12:38:46 -08:00
d82db402a3 fix: keyboard shortcuts now work after labels load (lazy keymap evaluation)
useLabelKeyboard now accepts labels as Label[] | (() => Label[]).
The keymap is rebuilt on every keypress from the getter result instead of
being captured once at construction time — so keys 1–9 now fire correctly
after the async /api/config/labels fetch completes.

LabelView passes () => labels.value so the reactive ref is read lazily.

New test: 'evaluates labels getter on each keypress' covers the async-load
scenario (empty list → no match; push a label → key fires).
2026-03-04 12:32:25 -08:00
ba25ee47a5 fix: pin bucket grid to bottom of viewport with sticky footer; prevents mis-click from layout shift 2026-03-04 12:26:04 -08:00
cf69452e42 feat: implement FetchView — SSE progress bars, account selection, targeted fetch 2026-03-04 12:23:58 -08:00
a9f7ba1b0c feat: implement StatsView — label distribution bars, file info, download 2026-03-04 12:21:21 -08:00
d372155e4b feat: implement SettingsView — IMAP account management, test connection, display toggles 2026-03-04 12:20:30 -08:00
7fa62ae073 feat: add useApiSSE helper for Server-Sent Events connections 2026-03-04 12:17:46 -08:00
7bd37ef982 feat: add Vue Router + stow-able AppSidebar; stub Fetch/Stats/Settings views 2026-03-04 12:12:26 -08:00
f38c73db97 feat: add GET /api/fetch/stream SSE endpoint for real-time IMAP progress 2026-03-04 12:05:23 -08:00
965362f5e3 feat: add POST /api/accounts/test endpoint 2026-03-04 12:04:42 -08:00