Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
99 commits
Select commit Hold shift + click to select a range
8b37e5c
feat(#334): new KB Server microservice (lamb-kb-server/)
NoveliaYuki Apr 24, 2026
fa532bf
test(#334): three-tier KB Server test suite (unit/integration/e2e)
NoveliaYuki Apr 25, 2026
b2a45b8
test(#334): mutation testing — 32/32 mutations killed (100%)
NoveliaYuki Apr 25, 2026
65a9cce
fix(#334): catch TypeError on non-ASCII bearer tokens
NoveliaYuki May 2, 2026
3b7eefb
fix(#334): reject non-primitive extra_metadata at schema boundary
NoveliaYuki May 2, 2026
434a6bc
fix(#334): validate chunking_params against strategy allow-list
NoveliaYuki May 2, 2026
4792f24
fix(#334): atomic chunk_count update under concurrent ingestion
NoveliaYuki May 2, 2026
ab9bb8d
test(#334): use venv pytest in extended mutation scripts
NoveliaYuki May 2, 2026
52823e9
test(#334): cover 503-backend-unavailable at the e2e tier
NoveliaYuki May 2, 2026
2010566
test(#334): drop sys.modules eviction in qdrant integration test
NoveliaYuki May 2, 2026
7e39c96
chore: open refactor branch for KB server + LAMB integration
NoveliaYuki May 2, 2026
c0d8b74
feat(#337): LAMB backend integration for new KB Server (Knowledge Sto…
NoveliaYuki May 3, 2026
5f0ff9a
feat(#337): add knowledge_store_rag processor for new KB Server retri…
NoveliaYuki May 3, 2026
26bbf42
feat(#337): lamb ks CLI commands for new KB Server
NoveliaYuki May 3, 2026
c3c7d43
test(#337): Playwright API E2E for Knowledge Store CRUD
NoveliaYuki May 3, 2026
9e238f3
feat(#337): Knowledge Store frontend service + list/detail/add-content
NoveliaYuki May 3, 2026
4858703
feat(#337): unified Library + Knowledge Store creation wizard
NoveliaYuki May 3, 2026
1e7e4f3
i18n(#337): Knowledge Store keys in en/es/ca/eu
NoveliaYuki May 3, 2026
379c38e
feat(#337): unified Knowledge page hosts Libraries + Knowledge Stores
NoveliaYuki May 3, 2026
9cf6da9
test(#337): Playwright UI spec for Knowledge Store frontend
NoveliaYuki May 3, 2026
2c9ae1a
test(#337): full Library->KS->query->cite->FR-10 E2E workflow spec
NoveliaYuki May 3, 2026
44f5e8f
docs(#337): CLAUDE.md terminology + Knowledge Store ADRs
NoveliaYuki May 3, 2026
3288338
fix(#337): wizard close + step transitions broken by step-effect feed…
NoveliaYuki May 3, 2026
5d5120d
fix(#337): Knowledge Stores list shows owned vs shared correctly
NoveliaYuki May 3, 2026
6775ed3
feat(#337): auto-fill KS embedding endpoint from org provider config
NoveliaYuki May 3, 2026
941de04
chore(#337): SvelteSet + drop unused imports / svelte-ignore comments
NoveliaYuki May 3, 2026
867b895
chore(#337): kb-server v2 placeholder embedding env for chromadb vali…
NoveliaYuki May 3, 2026
8d7a0ad
docs(#337): add Verification Orchestration section to integration plan
NoveliaYuki May 3, 2026
db66aa3
test(#337): force workers=1 so specs do not race on shared LAMB state
NoveliaYuki May 3, 2026
648d126
style(#337): format frontend with prettier (one-time canonical pass)
NoveliaYuki May 4, 2026
86ac592
feat(#337): verify and harden the Knowledge Store lifecycle end-to-end
NoveliaYuki May 4, 2026
d41459b
Merge pull request #355 from Lamb-Project/projects/#334/new-kb-server…
NoveliaYuki May 5, 2026
8f72766
merge: resolve conflicts with projects/refactor/kbserver-lamb-integra…
NoveliaYuki May 5, 2026
7543a45
chore(#337): post-merge cleanup — prettier, lint, stale doc
NoveliaYuki May 5, 2026
80410aa
test(#337): add lamb-cli edge-case coverage for backend guardrails
NoveliaYuki May 5, 2026
0dd77c7
fix(#337): propagate --wait ingestion failures as non-zero exit
NoveliaYuki May 5, 2026
313c79d
feat(#337): redesign Libraries and Knowledge Stores page
NoveliaYuki May 6, 2026
52fb86d
test(#337): align tests with redesigned Library and KS UI
NoveliaYuki May 6, 2026
4df297d
docu(#337): plan server-side pagination for libraries and KS lists
NoveliaYuki May 6, 2026
c0ec87b
feat(#337): polish Library and Knowledge Stores UX after review
NoveliaYuki May 6, 2026
dd62a45
fix(#337): treat keyless providers as configured in KS options
NoveliaYuki May 6, 2026
b10f123
feat(#337): tighten list-page UX after second review pass
NoveliaYuki May 6, 2026
952a776
test(#337): retarget wizard tests at the contextual create buttons
NoveliaYuki May 6, 2026
f6efdad
feat(#337): refine wizard steps 2, 4 and 5 after deeper UX review
NoveliaYuki May 7, 2026
1908ec8
test(#337): click Next on Step 2 in lieu of removed Skip button
NoveliaYuki May 7, 2026
fbdb383
fix(#337): five small UX defects in libraries / KS wizard
NoveliaYuki May 7, 2026
c03eb6d
fix(#337): drop redundant Ingestion card and make Step 4 Skip honest
NoveliaYuki May 7, 2026
11c6e1b
fix(#337): make Step 4 Deselect all stick
NoveliaYuki May 7, 2026
a1f8719
fix(#337): make Step 5 reflect a Skip in Step 4 honestly
NoveliaYuki May 7, 2026
9c3d4b5
fix(#337): host Step 5 Create button in the wizard footer
NoveliaYuki May 7, 2026
a638d51
fix(#337): stop wizard mount from stomping a saved draft
NoveliaYuki May 7, 2026
723bcbf
fix(#337): keep auto-save on while resume banner is up
NoveliaYuki May 7, 2026
1b93b03
fix(#337): persist current wizard step in the draft
NoveliaYuki May 8, 2026
d5eb8a2
feat(#337): persist queued File objects via IndexedDB
NoveliaYuki May 9, 2026
85ba322
fix(#337): make wizard X button close silently
NoveliaYuki May 9, 2026
400db0c
Merge pull request #357 from Lamb-Project/feat/#337/verify-ks-lifecycle
NoveliaYuki May 10, 2026
376cbfa
feat(#365): unify Add Content with Create Knowledge wizard and polish UX
NoveliaYuki May 10, 2026
afe8971
fix(#365): backend pagination caps, embedding-model default, and item…
NoveliaYuki May 10, 2026
93bc873
fix(#365): satisfy prettier and eslint on touched files
NoveliaYuki May 10, 2026
3699c40
Merge pull request #366 from Lamb-Project/feat/#365/frontend-refineme…
NoveliaYuki May 10, 2026
077e801
fix(#367): derive subprocess cwd from __file__ in lifespan test
NoveliaYuki May 11, 2026
8486ce4
Merge pull request #368 from Lamb-Project/fix/#367/portable-cwd-in-em…
NoveliaYuki May 11, 2026
9953af7
feat(#370): view library content and invert delete-confirm flow
NoveliaYuki May 12, 2026
6d4849c
fix(#370): discard stale library responses in wizard picker
NoveliaYuki May 12, 2026
db0f686
Merge pull request #376 from Lamb-Project/feat/#370/view-library-item…
NoveliaYuki May 12, 2026
af13f09
fix(#377): migrate url_import to firecrawl-py 2.x API
NoveliaYuki May 12, 2026
bbab916
Merge pull request #378 from Lamb-Project/fix/#377/firecrawl-py-2x-mi…
NoveliaYuki May 12, 2026
aba1cc0
feat: library↔KS visibility, view-original, items-load reliability
NoveliaYuki May 12, 2026
3b52ebc
feat(i18n): add defaultName key to libraries locale section
NoveliaYuki May 13, 2026
f4b210e
fix(url-import): fall back to markitdown when no Firecrawl key config…
NoveliaYuki May 13, 2026
7c07d9f
feat(libraries): replace view buttons with eye icon, tabbed content m…
NoveliaYuki May 13, 2026
cefa42b
fix(libraries): neutral eye button, distinguish youtube error types
NoveliaYuki May 13, 2026
ddde898
fix(ks): permalink routing, auth, ingestion safety, filter and list UX
NoveliaYuki May 14, 2026
a7ce880
feat(ks): ingestion progress popup after adding content from list view
NoveliaYuki May 14, 2026
270be51
fix(modals): allow click-outside to close ConfirmationModal
NoveliaYuki May 14, 2026
aab8291
fix(filters): replace oversized clear-filters button with compact ico…
NoveliaYuki May 14, 2026
4d4c6ad
fix(libraries): simplify KS panel to list, unify sort order by name asc
NoveliaYuki May 14, 2026
7888a07
fix(libraries): tighten KS panel rows, drop item count, use icon for …
NoveliaYuki May 14, 2026
8543472
fix(libraries): make KS panel collapsible, collapsed by default
NoveliaYuki May 14, 2026
0708639
fix(libraries): show Private badge alongside Shared in KS panel
NoveliaYuki May 14, 2026
f8871c1
test: fix full test suite across all layers
NoveliaYuki May 14, 2026
167a40c
fix(backend): explicit dotenv path and KB server host redirects for d…
NoveliaYuki May 14, 2026
69dae8f
fix(ui): remove column resizing, fix column widths/alignment, clear-f…
NoveliaYuki May 14, 2026
5528368
feat(ui): schema-driven plugin parameter UI + KS chunking edit #334
NoveliaYuki May 17, 2026
258948d
refactor(ks-detail): Phase C rewrite + fix share-toggle flicker #334
NoveliaYuki May 24, 2026
521543e
chore: sync working tree to PR branch #334
NoveliaYuki May 24, 2026
5bfa0a1
fix: library images not displaying in UI
NoveliaYuki Jun 7, 2026
f4921b4
Merge origin/main into projects/refactor/kbserver-lamb-integration
NoveliaYuki Jun 7, 2026
0507d1f
Merge remote-tracking branch 'origin/main' into projects/refactor/kbs…
NoveliaYuki Jun 8, 2026
c8cea8c
fix(backend): resolve duplicate route, swallowed 404, and improve cod…
NoveliaYuki Jun 9, 2026
b3dfef5
fix(frontend): replace unsanitized markdown rendering with DOMPurify …
NoveliaYuki Jun 9, 2026
19c191d
fix(frontend): apply design system tokens and i18n to common componen…
NoveliaYuki Jun 9, 2026
5bde2ae
fix(frontend): redirect icon imports and add i18n to KS/library/wizar…
NoveliaYuki Jun 9, 2026
4787a96
fix(lamb-kb-server): centralize config, fix idempotency, and improve …
NoveliaYuki Jun 9, 2026
f8a9296
fix(lamb-kb-server): fix test failures and lint issues #334
NoveliaYuki Jun 9, 2026
0cbb89a
fix(library-manager): improve code quality, extract shared MIME modul…
NoveliaYuki Jun 9, 2026
accfdbb
test(library-manager): add coverage tests and fix lint #334
NoveliaYuki Jun 9, 2026
0b30b5c
style(frontend): apply prettier formatting #334
NoveliaYuki Jun 9, 2026
6270383
Merge remote-tracking branch 'origin/dev' into projects/refactor/kbse…
NoveliaYuki Jun 9, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
16 changes: 16 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,29 @@ wheels/

# Virtual Environments
.env
.env.local
.env.*.local
**/.env.local
**/.env.*.local
.venv
env/
venv/
ENV/
env.bak/
venv.bak/

# Secrets / credentials (any depth)
*.pem
*.key
secrets.json
credentials.json

# Playwright / vitest artifacts
**/test-results/.last-run.json
**/test-results/
playwright-report/
.playwright/

# Backend specific
backend/__pycache__/
backend/.env
Expand Down
85 changes: 81 additions & 4 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,15 @@ Organizations are the tenant boundary. Each org isolates users, assistants, KBs,

A separate microservice (FastAPI, port 9091) that serves as a **document repository**. It imports documents into a structured, permalinkable markdown format. It does NOT chunk, embed, or interact with vector databases — that is the KB Server's responsibility.

**Terminology:** Libraries **IMPORT** content (document repository). Knowledge Bases **INGEST** content (chunking + embedding). These terms are used consistently throughout the codebase and must not be confused.
**Terminology — three distinct concepts in this repo:**

| Concept | Verb | Service | LAMB route | Storage |
|---------|------|---------|-----------|---------|
| **Libraries** | IMPORT | Library Manager (port 9091) | `/creator/libraries/*` | structured markdown on disk |
| **Knowledge Bases** | INGEST (legacy) | `lamb-kb-server-stable/` (port 9090) | `/creator/knowledgebases/*` | ChromaDB only, file-upload model |
| **Knowledge Stores** | INGEST (new) | `lamb-kb-server/` (port 9092) | `/creator/knowledge-stores/*` | pluggable vector DB, library-only ingestion |

These terms are used consistently throughout the codebase and must not be confused. "Knowledge Bases" and "Knowledge Stores" are NOT synonyms — they refer to two parallel, coexisting integrations with different KB Server backends. New work should target Knowledge Stores; the Knowledge Base surface is preserved unchanged for backward compatibility.

**Key decisions:**
- LAMB is the only caller. Single bearer token auth, no user-level ACL (LAMB handles that).
Expand All @@ -127,6 +135,22 @@ A separate microservice (FastAPI, port 9091) that serves as a **document reposit

**LAMB integration:** Creator Interface endpoints (`/creator/libraries/...`) validate ACL and proxy to the Library Manager. The `lamb-cli` commands (`lamb library ...`) are in `lamb-cli/src/lamb_cli/commands/library.py`. Svelte frontend at `/libraries` route with components in `frontend/svelte-app/src/lib/components/libraries/`.

### Knowledge Stores — new KB Server (`lamb-kb-server/`)

A separate microservice (FastAPI, port 9092) — pluggable redesign of the legacy KB Server. Pure compute service: chunks, embeds, and stores vectors. Receives JSON payloads from LAMB containing pre-extracted text + permalinks; **never calls the Library Manager directly**. Coexists with the legacy stable KB Server (port 9090) — both run simultaneously per #334 NFR-1.

**Key decisions** (see `lamb-kb-server/Documentation/` for full ADRs):
- LAMB owns ACL, multi-tenancy, and content delivery. KB Server is a single-bearer-token compute service.
- Plugin architecture: 3 vector-DB backends (ChromaDB, Qdrant), 4 chunking strategies (simple, hierarchical/parent-child, by_page, by_section), 3 embedding vendors (openai, ollama, local).
- **Library-only ingestion:** Knowledge Stores are populated exclusively by linking Library items. No direct file upload path.
- **Locked store setup:** chunking strategy, embedding vendor/model, and vector DB backend are immutable after creation. Only `name` and `description` are mutable.
- **Per-request embedding credentials:** sent on every `/add-content` and `/query`, held in memory only by the KB Server. LAMB resolves them from `setups.default.providers.{vendor}.api_key` (the same org-level key used by chat completions and RAG).
- **Async ingestion:** SQLite-backed job queue with polling (no webhooks). LAMB queues `add-content`, gets a `job_id`, polls `/jobs/{job_id}` until ready/failed.
- **Per-org filesystem isolation:** vectors live at `data/storage/{org_id}/{collection_id}/`.
- **FR-10:** a Library item that is referenced by any active Knowledge Store cannot be deleted from its Library — LAMB enforces this in `DELETE /creator/libraries/{lib}/items/{item}` against the `kb_content_links` table.

**LAMB integration:** Creator Interface endpoints (`/creator/knowledge-stores/...`) validate ACL and proxy to the new KB Server. Tables: `knowledge_stores` + `kb_content_links` in LAMB DB (separate from `kb_registry` which serves the legacy stable KBs). HTTP client at `backend/creator_interface/knowledge_store_client.py`. RAG processor at `backend/lamb/completions/rag/knowledge_store_rag.py` (sibling of `simple_rag.py` — assistants opt in via `rag_processor='knowledge_store_rag'`). The `lamb-cli` commands are `lamb ks ...` (alias `lamb knowledge-store ...`) in `lamb-cli/src/lamb_cli/commands/knowledge_store.py`. Svelte frontend integrated into the unified `/libraries` page (sub-tab "Knowledge Stores" + primary "Create Knowledge" wizard); components in `frontend/svelte-app/src/lib/components/knowledgeStores/` and the wizard in `frontend/svelte-app/src/lib/components/knowledge/`. Direct entry point at `/knowledge-stores` redirects to `/libraries?section=knowledge-stores`.

### Database
- **LAMB DB** — SQLite with WAL mode (`lamb_v4.db` at `LAMB_DB_PATH`). Schema managed in `backend/lamb/database_manager.py`.
- **Open WebUI DB** — `open-webui/backend/data/webui.db`. For historical reasons, Open WebUI is still the authentication provider — LAMB delegates user auth and session management to OWI. This is a known coupling targeted for refactoring (see GitHub issues).
Expand All @@ -144,7 +168,8 @@ Svelte 5 + SvelteKit + Vite + TailwindCSS 4. JavaScript with JSDoc (not TypeScri
## Key Configuration

- Backend env: `backend/.env` (copy from `backend/.env.example`)
- KB Server env: `lamb-kb-server-stable/backend/.env` (copy from `.env.example`)
- KB Server (legacy) env: `lamb-kb-server-stable/backend/.env` (copy from `.env.example`)
- KB Server (new, Knowledge Stores) env: `lamb-kb-server/backend/.env` — requires `LAMB_API_TOKEN`. Backend reads it via `LAMB_KB_SERVER_V2` / `LAMB_KB_SERVER_V2_TOKEN`.
- Library Manager env: `library-manager/backend/.env` (copy from `.env.example`) — requires `LAMB_API_TOKEN`
- Playwright env: `testing/playwright/.env` (copy from `.env.sample`)
- Frontend runtime config: `frontend/svelte-app/static/config.js` (copy from `config.js.sample`)
Expand All @@ -155,7 +180,7 @@ Svelte 5 + SvelteKit + Vite + TailwindCSS 4. JavaScript with JSDoc (not TypeScri

`open-webui/` and `lamb-kb-server-stable/` are separate projects maintained in their own repositories. They are included here only as stable snapshots so Docker Compose can launch them alongside LAMB. **Do not edit code in these directories** — changes belong in their upstream repos. The `frontend/build/` directory is build output. All three are excluded from search via `.cursorignore`.

Note: `library-manager/` is NOT vendored — it is developed in-tree as part of this repository. Edit freely.
Note: `library-manager/` and `lamb-kb-server/` (the new KB Server backing Knowledge Stores) are NOT vendored — both are developed in-tree as part of this repository. Edit freely.

## Version Bumping

Expand All @@ -166,4 +191,56 @@ Dev version lives in `frontend/svelte-app/scripts/generate-version.js`. Run `nod
* DO NOT include authoriship information in commits (No Co-authored-By, signed-off-by , or similar)
* Commit messages should be concise and descriptive without aditional metadata.
* Include the Issue ID in commit messages like #{issue number}


## Design System

The Svelte frontend follows a strict design-system contract. Primitives live in `frontend/svelte-app/src/lib/components/ui/` and tokens in `frontend/svelte-app/src/app.css`. See `.claude/plans/elegant-mixing-adleman.md` for the full plan, primitive APIs, token list, and verification checklist.

### Consistency Contract (the rules everything follows)

**Action -> primitive mapping (locked).** Same intent always renders with the same primitive, same icon, same variant, same position:

| Action | Primitive | Icon | Variant | Position |
|---|---|---|---|---|
| List "Create new" CTA | `Button` | `Plus` (iconLeft) | `primary` | top-right of page header |
| Row "View" | `IconButton` | `Eye` | `ghost`, sm | leftmost in row actions |
| Row "Edit" | `IconButton` | `Pencil` | `ghost`, sm | inline next to value, or overflow |
| Row "More" | `OverflowMenu` | `MoreHorizontal` | `ghost` | rightmost in row actions |
| Modal close | `IconButton` | `X` | `ghost`, sm | top-right of modal header |
| Per-item remove | `IconButton` | `X` | `danger-ghost`, sm | right of item row |
| Confirm destructive | `ConfirmationModal` | `AlertCircle` header / `Trash2` confirm | `variant=danger` | - |
| Retry on error | `Button` | `RefreshCw` | `secondary` | end of error Banner |
| Loading | `Skeleton.*` | - | - | always replaces "Loading..." text |
| Async write feedback | `toast` | varies | `success` / `danger` | top-right stack |

Overflow menus always render Delete last with a divider above it and `text-danger` styling.

**Status pill mapping (locked).** Resolve via `statusBadgeProps(status)` in `src/lib/utils/statusBadge.js`; never hand-code badge colors. Mapping:

| Status | Badge variant | Icon | Label |
|---|---|---|---|
| `ready` / completed | `success` | `CheckCircle2` | Ready |
| `processing` / `pending` / `queued` | `info` | `Loader2` (spin) | Processing |
| `failed` / `error` | `danger` | `AlertCircle` | Failed |
| `empty` (count === 0) | `warning` | `AlertCircle` | Empty |
| `private` | `neutral` | `Lock` | Private |
| `shared` | `success` | `Users` | Shared |
| immutable field | `neutral` | `Lock` | Locked |

**Color rule.** Brand color is accessed ONLY via `bg-brand` / `text-brand` / `border-brand` / `ring-brand`. Any literal `#2271b3` or `[#2271b3]` outside `app.css` is a violation. Status colors come exclusively from the `success-* / info-* / warning-* / danger-*` tokens — never `bg-green-100`, `text-red-700`, etc.

**Copy rule.** All `variant="danger"` confirmation modals MUST include the literal `common.cannotBeUndone` line in the body. `ConfirmationModal` enforces this automatically.

**Modal header rule.** Canonical header: `bg-surface` (white), bottom `border-border`, title `type-section-title`, close `IconButton(X, ghost, sm)` top-right. No `bg-blue-50`, no `bg-red-50`, no gradient backgrounds — anywhere.

**Toast rule.** Every async write that succeeds calls `toast.success(...)`; every async write that fails calls `toast.error(...)` (with inline-only when the user must act in place to recover). Inline persistent `successMessage` state is a smell — route it through the toast store at `src/lib/stores/toast.js`.

**Perceived-performance rule.** Never block on the full payload when you can show the first chunk now. Render-as-you-receive (page 1 first, then prefetch the rest), optimistic UI for writes, stale-while-revalidate on navigation, cache list responses keyed by `(orgId, filters, page)`, stream long operations, defer non-critical work (e.g., collapsible panels), and suppress skeletons that would flicker for under 300 ms.

### Icons

Always import from `$lib/components/ui/icons.js` (a curated re-export of `lucide-svelte`). `flowbite-svelte` and `flowbite-svelte-icons` are removed from the project — do not reintroduce them.

### Primitives barrel

`import { Button, IconButton, Modal, Badge, Card, Toast, Tabs, FormField, Dropdown, OverflowMenu, Dropzone, Stepper, Banner, Collapsible, Checkbox, EmptyState, Skeleton, SkeletonRow, SkeletonCard, SkeletonTable } from '$lib/components/ui';`
4 changes: 4 additions & 0 deletions Caddyfile
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ lamb.yourdomain.com {
redir https://owi.lamb.yourdomain.com{uri} 301
}

handle /docs/* {
reverse_proxy backend:9099
}

handle {
root * /var/www/frontend
try_files {path} /index.html
Expand Down
Loading