|
@@ -91,7 +91,7 @@ to its grants.
|
|
|
| Discovery | `chatto.discovery.v1.ServerDiscoveryService` | `GetServer` (public) |
|
|
| Discovery | `chatto.discovery.v1.ServerDiscoveryService` | `GetServer` (public) |
|
|
|
| Server | `ServerService` | `GetMotd`, `GetRuntimeConfig` |
|
|
| Server | `ServerService` | `GetMotd`, `GetRuntimeConfig` |
|
|
|
| Viewer | `ViewerService` | `GetViewer` |
|
|
| Viewer | `ViewerService` | `GetViewer` |
|
|
|
-| My account | `MyAccountService` | `UpdateProfile`, `UpdateSettings`, `SetPresence`, `SetCustomStatus`, `DeleteCustomStatus`, `ChangePassword`, `DeleteMyAccount` (avatar upload was removed in 0.5.0b4) |
|
|
|
|
|
|
|
+| My account | `MyAccountService` | `UpdateProfile`, `UpdateSettings`, `SetPresence` (legacy live report), `GetPresencePreference`, `SetPresencePreference`, `RefreshPresence`, `SetCustomStatus`, `DeleteCustomStatus`, `ChangePassword`, `DeleteMyAccount` (avatar upload was removed in 0.5.0b4) |
|
|
|
| Roles | `RoleService` | `ListRoles`, `GetRole`, `BatchGetRoles` |
|
|
| Roles | `RoleService` | `ListRoles`, `GetRole`, `BatchGetRoles` |
|
|
|
| Room directory | `RoomDirectoryService` | `ListRooms`, `ListRoomGroups`, `GetRoomGroup`, `BatchGetRoomGroups`, `GetRoom`, `BatchGetRooms` |
|
|
| Room directory | `RoomDirectoryService` | `ListRooms`, `ListRoomGroups`, `GetRoomGroup`, `BatchGetRoomGroups`, `GetRoom`, `BatchGetRooms` |
|
|
|
| Rooms | `RoomService` | `CreateRoom`, `UpdateRoom`, `ArchiveRoom`, `UnarchiveRoom`, `JoinRoom`, `JoinRoomGroup`, `StartDM`, `LeaveRoom`, `AddMember`, `RemoveMember`, `ListMembers`, `GetMember`, `BatchGetMembers`, `BanMember`, `UnbanMember`, `ListBans`, `RefreshTypingIndicator`, `GetRoomEvents`, `GetRoomEventsAround`, `MarkRoomAsRead`, `ListRoomAttachments` |
|
|
| Rooms | `RoomService` | `CreateRoom`, `UpdateRoom`, `ArchiveRoom`, `UnarchiveRoom`, `JoinRoom`, `JoinRoomGroup`, `StartDM`, `LeaveRoom`, `AddMember`, `RemoveMember`, `ListMembers`, `GetMember`, `BatchGetMembers`, `BanMember`, `UnbanMember`, `ListBans`, `RefreshTypingIndicator`, `GetRoomEvents`, `GetRoomEventsAround`, `MarkRoomAsRead`, `ListRoomAttachments` |
|
|
@@ -112,7 +112,7 @@ to its grants.
|
|
|
| Admin: diagnostics | `chatto.admin.v1.AdminDiagnosticsService` | `GetSystemInfo` (raw response) |
|
|
| Admin: diagnostics | `chatto.admin.v1.AdminDiagnosticsService` | `GetSystemInfo` (raw response) |
|
|
|
| Admin: permissions | `chatto.admin.v1.AdminPermissionService` | `GetRole/UserPermissionMatrix`, `ListRole/UserPermissionDecisions`, `ExplainPermissions`, `SetRolePermission`, `SetUserPermission` (raw responses where the permission shape is server-version-dependent) |
|
|
| Admin: permissions | `chatto.admin.v1.AdminPermissionService` | `GetRole/UserPermissionMatrix`, `ListRole/UserPermissionDecisions`, `ExplainPermissions`, `SetRolePermission`, `SetUserPermission` (raw responses where the permission shape is server-version-dependent) |
|
|
|
| Voice calls | `VoiceCallService` | `ListActiveCalls`, `GetActiveCall`, `BatchGetActiveCalls`, `JoinCall`, `LeaveCall`, `CreateCallToken` |
|
|
| Voice calls | `VoiceCallService` | `ListActiveCalls`, `GetActiveCall`, `BatchGetActiveCalls`, `JoinCall`, `LeaveCall`, `CreateCallToken` |
|
|
|
-| Realtime (WS) | `chatto.realtime.v1` protobuf WS (protocol v4) | `stream_events(client)` / `RealtimeConnection` — the client sends one `RealtimeSubscribe` handshake; the server streams `event` (a 48-member oneof of thin, caller-scoped hints), `snapshot`, `caught_up`, `heartbeat`, and `close` (with a `RealtimeCloseCode` and `retry_after`) |
|
|
|
|
|
|
|
+| Realtime (WS) | `chatto.realtime.v1` protobuf WS (protocol v4) | `stream_events(client)` / `RealtimeConnection` — the client sends one `RealtimeSubscribe` handshake; the server streams `event` (a 48-member oneof of thin, caller-scoped hints, incl. `viewer_presence_preference_changed` added in 0.5.0b6), `snapshot`, `caught_up`, `heartbeat`, and `close` (with a `RealtimeCloseCode` and `retry_after`) |
|
|
|
|
|
|
|
|
### Naming conventions
|
|
### Naming conventions
|
|
|
|
|
|
|
@@ -134,9 +134,10 @@ to its grants.
|
|
|
- Server profile fields are no longer inside `server.profile`; the shape is now `ServerPublicProfile` returned by `ServerDiscoveryService.GetServer`.
|
|
- Server profile fields are no longer inside `server.profile`; the shape is now `ServerPublicProfile` returned by `ServerDiscoveryService.GetServer`.
|
|
|
- No more `motd` on the public profile; it is a separate authenticated RPC (`ServerService.GetMotd`).
|
|
- No more `motd` on the public profile; it is a separate authenticated RPC (`ServerService.GetMotd`).
|
|
|
- Room groups can contain `SidebarLink` items (not just rooms). `RoomGroup.sidebar_links` exposes them.
|
|
- Room groups can contain `SidebarLink` items (not just rooms). `RoomGroup.sidebar_links` exposes them.
|
|
|
-- **Never regenerate protos from `chattocorp/chatto@main`.** `scripts/generate_pb.sh` now defaults to `v<version>` (from `pyproject.toml`); override with `CHATTO_REF=<tag>` only when you know the deployed server has caught up. chattolib 0.4.19 shipped once from `main` and broke realtime for every downstream client because Chatto's main had a protocol-v2 rewrite that the deployed 0.4.19 server did not speak.
|
|
|
|
|
|
|
+- **0.5.0b6 split presence into a *saved preference* and a *live report*.** `SetPresence` is now the legacy, transient live report (still rejects `OFFLINE`/`UNSPECIFIED`); a saved choice takes precedence over it, even a `user_selected` one. The new pair is `GetPresencePreference`/`SetPresencePreference` (choice for every device on the server; `OFFLINE` = "Appear Offline" and *is* allowed there; a stale `expected_revision` returns `ABORTED`) plus `RefreshPresence` for 30-second liveness. `Message` also gained `viewer_state` (`MessageViewerState.can_reply_in_thread`), resolved per viewer even before a thread exists.
|
|
|
|
|
+- **Never regenerate protos from `chattocorp/chatto@main`.** `scripts/generate_pb.sh` defaults to a tag derived from `pyproject.toml`: `v<base>` for finals, and `v<base>-<kind>.<n>` for PEP 440 pre-releases (`0.5.0b6` → `v0.5.0-beta.6`), probing candidates with `git ls-remote` (exact ref match; the REST `/tags/{name}` endpoint 404s on lightweight tags). Override with `CHATTO_REF=<tag>` only when you know the deployed server has caught up. chattolib 0.4.19 shipped once from `main` and broke realtime for every downstream client because Chatto's main had a protocol-v2 rewrite that the deployed 0.4.19 server did not speak.
|
|
|
|
|
|
|
|
### Known bugs
|
|
### Known bugs
|
|
|
|
|
|
|
|
-- **Realtime is now protocol v4 — there are no projection frames.** The v2/v3 "projection" frames (`RealtimeProjectionEvent` / per-op `RealtimeProjectionOperation`) no longer exist. Instead the client sends a single `RealtimeSubscribe` handshake and the server streams `event` frames (a 48-member `oneof` of *thin, caller-scoped hints* — identifiers, not full resources), plus `snapshot` (one initial state), `caught_up` (recovery-to-live boundary), `heartbeat`, and `close` (with a `RealtimeCloseCode` and a `retry_after` duration). Live events carry IDs, so clients hydrate the referenced resource via the matching ConnectRPC (e.g. `get_message`) using the event's `cursor`. `Bot._handle_live` re-derives `BotMessageEvent` by hydrating the posted message.
|
|
|
|
|
|
|
+- **Realtime is now protocol v4 — there are no projection frames.** The v2/v3 "projection" frames (`RealtimeProjectionEvent` / per-op `RealtimeProjectionOperation`) no longer exist. Instead the client sends a single `RealtimeSubscribe` handshake and the server streams `event` frames (a 48-member `oneof` of *thin, caller-scoped hints* — identifiers, not full resources), plus `snapshot` (one initial state), `caught_up` (recovery-to-live boundary), `heartbeat`, and `close` (with a `RealtimeCloseCode` and `retry_after`). Live events carry IDs, so clients hydrate the referenced resource via the matching ConnectRPC (e.g. `get_message`) using the event's `cursor`. `Bot._handle_live` re-derives `BotMessageEvent` by hydrating the posted message. Since 0.5.0b6 the oneof has a 48th member, `viewer_presence_preference_changed` (an empty payload delivered only to the account whose own presence *preference* changed; `Bot` dispatches it as `kind="presence_preference"` and the new choice is read back via `get_presence_preference`).
|
|
|
- `RealtimeClose.code` is the enum `RealtimeCloseCode` (e.g. `SESSION_TERMINATED`, `RESYNC_REQUIRED`, `UNSUPPORTED_PROTOCOL`); `chattolib.realtime` maps it to its short name for `ChattoRealtimeCloseError.code`. A non-`reconnect` close (e.g. `SESSION_TERMINATED`) means the bot should stop, not reconnect.
|
|
- `RealtimeClose.code` is the enum `RealtimeCloseCode` (e.g. `SESSION_TERMINATED`, `RESYNC_REQUIRED`, `UNSUPPORTED_PROTOCOL`); `chattolib.realtime` maps it to its short name for `ChattoRealtimeCloseError.code`. A non-`reconnect` close (e.g. `SESSION_TERMINATED`) means the bot should stop, not reconnect.
|