project-nomad/admin/app/models
Chris Sherwood e68c753e39 feat(KB): surface embedding-disk estimate in curated tier-change modal (RFC #883 §1)
When a user picks a tier in TierSelectionModal, show how much additional
disk space the AI Assistant will need if the new ZIMs are indexed, plus
a policy-aware footer explaining whether they'll auto-index (Always) or
wait for opt-in (Manual). Estimates consume #891's KbRatioRegistry via a
new POST /api/rag/estimate-batch endpoint.

Backend
- New POST /api/rag/estimate-batch route + RagController.estimateBatch
- VineJS schema accepting array of {filename, sizeBytes}, capped at 500
- KbRatioRegistry.estimateBatch aggregates via the existing prefix-match
  lookup, returns {totalChunks, totalBytes, hasUnknown}
- New BYTES_PER_CHUNK_ON_DISK constant (~8 KB: 3 KB vector + ~3 KB chunk
  text + ~2 KB payload/index overhead). Tunable; will be replaced by
  Phase 4 self-calibration once we have real measurements.
- Controller normalizes incoming filenames via path.basename so callers
  that send full paths or URLs still match registry prefixes correctly.

Frontend
- api.estimateEmbeddingBatch() client method
- TierSelectionModal: when localSelectedSlug is set, resolve the tier's
  resources (incl. inherited tiers), POST to /estimate-batch, and render
  a new info block with the +~X GB figure + ingest-policy copy. Also
  fetches rag.defaultIngestPolicy so the same block surfaces whether
  indexing will fire automatically or wait for the user.
- resourceFilename() helper extracts the basename from the resource URL
  so the registry lookup hits the right prefix regardless of mirror.

Tests
- 4 new cases in tests/unit/kb_ratio_lookup.spec.ts covering the
  estimateBatch aggregator: standard sum, unknown-flagging, video-only
  ZIM (0 chunks but known, hasUnknown stays false), empty input.

Stacks on feat/kb-ratio-registry (#891) — consumes the registry table
seeded by that PR. Once #891 merges to rc, this PR auto-rebases.

Out of scope for this PR (deferred to follow-ups):
- Per-batch opt-in checkbox (RFC §1's '☑ Also index these for AI') needs
  a per-batch policy override path and is a separate PR
- Guardrail modal at 50 GB / 10% free / 6 hr thresholds (RFC §7) is also
  separate; this PR is informational, not gating
- Time-to-embed estimate awaits a chunks-per-second metric per host
2026-05-20 10:16:00 -07:00
..
benchmark_result.ts feat(benchmark): Require full benchmark with AI for community sharing (#99) 2026-01-25 00:24:31 -08:00
benchmark_setting.ts feat: Add system benchmark feature with NOMAD Score 2026-01-22 21:48:12 -08:00
chat_message.ts feat: [wip] native AI chat interface 2026-01-31 20:39:49 -08:00
chat_session.ts feat: [wip] native AI chat interface 2026-01-31 20:39:49 -08:00
collection_manifest.ts feat: curated content system overhaul 2026-02-11 15:44:46 -08:00
custom_library_source.ts feat(Content): custom ZIM library sources with pre-seeded mirrors (#593) 2026-05-20 10:16:00 -07:00
installed_resource.ts feat: curated content system overhaul 2026-02-11 15:44:46 -08:00
kb_ingest_state.ts feat(KB): per-file ingest state machine (Phase 1 of RFC #883) (#888) 2026-05-20 10:16:00 -07:00
kb_ratio_registry.ts feat(KB): surface embedding-disk estimate in curated tier-change modal (RFC #883 §1) 2026-05-20 10:16:00 -07:00
kv_store.ts feat(AI Assistant): custom name option for AI Assistant 2026-03-04 20:05:14 -08:00
map_marker.ts feat(maps): add scale bar and location markers (#636) 2026-04-03 14:26:50 -07:00
service.ts feat: support for updating services 2026-03-11 14:08:09 -07:00
wikipedia_selection.ts feat: Add dedicated Wikipedia Selector with smart package management 2026-01-31 21:00:51 -08:00