ToolUp.KnowledgeBase
ToolUp.KnowledgeBase
User-facing canonical consumer of ToolUp.RAG. Multi-page Feliz module covering document upload + multi-format extraction (PDF / PPTX / DOCX / XLSX / CSV / TXT / MD), notes, AI context, narrative-commit, ingestion-status surfacing. Drop it into an app that uses RAG and users have a working knowledge base.
Layering:
ToolUp.Platform ← interfaces, shell, file management, scope, RBAC
↑
ToolUp.AI ← agent loop, system-prompt composition, BYOK
↑
ToolUp.RAG ← vector store, retrieval pipeline, ingestion runtime
↑
ToolUp.KnowledgeBase ← document upload, extraction, KB UI, narrative-commit
RAG knows nothing about KB; KB depends on RAG (registers an IIngestionStatusObserver, enqueues IngestionJobs).
When to use this companion
- Users need to upload documents (PDFs, reports, spreadsheets) and chat with an assistant grounded in them.
- "Save to Knowledge Base" buttons on other modules (narrative-commit).
- Per-team isolated knowledge bases — each team sees only their own documents.
- Notes — short text snippets the user types directly, indexed alongside files.
- Standing AI context — persistent team-level instructions the assistant always sees.
When NOT to use this companion
- Programmatic-only ingestion — depend on
ToolUp.RAG.Core'sIngestionQueuedirectly; skip the KB UI. - Custom document upload flows — keep RAG, write your own module against the
IRetrievalPipelineinterface andVectorisationHandlerextension point. - Single-format ingestion (only PDFs, only CSVs) — the multi-format extraction layer carries weight you don't need; write a thinner consumer.
What's in the box
Three packages:
| Package | What it is |
|---|---|
ToolUp.KnowledgeBase.Core |
Shared types: KnowledgeApi Fable.Remoting contract, KnowledgeDocument, IngestionStatus, KnowledgeSource (UploadedFile \| FromNarrative \| Note), NoteSource, AddNoteRequest, UpdateNoteRequest, AIContextEntry, IngestionStatusUpdate. Plus the wire-format literal IngestionStatusNotificationKey = "KnowledgeBase.IngestionStatus". |
ToolUp.KnowledgeBase.Server |
Document upload + multi-format extraction (PDF / PPTX / DOCX / XLSX / CSV), ingestion observer, narrative-commit, notes / AI-context API, KnowledgeBase.Server.knowledgeApi. Depends on ToolUp.AI.Server + ToolUp.RAG.Server. Heavy NuGet deps (PdfPig, DocumentFormat.OpenXml) stay scoped here. |
ToolUp.KnowledgeBase.Client |
Multi-page Feliz module: /documents, /notes, /ai-context. Narrative-commit installer (KnowledgeBaseView.installNarrativeCommit). KB icons. |
Quick start
Add the packages:
<PackageReference Include="ToolUp.KnowledgeBase.Server" />
<PackageReference Include="ToolUp.KnowledgeBase.Client" />
Wire the server composition root (depends on RAGServerApp being in place):
open ToolUp.KnowledgeBase
// In the module registration list:
let kbModule =
ServerModule.create "KnowledgeBase"
|> ServerModule.withGuardedApi KnowledgeBase.Server.knowledgeApi
|> ServerModule.withDataTypes [ KnowledgeBase.Server.kbDataType ]
let ingestionStatusObserver = KnowledgeBase.Server.makeIngestionStatusObserver()
RAGServerApp.create (aiProviderFactory, aiConfigStore, embedder)
|> RAGServerApp.withConfig serverConfig
|> RAGServerApp.addModules [ kbModule; (* other modules *) ]
|> RAGServerApp.withIngestionStatusObserver ingestionStatusObserver
|> RAGServerApp.run
Wire the client composition root:
open ToolUp.KnowledgeBase
KnowledgeBaseView.installNarrativeCommit ()
let modules = [
KnowledgeBaseView.register ()
// ... other modules
]
AIClientConfig.withAIAssistant aiMode clientConfig modules
|> Program.withReactSynchronous "elmish-app"
|> Program.run
That's it. The Knowledge Base sidebar entry appears with three pages: Documents (upload + list + delete), Notes (text snippets), AI Context (standing team instructions for the assistant).
Three integration contracts
External KB replacements (apps that want to provide their own KB module instead of using the built-in one) must honour:
- NarrativeCommit handler — call
Toolup.NarrativeCommit.installwith your submit handler. Other modules' "Save to Knowledge Base" buttons resolve through this hook. IIngestionStatusObserver— wired explicitly intocomposeWithRAG; not auto-injected. The observer surfaces per-document status (Pending / Extracting / Chunking / Embedding / Indexed / Failed) to the UI.- Notification-key contract — the literal
"KnowledgeBase.IngestionStatus"is the wire format the AI side panel subscribes to. An external KB either matches it or accepts that the AI panel won't surface its progress.
These are the only contracts. Internally, KnowledgeBase.Server is just an IFormApi-like Fable.Remoting handler that the SDK shell injects.
Multi-format extraction
The shipped extractors:
- PDF —
UglyToad.PdfPig. Per-page text extraction. Scanned PDFs (image-only) get empty text; pair with anIOcrProvidercompanion (deferred) to fill them. - PPTX —
DocumentFormat.OpenXml. Per-slide text + speaker notes. - DOCX —
DocumentFormat.OpenXml. Paragraph-by-paragraph; tables flattened to row-comma-separated. - XLSX —
DocumentFormat.OpenXml. Per-sheet, header-aware chunking. - CSV / TSV — header-aware row-wise chunking.
- TXT / MD — passed through to
Chunking.splitByTokens.
Other formats are accepted as raw text; deployments needing them write a custom VectorisationHandler per format.
Phase-coherent terminology
In this companion's docs, "chunk" means the unit of indexed text (post-splitting); "document" means the user-uploaded file. A 100-page PDF produces one document and ~50-500 chunks depending on chunking config.
Concepts
See concepts.md for the upload → extract → chunk → ingest pipeline, ingestion-status flow, narrative-commit mechanism, notes + AI context storage model.
API reference
See api-reference.md for the full KnowledgeApi Fable.Remoting contract, server-side handler shape, client view types.
Extending
See extending.md for replacing the built-in KB module with a custom one, adding new extractors, customising the upload-status UI.