Add deferred lifecycle features: storage selection, dedup, gallery, live metrics, checkpoints, recommendations, invite - #22
Open
whittenator wants to merge 5 commits into
Open
Conversation
…rain link Additive columns (migration 0010): workspaces.storage_backend/storage_config, experiment_runs.checkpoints, al_runs.last_train_run_id. Adds boto3 dependency for the S3 storage backend. Feature implementations that use these land in follow-up commits. https://claude.ai/code/session_019z4CBrSBy1zDWkJb7KhjKr
…flow
- similarity_service.py: pgvector cosine NN + duplicate-pair detection with a
Python fallback for SQLite.
- api/assets.py: GET /assets/{id}/similar, GET /datasets/{id}/duplicates,
POST /datasets/{id}/embeddings (dispatches the embeddings task).
- duplicates.tsx: dedup gallery with generate-embeddings flow.
- admin/users.tsx: invite form now calls POST /api/workspaces/{id}/members
with proper error surfacing.
Frontend route wiring for the duplicates page lands with the App.jsx
integration commit.
https://claude.ai/code/session_019z4CBrSBy1zDWkJb7KhjKr
- experiments.py: GET /api/experiments/runs/{runId}/metrics/stream (SSE) sharing
a metrics-parsing helper with the snapshot endpoint; [runId].tsx consumes it
via EventSource with polling fallback.
- ops.py: POST /api/datasets/{id}/prelabel dispatches the prelabels task
(409 when no model, 502 on dispatch failure).
- browse.tsx: filterable/paginated asset thumbnail gallery with a prelabel
action.
Route wiring for the browse page lands with the App.jsx integration commit.
https://claude.ai/code/session_019z4CBrSBy1zDWkJb7KhjKr
- POST /api/al/runs/{id}/retrain: launches training from an AL run's resolved
items (409 if none resolved), records last_train_run_id.
- GET /api/al/runs/{id}/progress: resolved/pending counts + last retrain link.
- active_learning_service.resolution_stats helper.
- [alRunId].tsx: retrain panel with spawned-run link and job polling.
https://claude.ai/code/session_019z4CBrSBy1zDWkJb7KhjKr
…ive metrics, checkpoints, recommendations, invite
Implements the roadmap features deferred from the audit remediation PR.
Storage:
- Per-workspace object-storage backend selection (MinIO or S3/boto3) via a
strategy layer (services/storage_backends.py); owner/admin settings API
(api/settings.py) with secret redaction + connection test; settings UI
(pages/settings/storage.tsx). Workspace.storage_backend/storage_config
columns (migration 0010). storage.py stays backward compatible.
Dataset curation & analysis:
- Embedding similarity search + duplicate detection over Asset.embedding
(pgvector on Postgres, Python cosine fallback on SQLite): /api/assets/{id}/
similar, /api/datasets/{id}/duplicates, /api/datasets/{id}/embeddings, and a
dedup UI (duplicates.tsx).
- Asset browse/filter gallery (browse.tsx) + dataset-wide prelabel trigger
(POST /api/datasets/{id}/prelabel).
- Server-driven 'suggested improvements' recommendations engine
(/api/datasets/{id}/recommendations) surfaced on the metrics page.
Training:
- Intermediate checkpoint persistence + resume (ExperimentRun.checkpoints,
resume_from through launch_training, Ultralytics resume support,
experiments/new.tsx control).
- Live training metrics via SSE (/api/experiments/runs/{id}/metrics/stream)
consumed by EventSource with polling fallback.
Admin: wired the workspace member-invite form to POST /api/workspaces/{id}/members.
Wiring: settings router in main.py; /settings/storage, /datasets/:id/browse,
/datasets/:id/duplicates routes + nav in App.jsx; browse/duplicates links on
the dataset page.
Tests: 224 backend unit tests pass (44 new); frontend builds, ESLint clean,
17 vitest tests pass, no new TypeScript errors; ruff/black clean.
https://claude.ai/code/session_019z4CBrSBy1zDWkJb7KhjKr
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Implements the roadmap/lifecycle features that were intentionally deferred from the audit-remediation PR (#21) — the items listed under "Deferred (roadmap, not bugs)" and Phase 2/3 of
AUDIT.md. Built as 8 independent feature slices with a single migration (0010) and central router/route wiring.Features
Storage — per-workspace MinIO vs S3 selection
services/storage_backends.py) supporting MinIO and S3 (boto3, import-guarded);services/storage.pystays backward-compatible (12+ call sites unchanged).api/settings.py): GET/PUT storage config with secret-key redaction, plus a connection-test endpoint.pages/settings/storage.tsx) +SETTINGSnav entry.Workspace.storage_backend/storage_configcolumns.Dataset curation & analysis
Asset.embedding(pgvector cosine on Postgres, Python-cosine fallback on SQLite):GET /api/assets/{id}/similar,GET /api/datasets/{id}/duplicates,POST /api/datasets/{id}/embeddings, and a dedup UI (duplicates.tsx).browse.tsx) with thumbnail grid, status/split filters, pagination.POST /api/datasets/{id}/prelabel) wiring the existing prelabel task to a model artifact.GET /api/datasets/{id}/recommendations) — server-derived, prioritized (imbalance / unused classes / low coverage / empty images / small dataset / tiny objects / resolution spread / review backlog) — surfaced on the metrics page.Training
ExperimentRun.checkpoints,resume_fromthroughlaunch_training, Ultralytics resume support, and a resume control inexperiments/new.tsx.GET /api/experiments/runs/{id}/metrics/streamconsumed withEventSource(polling retained as fallback).Active learning
POST /api/al/runs/{id}/retrainlaunches training from resolved items (409 if none), recordsALRun.last_train_run_id;GET /api/al/runs/{id}/progress; retrain UI panel.Admin
POST /api/workspaces/{id}/memberswith proper success/error surfacing.Wiring (central, to avoid conflicts)
main.py: settings router.App.jsx:/settings/storage,/datasets/:id/browse,/datasets/:id/duplicatesroutes +SETTINGSnav + browse/duplicates links on the dataset page.0010_feature_columns(single clean head over0009), all columns nullable/defaulted withIF NOT EXISTS-style guards.Test plan
ruff/blackclean; full app imports; all 8 new endpoint groups verified registered; migration head verified.tscerror count unchanged from base (14 pre-existing, 0 new).🤖 Generated with Claude Code
https://claude.ai/code/session_019z4CBrSBy1zDWkJb7KhjKr
Generated by Claude Code