Canonical Chat runtime
Cross-package ownership and offline behavior for the Web chat runtime.
Canonical Chat runtime
Web Chat has one application runtime: Canonical Chat. ChatRuntimeProvider composes the
Canonical store, IndexedDB repository, synchronization coordinator, outbound coordinator,
and shared chat surface. There is no Legacy Message store, REST client, controller, or
runtime selector in the application layer.
The authenticated online shell may read /v1/users/me/protocol-capabilities for optional
Canonical limits. A missing or invalid response uses conservative Canonical defaults; it
never selects another runtime. Browser and Electron Socket owners always request
messageProtocolVersion='canonical-v1' in a fresh device.hello. Resume preserves the
protocol confirmed by the current session.
Ownership
features/canonical-chat/ UI, controller, hooks, runtime, and React composition
lib/canonical-chat/ Protocol, store, persistence, sync, projection, voice, and outbound modules
packages/realtime-contract/ Validated Socket schemas
packages/*-adapter/ Browser and Electron Socket ownersNetwork responses and Socket events enter the same Canonical snapshot reducer. React renders projections from the store; it does not build a second message timeline.
Offline authenticated mode
The host-managed authenticated shell mounts OfflineCanonicalChatRuntimeProvider when the
account is available but the host reports offline. This opens the same user-scoped
Canonical IndexedDB repository and renders its cached active/latest segment. Local-only
mode does not start WebSocket, bootstrap/catch-up, outbound delivery, read-position writes,
remote search, or thinking polling. Composer submission remains blocked until the online
runtime remounts.
Detailed DTO, cursor, segment, and synchronization rules live in
apps/web/src/lib/canonical-chat/README.md.
API codegen
TypeScript clients are generated from the backend's OpenAPI spec via `@hey-api/openapi-ts`. `pnpm api:generate` writes to `packages/api-client/src/generated/` — never edit those files by hand.
Widget host deps
Why widget bundles resolve `react` and `@todayai-labs/tck` to the app's own module instances, what the ESM island cost before that, and which options were rejected.