Skip to content

feat(#365): frontend refinement for libraries and knowledge stores#366

Merged
NoveliaYuki merged 3 commits into
projects/refactor/kbserver-lamb-integrationfrom
feat/#365/frontend-refinement-libraries-ks
May 10, 2026
Merged

feat(#365): frontend refinement for libraries and knowledge stores#366
NoveliaYuki merged 3 commits into
projects/refactor/kbserver-lamb-integrationfrom
feat/#365/frontend-refinement-libraries-ks

Conversation

@NoveliaYuki
Copy link
Copy Markdown
Collaborator

Purpose

Refine the libraries and knowledge stores wizard UX after end-to-end testing on top of the kbserver-integration branch. Removes the duplicate "Create with Knowledge Store" entry point, unifies the KS-detail "Add Content" button with the same Create Knowledge wizard, fixes a cluster of correctness bugs surfaced during testing, and improves error surfacing throughout the flow.

Changes

Single wizard for both creation paths. The "Create with Knowledge Store" button on the Libraries tab is gone. The KS-detail "Add Content" button now mounts the same CreateKnowledgeWizard, pre-filling Step 3 with the current KS via initialState = { ksPath: 'existing', existingKsId, ksName }. The wizard's title and submit button are context-aware — "Add Content" / "Add" when an existing KS is targeted, "Create Knowledge" / "Create" otherwise. Step 2 (Library Content) is no longer skipped for existing-library flows, so users can queue new uploads into an existing library and ingest them in one pass; Step 4 picker merges pending and existing items behind a "NEW" badge.

Wizard correctness. Three loaders (loadLibraries, loadStores, loadOptions) now use a *Loaded sentinel instead of length === 0 to gate their $effect, ending the infinite-loop "Loading…" state when the API returned 0 rows. The path radio choice is dispatched into wizardState immediately so the draft persists the last-clicked option even if other validation hasn't passed. Step 4 selection state is gated by a selectionInitialized flag so Back/Next no longer re-checks deselected items. Step 3 auto-expands the Advanced section when required fields are empty and falls back to a text input for the embedding model when the org has no allowed_embedding_models configured (with the vendor plugin's declared default seeded server-side as a safety net). Step 5 pre-flight check aggregates duplicate-name conflicts (library + KS) into a single message instead of failing one-at-a-time.

Server error surfacing. A readableError helper extracts FastAPI's detail payload (string and dict shapes) at every error site that previously fell through to Axios's bare "Request failed with status code N" — Step 8 Review/Create, Step 1 / 3 loaders, the standalone Library modal, and the Library Detail upload/delete handlers. The FR-10 delete-blocked-by-KS response (dict-shaped detail) is now rendered in a dedicated section inside the confirmation modal: each referencing KS gets a row with item count and an inline "Remove from KS" button calling removeContent so users can clear the references without leaving the dialog.

Backend caps and fallbacks. The /creator/libraries/{id}/items cap was le=100, but the wizard requests limit=200 for the picker — a mismatch that surfaced as 422 in Step 4. Cap raised to le=500 on both the LAMB router and the underlying library-manager endpoint. get_org_options now seeds embedding_models[vendor] with the vendor plugin's declared model default when the org's allowed_embedding_models is empty, so the dropdown is never silently empty. get_accessible_libraries returns an item_count from a correlated subquery on library_items so the libraries list column reflects reality instead of always showing 0.

UX polish. PDF / DOCX / etc. uploads through the wizard now route to markitdown_import via the same pluginForFile extension check the Library Detail page uses (the wizard previously always sent simple_import, which 400'd on anything but txt/md/html). Library detail refreshes after upload / import / delete are silent so the panel no longer flashes back to the loading skeleton. Wizard's Done step honours the user's choice between "Open Knowledge Store" / "Open Library" / "Create another" — both mounting points (/libraries page and KnowledgeStoreDetail) check the dispatched target field and route accordingly. Added two compact navigation shortcuts (Go to start, Go to review) in the wizard footer. Long descriptions clamp to 3 lines with full text in tooltip; the page header <h1> uses leading-tight so descenders aren't clipped at the sm: breakpoint.

Related

Removes the redundant "Create with Knowledge Store" button from the
Libraries tab, repoints the KS-detail "Add Content" button at the same
unified Create Knowledge wizard with the current KS pre-selected at
Step 3, and surfaces an "Add Content" / "Add" title/button when the
wizard is launched in that mode. Step 2 (Library Content) now runs for
existing-library flows too so users can queue new files / URLs into an
existing library and ingest them in a single pass; Step 4 picker merges
pending uploads with existing items behind a "NEW" badge and persists
deselect state across navigation. Step 3 highlights missing required
fields in red, auto-expands the Advanced section when fields are empty,
and falls back to a text input for the embedding model when the org's
options endpoint returns no models for the chosen vendor. Pre-flight
check in Step 5 aggregates duplicate-name conflicts for both library
and KS into a single message; server errors (string and dict-shaped
detail bodies, including the FR-10 delete-blocked-by-KS payload) now
surface verbatim in dialogs instead of bare "Request failed with status
code N". Delete-blocked modal lists referencing knowledge stores with
item counts and inline "Remove from KS" buttons. Wizard's "Open
Library" / "Open Knowledge Store" / "Create another" honour the user's
choice instead of always navigating to the freshly-created KS. PDF and
other non-text uploads through the wizard route to markitdown_import to
match the Library Detail inline-upload behaviour. Library detail page
silently refreshes after upload / import / delete so the panel no
longer flashes back to the loading skeleton, and the page header uses
leading-tight so descenders aren't clipped at the sm breakpoint.
… count

- creator_interface/library_router.py: raise GET /libraries/{id}/items
  limit cap from le=100 to le=500 so the wizard's 200-item picker
  request stops 422-ing.
- library-manager/backend/routers/content.py: same cap raised on the
  underlying library-manager endpoint that the LAMB backend forwards
  to (the previous bump was useless without this).
- creator_interface/knowledge_store_client.py: when the org has not
  configured allowed_embedding_models for a vendor, fall back to the
  vendor plugin's own ``model`` parameter default so the wizard's
  Embedding model dropdown is never silently empty (which left Step 3
  Next disabled with no actionable hint).
- lamb/database_manager.py: get_accessible_libraries now returns an
  ``item_count`` derived from a correlated subquery on
  {prefix}library_items. Counts every status (pending / completed /
  failed) so the Libraries list column matches what users see in the
  detail view, instead of always rendering as 0.
@NoveliaYuki NoveliaYuki added the enhancement New feature or request label May 10, 2026
@NoveliaYuki NoveliaYuki self-assigned this May 10, 2026
- prettier: format the six files prettier flagged after the initial commits.
- prettierignore: exclude static/config.js (runtime-generated copy of
  config.js.sample, not meant to be linted).
- eslint: drop unused imports (`user`), unused locals (`result`), unused
  catch parameters, and the leftover ``openWizard`` shortcut on
  /libraries/+page.svelte. Convert ``new Set(...)`` to ``new SvelteSet(...)``
  for the polling-side ``pendingItemIds`` so it reuses Svelte's reactive
  collection. Park the legitimate ``$state(new SvelteSet(...))`` patterns
  behind ``// eslint-disable-next-line svelte/no-unnecessary-state-wrap``
  with a comment explaining the reassignment-needs-$state nuance.
- jsdoc: extend the ``WizardState`` typedef with ``selectionInitialized``
  so svelte-check no longer flags the new field as unknown.
@NoveliaYuki
Copy link
Copy Markdown
Collaborator Author

Pushed fix(#365): satisfy prettier and eslint on touched files — addresses lint-suite feedback after running the full check matrix locally.

Test results on the post-fix-up state:

Suite Result
Frontend npm run lint (prettier + eslint) clean on all 12 touched files; the 365 remaining errors elsewhere predate this PR
Frontend npm run check (svelte-check) 913 errors / 35 warnings — same count as base (1 less, since this PR adds the missing selectionInitialized typedef field)
Frontend npm run test:unit 7/7 passed
library-manager pytest 52/52 passed
lamb-kb-server-stable pytest (-m 'not slow') 66/66 passed
Playwright 24 failed / 7 passed / 122 did-not-run / 1 skipped — same pattern observed against base (sampled tests/knowledge_store_ui.spec.js, identical seed-time failure on both PR and base), so all current Playwright reds are pre-existing test-infra issues, not regressions from this PR

@NoveliaYuki NoveliaYuki merged commit 3699c40 into projects/refactor/kbserver-lamb-integration May 10, 2026
@NoveliaYuki NoveliaYuki deleted the feat/#365/frontend-refinement-libraries-ks branch May 10, 2026 19:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant