229 lines
6.6 KiB
Markdown
229 lines
6.6 KiB
Markdown
# 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 |
|
|
| `user.mentioned` | → client | User was @mentioned in a channel |
|
|
| `workflow.assigned` | → client | Workflow stage assigned to team/user |
|
|
| `workflow.claimed` | → client | Workflow assignment claimed |
|
|
| `workflow.advanced` | → client | Workflow stage advanced |
|
|
| `workflow.completed` | → client | Workflow instance completed |
|
|
| `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`, `kb.ready`, `kb.error`, `grant.changed`,
|
|
`memory.extracted`, `user.mentioned`, `workflow.assigned`,
|
|
`workflow.claimed`, `task.completed`, `task.failed`,
|
|
`task.budget_exceeded`
|
|
|
|
See [enums.md](enums.md#notification-types) for full descriptions.
|
|
|
|
### 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.
|