The managed-skill library was regenerated: 94 narrow per-incident skills
replaced by 25 broader ones (radiance-*, llamacpp-*, homepage-*, fleet/
endpoint ops). Git renders this as mass delete + mass add because whole
directories changed name; old content stays in history at 12c5e88.
Surface check: the 25 on disk are exactly the skills the harness advertises
this session.
30 lines
2.9 KiB
Markdown
30 lines
2.9 KiB
Markdown
---
|
|
name: openwebui-picker-acl-repair
|
|
description: "Fix OpenWebUI 0.6 \"No results found\" / Model not found in the model picker for non-admin users (Dankclaw fleet) after a connection rebuild."
|
|
---
|
|
|
|
# OpenWebUI 0.6 picker ACL repair (Dankclaw)
|
|
|
|
Symptom: admin sees models in OpenWebUI; regular users get "No results found" in the picker, or chat answers "Model not found". Cause: an OpenAI-connection rebuild (config keys `openai.api_base_urls` / `openai.api_configs` in the `config` table) that dropped the ACL pair for the model.
|
|
|
|
## Law
|
|
A non-admin user sees an external OpenAI-connection model only if BOTH exist in `webui.db`:
|
|
1. `model` table (singular) row: `id` == upstream model id, `base_model_id` NULL, `is_active` 1, `meta` JSON (description etc.).
|
|
2. `access_grant` row: `(resource_type='model', resource_id=<model id>, principal_type='user', principal_id='*', permission='read')`.
|
|
|
|
The aggregation (`utils/models.py get_filtered_models`) drops info-less models for `role=user`; admins bypass. `get_all_models` responses are served from `model_ids` in `api_config` when non-empty (no upstream fetch). An alias row (`id` != upstream, `base_model_id` set) renders in the picker but chat fails "Model not found" — id must equal the upstream id.
|
|
|
|
## Steps
|
|
1. Reproduce as the affected role: in a browser tab, `fetch("/api/models", {headers:{Authorization:"Bearer "+localStorage.token}})` → `data: []` while an admin API key (`api_key` table, column `key`, `sk-…`) lists the model.
|
|
2. DB at `/home/dank/Containers/open-webui/data/webui.db` (host; no sqlite3 CLI on Dankclaw — use host `python3` heredoc over ssh; container path `/app/backend/data`).
|
|
3. Insert/repair the pair (uuid4 id, epoch-ms `created_at`):
|
|
- `model`: id/name = upstream id, base_model_id NULL, is_active 1, user_id = admin uid (role='admin' in `user` table), meta `{"description": "…"}`.
|
|
- `access_grant`: shape above.
|
|
4. Cache: `MODELS_CACHE_TTL` defaults to 1 s — no restart needed for lists; a restart (`systemctl --user restart open-webui`, rootless) only if config edits were cached oddly. An OpenWebUI restart invalidates browser JWTs (401) — expect a silent SSO re-round-trip; kill stale tabs first so OAuth `state` cookies don't race (MismatchingStateError → clear cookies/storage, one clean flow).
|
|
5. Verify end-to-end: pick the model in the UI, send a short exact-match prompt, confirm the reply; check `/api/models` as the user role lists the id.
|
|
|
|
## Related knobs
|
|
- User API keys (User menu → Settings → Account → API keys → Show → Create new secret key) require `user.permissions` JSON `features.api_keys=true` in `config` (default false).
|
|
- New SSO signups land as role `pending` (`ui.default_user_role=pending`) — activate: `UPDATE user SET role='user' WHERE email LIKE …`. Table is `user`, singular; no `active` column.
|
|
- Anubis gates `ai.franksdank.cloud` for headless browsers (webdriver detection): drive direct `:3005` for UI work, or emulate a desktop Chrome UA.
|