Changeset 0.11.0 (#62)

This commit is contained in:
2026-02-25 13:29:15 +00:00
parent d2ec55b16d
commit c9d8e9457e
56 changed files with 5664 additions and 91 deletions

View File

@@ -21,10 +21,14 @@ docker compose up -d
- **Model Catalog**: Three-state visibility (enabled/disabled/team-only) with admin controls
- **Message Trees**: Edit and regenerate with full conversation forking — navigate sibling branches
- **Notes**: Markdown notes with full-text search, folders, and tags
- **Extensions**: Browser extension system with custom renderers, tool bridge, and self-contained styling
- Built-in: Mermaid diagrams, KaTeX math, CSV tables, diff viewer, JS sandbox, regex tester
- **Server Tools**: Calculator and datetime tools (auto-registered, zero config)
- **Audit Log**: All admin operations logged with actor, action, and resource details
- **Security**: JWT + refresh tokens, optional mTLS, optional OIDC/Keycloak, environment classification banners
- **Airgapped**: Local vendor files (marked.js, DOMPurify), no CDN required
- **Security**: JWT + refresh tokens, AES-256-GCM API key encryption, optional mTLS, optional OIDC/Keycloak, environment classification banners
- **Airgapped**: Local vendor files (marked.js, DOMPurify, KaTeX, mermaid.js), no CDN required
- **Mobile**: Responsive design, PWA manifest
- **Real-time**: WebSocket event bus for tool bridge, live updates
## Architecture
@@ -49,9 +53,9 @@ docker compose up -d
└───────────────────┘
```
**Go backend** (vanilla, no framework beyond Gin) with a store layer abstracting all database access. Providers package handles LLM API calls. Capabilities package resolves model features from catalog data, known model tables, and heuristic inference.
**Go backend** (vanilla, no framework beyond Gin) with a store layer abstracting all database access. Providers package handles LLM API calls. Capabilities package resolves model features from catalog data, known model tables, and heuristic inference. Server tools (calculator, datetime) auto-register via `init()`. EventBus + WebSocket hub routes tool calls between backend and browser extensions.
**Frontend** is vanilla JavaScript — no build step, no bundler. Five files: `api.js` (HTTP client), `app.js` (state + logic), `ui.js` (DOM rendering), `events.js` (event bus + WebSocket), `debug.js` (admin debug panel).
**Frontend** is vanilla JavaScript — no build step, no bundler. 15 files organized by domain: `api.js` (HTTP client), `app.js` (state + init), `chat.js` (send, regen, edit, branch), `events.js` (event bus + WebSocket), `extensions.js` (loader, registry, renderer pipeline, tool bridge), `ui-core.js` (DOM rendering + streaming), `ui-format.js` (markdown, code blocks), `ui-primitives.js` (shared components), `ui-settings.js` / `ui-admin.js` (settings and admin panels), `notes.js`, `tokens.js`, `debug.js`, `settings-handlers.js`, `admin-handlers.js`.
## Configuration
@@ -66,6 +70,7 @@ All configuration via environment variables. See `server/.env.example` for the f
| `JWT_SECRET` | (required) | Token signing key |
| `SWITCHBOARD_ADMIN_USERNAME` | ` ` | Bootstrap admin username |
| `SWITCHBOARD_ADMIN_PASSWORD` | ` ` | Bootstrap admin password |
| `ENCRYPTION_KEY` | ` ` | AES key for API key encryption (required if encrypted keys exist) |
| `SEED_USERS` | ` ` | Dev/test only: `user:pass:role,user2:pass2:role2` |
## Deployment
@@ -91,8 +96,8 @@ docker compose --profile dev up # include Adminer DB UI
Build and push both images:
```bash
docker build -f server/Dockerfile -t your-registry/switchboard-api:0.9.2 server/
docker build -f Dockerfile.frontend -t your-registry/switchboard-fe:0.9.2 .
docker build -f server/Dockerfile -t your-registry/switchboard-api:0.11.0 server/
docker build -f Dockerfile.frontend -t your-registry/switchboard-fe:0.11.0 .
```
**Backend deployment:**
@@ -100,7 +105,7 @@ docker build -f Dockerfile.frontend -t your-registry/switchboard-fe:0.9.2 .
```yaml
containers:
- name: api
image: your-registry/switchboard-api:0.9.2
image: your-registry/switchboard-api:0.11.0
ports:
- containerPort: 8080
env:
@@ -120,7 +125,7 @@ containers:
```yaml
containers:
- name: frontend
image: your-registry/switchboard-fe:0.9.2
image: your-registry/switchboard-fe:0.11.0
ports:
- containerPort: 80
env:
@@ -140,7 +145,7 @@ Set `BASE_PATH=/chat` to serve the application under a subpath. The frontend rea
### Airgapped / Disconnected
The Docker build bakes in `marked.js` and `DOMPurify` from npm during the vendor stage. No CDN calls at runtime. The `src/vendor/` directory contains local copies as fallback for development without Docker.
The Docker build bakes in `marked.js`, `DOMPurify`, and `KaTeX` (JS + CSS + fonts) from npm during the vendor stage. Mermaid.js loads dynamically from local vendor with CDN fallback. No CDN calls at runtime in airgapped deployments. The `src/vendor/` directory contains local copies as fallback for development without Docker.
## Database
@@ -161,18 +166,20 @@ scripts/db-migrate.sh
scripts/db-validate.sh
```
### Key Tables (v0.9)
### Key Tables (v0.11)
| Table | Purpose |
|-------|---------|
| `users` | Accounts with role, avatar, settings |
| `users` | Accounts with role, avatar, settings, encrypted vault (UEK) |
| `provider_configs` | API provider configurations (scope: global/team/personal) |
| `model_catalog` | Synced model list with capabilities and visibility |
| `model_catalog` | Synced model list with capabilities, visibility, and type |
| `personas` | Model presets (scope: global/team/personal) |
| `channels` | Conversations with type (direct/group/channel) |
| `messages` | Message tree with parent_id for forking |
| `messages` | Message tree with parent_id for forking, tool_calls JSONB |
| `teams` / `team_members` | Organizational units |
| `notes` | Markdown notes with full-text search |
| `extensions` / `extension_user_settings` | Browser extension registry and per-user config |
| `usage_log` / `model_pricing` | Token usage tracking and cost calculation |
| `audit_log` | Admin action audit trail |
| `user_model_settings` | Per-user model visibility and sort preferences |
@@ -214,7 +221,17 @@ All endpoints under `/api/v1/`. Authentication via `Authorization: Bearer <token
- `GET/PUT /admin/settings/:key` — Global settings and policies
- `GET/POST /admin/configs` — Global provider configs
- `GET/POST /admin/models/fetch` — Model catalog sync
- `GET/PUT /admin/roles/:role` — Model role configuration
- `GET /admin/usage` — Usage dashboard
- `GET /admin/audit` — Audit log
- `GET/POST/PUT/DELETE /admin/extensions` — Extension management
### Extensions
- `GET /extensions?tier=browser` — List enabled browser extensions
- `GET /extensions/:id/assets/*path` — Serve extension assets (public, no auth)
### WebSocket
- `GET /ws?token=<jwt>` — EventBus WebSocket for real-time events and tool bridge
## Development