Files
owui-tools/docs/configuration.md
T
2026-09-15 15:24:03 -04:00

185 lines
8.0 KiB
Markdown

# Configuration
Everything you are meant to edit is in [`../configs/`](../configs/). Nothing else in the
tree needs changing to run this.
```
configs/
owuitools.env the stack's settings and its one required token (gitignored)
owuitools.env.example the template to copy it from (tracked)
tools.toml which tools the assistant can see
vms.toml the machines the VM sub-agent can be given
vmd.env the VM daemon's settings, installed to /etc/owuivm/
host.env.example overrides for vm/host/install.sh (optional)
assistant/
system-prompt.md what you paste into Open WebUI
agent/
params.env the sub-agent's model, sampling and session bounds
tools.toml every one of the sub-agent's tool definitions
prompt.md its system prompt, shared by both machines
prompt.ubuntu.md the Ubuntu half
prompt.windows.md the Windows half
prompt.screen.md the part about looking at the screen
services/
gateway.nginx.conf the ingress proxy
egress.squid.conf the one route to the internet
searxng.settings.yml the search back end
vmgw.nginx.conf.template the sub-agent's one path to Ollama
```
---
## `owuitools.env`
Copy the example and fill it in:
```sh
cp configs/owuitools.env.example configs/owuitools.env
sed -i "s|^OWUITOOLS_AUTH_TOKEN=.*|OWUITOOLS_AUTH_TOKEN=$(openssl rand -hex 32)|" \
configs/owuitools.env
```
`.env` in the project root is a symlink to it, because that is the file `docker compose`
reads. Both are gitignored.
**`OWUITOOLS_AUTH_TOKEN` is the only required setting.** The same value goes in Open WebUI's
tool connection, and in the `vm_agent_progress` filter's valve if you use it.
| Setting | Default | What it does |
|---|---|---|
| `OWUITOOLS_AUTH_TOKEN` | — | **Required.** The bearer token Open WebUI presents. |
| `OWUITOOLS_CONTACT` | `owuitools@localhost` | Goes in the User-Agent. Wikimedia **403s** without a real one — see [setup/contact.md](setup/contact.md). |
| `OWUITOOLS_MAX_RESPONSE_CHARS` | `12000` | Ceiling on any one tool response. Open WebUI does not truncate tool results, so this is what stands between one greedy fetch and a blown context. |
| `OWUITOOLS_PROBE_RATE_PER_HOUR` | `30` | Per-user hourly budget for the four tools that touch a named host. `0` disables the limiter. |
| `OWUITOOLS_LOG_LEVEL` | `INFO` | |
| `OWUITOOLS_VM_WAIT_SECONDS` | `7000` | How long one `vm_agent` call may block. One of [three clocks](advanced-params.md#the-three-clocks). |
| `OWUITOOLS_GITHUB_TOKEN` | — | Optional. [setup/github-token.md](setup/github-token.md) |
| `OWUITOOLS_STACKEXCHANGE_KEY` | — | Optional. [setup/stackexchange.md](setup/stackexchange.md) |
| `OWUITOOLS_NVD_KEY` | — | Optional. [setup/nvd.md](setup/nvd.md) |
---
## `tools.toml` — the on/off switch
One line per tool. `false` **removes** it: the operation leaves the OpenAPI spec, so the
model is never told it exists, and the endpoint stops answering.
That matters because the 22 schemas cost about **9,700 tokens on every turn of every
conversation**, whether or not a tool is used. A tool you will not use is a standing tax.
```toml
[tools]
web_search = true
pcb_calc = false # not doing electronics
```
Tools needing setup carry a comment pointing at the page for it. After editing:
```sh
docker compose restart api
```
…and then **re-save the tool connection in Open WebUI**, which caches the spec it fetched.
Both steps are needed.
A tool the file does not mention stays **on**, so an old config never silently removes a new
tool. A name that does not exist is reported in the log and ignored.
---
## `vms.toml` — the machines
```toml
[[machine]]
id = "ubuntu"
name = "Ubuntu"
iso = "ubuntu*.iso"
```
**`id` is identity, not a label.** It names the base disk, the systemd unit instance, the
saved-machine directory, and the value the assistant passes as `os` — and it appears in
regex allowlists inside the privileged launch scripts, which is what lets those scripts
refuse a path. Changing it does not rename a machine; it describes one that does not exist.
**`name` is yours.** Change it here, or press **Rename** in the maintenance app. Renames
made in the app are written to `/var/lib/owuivm/registry/vm-names.toml` and merged over the
top, so the registry keeps its comments.
`shell`, `project` and `example` are prompt text, substituted into the sub-agent's tool
descriptions so one set of definitions describes both machines.
---
## `agent/` — the second model
`params.env` holds its model, sampling and session bounds; see
[advanced-params.md](advanced-params.md).
`tools.toml` holds **every one of its tool definitions** — name, description and parameters.
The descriptions are prompt text the model reads, and rewording one is often the most
effective change available. It is bind-mounted, so:
```sh
docker compose restart vmagent
```
is enough — no rebuild.
What that file **cannot** do is give the agent a new capability. Dispatch lives in code, and
a tool named there with nothing behind it is refused at startup, naming the file. There is
an allowlist (`DISPATCHABLE` in `vmagent/app/tools.py`) precisely so that a config file
cannot widen what the agent can reach.
The prompts beside it are loaded the same way. If `prompt.md` is missing the agent
**refuses to start**: one that runs with no instructions still calls tools and still reports
success, which is the worst failure available.
---
## `services/` — the supporting containers
Bind-mounted read-only into their containers. Restart the one you changed.
| File | Container | Watch out for |
|---|---|---|
| `gateway.nginx.conf` | `owuitools-gw` | `/tools/vm_agent` has its own 7200s timeout; everything else keeps 240s |
| `egress.squid.conf` | `owuitools-egress` | The private-range denies are a security control, not tuning |
| `searxng.settings.yml` | `owuitools-searxng` | Set your own `secret_key`. The engine list is a measurement from one IP — see [setup/searxng.md](setup/searxng.md) |
| `vmgw.nginx.conf.template` | `owuitools-vmgw` | The `location =` exact matches are load-bearing. Ollama is unauthenticated and serves `DELETE /api/delete` |
**Restarting `netguard` or `vmguard` strands the containers that share their network
namespace.** They keep running, keep passing their own healthchecks, and have no route to
anything. Recreate the dependents too:
```sh
docker compose up -d --force-recreate netguard api searxng
docker compose up -d --force-recreate vmguard vmagent
```
---
## Host-side settings
The VM sub-agent's daemon reads `/etc/owuivm/vmd.env`, created from
[`../configs/vmd.env`](../configs/vmd.env) by `vm/host/install.sh` — **only if it is not
already there**, because the live copy holds the Gitea token. Edit the live file to change
the running daemon.
`configs/host.env` (optional, gitignored) overrides what `install.sh` works out for itself.
Copy `host.env.example` if any of its guesses are wrong for your machine.
Nothing in it is required — the installer derives the operator from `sudo`, the VM's memory
and CPU from `nproc` and installed RAM, and defaults the pool to `/Pool`. What you are most
likely to need is:
| Setting | Why |
|---|---|
| `OWUIVM_POOL_ROOT` | Your ZFS pool's mountpoint. `/Pool` is this project's default and nothing more — `zfs list` shows yours. The installer creates `<pool>/vmrun` and `<pool>/vmprojects` if they are missing. |
| `OWUIVM_GITEA_ALLOW` | The daemon runs `IPAddressDeny=any`. Gitea is not on the allowlist by default, because a fresh install has none. |
| `OWUIVM_ALLOWED_CPUS` | Pin the VM to particular cores. Empty — the default — means no pinning. |
These are read at **install time** and written into the units and scripts, so re-run
`sudo ./vm/host/install.sh` after changing them. The installer refuses to install a file
that still has an unrendered placeholder in it, so a value added to a template and not to
the installer fails loudly rather than producing a unit that will not start.