API reference
API reference
Public surface of ToolUp.KnowledgeBase.
ToolUp.KnowledgeBase.Core
KnowledgeApi (Fable.Remoting contract)
type IKnowledgeApi = {
UploadDocument: UploadDocumentRequest -> Async<Result<KnowledgeDocument, KnowledgeError>>
ListDocuments: unit -> Async<KnowledgeDocument list>
GetDocument: DocumentId -> Async<KnowledgeDocument option>
DeleteDocument: DocumentId -> Async<unit>
ResetKnowledgeBase: unit -> Async<unit>
IngestNarrative: IngestNarrativeRequest -> Async<Result<KnowledgeDocument, KnowledgeError>>
AddNote: AddNoteRequest -> Async<Result<KnowledgeDocument, KnowledgeError>>
UpdateNote: UpdateNoteRequest -> Async<Result<KnowledgeDocument, KnowledgeError>>
GetAIContext: unit -> Async<AIContextEntry list>
SetAIContext: AIContextEntry list -> Async<unit>
GetIngestionStatus: DocumentId -> Async<IngestionStatus option>
}
and UploadDocumentRequest = {
FileName: string
ContentType: string
Bytes: byte[]
}
and IngestNarrativeRequest = {
Title: string
Body: string
SourceModule: string
}
and AddNoteRequest = {
Title: string option
Body: string
}
and UpdateNoteRequest = {
DocumentId: DocumentId
Title: string option
Body: string
}
and AIContextEntry = {
Id: Guid
Text: string
Order: int
}
KnowledgeDocument
type KnowledgeDocument = {
DocumentId: DocumentId
FileName: string
ContentType: string
Source: KnowledgeSource
UploadedBy: string
UploadedAt: DateTime
SizeBytes: int64
Status: IngestionStatus
ChunkCount: int option
Reason: string option // populated when Status = Failed
}
and KnowledgeSource =
| UploadedFile
| FromNarrative of FromNarrativeSource
| Note of NoteSource
and FromNarrativeSource = {
SourceModule: string
OriginalTitle: string
}
and NoteSource = {
NoteTitle: string option
}
and IngestionStatus =
| Pending
| Extracting
| Chunking
| Embedding
| Indexed
| Failed
IngestionStatusUpdate (SSE wire format)
type IngestionStatusUpdate = {
DocumentId: Guid
Status: IngestionStatus
Progress: float option // 0.0 - 1.0
ChunksIndexed: int
ChunksTotal: int option
Reason: string option
}
Notification kind: [<Literal>] IngestionStatusNotificationKey = "KnowledgeBase.IngestionStatus".
KnowledgeError
type KnowledgeError =
| InvalidFileType of string
| FileTooLarge of {| MaxBytes: int64; ActualBytes: int64 |}
| ExtractionFailed of string
| StorageError of string
| NotFound
| Forbidden
ToolUp.KnowledgeBase.Server
KnowledgeBase.Server.knowledgeApi
The Fable.Remoting handler. Pass directly to ServerModule.withGuardedApi:
let kbModule =
ServerModule.create "KnowledgeBase"
|> ServerModule.withGuardedApi KnowledgeBase.Server.knowledgeApi
|> ServerModule.withDataTypes [ KnowledgeBase.Server.kbDataType ]
KnowledgeBase.Server.kbDataType
DataType declaration for the KB module:
let kbDataType : DataType = {
Info = { Id = "Knowledge"; DisplayName = "Knowledge base entries"; Schema = None }
Id = "Knowledge"
Detect = fun _ -> true // accepts any registered content-type for the kb route
Process = ...
}
KnowledgeBase.Server.kbVectorisationHandler
let kbVectorisationHandler : VectorisationHandler = {
DataTypeId = "Knowledge"
Vectorise = fun (fileName, dataObject) -> async {
// routes by content-type, extracts text, chunks, returns TextChunk list
}
}
Register via RAGServerApp.withVectorisationHandler.
KnowledgeBase.Server.makeIngestionStatusObserver
Factory for the IIngestionStatusObserver registered with composeWithRAG:
val makeIngestionStatusObserver: unit -> IIngestionStatusObserver
Register via RAGServerApp.withIngestionStatusObserver.
KnowledgeBase.Server.standingContextBuilder
Opt-in AI prompt builder that reads the team's standing context per outer turn:
val standingContextBuilder:
IBlobStorage -> ILogger option -> SystemPromptBuilder
Compose into AIAssistantServerConfig.SystemPrompt:
let combinedPrompt =
SystemPromptBuilder.compose [
SystemPromptBuilder.fromStatic "..."
KnowledgeBase.Server.standingContextBuilder blobStorage (Some logger)
SystemPromptBuilder.activeModuleContext
]
ToolUp.KnowledgeBase.Client
KnowledgeBaseView.installNarrativeCommit
val installNarrativeCommit: unit -> unit
Install the global Toolup.NarrativeCommit.submit handler. Call once at app boot before module registrations.
KnowledgeBaseView.register
val register: unit -> ErasedModule
Returns the KB ErasedModule for SDK registration. Multi-page module with /documents, /notes, /ai-context pages.
Toolup.NarrativeCommit (global submitter)
module Toolup.NarrativeCommit =
val install: handler: (NarrativeCommitRequest -> Async<unit>) -> unit
val submit: NarrativeCommitRequest -> unit // fire-and-forget; logs on failure
and NarrativeCommitRequest = {
Title: string
Body: string
SourceModule: string
}
Other modules call Toolup.NarrativeCommit.submit to push content into KB. No compile-time dependency on KB.
KnowledgeBaseIcons
module KnowledgeBaseIcons =
val documentIcon: ReactElement
val noteIcon: ReactElement
val aiContextIcon: ReactElement
val resetIcon: ReactElement
Exposed for apps replacing the built-in KB module — re-use the same icon set.
Events emitted to IEventStore
Under SourceModule = "_platform.kb":
DocumentUploadedDocumentDeletedDocumentExtractionFailedKnowledgeBaseResetAIContextUpdated
Under SourceModule = "_platform.ingestion" (forwarded from RAG):
KnowledgeChunkIndexedKnowledgeChunkFailed
Notifications published
Notification kind: "KnowledgeBase.IngestionStatus". Payload: IngestionStatusUpdate. Subscribers:
- KB Documents page (per-document status pill).
- AI assistant side panel (indexing-in-progress indicator).
HTTP endpoints
Auto-injected by ServerModule.withGuardedApi:
POST /api/IKnowledgeApi/UploadDocumentPOST /api/IKnowledgeApi/ListDocumentsPOST /api/IKnowledgeApi/GetDocumentPOST /api/IKnowledgeApi/DeleteDocumentPOST /api/IKnowledgeApi/ResetKnowledgeBasePOST /api/IKnowledgeApi/IngestNarrativePOST /api/IKnowledgeApi/AddNotePOST /api/IKnowledgeApi/UpdateNotePOST /api/IKnowledgeApi/GetAIContextPOST /api/IKnowledgeApi/SetAIContextPOST /api/IKnowledgeApi/GetIngestionStatus
All gated by makePermissionGuardedApi against the caller's ModulePermissions.
Blob layout
Per team scope (team-{teamId}/):
kb-documents/{documentId}.{ext}— original file byteskb-documents/{documentId}.meta.json—KnowledgeDocumentmetadatakb-ai-context/entries.json—AIContextEntry list
Reset deletes everything under kb-documents/ and kb-ai-context/ for the scope.
Configuration knobs
Server-side (in KnowledgeBase.Server):
MaxFileSizeBytes(default100 * 1024 * 1024= 100 MB)AllowedContentTypes(default:application/pdf,application/vnd.openxmlformats-officedocument.*,text/plain,text/csv,text/markdown,application/json)ChunkingConfig— passes through to RAG; overrides the RAG default for KB documents specifically.
These aren't currently first-class fluent builders on RAGServerApp. Customise by replacing the shipped vectorisation handler with a custom one (see extending.md).