Tab: Knowledge
Master switch. The Knowledge tab is gated by the per-instance
knowledgeEnabledflag (configured on the Settings tab, see Settings). The default is off (packages/engine/src/instances/schema.ts:14). When the flag is off, thesearchKnowledge,getKnowledge, andwriteKnowledgetools are not registered ininstance_toolsand the assistant cannot use the knowledge base at all.
The Knowledge tab holds files the assistant can search and retrieve at runtime. Knowledge differs from memory in two ways:
| Aspect | Memory | Knowledge |
|---|---|---|
| Source | Extracted from conversations. | Authored by operators. |
| Granularity | Short factual statements. | Whole documents (Markdown, text, JSON). |
| Lifecycle | Auto-extracted, occasionally curated. | Curated and versioned by hand. |
| Tools | saveMemory, searchMemory. | searchKnowledge, getKnowledge, writeKnowledge. |
Adding files
Click Upload to add a file. Supported extensions (packages/engine/src/server/instances/instance-knowledge.controller.ts):
- Markdown (
.md) - Plain text (
.txt) - HTML (
.html)
Anything else is accepted but stored as text/plain. Files are split into overlapping chunks, embedded with the instance’s configured embedder, and stored in PostgreSQL across knowledge_documents (raw content + metadata) and knowledge_chunks (chunk text + vector column + tsvector). Filenames must be unique within an instance.
The embedder is chosen per instance on the Settings tab — OpenAI text-embedding-3-small or Amazon Titan Text Embeddings v2 — and each row stores the vector in the column matching that embedder’s dimension (1024 or 1536). See Settings → Embedder.
Switching the embedder deletes the knowledge base. Vectors are not converted between providers: changing the embedder drops every document and chunk for the instance, raw content included. Re-upload afterwards.
Editing files
Click a file to open the inline editor. Save commits the change. Edits are not versioned — keep external version control if you need history.
How the assistant uses knowledge
Knowledge is exposed to the assistant through three tools, all gated by the per-instance knowledgeEnabled flag (see Settings):
| Tool | Purpose |
|---|---|
searchKnowledge | Semantic + keyword hybrid search over chunks. Returns ranked snippets with scores. |
getKnowledge | Fetch the full raw content of one document by filename. |
writeKnowledge | Create or overwrite a document programmatically (audited). |
When knowledgeEnabled is on, the three tools are registered as normal tools alongside everything else; there is no special wiring in the Skills prompt section. The LLM picks searchKnowledge based on the tool’s own description (services, procedures, costs, FAQs, anything that may live in documents) and decides per turn whether the user’s question warrants a lookup — there is no automatic injection of knowledge into the prompt.
The typical flow:
- The user asks something that sounds document-shaped.
- The model emits a
searchKnowledgecall with a query (it may rephrase if results are poor). - The tool returns the top-N matching chunks (
content,score,source,chunkIndex) — already enough to ground most answers. - Only if the model needs the broader context of a specific file does it follow up with
getKnowledge({ filename }).
Retrieval — hybrid search with RRF
searchKnowledge is not keyword-only. It runs two backends in parallel and fuses them with Reciprocal Rank Fusion (k=60):
- pgvector cosine similarity against the chunk embeddings.
- PostgreSQL full-text search on the same chunks (
tsvectorwithsimpleconfig, no language-specific stopwords, so it works across languages).
The same pattern is used by the memory layer. The vector branch needs the credentials of the instance’s configured embedder — without them the search degrades to FTS-only rather than failing outright.
Limits
- Per-file size — hard cap 5 MB (
MAX_FILE_SIZE_BYTESininstance-knowledge.controller.ts). Uploads beyond this return400 Bad Request. - Files per instance — default 500 documents, configurable via
KNOWLEDGE_MAX_DOCS_PER_INSTANCE(config.knowledge.maxDocsPerInstance). Beyond the cap, new uploads return400until older docs are deleted. - Indexing latency — ingestion is asynchronous (chunk → embed → upsert). Until it finishes a document’s
statusstayspendingand the chunks are not yet searchable. - Versioning — none. Edits overwrite the chunks for that filename; keep external version control if you need history.