Configuration¶
kennis reads its settings from one TOML file, and its credentials from somewhere else entirely. This page lists every key; the reasoning behind the split is in Keep credentials out of the config.
Where the file lives¶
The platform configuration directory, which on Linux is
~/.config/kennis/config.toml. Setting KENNIS_CONFIG_DIR overrides it,
which is what makes a throwaway configuration possible without touching your
own.
Precedence¶
A value is taken from the first source that offers it:
- The environment, as
KENNIS_<SECTION>_<FIELD>- soKENNIS_EMBEDDING_BACKENDorKENNIS_EMBEDDING_API_KEY_ENV. config.tomlin the configuration directory.- The default shown in the tables below.
Exact names, not nested delimiters
pydantic-settings can split an environment variable on _ to find a
nested field. kennis does not use that. KENNIS_EMBEDDING_API_KEY_ENV
would resolve to embedding.api.key.env, match nothing, and be dropped
in silence - the field keeps its default and the person who set the
variable has no way to find out why. kennis walks its own model instead
and looks each name up exactly.
A name in the file that kennis does not read - a misspelling such as
chunking.sise, or a setting a later kennis removed - has no effect.
Every command says so on stderr, and the settings page says so at the
head of its kennis section. The next change to the configuration removes
it, because every write renders the whole file from the settings kennis
has.
Reading and changing settings¶
kennis config show # the whole file, as valid TOML
kennis config get # every setting and the value in effect
kennis config get embedding.model # one value, unstyled, for scripts
kennis config set embedding.backend ollama
kennis config init # the guided setup
Every write leaves every setting in the file, including those at their
default, whether it comes from config set, config init or the settings
page. The file then says what is in use, and it can be copied or synced to
another machine as it is. A value from the environment is never written into
it: an exported variable is for the shell that set it. config init replaces
the whole file, so on an existing one it asks first, and anything edited by
hand, comments included, is lost.
The settings page offers every setting except two: corpus.root, because
changing it under an open window moves the corpus from under every page, and
backup.folder, which is chosen in the page's Backup section. config init
asks only the settings where the right answer depends on you.
The [logging] section is read when kennis starts, so a change to it takes
effect the next time a command runs or the window is opened.
kennis config show writes the file to standard output and its warnings to
standard error, so kennis config show > config.toml produces a usable file
rather than one with a warning in the middle.
kennis config get <key> prints the bare value with no styling, so it can be
read by a script. kennis config get with no key prints the whole set,
highlighted.
Every setting¶
[embedding]¶
How chunks and queries become vectors.
| key | type | default | what it does |
|---|---|---|---|
backend |
fastembed / ollama / openai / none |
fastembed |
Backend used to embed chunks. fastembed downloads a 65 MB model the first time you index; none means lexical search only. |
model |
str |
BAAI/bge-small-en-v1.5 |
Model name, interpreted by the backend. |
normalise |
bool |
True |
Scale vectors to unit length, so cosine is a dot product. |
batch_size |
int |
64 |
Texts per backend request. |
base_url |
str |
"" |
Server address. Unused for fastembed. |
api_key_env |
str |
OPENAI_API_KEY |
Environment variable holding the key, for hosted backends. |
[chunking]¶
How a document is cut up before it is indexed.
| key | type | default | what it does |
|---|---|---|---|
size |
int |
1500 |
Target characters per chunk. |
overlap |
int |
200 |
Characters shared between neighbouring chunks. |
[retrieval]¶
How a search is run.
| key | type | default | what it does |
|---|---|---|---|
default_top_k |
int |
3 |
How many hits a search returns from each scope it searched, so a sweep can return this many times the number of scopes. |
corpus_method |
hybrid / bm25 / dense |
hybrid |
Retrieval method for corpus collections. |
context_method |
hybrid / bm25 / dense |
bm25 |
Retrieval method for a project's context bundle. bm25 keeps kennis context init offline and its index portable between machines; anything else needs an embedding backend. |
scores |
human / raw / none |
human |
How a search shows how well each hit matched, on the command line and to an agent: as levels, as the raw scores, or not at all. kennis search --scores overrides it for one search. |
[corpus]¶
Where the corpus lives and how documents are added to it.
| key | type | default | what it does |
|---|---|---|---|
root |
str |
"" |
Corpus directory. Empty means the platform data directory. |
keep_original |
bool |
False |
Keep the source file beside the document. |
default_group |
str |
"" |
Group new documents are filed under when none is given. |
[conversion]¶
How binary documents become markdown.
| key | type | default | what it does |
|---|---|---|---|
backend |
mineru / datalab |
mineru |
Converter for PDF, DOCX, PPTX and XLSX. mineru runs locally and is installed with kennis; datalab is hosted, needs an API key, and sends the document to a third party. |
mode |
fast / balanced / accurate |
balanced |
How hard the datalab backend works, and what it charges. Measured per page: fast 0.4c, balanced 0.4c, accurate 1.0c. The server only reuses a conversion when the mode matches, so changing this and re-adding a document pays for it again. mineru ignores this - it runs locally and costs nothing. |
repair_ligatures |
bool |
True |
Repair ligature damage against the PDF's own text layer, read with pypdfium2. mineru drops a letter from ff, fi and fl on some documents, which no reindex can undo. Costs 0.7ms a page and applies to mineru only - datalab showed no such damage. |
batch_size |
int |
8 |
Documents per converter run. 0 is one run. |
[literature]¶
How papers are identified and fetched.
| key | type | default | what it does |
|---|---|---|---|
request_delay |
float |
3.0 |
Least seconds between arXiv papers. A longer Crawl-delay in a host's robots.txt applies instead: arxiv.org asks for 15. |
unpaywall_email |
str |
"" |
Your email address, which Unpaywall requires, to look up a free and legal copy of a paper known only by its DOI. Empty: Unpaywall is not asked, and such a paper needs your own copy. |
citation_style |
str |
"" |
A .csl file to format citations with, such as one from the Zotero style repository. Empty: Harvard (Cite Them Right), which is installed with kennis. |
[terminal]¶
What the command line prints beside its reports.
| key | type | default | what it does |
|---|---|---|---|
messages |
all / warnings / errors |
all |
Which advice the command line prints: all of it, warnings and errors without hints, or errors alone. An error keeps the command that resolves it, and reports are always printed. |
[logging]¶
What is written to the log file.
| key | type | default | what it does |
|---|---|---|---|
level |
debug / info / warning / error |
info |
Detail written to the log file. |
max_bytes |
int |
1048576 |
Size at which the log rotates. |
backup_count |
int |
3 |
Rotated log files kept. |
[backup]¶
Where the encrypted backup of the corpus is written.
| key | type | default | what it does |
|---|---|---|---|
folder |
str |
"" |
Folder the encrypted backup is written to, often one a cloud client synchronises. The backup holds the full text of every document. |
[service]¶
How the process that owns the corpus behaves (milestone 14).
| key | type | default | what it does |
|---|---|---|---|
idle_minutes |
float |
30.0 |
Minutes the kennis service waits with no task, request or open window before it exits. The next command starts it again. |
Settings kennis deliberately does not offer¶
A setting that nothing honours is worse than a missing one, because it is a promise. Where the design defers a mechanism, its setting is absent rather than present and ignored.
The model¶
Bases: BaseSettings
Every setting kennis honours.
Source code in src/kennis/engine/settings.py
settings_customise_sources
classmethod
¶
settings_customise_sources(settings_cls: type[BaseSettings], init_settings: PydanticBaseSettingsSource, env_settings: PydanticBaseSettingsSource, dotenv_settings: PydanticBaseSettingsSource, file_secret_settings: PydanticBaseSettingsSource) -> tuple[PydanticBaseSettingsSource, ...]
Environment, then the file, then defaults.
pydantic's own env_settings is replaced rather than supplemented:
leaving it in place would reintroduce delimiter splitting beside the
exact-name lookup, and two sources disagreeing about one variable is
worse than either.