160 lines
9.3 KiB
Markdown
160 lines
9.3 KiB
Markdown
|
|
---
|
||
|
|
name: open-webui-persona-setup
|
||
|
|
description: Create new Hermes profiles and Open WebUI personas for the family Open WebUI instance. Covers the runbook creation pattern, substitution tables, API gotchas, and peer validation workflow.
|
||
|
|
version: 1.0.0
|
||
|
|
author: Hermes Agent
|
||
|
|
license: MIT
|
||
|
|
metadata:
|
||
|
|
hermes:
|
||
|
|
tags: [open-webui, hermes-profiles, personas, runbooks]
|
||
|
|
related_skills: [ask-hermes, hermes-minimal-profile-setup]
|
||
|
|
---
|
||
|
|
|
||
|
|
# Open WebUI Persona Setup
|
||
|
|
|
||
|
|
Create new Hermes profiles and Open WebUI personas for the family Open WebUI instance at 10.0.0.204:8080. Covers the full pattern: Hermes-side profile creation, runbook authoring, Open WebUI REST API configuration, and peer validation.
|
||
|
|
|
||
|
|
## When to Use
|
||
|
|
|
||
|
|
- Adding a new family member or persona to the existing Open WebUI instance
|
||
|
|
- Creating a new Hermes profile to back a new Open WebUI persona
|
||
|
|
- Writing a runbook for a new persona following the established four-phase pattern
|
||
|
|
|
||
|
|
## Architecture
|
||
|
|
|
||
|
|
One Open WebUI instance (10.0.0.204:8080, Docker), multiple Hermes profiles as API backends (10.0.0.42). Each persona gets:
|
||
|
|
|
||
|
|
- A dedicated Hermes profile (open1, openz, openg, openj, ...)
|
||
|
|
- A dedicated API server port (8653, 8654, 8655, 8656, ...)
|
||
|
|
- An Open WebUI group, user account, preset, and LLM connection
|
||
|
|
- Memory isolation via separate Hermes profiles (each profile has its own memory scope)
|
||
|
|
|
||
|
|
Voice I/O (STT/TTS) happens in Open WebUI (browser/PWA). Hermes handles agent logic only. STT uses Web API (browser-native) or Local Whisper. TTS uses Kokoro at 10.0.0.16:8880.
|
||
|
|
|
||
|
|
## Runbook Creation Pattern
|
||
|
|
|
||
|
|
When creating a runbook for a new persona, follow this exact sequence:
|
||
|
|
|
||
|
|
### 1. Read the sibling runbooks
|
||
|
|
|
||
|
|
All runbooks live in `/home/n8n/workspace/open1/`:
|
||
|
|
|
||
|
|
| File | Persona | Permission Level |
|
||
|
|
|------|---------|-----------------|
|
||
|
|
| `openz_runbook_for_zoe.md` | Zoe (kid) | Restricted — web + voice + memories only |
|
||
|
|
| `openg_runbook.md` | Guest | Full access (Operators-level) |
|
||
|
|
| `openj_runbook_for_jennifer.md` | Jennifer (wife) | Full access (Operators-level) |
|
||
|
|
|
||
|
|
Pick the closest match as your template. For full-access personas, use `openg_runbook.md`. For restricted personas, use `openz_runbook_for_zoe.md`.
|
||
|
|
|
||
|
|
### 2. Build a substitution table
|
||
|
|
|
||
|
|
Map every template value to the new persona's values:
|
||
|
|
|
||
|
|
| Element | Template | New |
|
||
|
|
|---------|----------|-----|
|
||
|
|
| Profile name | openg | openX |
|
||
|
|
| Port | 8655 | next available (see Port Registry) |
|
||
|
|
| Model name | Hermes Agent (openg) | Hermes Agent (openX) |
|
||
|
|
| Group name | Guests | <NewGroup> |
|
||
|
|
| Preset name/id | Hermes-Guest / hermes-guest | Hermes-<Group> / hermes-<group> |
|
||
|
|
| User display name | <guest> | <ActualName> |
|
||
|
|
| User email | <guest-email> | <actual-email> |
|
||
|
|
| User password | <guest-password> | <actual-password> |
|
||
|
|
| TTS voice | af_heart | af_heart (or af_nova for kids) |
|
||
|
|
| url_idx | 2 | previous + 1 |
|
||
|
|
| System prompt | empty | empty (or guardrail prompt for kids) |
|
||
|
|
| Permissions | Operators-level | Operators-level (or Kids-level) |
|
||
|
|
|
||
|
|
### 3. Write the runbook
|
||
|
|
|
||
|
|
Substitute every value from the table. Check every occurrence of port numbers, model names, group names, preset IDs, and url_idx values. Do NOT leave placeholder values — fill in concrete credentials.
|
||
|
|
|
||
|
|
### 4. Add a "second member" section
|
||
|
|
|
||
|
|
Include a section (like openg §10) documenting the one-call operation to add another user to the same group. Note the shared-memory implication: all users in the same group share the same Hermes profile's memory.
|
||
|
|
|
||
|
|
### 5. Validate with a peer
|
||
|
|
|
||
|
|
See Validation Workflow below.
|
||
|
|
|
||
|
|
## Common API Gotchas
|
||
|
|
|
||
|
|
These were discovered across all four phases (open1, openz, openg, openj). Every runbook MUST reflect these:
|
||
|
|
|
||
|
|
1. **List group users is POST, not GET.** The endpoint `POST /api/v1/groups/id/{id}/users` returns `list[UserInfoResponse]` (bare array of user objects with id/name/email/role), NOT `{user_ids: [...]}`. A GET returns HTTP 405. This bug existed in the first three runbooks and was fixed in openj.
|
||
|
|
|
||
|
|
2. **Add users to group returns GroupResponse, not `{success: true}`.** The response includes the group object with updated `member_count`.
|
||
|
|
|
||
|
|
3. **User creation endpoint is `POST /api/v1/auths/add`, NOT `/api/v1/users/add`.** The wrong endpoint returns HTTP 405. The response includes a JWT for the new user.
|
||
|
|
|
||
|
|
4. **access_grants field shape is critical.** Use `principal_type` (not `type` or `group_type`), `principal_id` (not `id` or `group_id`), `permission` (not `access` or `read_write`). Wrong field names are silently dropped by the API — HTTP 200 either way. Always verify with a read-back. The safe path: create without grants, then do a separate access-update, then verify.
|
||
|
|
|
||
|
|
5. **Open WebUI persists settings in SQLite, not env vars.** Editing `/root/.env` after first launch has no effect. Use the REST API (`/openai/config/update`) to change connections.
|
||
|
|
|
||
|
|
6. **Model discovery has a delay.** After adding a new connection via `/openai/config/update`, wait 5-10 seconds before listing models — Open WebUI discovers them asynchronously.
|
||
|
|
|
||
|
|
7. **The `meta.system` field layers on top of Hermes' default prompt.** Set to empty (`""`) for full-access personas. The Hermes default is still active underneath.
|
||
|
|
|
||
|
|
8. **Memory scope is per-profile, not per-preset.** The preset's `base_model_id` determines which Hermes profile handles the chat, which determines the memory scope. This is the entire reason for the multi-profile setup.
|
||
|
|
|
||
|
|
9. **Cross-grants break memory isolation.** Never grant one profile's base model to another persona's group. open1's base goes to Operators only, openz's to Kids only, openg's to Guests only, openj's to Family only.
|
||
|
|
|
||
|
|
10. **The `signin` endpoint returns a token, not a cookie.** All subsequent calls use `Authorization: Bearer <token>`. Token expires — re-signin on 401.
|
||
|
|
|
||
|
|
11. **Passwords are bcrypt-hashed on creation.** Plaintext is fine in the POST body; never log it.
|
||
|
|
|
||
|
|
12. **Email uniqueness is enforced.** Reusing an email for a different account will fail.
|
||
|
|
|
||
|
|
## Validation Workflow
|
||
|
|
|
||
|
|
After creating a runbook, validate it with a peer Hermes agent. The peer checks API behavior against the live Open WebUI source code at `github.com/open-webui/open-webui` (routers in `backend/open_webui/routers/auths.py`, `groups.py`, `models.py`).
|
||
|
|
|
||
|
|
```
|
||
|
|
hermes -p general chat -q "Validate the runbook at /home/n8n/workspace/open1/<runbook>.md.
|
||
|
|
Read the sibling runbooks for comparison.
|
||
|
|
Check: correctness (API endpoints, payload shapes, field names for Open WebUI 0.10.2),
|
||
|
|
completeness (all steps covered, second-member section present),
|
||
|
|
consistency (ports, model names, group names, preset IDs, url_idx values),
|
||
|
|
gotchas (all 12 carried forward, no missing),
|
||
|
|
substitution errors (no stale template values left in).
|
||
|
|
Use mcp_searxng_searxng_web_search to verify API behavior against the live Open WebUI
|
||
|
|
source code. Cite source URLs. Return a structured report with sections for Correctness,
|
||
|
|
Completeness, Consistency, Gotchas, and Substitution Errors." -Q --max-turns 20 --yolo
|
||
|
|
```
|
||
|
|
|
||
|
|
**After validation:** the peer may find bugs in ALL runbooks, not just the new one. When the peer flags an API issue (e.g., wrong HTTP method), check the sibling runbooks too — they likely share the same bug. Fix them all.
|
||
|
|
|
||
|
|
## Port Registry
|
||
|
|
|
||
|
|
| Profile | Port | Model Name | Owner |
|
||
|
|
|---------|------|------------|-------|
|
||
|
|
| open1 | 8653 | Hermes Agent (open1) | Rob (operator) |
|
||
|
|
| openz | 8654 | Hermes Agent (openz) | Zoe |
|
||
|
|
| openg | 8655 | Hermes Agent (openg) | Guest |
|
||
|
|
| openj | 8656 | Hermes Agent (openj) | Jennifer |
|
||
|
|
|
||
|
|
Reserved ports to avoid: 8644 (webhook), 8645 (wecom-callback), 8646 (msgraph-webhook). Use 8650+ for custom profiles. Next available: 8657.
|
||
|
|
|
||
|
|
## Key Files
|
||
|
|
|
||
|
|
All in `/home/n8n/workspace/open1/`:
|
||
|
|
|
||
|
|
| File | Purpose |
|
||
|
|
|------|---------|
|
||
|
|
| `open_web_ui_plan.md` | Master plan — architecture, Docker install, voice config, multi-profile setup, mobile access (61KB) |
|
||
|
|
| `openz_runbook_for_zoe.md` | Zoe's kid-persona runbook — restricted permissions, guardrail prompt, bank isolation |
|
||
|
|
| `openg_runbook.md` | Guest runbook — full access, no restrictions |
|
||
|
|
| `openj_runbook_for_jennifer.md` | Jennifer's runbook — full access, Family group |
|
||
|
|
| `openwebui_build_checklist.md` | Build/verification checklist with Phase A/B/C work order |
|
||
|
|
| `AGENTS.md` | open1 workspace context — architecture diagram, port table, conventions |
|
||
|
|
|
||
|
|
## Pitfalls
|
||
|
|
|
||
|
|
- **Don't leave placeholder values in runbooks.** Fill in concrete credentials before considering the runbook complete. The openg runbook has `<guest-email>` placeholders because guests are ephemeral; family members get concrete values.
|
||
|
|
- **Check url_idx carefully.** Each new connection increments the index. open1=0, openz=1, openg=2, openj=3. The next will be 4. Getting this wrong means the wrong model appears in the wrong persona's dropdown.
|
||
|
|
- **Cross-grants break memory isolation.** Never grant one profile's base model to another persona's group. The peer Hermes explicitly caught this in Phase A validation.
|
||
|
|
- **The peer may find bugs in ALL runbooks, not just the new one.** When the peer flags an API issue, check the sibling runbooks too — they likely share the same bug. The GET→POST bug existed in openz, openg, and the original openj draft.
|
||
|
|
- **Open WebUI version matters.** These runbooks target 0.10.2. If the instance is upgraded, re-validate API endpoints against the new version's source.
|
||
|
|
- **The Hermes API server is an agent runtime, not a pure LLM proxy.** Tool calls execute on the Hermes host (10.0.0.42), not the Open WebUI host (10.0.0.204).
|