Install the assistant
Build it, point it at the engine and Kvasir, and run it.
The wizard does this for you. This page is what it does, for when you would rather do it yourself.
git clone https://github.com/kineuro/nils-assistant
cd nils-assistant && npm ci && npm run build
Node 22. It is configured by the environment:
NILS_URL=http://127.0.0.1:8437 # the engine
KVASIR_URL=http://127.0.0.1:7100 # Kvasir
KVASIR_KEY_FILE=/srv/nils/assistant/kvasir.key # the key Kvasir minted for it
ASSISTANT_MODEL=qwen38-27b-fast # the model the stations name
DESK_ORIGIN=https://nils.example.org # the desk it answers
ASSISTANT_STATIONS=/srv/nils/assistant/stations # the stations' own directory
ASSISTANT_STORE=/srv/nils/assistant/assistant.sqlite
ASSISTANT_LEDGER=/srv/nils/assistant/ledger.sqlite
PORT=7300
node dist/app/server.mjs
Its models
The assistant reads the models Kvasir lists when it starts, and again every 30 seconds, so a model added or removed on the desk’s Language models page reaches the stations without a restart. The stations name ASSISTANT_MODEL while Kvasir lists it, and otherwise the first model Kvasir lists, a model in your systems before a provider’s. Where a purpose goes is still Kvasir’s policy to say.
Every call for a conversation carries the token of the person whose conversation it is, beside the assistant’s own key, so Kvasir uses that person’s own ChatGPT subscription where a station goes to ChatGPT.
Who may do what
The assistant asks the engine what each person holds, with that person’s token, and checks at its own doors:
| Doors | Need |
|---|---|
| every door for a person: conversations, shares, memory, standing grants, plans, teaching | assistant:use |
| writing the install’s instructions; everyone’s standing grants and plans | assistant-settings:work |
| institutional notes, teaching sets | review:work |
| teaching’s fine-tunes and candidates | kvasir:work |
A person without the assistant is refused with 403 and “no grant”. What a conversation reaches, and so what a share of it shows, is the lower of the person’s detail and the station’s ceiling: a person who does not see that much is refused the share, and told what it may have read. A standing grant is given only for a door whose grant the person holds. Groups and grants says what each grant and detail opens.
The stations
A station is one job the assistant does: turning words into a question, tuning a keyword, proposing an identity rule, planning several steps. Each is a directory with its brief, its tools and its evals, and they ship in the repository under stations/.
Copy that directory to ASSISTANT_STATIONS, or point the variable at your checkout. Changing a brief is a file, not a build.
As a service
# ~/.config/systemd/user/nils-assistant.service
[Unit]
Description=NILS assistant
After=nils-engine.service
[Service]
EnvironmentFile=%h/nils/assistant/assistant.env
ExecStart=/usr/bin/node %h/nils/assistant/dist/app/server.mjs
WorkingDirectory=%h/nils/assistant
Restart=on-failure
[Install]
WantedBy=default.target
with the variables above in assistant.env, one per line.
Next: connect the desk.
Updated 16 October 2026