128 lines
6.0 KiB
Markdown
128 lines
6.0 KiB
Markdown
# OWUI Tools
|
|
|
|
A tool server for [Open WebUI](https://github.com/open-webui/open-webui), and a VM
|
|
sub-agent that can actually try things.
|
|
|
|
A local assistant can reason, search and calculate. It cannot *check*. Asked whether a
|
|
PowerShell script works, it can only read documentation about PowerShell; asked for the
|
|
current version of a package, it recalls a number that was true when it was trained. This
|
|
fixes both halves: **22 tools** for looking things up and working things out, and one more
|
|
that hands a task to a second model driving a **real, throwaway virtual machine** which
|
|
writes the script, runs it, reads the actual error, fixes it, and comes back with evidence.
|
|
|
|
Everything runs on your own hardware. Nothing leaves the machine except the web requests a
|
|
tool makes on your behalf, and those go out through a proxy that refuses to touch your LAN.
|
|
|
|
> It speaks **OpenAPI**, which is what Open WebUI consumes natively — not the Model Context
|
|
> Protocol. If you are looking for an MCP server, this is not one.
|
|
|
|
```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
|
|
docker compose up -d --build
|
|
```
|
|
|
|
Then register it in Open WebUI and paste the system prompt —
|
|
**[docs/install-ubuntu-desktop.md](docs/install-ubuntu-desktop.md)** walks through the whole
|
|
thing on a clean machine.
|
|
|
|
## What it gives the assistant
|
|
|
|
| Group | Tools |
|
|
|---|---|
|
|
| **Web and research** | `web_search`, `fetch_page`, `wikipedia_lookup`, `search_stackexchange`, `search_papers` |
|
|
| **IT and reference** | `lookup_rfc`, `lookup_cve`, `read_man_page`, `lookup_package` |
|
|
| **Networking** | `subnet_calc`, `dns_lookup`, `inspect_tls`, `http_headers`, `lookup_ip_or_asn`, `network_reference` |
|
|
| **Electronics** | `ohms_law_power`, `component_calc`, `pcb_calc`, `wiring_calc`, `find_datasheet` |
|
|
| **Execution** | `matlab_run` (Octave, sandboxed), `vm_agent` (a real machine) |
|
|
|
|
Most need no setup at all. Turn any of them off in
|
|
[`configs/tools.toml`](configs/tools.toml) — that removes them from the spec rather than
|
|
hiding them, so you stop paying their schema tokens on every turn. Full list and what each
|
|
needs: **[docs/tools.md](docs/tools.md)**.
|
|
|
|
## Configuring it
|
|
|
|
Everything you are meant to edit is in **[`configs/`](configs/)** — the stack's settings,
|
|
the tool switch, the assistant's system prompt, and the sub-agent's prompts, parameters and
|
|
tool definitions. Nothing else in the tree needs changing to run this.
|
|
|
|
See **[docs/configuration.md](docs/configuration.md)**.
|
|
|
|
## Isolation
|
|
|
|
The tool server takes URLs chosen by a language model, so it is built on the assumption that
|
|
one day it will be persuaded to fetch something it should not.
|
|
|
|
- The app container has **no default route**. It lives in a network namespace whose only
|
|
permitted destinations are squid, valkey and the inbound request from its gateway.
|
|
- **squid refuses private address space** however politely it is asked.
|
|
- The filter **re-verifies itself** before its healthcheck passes: a firewall that silently
|
|
failed to apply is worse than none, because everything downstream carries on as though it
|
|
were enforced.
|
|
- Every container drops all capabilities, runs read-only where it can, and has memory and
|
|
pid limits.
|
|
|
|
The VM sub-agent adds a second boundary: the guest has real internet and no route to your
|
|
network, enforced primarily by a systemd address filter — *not* by a firewall, which fails
|
|
open on any `nft flush ruleset`. `tests/vm_host_asserts.sh` proves it by turning each layer
|
|
off in turn and re-running the same probe against the others.
|
|
|
|
Details, including what it deliberately does **not** prevent:
|
|
**[docs/vm-agent/overview.md](docs/vm-agent/overview.md)**.
|
|
|
|
## The VM sub-agent
|
|
|
|
`vm_agent` starts a throwaway Ubuntu or Windows machine, hands it to a second model with
|
|
about thirty tools — a shell, a file editor, a screen it can look at and click on, and a
|
|
lookup suite — and returns a report whose facts are assembled by the trusted side rather
|
|
than by the agent.
|
|
|
|
The machine is destroyed afterwards. The project folder survives on a quota'd dataset, and
|
|
can be published to Gitea as a release.
|
|
|
|
Setup is the one substantial piece of work here: **[docs/setup/vm-agent.md](docs/setup/vm-agent.md)**.
|
|
|
|
## Documentation
|
|
|
|
- **[docs/](docs/README.md)** — installation, configuration, every tool, the recommended
|
|
parameters, the filters.
|
|
- **[docs/operating.md](docs/operating.md)** — logs, rate limits, the cache, restarting
|
|
things safely, and what to check when something looks wrong.
|
|
- **[logs/](logs/README.md)** — every component writes its own file there, so there is one
|
|
place to look rather than nine `docker compose logs` invocations.
|
|
- **[docs/deployment/](docs/deployment/README.md)** — compose files for Ollama, Open WebUI
|
|
and Gitea, the three services that live outside this repo.
|
|
- **[docs/TUNING.md](docs/TUNING.md)** — the change log. Every entry is one change: what it
|
|
was meant to fix, and what measurably happened afterwards. Long, and the most useful
|
|
document here if you intend to modify anything.
|
|
- **[docs/testing/](docs/testing/README.md)** — the corpus the tuning was measured against:
|
|
forty graded prompts with rubrics, transcripts and scores.
|
|
|
|
## Requirements
|
|
|
|
Docker, an Ollama instance with a model, and Open WebUI. The VM sub-agent additionally needs
|
|
KVM, a ZFS pool and about 50 GB for base images — it is optional, and the tool removes
|
|
itself when the VM stack is absent.
|
|
|
|
Developed against Open WebUI 0.11.3 and `qwen3.8:latest` at a 160k context.
|
|
|
|
## Checking it works
|
|
|
|
```sh
|
|
./verify.py # what is set up, what is off, what is broken
|
|
```
|
|
|
|
A one-line-per-tool report, a full log in `logs/verify.log`, and a separate
|
|
`logs/verify-error-<tool>.log` for anything that fails. See
|
|
[docs/verifying.md](docs/verifying.md).
|
|
|
|
## Running the tests
|
|
|
|
```sh
|
|
./tests/smoke.sh # every tool, through the real gateway
|
|
python3 tests/test_*.py # unit tests, no container needed
|
|
sudo ./tests/vm_host_asserts.sh # the VM isolation suite
|
|
```
|