Changeset 0.28.0.1 (#173)

This commit is contained in:
2026-03-11 14:45:37 +00:00
parent 93c72daadf
commit 58313f7e31
57 changed files with 5139 additions and 3206 deletions

219
docs/ICD/websocket.md Normal file
View File

@@ -0,0 +1,219 @@
# WebSocket Protocol
Real-time bidirectional event bus. Single connection per client.
### Connection
```
ws://{host}{BASE_PATH}/ws?token={access_token}
```
**Lifecycle:**
- Server sends `ping` every 54 seconds
- Client must respond with `pong` within 60 seconds or disconnection
- Max message size: 4 KB
- Write deadline: 10 seconds
### Event Envelope
All messages are JSON:
```json
{
"type": "event.type",
"payload": { ... }
}
```
### Room Subscription
Clients subscribe to rooms for scoped event delivery:
```json
{ "type": "subscribe", "payload": { "room": "channel:uuid" } }
{ "type": "unsubscribe", "payload": { "room": "channel:uuid" } }
```
### Event Routing Table
| Prefix | Direction | Description |
|--------|-----------|-------------|
| `channel.created` | → client | New channel created |
| `channel.updated` | → client | Channel metadata changed |
| `channel.deleted` | → client | Channel removed |
| `message.created` | → client | New message in subscribed channel |
| `message.updated` | → client | Message content changed |
| `message.deleted` | → client | Message removed |
| `cursor.updated` | → client | Branch cursor moved |
| `typing.start` | ↔ both | Participant started typing (payload includes `participant_id`, `participant_type`) |
| `typing.stop` | ↔ both | Typing ended |
| `participant.joined` | → client | Participant added to channel |
| `participant.left` | → client | Participant removed from channel |
| `participant.updated` | → client | Participant role changed |
| `presence.update` | → client | Participant online/idle/offline status change |
| `model.changed` | → client | Channel model roster changed |
| `persona.updated` | → client | Persona metadata changed |
| `kb.updated` | → client | Knowledge base changed |
| `kb.document.status` | → client | Document processing status update |
| `note.created` | → client | Note created |
| `note.updated` | → client | Note content changed |
| `note.deleted` | → client | Note removed |
| `notification.new` | → client | New notification |
| `notification.read` | → client | Notification marked read |
| `memory.extracted` | → client | New memory extracted |
| `memory.status` | → client | Memory approved/rejected |
| `role.fallback` | → client | Role fallback triggered |
| `workspace.updated` | → client | Workspace state changed |
| `project.updated` | → client | Project metadata changed |
| `extension.updated` | → client | Extension config changed |
| `settings.updated` | → client | Global settings changed |
| `user.updated` | → client | User profile changed |
| `file.created` | → client | File uploaded or generated (§17b.4) |
| `file.deleted` | → client | File removed |
Direction: `→ client` = server-to-client only, `← client` = client-to-server
only, `↔ both` = bidirectional.
---
## 19. Appendix: Enums
### Channel Types
`direct` (single-user), `group` (multi-user/multi-model), `workflow` (staged)
### Participant Types
`user`, `persona`, `session`
### Participant Roles
`owner`, `member`, `observer`
### Presence Statuses
`online`, `idle`, `offline`
### Message Roles
`user`, `assistant`, `system`, `tool`
### Scopes
`personal`, `team`, `global`
### Visibility (model catalog)
`enabled`, `disabled`, `team`
### User Roles
`admin`, `user`
### Team Member Roles
`admin`, `member`
### Provider Types
`openai`, `anthropic`, `openrouter`, `venice` (extensible via registry)
### Model Types
`chat`, `embedding`, `image`
### Memory Scopes
`user`, `persona`
### Memory Statuses
`pending`, `approved`, `rejected`
### Workspace Owner Types
`user`, `project`
### Workspace Statuses
`active`, `archived`
### Index Statuses
`pending`, `indexing`, `ready`, `error`
### KB Document Statuses
`pending`, `chunking`, `embedding`, `ready`, `error`
### Provider Health Statuses
`healthy`, `degraded`, `down`
### Routing Policy Types
`provider_prefer`, `team_route`, `cost_limit`, `model_alias`
### Extension Tiers
`browser` (implemented), `starlark` (future), `sidecar` (future)
### Grant Types
`team_only`, `global`, `groups`
### Resource Grant Scopes
`persona`, `kb`
### Notification Types
`role.fallback`, `memory.extracted`, `system.announcement`, plus
extensible via notification service.
### Git Auth Types
`https_pat`, `https_basic`, `ssh_key`
### Policies
| Key | Default | Description |
|-----|---------|-------------|
| `allow_registration` | `"true"` | Allow new user self-registration |
| `allow_user_byok` | `"true"` | Allow users to add personal API keys |
| `allow_user_personas` | `"true"` | Allow users to create personal Personas |
| `allow_team_providers` | `"true"` | Allow team admins to configure team providers |
| `kb_direct_access` | `"true"` | Show KB picker in channel (false = strict enterprise mode) |
| `require_email` | `"false"` | Require email on registration |
| `default_system_prompt` | `""` | Injected into all conversations (admin override) |
---
## Page Routes (Non-API)
Server-rendered Go template surfaces. Not REST endpoints — these
return HTML pages.
| Route | Surface | Description |
|-------|---------|-------------|
| `/login` | Login | Standalone login/register page |
| `/` | Chat | Main chat interface |
| `/chat/:chatID` | Chat | Chat with specific channel loaded |
| `/editor` | Editor | Workspace file editor |
| `/editor/:wsId` | Editor | Editor with specific workspace |
| `/notes` | Notes | Notes interface |
| `/notes/:noteId` | Notes | Notes with specific note loaded |
| `/admin` | Admin | Platform administration |
| `/admin/:section` | Admin | Admin with specific section |
| `/settings` | Settings | User settings |
| `/settings/:section` | Settings | Settings with specific section |
All page routes (except `/login`) require authentication via
`AuthOrRedirect` middleware (reads `sb_token` cookie). Admin routes
additionally require `RequireAdminPage()`.
**Dynamic surface routing** for admin-installed extension surfaces is
not yet implemented. The current five surfaces are hardcoded in Go
route registration. Future: extension manifests declare surface routes,
the page engine dynamically registers them with appropriate data
loaders. See EXTENSIONS.md for the design direction.