Discourse operations
The discourse surface loads the per-task discourse tree (agent messages, blockers, resolutions, completion outcomes) for the cavi-control operator plane. It is a divergence point: it prefers the native WebSocket RPC discourse.tree, falls back to the operator-task discourse REST endpoint (canonical path first, plugin-alias path second), and normalizes whichever payload it gets into the TaskDiscourseSnapshot DTO.
Route/RPC owners: CAVI_CONTROL_OPERATOR_RPC_METHODS.discourseTree and the operatorTaskDiscoursePath / operatorTaskDiscoursePluginAliasPath helpers in extensions/cavi/contracts/paths.ts; the surface key is cavi.operator.taskDiscourse.
Source: extensions/cavi/discourse/.
Loader
loadTaskDiscourseLive
Request body / Parameters
| Field | Type | Required | Description |
|---|---|---|---|
| requestJson | JsonHttpRequest | required | HTTP transport for the REST fallback. |
| wsClient | GatewayWebSocketClient | null | optional | When present, tried first via discourse.tree. |
| taskId | string | required | Operator task id (trimmed; empty throws). |
Response
| Field | Type | Description |
|---|---|---|
| taskId | string | Echoed task id. |
| events | DiscourseEvent[] | Normalized message / blocker / resolution / completion events. |
Example
const snapshot = await loadTaskDiscourseLive(requestJson, wsClient, "task_42");
const timeline = snapshot.events.map((event) => ({ type: event.type, at: event.at }));Normalization helpers
normalizeTaskDiscourseSnapshot, normalizeDiscourseEvent, and the asDiscourse* coercion helpers are client-side (n/a capability) building blocks used by loadTaskDiscourseLive. They have no upstream equivalent — they exist to turn loosely-typed gateway payloads into the strict TaskDiscourse* domain types, and fallbackTaskDiscourse(taskId) supplies the degraded-mode snapshot. Documented here as internal surface; consumers normally call loadTaskDiscourseLive.