# Verifying an installation ```sh ./verify.py # the stack and every tool, ~40 seconds ./verify.py --quick # skip the tools that reach the internet, ~4 seconds ./verify.py --tool web_search ``` It changes nothing. It reads your config, asks Docker what is running, and calls each tool once with a known-good argument — the same path a real tool call takes. ## What the statuses mean There are two questions about every tool, and they are reported together because the answers are independent: **is it set up**, and **is it switched on**. | Status | Meaning | What to do | |---|---|---| | `All Set` | On, and it answered correctly | Nothing | | `All Set, Disabled` | Off, but everything it needs is in place | Nothing, unless you meant to leave it on | | `Needs Setup, Disabled` | Off, and it would not work yet anyway | Nothing urgent — the note says what it needs | | **`Needs Setup`** | **On and not ready.** The model is being offered a tool that will fail | Fix this first; the note names the missing piece and the page that covers it | | **`Error`** | On, set up, and failing | Read `logs/verify-error-.log` | | `Error, Disabled` | Failing, but nobody is being offered it | Fix before switching it on | | `Not Checked` | Skipped by `--quick`, or the API container is down | — | `Needs Setup` and `Error` are the two that print a second line under them. Everything else is one line on purpose: a report where the working case is quiet is a report you will actually read. ## What it writes - **`logs/verify.log`** — everything that was checked, including what each probe sent and the first part of what came back. This is the file to read when the summary says something you did not expect. - **`logs/verify-error-.log`** — one file per failing tool, containing only that tool's story: the call, the full error, and the setup page if it has one. This exists because when one thing is broken and twenty are fine, you want the one. Error files from a previous run are deleted when the tool passes, so a stale file cannot be found later and believed. ## Exit codes | Code | Meaning | |---|---| | `0` | Nothing is broken | | `1` | Something **enabled** is failing — the model will hit it | | `2` | Something needs setup, or something disabled is failing | So `./verify.py >/dev/null || echo "look at it"` is a reasonable thing to put in a cron job. ## What it cannot check **`vm_agent` is checked structurally, not by calling it** — a real call starts a virtual machine and runs a second model for minutes. It verifies the host daemon is running, that a base image exists and is frozen, and whether a Gitea token is present. Whether a session *succeeds* is what `sudo ./tests/vm_host_asserts.sh` and an actual session are for. **It does not check Open WebUI's side.** Whether the tool connection is registered, whether the system prompt was pasted, and whether the filters are installed are all state inside Open WebUI. [filters.md](filters.md) has commands for auditing that. **An optional API key is a note, not a setup step.** `search_stackexchange`, `lookup_cve` and `lookup_package` all work without one; a key only lifts a rate limit. Reporting those as "Needs Setup" would train you to ignore the column, so they report `All Set`.