@memberjunction/ng-conversations 6.2.0-edge.2 → 6.2.0-edge.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (279) hide show
  1. package/README.md +4 -7
  2. package/dist/lib/components/collection/collection-view.component.d.ts.map +1 -1
  3. package/dist/lib/components/collection/collection-view.component.js +1 -0
  4. package/dist/lib/components/collection/collection-view.component.js.map +1 -1
  5. package/dist/lib/components/composer/ai-composer.component.d.ts +14 -2
  6. package/dist/lib/components/composer/ai-composer.component.d.ts.map +1 -1
  7. package/dist/lib/components/composer/ai-composer.component.js +35 -4
  8. package/dist/lib/components/composer/ai-composer.component.js.map +1 -1
  9. package/dist/lib/components/conversation/conversation-chat-area.component.d.ts +632 -55
  10. package/dist/lib/components/conversation/conversation-chat-area.component.d.ts.map +1 -1
  11. package/dist/lib/components/conversation/conversation-chat-area.component.js +2748 -624
  12. package/dist/lib/components/conversation/conversation-chat-area.component.js.map +1 -1
  13. package/dist/lib/components/conversation/forks-popover.component.d.ts +37 -0
  14. package/dist/lib/components/conversation/forks-popover.component.d.ts.map +1 -0
  15. package/dist/lib/components/conversation/forks-popover.component.js +164 -0
  16. package/dist/lib/components/conversation/forks-popover.component.js.map +1 -0
  17. package/dist/lib/components/export/export-modal.component.d.ts +7 -2
  18. package/dist/lib/components/export/export-modal.component.d.ts.map +1 -1
  19. package/dist/lib/components/export/export-modal.component.js +16 -3
  20. package/dist/lib/components/export/export-modal.component.js.map +1 -1
  21. package/dist/lib/components/message/conversation-message-rating.component.d.ts.map +1 -1
  22. package/dist/lib/components/message/conversation-message-rating.component.js +11 -9
  23. package/dist/lib/components/message/conversation-message-rating.component.js.map +1 -1
  24. package/dist/lib/components/message/message-input.component.d.ts +121 -11
  25. package/dist/lib/components/message/message-input.component.d.ts.map +1 -1
  26. package/dist/lib/components/message/message-input.component.js +307 -106
  27. package/dist/lib/components/message/message-input.component.js.map +1 -1
  28. package/dist/lib/components/message/message-item.component.d.ts +178 -5
  29. package/dist/lib/components/message/message-item.component.d.ts.map +1 -1
  30. package/dist/lib/components/message/message-item.component.js +919 -306
  31. package/dist/lib/components/message/message-item.component.js.map +1 -1
  32. package/dist/lib/components/message/message-list.component.d.ts +92 -21
  33. package/dist/lib/components/message/message-list.component.d.ts.map +1 -1
  34. package/dist/lib/components/message/message-list.component.js +337 -52
  35. package/dist/lib/components/message/message-list.component.js.map +1 -1
  36. package/dist/lib/components/realtime/avatar/realtime-avatar-channel.d.ts +34 -0
  37. package/dist/lib/components/realtime/avatar/realtime-avatar-channel.d.ts.map +1 -0
  38. package/dist/lib/components/realtime/avatar/realtime-avatar-channel.js +75 -0
  39. package/dist/lib/components/realtime/avatar/realtime-avatar-channel.js.map +1 -0
  40. package/dist/lib/components/realtime/avatar/realtime-avatar-surface.component.d.ts +80 -0
  41. package/dist/lib/components/realtime/avatar/realtime-avatar-surface.component.d.ts.map +1 -0
  42. package/dist/lib/components/realtime/avatar/realtime-avatar-surface.component.js +202 -0
  43. package/dist/lib/components/realtime/avatar/realtime-avatar-surface.component.js.map +1 -0
  44. package/dist/lib/components/realtime/capture/realtime-camera-check-card.component.d.ts +45 -0
  45. package/dist/lib/components/realtime/capture/realtime-camera-check-card.component.d.ts.map +1 -0
  46. package/dist/lib/components/realtime/capture/realtime-camera-check-card.component.js +123 -0
  47. package/dist/lib/components/realtime/capture/realtime-camera-check-card.component.js.map +1 -0
  48. package/dist/lib/components/realtime/capture/realtime-capture-channel.d.ts +90 -0
  49. package/dist/lib/components/realtime/capture/realtime-capture-channel.d.ts.map +1 -0
  50. package/dist/lib/components/realtime/capture/realtime-capture-channel.js +223 -0
  51. package/dist/lib/components/realtime/capture/realtime-capture-channel.js.map +1 -0
  52. package/dist/lib/components/realtime/capture/realtime-capture-model.d.ts +98 -0
  53. package/dist/lib/components/realtime/capture/realtime-capture-model.d.ts.map +1 -0
  54. package/dist/lib/components/realtime/capture/realtime-capture-model.js +161 -0
  55. package/dist/lib/components/realtime/capture/realtime-capture-model.js.map +1 -0
  56. package/dist/lib/components/realtime/capture/realtime-capture-surface.component.d.ts +48 -0
  57. package/dist/lib/components/realtime/capture/realtime-capture-surface.component.d.ts.map +1 -0
  58. package/dist/lib/components/realtime/capture/realtime-capture-surface.component.js +205 -0
  59. package/dist/lib/components/realtime/capture/realtime-capture-surface.component.js.map +1 -0
  60. package/dist/lib/components/realtime/channels/client-context-channel.d.ts +19 -2
  61. package/dist/lib/components/realtime/channels/client-context-channel.d.ts.map +1 -1
  62. package/dist/lib/components/realtime/channels/client-context-channel.js +83 -9
  63. package/dist/lib/components/realtime/channels/client-context-channel.js.map +1 -1
  64. package/dist/lib/components/realtime/channels/realtime-channel-pane.component.d.ts +30 -9
  65. package/dist/lib/components/realtime/channels/realtime-channel-pane.component.d.ts.map +1 -1
  66. package/dist/lib/components/realtime/channels/realtime-channel-pane.component.js +78 -14
  67. package/dist/lib/components/realtime/channels/realtime-channel-pane.component.js.map +1 -1
  68. package/dist/lib/components/realtime/identity-verification/identity-verification-channel.d.ts +71 -0
  69. package/dist/lib/components/realtime/identity-verification/identity-verification-channel.d.ts.map +1 -0
  70. package/dist/lib/components/realtime/identity-verification/identity-verification-channel.js +259 -0
  71. package/dist/lib/components/realtime/identity-verification/identity-verification-channel.js.map +1 -0
  72. package/dist/lib/components/realtime/identity-verification/identity-verification-model.d.ts +129 -0
  73. package/dist/lib/components/realtime/identity-verification/identity-verification-model.d.ts.map +1 -0
  74. package/dist/lib/components/realtime/identity-verification/identity-verification-model.js +373 -0
  75. package/dist/lib/components/realtime/identity-verification/identity-verification-model.js.map +1 -0
  76. package/dist/lib/components/realtime/identity-verification/identity-verification-surface.component.d.ts +77 -0
  77. package/dist/lib/components/realtime/identity-verification/identity-verification-surface.component.d.ts.map +1 -0
  78. package/dist/lib/components/realtime/identity-verification/identity-verification-surface.component.js +420 -0
  79. package/dist/lib/components/realtime/identity-verification/identity-verification-surface.component.js.map +1 -0
  80. package/dist/lib/components/realtime/interactive-component/component-contract.d.ts +83 -0
  81. package/dist/lib/components/realtime/interactive-component/component-contract.d.ts.map +1 -0
  82. package/dist/lib/components/realtime/interactive-component/component-contract.js +292 -0
  83. package/dist/lib/components/realtime/interactive-component/component-contract.js.map +1 -0
  84. package/dist/lib/components/realtime/interactive-component/component-data-state.d.ts +39 -0
  85. package/dist/lib/components/realtime/interactive-component/component-data-state.d.ts.map +1 -0
  86. package/dist/lib/components/realtime/interactive-component/component-data-state.js +152 -0
  87. package/dist/lib/components/realtime/interactive-component/component-data-state.js.map +1 -0
  88. package/dist/lib/components/realtime/interactive-component/component-instance-engine.d.ts +109 -0
  89. package/dist/lib/components/realtime/interactive-component/component-instance-engine.d.ts.map +1 -0
  90. package/dist/lib/components/realtime/interactive-component/component-instance-engine.js +146 -0
  91. package/dist/lib/components/realtime/interactive-component/component-instance-engine.js.map +1 -0
  92. package/dist/lib/components/realtime/interactive-component/component-spec-content.d.ts +19 -0
  93. package/dist/lib/components/realtime/interactive-component/component-spec-content.d.ts.map +1 -0
  94. package/dist/lib/components/realtime/interactive-component/component-spec-content.js +39 -0
  95. package/dist/lib/components/realtime/interactive-component/component-spec-content.js.map +1 -0
  96. package/dist/lib/components/realtime/interactive-component/interactive-component-channel.d.ts +183 -0
  97. package/dist/lib/components/realtime/interactive-component/interactive-component-channel.d.ts.map +1 -0
  98. package/dist/lib/components/realtime/interactive-component/interactive-component-channel.js +761 -0
  99. package/dist/lib/components/realtime/interactive-component/interactive-component-channel.js.map +1 -0
  100. package/dist/lib/components/realtime/interactive-component/interactive-component-config.d.ts +25 -0
  101. package/dist/lib/components/realtime/interactive-component/interactive-component-config.d.ts.map +1 -0
  102. package/dist/lib/components/realtime/interactive-component/interactive-component-config.js +57 -0
  103. package/dist/lib/components/realtime/interactive-component/interactive-component-config.js.map +1 -0
  104. package/dist/lib/components/realtime/interactive-component/interactive-component-host.component.d.ts +40 -0
  105. package/dist/lib/components/realtime/interactive-component/interactive-component-host.component.d.ts.map +1 -0
  106. package/dist/lib/components/realtime/interactive-component/interactive-component-host.component.js +97 -0
  107. package/dist/lib/components/realtime/interactive-component/interactive-component-host.component.js.map +1 -0
  108. package/dist/lib/components/realtime/interactive-component/interactive-component-types.d.ts +144 -0
  109. package/dist/lib/components/realtime/interactive-component/interactive-component-types.d.ts.map +1 -0
  110. package/dist/lib/components/realtime/interactive-component/interactive-component-types.js +57 -0
  111. package/dist/lib/components/realtime/interactive-component/interactive-component-types.js.map +1 -0
  112. package/dist/lib/components/realtime/interactive-component/react-component-handle.d.ts +36 -0
  113. package/dist/lib/components/realtime/interactive-component/react-component-handle.d.ts.map +1 -0
  114. package/dist/lib/components/realtime/interactive-component/react-component-handle.js +55 -0
  115. package/dist/lib/components/realtime/interactive-component/react-component-handle.js.map +1 -0
  116. package/dist/lib/components/realtime/interactive-component/realtime-interactive-component-surface.component.d.ts +55 -0
  117. package/dist/lib/components/realtime/interactive-component/realtime-interactive-component-surface.component.d.ts.map +1 -0
  118. package/dist/lib/components/realtime/interactive-component/realtime-interactive-component-surface.component.js +210 -0
  119. package/dist/lib/components/realtime/interactive-component/realtime-interactive-component-surface.component.js.map +1 -0
  120. package/dist/lib/components/realtime/interactive-component/run-view-component-artifact-source.d.ts +32 -0
  121. package/dist/lib/components/realtime/interactive-component/run-view-component-artifact-source.d.ts.map +1 -0
  122. package/dist/lib/components/realtime/interactive-component/run-view-component-artifact-source.js +90 -0
  123. package/dist/lib/components/realtime/interactive-component/run-view-component-artifact-source.js.map +1 -0
  124. package/dist/lib/components/realtime/media/media-channel.d.ts +7 -0
  125. package/dist/lib/components/realtime/media/media-channel.d.ts.map +1 -1
  126. package/dist/lib/components/realtime/media/media-channel.js +28 -1
  127. package/dist/lib/components/realtime/media/media-channel.js.map +1 -1
  128. package/dist/lib/components/realtime/realtime-agent-banner.component.d.ts +8 -1
  129. package/dist/lib/components/realtime/realtime-agent-banner.component.d.ts.map +1 -1
  130. package/dist/lib/components/realtime/realtime-agent-banner.component.js +89 -71
  131. package/dist/lib/components/realtime/realtime-agent-banner.component.js.map +1 -1
  132. package/dist/lib/components/realtime/realtime-agent-orb.component.d.ts +21 -0
  133. package/dist/lib/components/realtime/realtime-agent-orb.component.d.ts.map +1 -0
  134. package/dist/lib/components/realtime/realtime-agent-orb.component.js +49 -0
  135. package/dist/lib/components/realtime/realtime-agent-orb.component.js.map +1 -0
  136. package/dist/lib/components/realtime/realtime-agent-picker.component.d.ts +44 -11
  137. package/dist/lib/components/realtime/realtime-agent-picker.component.d.ts.map +1 -1
  138. package/dist/lib/components/realtime/realtime-agent-picker.component.js +162 -50
  139. package/dist/lib/components/realtime/realtime-agent-picker.component.js.map +1 -1
  140. package/dist/lib/components/realtime/realtime-audio-visuals.d.ts +8 -2
  141. package/dist/lib/components/realtime/realtime-audio-visuals.d.ts.map +1 -1
  142. package/dist/lib/components/realtime/realtime-audio-visuals.js +14 -18
  143. package/dist/lib/components/realtime/realtime-audio-visuals.js.map +1 -1
  144. package/dist/lib/components/realtime/realtime-composer.component.d.ts +42 -2
  145. package/dist/lib/components/realtime/realtime-composer.component.d.ts.map +1 -1
  146. package/dist/lib/components/realtime/realtime-composer.component.js +137 -102
  147. package/dist/lib/components/realtime/realtime-composer.component.js.map +1 -1
  148. package/dist/lib/components/realtime/realtime-perception-chip.component.d.ts +71 -0
  149. package/dist/lib/components/realtime/realtime-perception-chip.component.d.ts.map +1 -0
  150. package/dist/lib/components/realtime/realtime-perception-chip.component.js +221 -0
  151. package/dist/lib/components/realtime/realtime-perception-chip.component.js.map +1 -0
  152. package/dist/lib/components/realtime/realtime-session-overlay.component.d.ts +264 -22
  153. package/dist/lib/components/realtime/realtime-session-overlay.component.d.ts.map +1 -1
  154. package/dist/lib/components/realtime/realtime-session-overlay.component.js +851 -135
  155. package/dist/lib/components/realtime/realtime-session-overlay.component.js.map +1 -1
  156. package/dist/lib/components/realtime/realtime-surface-placement-prefs.d.ts +14 -0
  157. package/dist/lib/components/realtime/realtime-surface-placement-prefs.d.ts.map +1 -0
  158. package/dist/lib/components/realtime/realtime-surface-placement-prefs.js +14 -0
  159. package/dist/lib/components/realtime/realtime-surface-placement-prefs.js.map +1 -0
  160. package/dist/lib/components/realtime/realtime-surface-stage.model.d.ts +74 -0
  161. package/dist/lib/components/realtime/realtime-surface-stage.model.d.ts.map +1 -0
  162. package/dist/lib/components/realtime/realtime-surface-stage.model.js +171 -0
  163. package/dist/lib/components/realtime/realtime-surface-stage.model.js.map +1 -0
  164. package/dist/lib/components/realtime/realtime-surface-tabs.component.d.ts +71 -13
  165. package/dist/lib/components/realtime/realtime-surface-tabs.component.d.ts.map +1 -1
  166. package/dist/lib/components/realtime/realtime-surface-tabs.component.js +232 -73
  167. package/dist/lib/components/realtime/realtime-surface-tabs.component.js.map +1 -1
  168. package/dist/lib/components/realtime/realtime-surface-tabs.model.d.ts +5 -0
  169. package/dist/lib/components/realtime/realtime-surface-tabs.model.d.ts.map +1 -1
  170. package/dist/lib/components/realtime/realtime-surface-tabs.model.js +8 -0
  171. package/dist/lib/components/realtime/realtime-surface-tabs.model.js.map +1 -1
  172. package/dist/lib/components/realtime/realtime-ui-config.d.ts +12 -2
  173. package/dist/lib/components/realtime/realtime-ui-config.d.ts.map +1 -1
  174. package/dist/lib/components/realtime/realtime-ui-config.js +5 -1
  175. package/dist/lib/components/realtime/realtime-ui-config.js.map +1 -1
  176. package/dist/lib/components/realtime/remote-browser/remote-browser-channel.d.ts +10 -1
  177. package/dist/lib/components/realtime/remote-browser/remote-browser-channel.d.ts.map +1 -1
  178. package/dist/lib/components/realtime/remote-browser/remote-browser-channel.js +42 -2
  179. package/dist/lib/components/realtime/remote-browser/remote-browser-channel.js.map +1 -1
  180. package/dist/lib/components/realtime/remote-browser/remote-browser-surface.component.d.ts +20 -3
  181. package/dist/lib/components/realtime/remote-browser/remote-browser-surface.component.d.ts.map +1 -1
  182. package/dist/lib/components/realtime/remote-browser/remote-browser-surface.component.js +44 -10
  183. package/dist/lib/components/realtime/remote-browser/remote-browser-surface.component.js.map +1 -1
  184. package/dist/lib/components/realtime/whiteboard/whiteboard-channel.d.ts +28 -44
  185. package/dist/lib/components/realtime/whiteboard/whiteboard-channel.d.ts.map +1 -1
  186. package/dist/lib/components/realtime/whiteboard/whiteboard-channel.js +76 -162
  187. package/dist/lib/components/realtime/whiteboard/whiteboard-channel.js.map +1 -1
  188. package/dist/lib/components/search/search-panel.component.d.ts +2 -0
  189. package/dist/lib/components/search/search-panel.component.d.ts.map +1 -1
  190. package/dist/lib/components/search/search-panel.component.js +25 -12
  191. package/dist/lib/components/search/search-panel.component.js.map +1 -1
  192. package/dist/lib/components/workspace/conversation-workspace.component.d.ts +22 -31
  193. package/dist/lib/components/workspace/conversation-workspace.component.d.ts.map +1 -1
  194. package/dist/lib/components/workspace/conversation-workspace.component.js +50 -63
  195. package/dist/lib/components/workspace/conversation-workspace.component.js.map +1 -1
  196. package/dist/lib/conversations.module.d.ts +30 -29
  197. package/dist/lib/conversations.module.d.ts.map +1 -1
  198. package/dist/lib/conversations.module.js +27 -5
  199. package/dist/lib/conversations.module.js.map +1 -1
  200. package/dist/lib/events/chat-events.d.ts +25 -0
  201. package/dist/lib/events/chat-events.d.ts.map +1 -1
  202. package/dist/lib/events/chat-events.js +36 -0
  203. package/dist/lib/events/chat-events.js.map +1 -1
  204. package/dist/lib/models/agent-turn.model.d.ts +5 -0
  205. package/dist/lib/models/agent-turn.model.d.ts.map +1 -1
  206. package/dist/lib/models/agent-turn.model.js.map +1 -1
  207. package/dist/lib/services/agent-state.service.d.ts +34 -8
  208. package/dist/lib/services/agent-state.service.d.ts.map +1 -1
  209. package/dist/lib/services/agent-state.service.js +82 -29
  210. package/dist/lib/services/agent-state.service.js.map +1 -1
  211. package/dist/lib/services/artifact-state.service.d.ts +0 -9
  212. package/dist/lib/services/artifact-state.service.d.ts.map +1 -1
  213. package/dist/lib/services/artifact-state.service.js +1 -32
  214. package/dist/lib/services/artifact-state.service.js.map +1 -1
  215. package/dist/lib/services/browser-realtime-media-host.d.ts +12 -0
  216. package/dist/lib/services/browser-realtime-media-host.d.ts.map +1 -1
  217. package/dist/lib/services/browser-realtime-media-host.js +19 -0
  218. package/dist/lib/services/browser-realtime-media-host.js.map +1 -1
  219. package/dist/lib/services/browser-recording-unload-guard.d.ts +30 -0
  220. package/dist/lib/services/browser-recording-unload-guard.d.ts.map +1 -0
  221. package/dist/lib/services/browser-recording-unload-guard.js +43 -0
  222. package/dist/lib/services/browser-recording-unload-guard.js.map +1 -0
  223. package/dist/lib/services/conversation-agent.service.d.ts +35 -11
  224. package/dist/lib/services/conversation-agent.service.d.ts.map +1 -1
  225. package/dist/lib/services/conversation-agent.service.js +65 -20
  226. package/dist/lib/services/conversation-agent.service.js.map +1 -1
  227. package/dist/lib/services/conversation-detail-window.store.d.ts +22 -4
  228. package/dist/lib/services/conversation-detail-window.store.d.ts.map +1 -1
  229. package/dist/lib/services/conversation-detail-window.store.js +50 -9
  230. package/dist/lib/services/conversation-detail-window.store.js.map +1 -1
  231. package/dist/lib/services/conversation-naming.d.ts +72 -22
  232. package/dist/lib/services/conversation-naming.d.ts.map +1 -1
  233. package/dist/lib/services/conversation-naming.js +84 -10
  234. package/dist/lib/services/conversation-naming.js.map +1 -1
  235. package/dist/lib/services/data-cache.service.d.ts +13 -5
  236. package/dist/lib/services/data-cache.service.d.ts.map +1 -1
  237. package/dist/lib/services/data-cache.service.js +39 -19
  238. package/dist/lib/services/data-cache.service.js.map +1 -1
  239. package/dist/lib/services/export.service.d.ts +26 -9
  240. package/dist/lib/services/export.service.d.ts.map +1 -1
  241. package/dist/lib/services/export.service.js +61 -18
  242. package/dist/lib/services/export.service.js.map +1 -1
  243. package/dist/lib/services/realtime-audio-recorder.d.ts +33 -5
  244. package/dist/lib/services/realtime-audio-recorder.d.ts.map +1 -1
  245. package/dist/lib/services/realtime-audio-recorder.js +71 -11
  246. package/dist/lib/services/realtime-audio-recorder.js.map +1 -1
  247. package/dist/lib/services/realtime-pairing.d.ts +10 -5
  248. package/dist/lib/services/realtime-pairing.d.ts.map +1 -1
  249. package/dist/lib/services/realtime-pairing.js +15 -6
  250. package/dist/lib/services/realtime-pairing.js.map +1 -1
  251. package/dist/lib/services/realtime-session.service.d.ts +3 -2
  252. package/dist/lib/services/realtime-session.service.d.ts.map +1 -1
  253. package/dist/lib/services/realtime-session.service.js +7 -2
  254. package/dist/lib/services/realtime-session.service.js.map +1 -1
  255. package/dist/lib/services/search.service.d.ts +7 -2
  256. package/dist/lib/services/search.service.d.ts.map +1 -1
  257. package/dist/lib/services/search.service.js +13 -4
  258. package/dist/lib/services/search.service.js.map +1 -1
  259. package/dist/lib/util/frame-zone.d.ts +10 -0
  260. package/dist/lib/util/frame-zone.d.ts.map +1 -0
  261. package/dist/lib/util/frame-zone.js +10 -0
  262. package/dist/lib/util/frame-zone.js.map +1 -0
  263. package/dist/lib/utils/conversation-branching.d.ts +4 -0
  264. package/dist/lib/utils/conversation-branching.d.ts.map +1 -0
  265. package/dist/lib/utils/conversation-branching.js +5 -0
  266. package/dist/lib/utils/conversation-branching.js.map +1 -0
  267. package/dist/lib/utils/conversation-forks.d.ts +315 -0
  268. package/dist/lib/utils/conversation-forks.d.ts.map +1 -0
  269. package/dist/lib/utils/conversation-forks.js +456 -0
  270. package/dist/lib/utils/conversation-forks.js.map +1 -0
  271. package/dist/public-api.d.ts +23 -1
  272. package/dist/public-api.d.ts.map +1 -1
  273. package/dist/public-api.js +30 -1
  274. package/dist/public-api.js.map +1 -1
  275. package/package.json +37 -32
  276. package/dist/lib/components/thread/thread-panel.component.d.ts +0 -126
  277. package/dist/lib/components/thread/thread-panel.component.d.ts.map +0 -1
  278. package/dist/lib/components/thread/thread-panel.component.js +0 -440
  279. package/dist/lib/components/thread/thread-panel.component.js.map +0 -1
@@ -4,11 +4,9 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
4
4
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6
6
  };
7
- var RealtimeWhiteboardChannel_1;
8
7
  import { RegisterClass } from '@memberjunction/global';
9
- import { CHANNEL_INBOUND_VIDEO_TRACK } from '@memberjunction/ai';
10
- import { ChannelInboundVideoBridge } from '@memberjunction/ai-realtime-client';
11
- import { BaseRealtimeChannelClient } from '@memberjunction/realtime-runtime';
8
+ import { REALTIME_CHANNEL_CONTRACT_VERSION } from '@memberjunction/ai-core-plus';
9
+ import { BaseRealtimeChannelClient, BuildToolBackedVerbs } from '@memberjunction/realtime-runtime';
12
10
  import { ApplyWhiteboardAgentTool, BuildWhiteboardExportSvg, RealtimeWhiteboardHostComponent, WHITEBOARD_TOOL_DEFINITIONS, WHITEBOARD_TOOL_PREFIX, WhiteboardState } from '@memberjunction/ng-whiteboard';
13
11
  /**
14
12
  * Whether a whiteboard tool result reports success.
@@ -118,14 +116,14 @@ export const WHITEBOARD_INTERACTION_NOTE_THROTTLE_MS = 4000;
118
116
  * ({@link WHITEBOARD_TOOL_DEFINITIONS}); {@link ApplyAgentTool} prefers the BOUND host
119
117
  * component (board mutation + violet pop-in / toast / presence-cursor garnish) and
120
118
  * falls back to the pure {@link ApplyWhiteboardAgentTool} engine call when no surface
121
- * is bound (e.g. the surface panel is collapsed) — the channel keeps working, just
119
+ * is bound (e.g. the board has not been shown yet) — the channel keeps working, just
122
120
  * without the garnish.
123
121
  * - **Perception**: {@link BindSurface} subscribes the host's coalesced (750 ms)
124
122
  * `SceneDelta` stream and pipes each delta into the live model's context as a
125
123
  * `[whiteboard]` background note; the agent-undo toast click flows the same way.
126
- * - **Surface**: {@link RealtimeWhiteboardHostComponent}, created dynamically by the
127
- * overlay's channel tab; the host's Focus toggle rides `Context.SetFocusMode` so the
128
- * shell can collapse/restore the main call column.
124
+ * - **Surface**: {@link RealtimeWhiteboardHostComponent}, created on the overlay's stage; the
125
+ * host's "Move to stage" button rides `Context.SetFocusMode`, and the board hears where the
126
+ * overlay placed it ({@link OnSurfacePlacementChange}) so the button offers the way back.
129
127
  * - **State of record**: every board mutation (user edits AND agent tool calls) requests
130
128
  * a save of {@link WhiteboardState.ToJSON} under channel name `'Whiteboard'` — the
131
129
  * host debounces and flushes at teardown.
@@ -137,7 +135,6 @@ export const WHITEBOARD_INTERACTION_NOTE_THROTTLE_MS = 4000;
137
135
  * incompatible payloads are tolerated — the board simply starts fresh.
138
136
  */
139
137
  let RealtimeWhiteboardChannel = class RealtimeWhiteboardChannel extends BaseRealtimeChannelClient {
140
- static { RealtimeWhiteboardChannel_1 = this; }
141
138
  /** The board's state of record — created fresh with the plugin (one per session). */
142
139
  State = new WhiteboardState();
143
140
  /** The live bound surface, when the channel tab's pane is instantiated. */
@@ -148,19 +145,9 @@ let RealtimeWhiteboardChannel = class RealtimeWhiteboardChannel extends BaseReal
148
145
  stateChangedSub = null;
149
146
  /** Per-widget ambient-interaction note throttles (ItemID → window state). */
150
147
  interactionThrottles = new Map();
151
- /** Shared video bridge streaming board frames to the model when the model supports inbound video. */
152
- videoBridge = null;
153
- /** Pacing timestamp for event-driven visual scene pushes (enforces max 1 fps). */
154
- lastPushTimestamp = 0;
155
148
  get ChannelName() {
156
149
  return 'Whiteboard';
157
150
  }
158
- /**
159
- * Sourced tracks: Whiteboard can source inbound video to the model when the model supports it.
160
- */
161
- GetSourcedTracks() {
162
- return [CHANNEL_INBOUND_VIDEO_TRACK];
163
- }
164
151
  /**
165
152
  * Produces the latest visual scene as a base64-encoded frame for the video bridge.
166
153
  * Renders the whiteboard SVG into an offscreen canvas and returns base64 JPEG.
@@ -178,127 +165,22 @@ let RealtimeWhiteboardChannel = class RealtimeWhiteboardChannel extends BaseReal
178
165
  return null;
179
166
  }
180
167
  }
181
- static WHITEBOARD_DEFAULT_CADENCE_MS = 1000;
182
- static WHITEBOARD_MIN_CADENCE_MS = 250;
183
- // NO liveness heartbeat here, deliberately. This channel is 100% CHANGE-DRIVEN: the only thing
184
- // that pushes a frame is a board mutation. A periodic keep-alive would have to be driven by its
185
- // own always-on interval — this channel does no work at all while the board is idle, and
186
- // resurrecting it every 15 seconds to re-send an unchanged picture is a cost with no shown
187
- // benefit. (It also cannot be smuggled in via the mutation path: a 15s elapsed-check inside
188
- // onUserMutation only runs when a mutation arrives, so on an idle board it is never evaluated —
189
- // which is exactly what the constant this replaced did.) If the inbound video track ever needs
190
- // keep-alive frames, that belongs on the track or the bridge, once, not per channel.
191
- /** Trailing timer to deliver the settled resting frame after rapid user drawing/edits. */
192
- whiteboardTrailingTimer = null;
193
- /** Last base64 JPEG frame pushed to the bridge, used for deduplication. */
194
- lastPushedWhiteboardFrame = null;
195
- /** Cancels any active trailing-edge settle timer and clears the handle. */
196
- clearWhiteboardTrailingTimer() {
197
- if (this.whiteboardTrailingTimer != null) {
198
- clearTimeout(this.whiteboardTrailingTimer);
199
- this.whiteboardTrailingTimer = null;
200
- }
201
- }
202
- /**
203
- * Resolves the effective push cadence in milliseconds based on the negotiated inbound video track.
204
- * Defaults to 1000ms (1 fps ceiling for Gemini Live), but clamps down to a minimum of 250ms (4 fps)
205
- * if the negotiated track specifies a higher `Rate`.
206
- */
207
- getNegotiatedVideoCadenceMs() {
208
- const client = this.Context?.Client;
209
- if (!client) {
210
- return RealtimeWhiteboardChannel_1.WHITEBOARD_DEFAULT_CADENCE_MS;
211
- }
212
- const tracks = client.EstablishedTracks;
213
- const videoTrack = tracks?.find((t) => t.Descriptor.Modality === 'video' &&
214
- t.Descriptor.Direction === 'inbound');
215
- const rate = videoTrack?.Descriptor.Rate;
216
- if (typeof rate === 'number' && rate > 0) {
217
- return Math.max(RealtimeWhiteboardChannel_1.WHITEBOARD_MIN_CADENCE_MS, Math.floor(1000 / rate));
218
- }
219
- return RealtimeWhiteboardChannel_1.WHITEBOARD_DEFAULT_CADENCE_MS;
220
- }
221
- /**
222
- * Pushes a frame to the video bridge, updating timestamp and deduplication cache.
223
- */
224
- pushWhiteboardFrame(frame) {
225
- this.lastPushTimestamp = Date.now();
226
- this.lastPushedWhiteboardFrame = frame;
227
- this.ensureVideoBridge()?.PushFrame(frame);
228
- }
229
168
  /**
230
- * Pushes the latest board visual scene when user mutations occur, with dynamic pacing,
231
- * deduplication, and a trailing-edge settle timer so the model sees the final resting state.
169
+ * The shared frame bridge, which now lives on the base channel (`VisualVideoBridge`). This accessor
170
+ * keeps the board's long-standing `videoBridge` handle — tests and tooling reach the bridge by that
171
+ * name — pointing at the one the pump actually writes to.
232
172
  */
233
- async onUserMutation() {
234
- try {
235
- const bridge = this.ensureVideoBridge();
236
- if (!bridge || !this.Context?.Client?.IsTrackEstablished('video', 'inbound')) {
237
- return;
238
- }
239
- const now = Date.now();
240
- const cadenceMs = this.getNegotiatedVideoCadenceMs();
241
- const elapsed = now - this.lastPushTimestamp;
242
- if (elapsed >= cadenceMs) {
243
- this.clearWhiteboardTrailingTimer();
244
- const frame = await this.GetLatestFrame();
245
- if (!frame) {
246
- return;
247
- }
248
- if (frame !== this.lastPushedWhiteboardFrame) {
249
- this.pushWhiteboardFrame(frame);
250
- }
251
- }
252
- else {
253
- // Within cooldown window: schedule trailing settle timer if not already armed.
254
- if (!this.whiteboardTrailingTimer) {
255
- const delay = Math.max(0, cadenceMs - elapsed);
256
- this.whiteboardTrailingTimer = setTimeout(async () => {
257
- this.whiteboardTrailingTimer = null;
258
- try {
259
- if (!this.Context?.Client?.IsTrackEstablished('video', 'inbound')) {
260
- return;
261
- }
262
- const frame = await this.GetLatestFrame();
263
- if (!frame) {
264
- return;
265
- }
266
- if (frame !== this.lastPushedWhiteboardFrame) {
267
- this.pushWhiteboardFrame(frame);
268
- }
269
- }
270
- catch (err) {
271
- console.error('[RealtimeWhiteboardChannel] Error in whiteboard trailing settle timer:', err);
272
- }
273
- }, delay);
274
- }
275
- }
276
- }
277
- catch (err) {
278
- console.error('[RealtimeWhiteboardChannel] Error in onUserMutation:', err);
279
- }
173
+ get videoBridge() {
174
+ return this.VisualVideoBridge;
280
175
  }
281
- /**
282
- * Pushes exactly ONE confirmation frame after an agent tool mutates the board, and
283
- * informs the model context so it does not loop narrating its own change.
284
- */
285
- async pushAgentConfirmationFrame() {
286
- try {
287
- const bridge = this.ensureVideoBridge();
288
- if (!bridge || !this.Context?.Client?.IsTrackEstablished('video', 'inbound')) {
289
- return;
290
- }
291
- this.clearWhiteboardTrailingTimer();
292
- const frame = await this.GetLatestFrame();
293
- if (frame) {
294
- this.pushWhiteboardFrame(frame);
295
- this.Context?.SendContextNote('[whiteboard] visual confirmation of your action (background — do NOT narrate or announce your own change; continue naturally)');
296
- }
297
- }
298
- catch (err) {
299
- console.error('[RealtimeWhiteboardChannel] Error in pushAgentConfirmationFrame:', err);
300
- }
176
+ set videoBridge(bridge) {
177
+ this.VisualVideoBridge = bridge;
301
178
  }
179
+ // The change-driven frame pump (leading edge, trailing settle, dedupe, negotiated cadence, one
180
+ // confirmation frame after an agent edit) used to live here. It is now the base channel's
181
+ // `EnableVisualPerception` pump, enabled from OnInitialize — this channel only says WHEN its picture
182
+ // changed. The behavior is unchanged, including (deliberately) the shared bridge's fixed-rate poller:
183
+ // see `StartBridgePoller` in OnInitialize.
302
184
  get ToolNamePrefix() {
303
185
  return WHITEBOARD_TOOL_PREFIX;
304
186
  }
@@ -308,6 +190,10 @@ let RealtimeWhiteboardChannel = class RealtimeWhiteboardChannel extends BaseReal
308
190
  get TabIcon() {
309
191
  return 'fa-solid fa-chalkboard';
310
192
  }
193
+ /** The board can be shared on its own: the call's Share menu offers it under "This panel" while it is on screen. */
194
+ get SurfaceShareable() {
195
+ return true;
196
+ }
311
197
  GetToolDefinitions() {
312
198
  return WHITEBOARD_TOOL_DEFINITIONS;
313
199
  }
@@ -328,31 +214,59 @@ let RealtimeWhiteboardChannel = class RealtimeWhiteboardChannel extends BaseReal
328
214
  IconClass: 'fa-solid fa-chalkboard'
329
215
  };
330
216
  }
331
- /** Persist the board (host-debounced) on EVERY board mutation — user edits AND agent tools. */
217
+ /**
218
+ * The board's self-description: what it holds, every `Whiteboard_*` tool as a verb (so a tool a
219
+ * subclass adds shows up here too), and that the model can SEE it (frames), not just read its state.
220
+ */
221
+ GetDescriptor() {
222
+ return {
223
+ Key: this.ChannelName,
224
+ Version: REALTIME_CHANNEL_CONTRACT_VERSION,
225
+ DisplayName: this.TabTitle,
226
+ OwningPackage: '@memberjunction/ng-conversations',
227
+ Instructions: 'A shared canvas you and the user can both draw, write and annotate on live. Whatever you add ' +
228
+ 'appears instantly, and you perceive what the user adds. Use it to sketch, diagram and explain ' +
229
+ 'visually; do not narrate minor edits.',
230
+ Nouns: [
231
+ {
232
+ Name: 'pages',
233
+ Description: 'The board\'s pages, in order; each holds the items (notes, shapes, connectors, text, widgets) drawn on it.',
234
+ Schema: { type: 'array', items: { type: 'object' } }
235
+ }
236
+ ],
237
+ Verbs: BuildToolBackedVerbs(this.GetToolDefinitions(), this.ToolNamePrefix),
238
+ Events: [
239
+ { Name: 'state_changed', Description: 'The board changed (by you or the user).' },
240
+ { Name: 'frame_pushed', Description: 'A picture of the board was sent to you.' }
241
+ ],
242
+ DisplayPolicy: 'open-on-start',
243
+ DefaultAvailability: 'all-sessions',
244
+ MaxExposure: 'pixels'
245
+ };
246
+ }
247
+ /**
248
+ * Persist the board (host-debounced) on EVERY board mutation — user edits AND agent tools — and drive
249
+ * the visual pump. The board feeds the model its own perception (coalesced scene deltas from the
250
+ * bound surface), so state changes are recorded for events and frame tagging only (`Perceive: false`):
251
+ * the structured note would duplicate the deltas.
252
+ */
332
253
  OnInitialize() {
333
254
  this.stateChangedSub?.unsubscribe();
334
- this.clearWhiteboardTrailingTimer();
255
+ this.EnableVisualPerception(this, {
256
+ ConfirmationNote: '[whiteboard] visual confirmation of your action (background — do NOT narrate or announce your own change; continue naturally)',
257
+ // Preserves what the board always did: it started the bridge's fixed-rate poller despite being
258
+ // designed heartbeat-free. Flagged for the reviewer; remove to make the board purely change-driven.
259
+ StartBridgePoller: true
260
+ });
335
261
  this.stateChangedSub = this.State.Changed$.subscribe((change) => {
336
262
  this.Context?.RequestSave(this.State.ToJSON());
337
- // Only user edits (and scene replacements like undo) drive the user settle-debounce pipeline.
263
+ this.RecordChange({ Author: change.Author, Perceive: false });
264
+ // Only user edits (and scene replacements like undo) drive the settle-debounce pipeline.
338
265
  // Agent edits are confirmed with a single frame in ApplyAgentTool.
339
266
  if (change.Author === 'user' || change.Op === 'replace') {
340
- void this.onUserMutation();
267
+ void this.NotifyVisualChange();
341
268
  }
342
269
  });
343
- this.ensureVideoBridge();
344
- }
345
- OnSessionStarted() {
346
- this.ensureVideoBridge();
347
- }
348
- ensureVideoBridge() {
349
- if (!this.videoBridge && this.Context) {
350
- this.videoBridge = new ChannelInboundVideoBridge(() => this.Context?.Client, this);
351
- }
352
- if (this.videoBridge && !this.videoBridge.IsActive && this.Context?.Client?.IsTrackEstablished('video', 'inbound')) {
353
- this.videoBridge.Start?.();
354
- }
355
- return this.videoBridge;
356
270
  }
357
271
  /**
358
272
  * Wires the dynamically-created board host: inputs (shared state engine + agent name)
@@ -360,7 +274,7 @@ let RealtimeWhiteboardChannel = class RealtimeWhiteboardChannel extends BaseReal
360
274
  * outputs are subscribed back into the host context — the overlay never sees any of it.
361
275
  */
362
276
  BindSurface(instance) {
363
- this.ensureVideoBridge();
277
+ this.EnsureVideoBridge();
364
278
  this.releaseSurface();
365
279
  this.host = instance;
366
280
  instance.State = this.State;
@@ -475,7 +389,7 @@ let RealtimeWhiteboardChannel = class RealtimeWhiteboardChannel extends BaseReal
475
389
  /**
476
390
  * Executes one `Whiteboard_*` tool call LOCALLY. Prefers the live bound host (board
477
391
  * mutation + UI garnish); falls back to the pure engine function when no surface is
478
- * bound so the channel keeps working with the pane collapsed.
392
+ * bound so the channel keeps working before the board is first shown.
479
393
  */
480
394
  ApplyAgentTool(toolName, argsJson) {
481
395
  let result;
@@ -492,7 +406,7 @@ let RealtimeWhiteboardChannel = class RealtimeWhiteboardChannel extends BaseReal
492
406
  // quiet about it — so the failure would vanish from the user's view while the model carried on.
493
407
  // It would also push a frame identical to the last one, since a failed tool changes nothing.
494
408
  if (toolSucceeded(result)) {
495
- void this.pushAgentConfirmationFrame();
409
+ void this.ConfirmVisualChange();
496
410
  }
497
411
  return result;
498
412
  }
@@ -509,6 +423,10 @@ let RealtimeWhiteboardChannel = class RealtimeWhiteboardChannel extends BaseReal
509
423
  RestoreState(stateJson) {
510
424
  return this.State.LoadFromJSON(stateJson);
511
425
  }
426
+ /** Keeps the board's "Move to stage" / "Back to tab" button true to where the host placed it. */
427
+ OnSurfacePlacementChange(placement) {
428
+ this.host?.SetOnStage(placement === 'stage');
429
+ }
512
430
  /**
513
431
  * Exit focus mode THROUGH the bound host (its own Focus button state stays in sync; it
514
432
  * re-emits `FocusModeChange(false)` → `Context.SetFocusMode(false)`). When no surface is
@@ -520,13 +438,9 @@ let RealtimeWhiteboardChannel = class RealtimeWhiteboardChannel extends BaseReal
520
438
  }
521
439
  }
522
440
  Dispose() {
523
- this.clearWhiteboardTrailingTimer();
524
- this.videoBridge?.Stop();
525
- this.videoBridge = null;
526
441
  this.stateChangedSub?.unsubscribe();
527
442
  this.stateChangedSub = null;
528
- this.lastPushedWhiteboardFrame = null;
529
- super.Dispose(); // releases the surface binding + context
443
+ super.Dispose(); // releases the surface binding, the visual pump + bridge, and the context
530
444
  }
531
445
  /** Unsubscribes surface outputs, cancels pending ambient notes and drops the host reference. */
532
446
  releaseSurface() {
@@ -538,7 +452,7 @@ let RealtimeWhiteboardChannel = class RealtimeWhiteboardChannel extends BaseReal
538
452
  this.host = null;
539
453
  }
540
454
  };
541
- RealtimeWhiteboardChannel = RealtimeWhiteboardChannel_1 = __decorate([
455
+ RealtimeWhiteboardChannel = __decorate([
542
456
  RegisterClass(BaseRealtimeChannelClient, 'RealtimeWhiteboardChannel')
543
457
  ], RealtimeWhiteboardChannel);
544
458
  export { RealtimeWhiteboardChannel };
@@ -1 +1 @@
1
- {"version":3,"file":"whiteboard-channel.js","sourceRoot":"","sources":["../../../../../src/lib/components/realtime/whiteboard/whiteboard-channel.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Type } from '@angular/core';\nimport { Subscription } from 'rxjs';\nimport { RegisterClass } from '@memberjunction/global';\nimport { CHANNEL_INBOUND_VIDEO_TRACK, RealtimeToolDefinition, RealtimeTrack, RealtimeTrackDescriptor } from '@memberjunction/ai';\nimport { ChannelInboundVideoBridge, IChannelFrameProvider } from '@memberjunction/ai-realtime-client';\nimport { BaseRealtimeChannelClient, ChannelOnboardingDetails } from '@memberjunction/realtime-runtime';\nimport {\n ApplyWhiteboardAgentTool, BuildWhiteboardExportSvg, RealtimeWhiteboardHostComponent, WHITEBOARD_TOOL_DEFINITIONS,\n WHITEBOARD_TOOL_PREFIX, WhiteboardState, WhiteboardWidgetInteractionEvent, WhiteboardWidgetSubmitEvent\n} from '@memberjunction/ng-whiteboard';\n\n/**\n * Whether a whiteboard tool result reports success.\n *\n * `ApplyWhiteboardAgentTool` returns a JSON `WhiteboardToolResult` string — `{ success: true, … }`\n * or `{ success: false, error }` — for every tool and every failure path. Anything that does not\n * parse as an object with `success === true` is treated as NOT a successful mutation, which is the\n * safe direction: the cost of missing a confirmation frame is one stale picture until the next\n * change, while the cost of a false one is telling the model an edit landed when it did not.\n */\nfunction toolSucceeded(result: string): boolean {\n try {\n const parsed: unknown = JSON.parse(result);\n return parsed !== null && typeof parsed === 'object' && (parsed as { success?: unknown }).success === true;\n } catch {\n // A non-JSON result cannot be confirmed as a mutation — the host returned something this\n // channel does not understand, so it does not get a \"your change is on screen\" note.\n return false;\n }\n}\n\n/**\n * Asynchronously rasterizes an SVG string to a JPEG base64 string (without the `data:image/jpeg;base64,` prefix)\n * using an offscreen canvas. Returns null in non-DOM environments or when rendering fails.\n */\nexport async function RasterizeSvgToJpegBase64(svg: string, width = 1280, height = 720): Promise<string | null> {\n if (typeof document === 'undefined' || typeof Image === 'undefined') {\n return null;\n }\n return new Promise<string | null>((resolve) => {\n let url: string | null = null;\n let timer: ReturnType<typeof setTimeout> | null = null;\n\n const cleanup = () => {\n if (timer != null) {\n clearTimeout(timer);\n timer = null;\n }\n if (url) {\n URL.revokeObjectURL(url);\n url = null;\n }\n };\n\n try {\n const img = new Image();\n const svgBlob = new Blob([svg], { type: 'image/svg+xml;charset=utf-8' });\n url = URL.createObjectURL(svgBlob);\n\n // Capped wait: resolve null and revoke URL if the Image never fires onload or onerror (item 61)\n timer = setTimeout(() => {\n console.error('[RealtimeWhiteboardChannel] SVG rasterization timed out after 5000ms');\n cleanup();\n resolve(null);\n }, 5000);\n\n img.onload = () => {\n try {\n const canvas = document.createElement('canvas');\n canvas.width = width;\n canvas.height = height;\n const ctx = canvas.getContext('2d');\n if (!ctx) {\n cleanup();\n resolve(null);\n return;\n }\n ctx.fillStyle = '#ffffff';\n ctx.fillRect(0, 0, width, height);\n ctx.drawImage(img, 0, 0, width, height);\n cleanup();\n const dataUrl = canvas.toDataURL('image/jpeg', 0.85);\n const comma = dataUrl.indexOf(',');\n resolve(comma >= 0 ? dataUrl.slice(comma + 1) : dataUrl);\n } catch (err) {\n console.error('[RealtimeWhiteboardChannel] Failed to rasterize SVG canvas to JPEG:', err);\n cleanup();\n resolve(null);\n }\n };\n img.onerror = (err) => {\n console.error('[RealtimeWhiteboardChannel] Failed to load SVG image for rasterization:', err);\n cleanup();\n resolve(null);\n };\n img.src = url;\n } catch (err) {\n console.error('[RealtimeWhiteboardChannel] Failed to initialize SVG rasterization:', err);\n cleanup();\n resolve(null);\n }\n });\n}\n\n/**\n * Per-widget throttle window for AMBIENT interaction context notes: at most one note per\n * widget per this many ms — within the window the LATEST summary wins (chatty widgets\n * collapse to one trailing-edge note instead of flooding the model's context).\n */\nexport const WHITEBOARD_INTERACTION_NOTE_THROTTLE_MS = 4000;\n\n/** Per-widget ambient-note throttle bookkeeping. */\ninterface InteractionThrottleEntry {\n /** When this widget's last ambient note was sent (epoch ms). */\n LastSentAt: number;\n /** Trailing-edge timer for a deferred note, or null when the window is idle. */\n Timer: ReturnType<typeof setTimeout> | null;\n /** The latest event received within the open window (sent when the timer fires). */\n Pending: WhiteboardWidgetInteractionEvent | null;\n}\n\n/**\n * The LIVE WHITEBOARD as a pluggable interactive channel — the canonical\n * {@link BaseRealtimeChannelClient} implementation, resolved from the `MJ: AI Agent\n * Channels` registry row whose `ClientPluginClass` is `'RealtimeWhiteboardChannel'`.\n *\n * One instance per session (created via ClassFactory at session start). It owns the\n * board's {@link WhiteboardState} engine and contributes the channel's full contract:\n *\n * - **Action**: the `Whiteboard_*` client-executed tool set\n * ({@link WHITEBOARD_TOOL_DEFINITIONS}); {@link ApplyAgentTool} prefers the BOUND host\n * component (board mutation + violet pop-in / toast / presence-cursor garnish) and\n * falls back to the pure {@link ApplyWhiteboardAgentTool} engine call when no surface\n * is bound (e.g. the surface panel is collapsed) — the channel keeps working, just\n * without the garnish.\n * - **Perception**: {@link BindSurface} subscribes the host's coalesced (750 ms)\n * `SceneDelta` stream and pipes each delta into the live model's context as a\n * `[whiteboard]` background note; the agent-undo toast click flows the same way.\n * - **Surface**: {@link RealtimeWhiteboardHostComponent}, created dynamically by the\n * overlay's channel tab; the host's Focus toggle rides `Context.SetFocusMode` so the\n * shell can collapse/restore the main call column.\n * - **State of record**: every board mutation (user edits AND agent tool calls) requests\n * a save of {@link WhiteboardState.ToJSON} under channel name `'Whiteboard'` — the\n * host debounces and flushes at teardown.\n *\n * A PRIOR session's persisted board is restored through {@link RestoreState} (invoked by\n * the session host after Initialize, before any surface binding): the saved JSON is\n * rehydrated IN PLACE into the same {@link WhiteboardState} instance, so the save\n * subscription and any later surface binding keep pointing at one engine. Malformed or\n * incompatible payloads are tolerated — the board simply starts fresh.\n */\n@RegisterClass(BaseRealtimeChannelClient, 'RealtimeWhiteboardChannel')\nexport class RealtimeWhiteboardChannel extends BaseRealtimeChannelClient<RealtimeWhiteboardHostComponent> implements IChannelFrameProvider {\n /** The board's state of record — created fresh with the plugin (one per session). */\n public readonly State = new WhiteboardState();\n\n /** The live bound surface, when the channel tab's pane is instantiated. */\n private host: RealtimeWhiteboardHostComponent | null = null;\n /** Output subscriptions on the bound surface (SceneDelta / AgentUndo / FocusModeChange). */\n private surfaceSubs: Subscription[] = [];\n /** Board-mutation subscription driving the debounced state-of-record save. */\n private stateChangedSub: Subscription | null = null;\n /** Per-widget ambient-interaction note throttles (ItemID → window state). */\n private interactionThrottles = new Map<string, InteractionThrottleEntry>();\n /** Shared video bridge streaming board frames to the model when the model supports inbound video. */\n private videoBridge: ChannelInboundVideoBridge | null = null;\n /** Pacing timestamp for event-driven visual scene pushes (enforces max 1 fps). */\n private lastPushTimestamp = 0;\n\n public get ChannelName(): string {\n return 'Whiteboard';\n }\n\n /**\n * Sourced tracks: Whiteboard can source inbound video to the model when the model supports it.\n */\n public override GetSourcedTracks(): readonly RealtimeTrackDescriptor[] {\n return [CHANNEL_INBOUND_VIDEO_TRACK];\n }\n\n /**\n * Produces the latest visual scene as a base64-encoded frame for the video bridge.\n * Renders the whiteboard SVG into an offscreen canvas and returns base64 JPEG.\n */\n public async GetLatestFrame(): Promise<string | null> {\n if (!this.State) {\n return null;\n }\n try {\n const svg = BuildWhiteboardExportSvg(this.State);\n return await RasterizeSvgToJpegBase64(svg);\n } catch (err) {\n console.error('[RealtimeWhiteboardChannel] Failed to export whiteboard frame:', err);\n return null;\n }\n }\n\n private static readonly WHITEBOARD_DEFAULT_CADENCE_MS = 1000;\n private static readonly WHITEBOARD_MIN_CADENCE_MS = 250;\n\n // NO liveness heartbeat here, deliberately. This channel is 100% CHANGE-DRIVEN: the only thing\n // that pushes a frame is a board mutation. A periodic keep-alive would have to be driven by its\n // own always-on interval — this channel does no work at all while the board is idle, and\n // resurrecting it every 15 seconds to re-send an unchanged picture is a cost with no shown\n // benefit. (It also cannot be smuggled in via the mutation path: a 15s elapsed-check inside\n // onUserMutation only runs when a mutation arrives, so on an idle board it is never evaluated —\n // which is exactly what the constant this replaced did.) If the inbound video track ever needs\n // keep-alive frames, that belongs on the track or the bridge, once, not per channel.\n\n /** Trailing timer to deliver the settled resting frame after rapid user drawing/edits. */\n private whiteboardTrailingTimer: ReturnType<typeof setTimeout> | null = null;\n /** Last base64 JPEG frame pushed to the bridge, used for deduplication. */\n private lastPushedWhiteboardFrame: string | null = null;\n\n /** Cancels any active trailing-edge settle timer and clears the handle. */\n private clearWhiteboardTrailingTimer(): void {\n if (this.whiteboardTrailingTimer != null) {\n clearTimeout(this.whiteboardTrailingTimer);\n this.whiteboardTrailingTimer = null;\n }\n }\n\n /**\n * Resolves the effective push cadence in milliseconds based on the negotiated inbound video track.\n * Defaults to 1000ms (1 fps ceiling for Gemini Live), but clamps down to a minimum of 250ms (4 fps)\n * if the negotiated track specifies a higher `Rate`.\n */\n private getNegotiatedVideoCadenceMs(): number {\n const client = this.Context?.Client;\n if (!client) {\n return RealtimeWhiteboardChannel.WHITEBOARD_DEFAULT_CADENCE_MS;\n }\n const tracks: readonly RealtimeTrack[] = client.EstablishedTracks;\n const videoTrack = tracks?.find(\n (t: RealtimeTrack) =>\n t.Descriptor.Modality === 'video' &&\n t.Descriptor.Direction === 'inbound'\n );\n const rate = videoTrack?.Descriptor.Rate;\n if (typeof rate === 'number' && rate > 0) {\n return Math.max(\n RealtimeWhiteboardChannel.WHITEBOARD_MIN_CADENCE_MS,\n Math.floor(1000 / rate)\n );\n }\n return RealtimeWhiteboardChannel.WHITEBOARD_DEFAULT_CADENCE_MS;\n }\n\n /**\n * Pushes a frame to the video bridge, updating timestamp and deduplication cache.\n */\n private pushWhiteboardFrame(frame: string): void {\n this.lastPushTimestamp = Date.now();\n this.lastPushedWhiteboardFrame = frame;\n this.ensureVideoBridge()?.PushFrame(frame);\n }\n\n /**\n * Pushes the latest board visual scene when user mutations occur, with dynamic pacing,\n * deduplication, and a trailing-edge settle timer so the model sees the final resting state.\n */\n private async onUserMutation(): Promise<void> {\n try {\n const bridge = this.ensureVideoBridge();\n if (!bridge || !this.Context?.Client?.IsTrackEstablished('video', 'inbound')) {\n return;\n }\n\n const now = Date.now();\n const cadenceMs = this.getNegotiatedVideoCadenceMs();\n const elapsed = now - this.lastPushTimestamp;\n\n if (elapsed >= cadenceMs) {\n this.clearWhiteboardTrailingTimer();\n const frame = await this.GetLatestFrame();\n if (!frame) {\n return;\n }\n if (frame !== this.lastPushedWhiteboardFrame) {\n this.pushWhiteboardFrame(frame);\n }\n } else {\n // Within cooldown window: schedule trailing settle timer if not already armed.\n if (!this.whiteboardTrailingTimer) {\n const delay = Math.max(0, cadenceMs - elapsed);\n this.whiteboardTrailingTimer = setTimeout(async () => {\n this.whiteboardTrailingTimer = null;\n try {\n if (!this.Context?.Client?.IsTrackEstablished('video', 'inbound')) {\n return;\n }\n const frame = await this.GetLatestFrame();\n if (!frame) {\n return;\n }\n if (frame !== this.lastPushedWhiteboardFrame) {\n this.pushWhiteboardFrame(frame);\n }\n } catch (err) {\n console.error('[RealtimeWhiteboardChannel] Error in whiteboard trailing settle timer:', err);\n }\n }, delay);\n }\n }\n } catch (err) {\n console.error('[RealtimeWhiteboardChannel] Error in onUserMutation:', err);\n }\n }\n\n /**\n * Pushes exactly ONE confirmation frame after an agent tool mutates the board, and\n * informs the model context so it does not loop narrating its own change.\n */\n private async pushAgentConfirmationFrame(): Promise<void> {\n try {\n const bridge = this.ensureVideoBridge();\n if (!bridge || !this.Context?.Client?.IsTrackEstablished('video', 'inbound')) {\n return;\n }\n this.clearWhiteboardTrailingTimer();\n const frame = await this.GetLatestFrame();\n if (frame) {\n this.pushWhiteboardFrame(frame);\n this.Context?.SendContextNote(\n '[whiteboard] visual confirmation of your action (background — do NOT narrate or announce your own change; continue naturally)'\n );\n }\n } catch (err) {\n console.error('[RealtimeWhiteboardChannel] Error in pushAgentConfirmationFrame:', err);\n }\n }\n\n public get ToolNamePrefix(): string {\n return WHITEBOARD_TOOL_PREFIX;\n }\n\n public get TabTitle(): string {\n return 'Whiteboard';\n }\n\n public get TabIcon(): string {\n return 'fa-solid fa-chalkboard';\n }\n\n public GetToolDefinitions(): RealtimeToolDefinition[] {\n return WHITEBOARD_TOOL_DEFINITIONS;\n }\n\n public override GetSurfaceComponent(): Type<RealtimeWhiteboardHostComponent> {\n return RealtimeWhiteboardHostComponent;\n }\n\n /** First-run intro shown the first time the user opens the Whiteboard tab (once per user). */\n public override GetOnboardingDetails(): ChannelOnboardingDetails {\n return {\n Heading: 'Whiteboard',\n Description:\n 'A shared canvas the agent can sketch, write and annotate on live during the call — ' +\n 'whatever it draws appears here instantly, and anything you add is something it can see too.',\n Tips: [\n 'Watch the board fill in as you talk — the agent updates it in real time.',\n 'Add your own notes or shapes; the agent perceives your edits and can build on them.',\n 'Use Focus to give the board the whole screen, and save it to artifacts to keep it.'\n ],\n IconClass: 'fa-solid fa-chalkboard'\n };\n }\n\n /** Persist the board (host-debounced) on EVERY board mutation — user edits AND agent tools. */\n protected override OnInitialize(): void {\n this.stateChangedSub?.unsubscribe();\n this.clearWhiteboardTrailingTimer();\n this.stateChangedSub = this.State.Changed$.subscribe((change) => {\n this.Context?.RequestSave(this.State.ToJSON());\n // Only user edits (and scene replacements like undo) drive the user settle-debounce pipeline.\n // Agent edits are confirmed with a single frame in ApplyAgentTool.\n if (change.Author === 'user' || change.Op === 'replace') {\n void this.onUserMutation();\n }\n });\n this.ensureVideoBridge();\n }\n\n public override OnSessionStarted(): void {\n this.ensureVideoBridge();\n }\n\n private ensureVideoBridge(): ChannelInboundVideoBridge | null {\n if (!this.videoBridge && this.Context) {\n this.videoBridge = new ChannelInboundVideoBridge(() => this.Context?.Client, this);\n }\n if (this.videoBridge && !this.videoBridge.IsActive && this.Context?.Client?.IsTrackEstablished('video', 'inbound')) {\n this.videoBridge.Start?.();\n }\n return this.videoBridge;\n }\n\n /**\n * Wires the dynamically-created board host: inputs (shared state engine + agent name)\n * are set BEFORE the component's first change detection, and the perception/garnish\n * outputs are subscribed back into the host context — the overlay never sees any of it.\n */\n public BindSurface(instance: RealtimeWhiteboardHostComponent): void {\n this.ensureVideoBridge();\n this.releaseSurface();\n this.host = instance;\n instance.State = this.State;\n instance.AgentName = this.Context?.AgentName ?? 'Agent';\n this.surfaceSubs.push(\n // The board's coalesced scene delta — the perception feed the agent \"sees\".\n instance.SceneDelta.subscribe((deltaJson: string) => {\n // Background PERCEPTION, not conversation: the model sees every user edit without\n // being told, but must not narrate minor changes — only react when something is\n // significant (or when asked). The etiquette rides in the note itself so any\n // realtime model gets it regardless of system-prompt sync state.\n this.Context?.SendContextNote(\n '[whiteboard] board update (background context — do NOT comment on minor edits; ' +\n 'only mention it if the change is significant to the discussion): ' + deltaJson);\n }),\n // The user clicked Undo on the agent-action toast (the undo already applied locally).\n instance.AgentUndo.subscribe(() => {\n this.Context?.SendContextNote('[whiteboard] user undid your last change');\n }),\n // A sandboxed HTML widget submitted user input (MJWhiteboard.submit) — already\n // validated, size-capped and not canceled (the host's cancelable WidgetSubmitting\n // event ran first). Surface it to the agent so it can react to quiz answers /\n // micro-form input it asked for.\n instance.WidgetSubmitted.subscribe((submit: WhiteboardWidgetSubmitEvent) => {\n // Durable awareness first (the note persists in the model's context)…\n this.Context?.SendContextNote(\n `[whiteboard] the user submitted input in widget \"${submit.Title || submit.ItemID}\": ${submit.DataJson}`);\n // …then make the model REACT — a submission is explicit user input the user is\n // waiting on; without this trigger, SendContextNote alone produces dead silence\n // (\"I clicked Submit and nothing happened\").\n this.Context?.RequestSpokenResponse?.(\n `The user just submitted input in the whiteboard widget \"${submit.Title || submit.ItemID}\": ${submit.DataJson}. ` +\n `React to it now in your own voice — acknowledge their choice and continue naturally.`);\n }),\n // AMBIENT widget telemetry (the injected recorder, NOT widget-authored script):\n // clicks / changes / typing summarized by the board. Pure background perception —\n // throttled per widget so chatty widgets don't flood the model's context, and framed\n // with do-not-respond etiquette (explicit MJWhiteboard.submit input arrives above).\n instance.WidgetInteraction.subscribe((interaction: WhiteboardWidgetInteractionEvent) => {\n this.onWidgetInteraction(interaction);\n }),\n // The board's Focus toggle — ask the shell to collapse/restore the main call column.\n instance.FocusModeChange.subscribe((focused: boolean) => {\n this.Context?.SetFocusMode(focused);\n }),\n // \"Save to artifacts\": snapshot the board as a first-class versioned artifact.\n instance.SaveToArtifactsRequested.subscribe(() => {\n void this.saveBoardAsArtifact();\n })\n );\n }\n\n public override UnbindSurface(): void {\n this.releaseSurface();\n }\n\n /**\n * Routes one ambient widget-interaction batch to the agent as a throttled background\n * context note: outside an open window the note goes out immediately and opens a\n * {@link WHITEBOARD_INTERACTION_NOTE_THROTTLE_MS} window; within the window the LATEST\n * event is stashed and a trailing-edge timer sends it when the window closes (one note\n * per widget per window, latest summary wins).\n */\n private onWidgetInteraction(interaction: WhiteboardWidgetInteractionEvent): void {\n const now = Date.now();\n const entry = this.interactionThrottles.get(interaction.ItemID);\n if (!entry || (entry.Timer === null && now - entry.LastSentAt >= WHITEBOARD_INTERACTION_NOTE_THROTTLE_MS)) {\n this.sendInteractionNote(interaction);\n this.interactionThrottles.set(interaction.ItemID, { LastSentAt: now, Timer: null, Pending: null });\n return;\n }\n entry.Pending = interaction; // latest wins within the window\n if (entry.Timer === null) {\n const wait = Math.max(0, entry.LastSentAt + WHITEBOARD_INTERACTION_NOTE_THROTTLE_MS - now);\n entry.Timer = setTimeout(() => {\n entry.Timer = null;\n const pending = entry.Pending;\n entry.Pending = null;\n if (pending) {\n entry.LastSentAt = Date.now();\n this.sendInteractionNote(pending);\n }\n }, wait);\n }\n }\n\n /** The ambient-note framing: background etiquette rides in the note itself (like scene deltas). */\n private sendInteractionNote(interaction: WhiteboardWidgetInteractionEvent): void {\n this.Context?.SendContextNote(\n `[whiteboard] ambient activity in widget \"${interaction.Title || interaction.ItemID}\" ` +\n '(background — do NOT respond unless it is significant or you are asked; ' +\n `explicit submissions arrive separately): ${interaction.Summary}`);\n }\n\n /** Cancels all pending ambient-note timers and resets the per-widget throttle windows. */\n private clearInteractionThrottles(): void {\n for (const entry of this.interactionThrottles.values()) {\n if (entry.Timer !== null) {\n clearTimeout(entry.Timer);\n }\n }\n this.interactionThrottles.clear();\n }\n\n /**\n * Persists the current board as a `MJ: Artifacts` snapshot via the host context\n * (best-effort; the host logs failures). On success the agent is told via a context\n * note so it can reference the saved artifact naturally.\n */\n private async saveBoardAsArtifact(): Promise<void> {\n const ctx = this.Context;\n if (!ctx) {\n return;\n }\n const now = new Date();\n const name = `Whiteboard — ${now.toLocaleDateString()} ${now.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}`;\n const artifactId = await ctx.SaveAsArtifact(name, this.State.ToJSON());\n if (artifactId) {\n ctx.SendContextNote(`[whiteboard] the user saved the current board as the artifact \"${name}\"`);\n }\n }\n\n /**\n * Executes one `Whiteboard_*` tool call LOCALLY. Prefers the live bound host (board\n * mutation + UI garnish); falls back to the pure engine function when no surface is\n * bound so the channel keeps working with the pane collapsed.\n */\n public ApplyAgentTool(toolName: string, argsJson: string): string {\n let result: string;\n if (this.host) {\n result = this.host.ApplyAgentTool(toolName, argsJson);\n } else {\n result = ApplyWhiteboardAgentTool(this.State, toolName, argsJson);\n }\n // A SUCCESSFUL agent tool triggers exactly ONE immediate visual confirmation frame and a note\n // telling the model not to narrate its own change. A FAILED one must trigger neither: every\n // failure path returns `{ success: false, error }` (bad JSON args, unknown tool, per-tool\n // validation), and confirming it would tell the model its edit landed AND instruct it to stay\n // quiet about it — so the failure would vanish from the user's view while the model carried on.\n // It would also push a frame identical to the last one, since a failed tool changes nothing.\n if (toolSucceeded(result)) {\n void this.pushAgentConfirmationFrame();\n }\n return result;\n }\n\n /** The board's serialized state of record (persisted under {@link ChannelName}). */\n public override SerializeState(): string | null {\n return this.State.ToJSON();\n }\n\n /**\n * Rehydrates a prior session's saved board into THIS session's state engine (in place —\n * the {@link State} instance and its subscriptions are preserved). Returns `true` on\n * success; malformed / incompatible JSON returns `false` and the board stays fresh\n * (never throws — {@link WhiteboardState.LoadFromJSON} is tolerant by contract).\n */\n public override RestoreState(stateJson: string): boolean {\n return this.State.LoadFromJSON(stateJson);\n }\n\n /**\n * Exit focus mode THROUGH the bound host (its own Focus button state stays in sync; it\n * re-emits `FocusModeChange(false)` → `Context.SetFocusMode(false)`). When no surface is\n * bound the overlay's defensive flag clear covers it.\n */\n public override RequestFocusExit(): void {\n if (this.host?.FocusMode) {\n this.host.ToggleFocus();\n }\n }\n\n public override Dispose(): void {\n this.clearWhiteboardTrailingTimer();\n this.videoBridge?.Stop();\n this.videoBridge = null;\n this.stateChangedSub?.unsubscribe();\n this.stateChangedSub = null;\n this.lastPushedWhiteboardFrame = null;\n super.Dispose(); // releases the surface binding + context\n }\n\n /** Unsubscribes surface outputs, cancels pending ambient notes and drops the host reference. */\n private releaseSurface(): void {\n for (const sub of this.surfaceSubs) {\n sub.unsubscribe();\n }\n this.surfaceSubs = [];\n this.clearInteractionThrottles();\n this.host = null;\n }\n}\n\n/**\n * Tree-shaking prevention: the whiteboard channel is resolved dynamically through the\n * ClassFactory (by the registry row's `ClientPluginClass` key), so this static call is\n * what keeps its `@RegisterClass` side effect from being eliminated by the bundler.\n * Called by `RealtimeSessionService` alongside the realtime-client driver Load calls.\n */\nexport function LoadRealtimeWhiteboardChannel(): void {\n // intentional no-op — the import side effect performs the registration\n}\n\n/** @deprecated Use {@link RasterizeSvgToJpegBase64}. */\nexport async function rasterizeSvgToJpegBase64(svg: string, width = 1280, height = 720): Promise<string | null> {\n return RasterizeSvgToJpegBase64(svg, width, height);\n}\n"]}
1
+ {"version":3,"file":"whiteboard-channel.js","sourceRoot":"","sources":["../../../../../src/lib/components/realtime/whiteboard/whiteboard-channel.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Type } from '@angular/core';\nimport { Subscription } from 'rxjs';\nimport { RegisterClass } from '@memberjunction/global';\nimport { RealtimeToolDefinition } from '@memberjunction/ai';\nimport { REALTIME_CHANNEL_CONTRACT_VERSION, type RealtimeChannelDescriptor } from '@memberjunction/ai-core-plus';\nimport { ChannelInboundVideoBridge, IChannelFrameProvider, type MediaPlacement } from '@memberjunction/ai-realtime-client';\nimport { BaseRealtimeChannelClient, BuildToolBackedVerbs, ChannelOnboardingDetails } from '@memberjunction/realtime-runtime';\nimport {\n ApplyWhiteboardAgentTool, BuildWhiteboardExportSvg, RealtimeWhiteboardHostComponent, WHITEBOARD_TOOL_DEFINITIONS,\n WHITEBOARD_TOOL_PREFIX, WhiteboardState, WhiteboardWidgetInteractionEvent, WhiteboardWidgetSubmitEvent\n} from '@memberjunction/ng-whiteboard';\n\n/**\n * Whether a whiteboard tool result reports success.\n *\n * `ApplyWhiteboardAgentTool` returns a JSON `WhiteboardToolResult` string — `{ success: true, … }`\n * or `{ success: false, error }` — for every tool and every failure path. Anything that does not\n * parse as an object with `success === true` is treated as NOT a successful mutation, which is the\n * safe direction: the cost of missing a confirmation frame is one stale picture until the next\n * change, while the cost of a false one is telling the model an edit landed when it did not.\n */\nfunction toolSucceeded(result: string): boolean {\n try {\n const parsed: unknown = JSON.parse(result);\n return parsed !== null && typeof parsed === 'object' && (parsed as { success?: unknown }).success === true;\n } catch {\n // A non-JSON result cannot be confirmed as a mutation — the host returned something this\n // channel does not understand, so it does not get a \"your change is on screen\" note.\n return false;\n }\n}\n\n/**\n * Asynchronously rasterizes an SVG string to a JPEG base64 string (without the `data:image/jpeg;base64,` prefix)\n * using an offscreen canvas. Returns null in non-DOM environments or when rendering fails.\n */\nexport async function RasterizeSvgToJpegBase64(svg: string, width = 1280, height = 720): Promise<string | null> {\n if (typeof document === 'undefined' || typeof Image === 'undefined') {\n return null;\n }\n return new Promise<string | null>((resolve) => {\n let url: string | null = null;\n let timer: ReturnType<typeof setTimeout> | null = null;\n\n const cleanup = () => {\n if (timer != null) {\n clearTimeout(timer);\n timer = null;\n }\n if (url) {\n URL.revokeObjectURL(url);\n url = null;\n }\n };\n\n try {\n const img = new Image();\n const svgBlob = new Blob([svg], { type: 'image/svg+xml;charset=utf-8' });\n url = URL.createObjectURL(svgBlob);\n\n // Capped wait: resolve null and revoke URL if the Image never fires onload or onerror (item 61)\n timer = setTimeout(() => {\n console.error('[RealtimeWhiteboardChannel] SVG rasterization timed out after 5000ms');\n cleanup();\n resolve(null);\n }, 5000);\n\n img.onload = () => {\n try {\n const canvas = document.createElement('canvas');\n canvas.width = width;\n canvas.height = height;\n const ctx = canvas.getContext('2d');\n if (!ctx) {\n cleanup();\n resolve(null);\n return;\n }\n ctx.fillStyle = '#ffffff';\n ctx.fillRect(0, 0, width, height);\n ctx.drawImage(img, 0, 0, width, height);\n cleanup();\n const dataUrl = canvas.toDataURL('image/jpeg', 0.85);\n const comma = dataUrl.indexOf(',');\n resolve(comma >= 0 ? dataUrl.slice(comma + 1) : dataUrl);\n } catch (err) {\n console.error('[RealtimeWhiteboardChannel] Failed to rasterize SVG canvas to JPEG:', err);\n cleanup();\n resolve(null);\n }\n };\n img.onerror = (err) => {\n console.error('[RealtimeWhiteboardChannel] Failed to load SVG image for rasterization:', err);\n cleanup();\n resolve(null);\n };\n img.src = url;\n } catch (err) {\n console.error('[RealtimeWhiteboardChannel] Failed to initialize SVG rasterization:', err);\n cleanup();\n resolve(null);\n }\n });\n}\n\n/**\n * Per-widget throttle window for AMBIENT interaction context notes: at most one note per\n * widget per this many ms — within the window the LATEST summary wins (chatty widgets\n * collapse to one trailing-edge note instead of flooding the model's context).\n */\nexport const WHITEBOARD_INTERACTION_NOTE_THROTTLE_MS = 4000;\n\n/** Per-widget ambient-note throttle bookkeeping. */\ninterface InteractionThrottleEntry {\n /** When this widget's last ambient note was sent (epoch ms). */\n LastSentAt: number;\n /** Trailing-edge timer for a deferred note, or null when the window is idle. */\n Timer: ReturnType<typeof setTimeout> | null;\n /** The latest event received within the open window (sent when the timer fires). */\n Pending: WhiteboardWidgetInteractionEvent | null;\n}\n\n/**\n * The LIVE WHITEBOARD as a pluggable interactive channel — the canonical\n * {@link BaseRealtimeChannelClient} implementation, resolved from the `MJ: AI Agent\n * Channels` registry row whose `ClientPluginClass` is `'RealtimeWhiteboardChannel'`.\n *\n * One instance per session (created via ClassFactory at session start). It owns the\n * board's {@link WhiteboardState} engine and contributes the channel's full contract:\n *\n * - **Action**: the `Whiteboard_*` client-executed tool set\n * ({@link WHITEBOARD_TOOL_DEFINITIONS}); {@link ApplyAgentTool} prefers the BOUND host\n * component (board mutation + violet pop-in / toast / presence-cursor garnish) and\n * falls back to the pure {@link ApplyWhiteboardAgentTool} engine call when no surface\n * is bound (e.g. the board has not been shown yet) — the channel keeps working, just\n * without the garnish.\n * - **Perception**: {@link BindSurface} subscribes the host's coalesced (750 ms)\n * `SceneDelta` stream and pipes each delta into the live model's context as a\n * `[whiteboard]` background note; the agent-undo toast click flows the same way.\n * - **Surface**: {@link RealtimeWhiteboardHostComponent}, created on the overlay's stage; the\n * host's \"Move to stage\" button rides `Context.SetFocusMode`, and the board hears where the\n * overlay placed it ({@link OnSurfacePlacementChange}) so the button offers the way back.\n * - **State of record**: every board mutation (user edits AND agent tool calls) requests\n * a save of {@link WhiteboardState.ToJSON} under channel name `'Whiteboard'` — the\n * host debounces and flushes at teardown.\n *\n * A PRIOR session's persisted board is restored through {@link RestoreState} (invoked by\n * the session host after Initialize, before any surface binding): the saved JSON is\n * rehydrated IN PLACE into the same {@link WhiteboardState} instance, so the save\n * subscription and any later surface binding keep pointing at one engine. Malformed or\n * incompatible payloads are tolerated — the board simply starts fresh.\n */\n@RegisterClass(BaseRealtimeChannelClient, 'RealtimeWhiteboardChannel')\nexport class RealtimeWhiteboardChannel extends BaseRealtimeChannelClient<RealtimeWhiteboardHostComponent> implements IChannelFrameProvider {\n /** The board's state of record — created fresh with the plugin (one per session). */\n public readonly State = new WhiteboardState();\n\n /** The live bound surface, when the channel tab's pane is instantiated. */\n private host: RealtimeWhiteboardHostComponent | null = null;\n /** Output subscriptions on the bound surface (SceneDelta / AgentUndo / FocusModeChange). */\n private surfaceSubs: Subscription[] = [];\n /** Board-mutation subscription driving the debounced state-of-record save. */\n private stateChangedSub: Subscription | null = null;\n /** Per-widget ambient-interaction note throttles (ItemID → window state). */\n private interactionThrottles = new Map<string, InteractionThrottleEntry>();\n public get ChannelName(): string {\n return 'Whiteboard';\n }\n\n /**\n * Produces the latest visual scene as a base64-encoded frame for the video bridge.\n * Renders the whiteboard SVG into an offscreen canvas and returns base64 JPEG.\n */\n public async GetLatestFrame(): Promise<string | null> {\n if (!this.State) {\n return null;\n }\n try {\n const svg = BuildWhiteboardExportSvg(this.State);\n return await RasterizeSvgToJpegBase64(svg);\n } catch (err) {\n console.error('[RealtimeWhiteboardChannel] Failed to export whiteboard frame:', err);\n return null;\n }\n }\n\n /**\n * The shared frame bridge, which now lives on the base channel (`VisualVideoBridge`). This accessor\n * keeps the board's long-standing `videoBridge` handle — tests and tooling reach the bridge by that\n * name — pointing at the one the pump actually writes to.\n */\n private get videoBridge(): ChannelInboundVideoBridge | null {\n return this.VisualVideoBridge;\n }\n private set videoBridge(bridge: ChannelInboundVideoBridge | null) {\n this.VisualVideoBridge = bridge;\n }\n\n // The change-driven frame pump (leading edge, trailing settle, dedupe, negotiated cadence, one\n // confirmation frame after an agent edit) used to live here. It is now the base channel's\n // `EnableVisualPerception` pump, enabled from OnInitialize — this channel only says WHEN its picture\n // changed. The behavior is unchanged, including (deliberately) the shared bridge's fixed-rate poller:\n // see `StartBridgePoller` in OnInitialize.\n\n public get ToolNamePrefix(): string {\n return WHITEBOARD_TOOL_PREFIX;\n }\n\n public get TabTitle(): string {\n return 'Whiteboard';\n }\n\n public get TabIcon(): string {\n return 'fa-solid fa-chalkboard';\n }\n\n /** The board can be shared on its own: the call's Share menu offers it under \"This panel\" while it is on screen. */\n public override get SurfaceShareable(): boolean {\n return true;\n }\n\n public GetToolDefinitions(): RealtimeToolDefinition[] {\n return WHITEBOARD_TOOL_DEFINITIONS;\n }\n\n public override GetSurfaceComponent(): Type<RealtimeWhiteboardHostComponent> {\n return RealtimeWhiteboardHostComponent;\n }\n\n /** First-run intro shown the first time the user opens the Whiteboard tab (once per user). */\n public override GetOnboardingDetails(): ChannelOnboardingDetails {\n return {\n Heading: 'Whiteboard',\n Description:\n 'A shared canvas the agent can sketch, write and annotate on live during the call — ' +\n 'whatever it draws appears here instantly, and anything you add is something it can see too.',\n Tips: [\n 'Watch the board fill in as you talk — the agent updates it in real time.',\n 'Add your own notes or shapes; the agent perceives your edits and can build on them.',\n 'Use Focus to give the board the whole screen, and save it to artifacts to keep it.'\n ],\n IconClass: 'fa-solid fa-chalkboard'\n };\n }\n\n /**\n * The board's self-description: what it holds, every `Whiteboard_*` tool as a verb (so a tool a\n * subclass adds shows up here too), and that the model can SEE it (frames), not just read its state.\n */\n public override GetDescriptor(): RealtimeChannelDescriptor {\n return {\n Key: this.ChannelName,\n Version: REALTIME_CHANNEL_CONTRACT_VERSION,\n DisplayName: this.TabTitle,\n OwningPackage: '@memberjunction/ng-conversations',\n Instructions:\n 'A shared canvas you and the user can both draw, write and annotate on live. Whatever you add ' +\n 'appears instantly, and you perceive what the user adds. Use it to sketch, diagram and explain ' +\n 'visually; do not narrate minor edits.',\n Nouns: [\n {\n Name: 'pages',\n Description: 'The board\\'s pages, in order; each holds the items (notes, shapes, connectors, text, widgets) drawn on it.',\n Schema: { type: 'array', items: { type: 'object' } }\n }\n ],\n Verbs: BuildToolBackedVerbs(this.GetToolDefinitions(), this.ToolNamePrefix),\n Events: [\n { Name: 'state_changed', Description: 'The board changed (by you or the user).' },\n { Name: 'frame_pushed', Description: 'A picture of the board was sent to you.' }\n ],\n DisplayPolicy: 'open-on-start',\n DefaultAvailability: 'all-sessions',\n MaxExposure: 'pixels'\n };\n }\n\n /**\n * Persist the board (host-debounced) on EVERY board mutation — user edits AND agent tools — and drive\n * the visual pump. The board feeds the model its own perception (coalesced scene deltas from the\n * bound surface), so state changes are recorded for events and frame tagging only (`Perceive: false`):\n * the structured note would duplicate the deltas.\n */\n protected override OnInitialize(): void {\n this.stateChangedSub?.unsubscribe();\n this.EnableVisualPerception(this, {\n ConfirmationNote:\n '[whiteboard] visual confirmation of your action (background — do NOT narrate or announce your own change; continue naturally)',\n // Preserves what the board always did: it started the bridge's fixed-rate poller despite being\n // designed heartbeat-free. Flagged for the reviewer; remove to make the board purely change-driven.\n StartBridgePoller: true\n });\n this.stateChangedSub = this.State.Changed$.subscribe((change) => {\n this.Context?.RequestSave(this.State.ToJSON());\n this.RecordChange({ Author: change.Author, Perceive: false });\n // Only user edits (and scene replacements like undo) drive the settle-debounce pipeline.\n // Agent edits are confirmed with a single frame in ApplyAgentTool.\n if (change.Author === 'user' || change.Op === 'replace') {\n void this.NotifyVisualChange();\n }\n });\n }\n\n /**\n * Wires the dynamically-created board host: inputs (shared state engine + agent name)\n * are set BEFORE the component's first change detection, and the perception/garnish\n * outputs are subscribed back into the host context — the overlay never sees any of it.\n */\n public BindSurface(instance: RealtimeWhiteboardHostComponent): void {\n this.EnsureVideoBridge();\n this.releaseSurface();\n this.host = instance;\n instance.State = this.State;\n instance.AgentName = this.Context?.AgentName ?? 'Agent';\n this.surfaceSubs.push(\n // The board's coalesced scene delta — the perception feed the agent \"sees\".\n instance.SceneDelta.subscribe((deltaJson: string) => {\n // Background PERCEPTION, not conversation: the model sees every user edit without\n // being told, but must not narrate minor changes — only react when something is\n // significant (or when asked). The etiquette rides in the note itself so any\n // realtime model gets it regardless of system-prompt sync state.\n this.Context?.SendContextNote(\n '[whiteboard] board update (background context — do NOT comment on minor edits; ' +\n 'only mention it if the change is significant to the discussion): ' + deltaJson);\n }),\n // The user clicked Undo on the agent-action toast (the undo already applied locally).\n instance.AgentUndo.subscribe(() => {\n this.Context?.SendContextNote('[whiteboard] user undid your last change');\n }),\n // A sandboxed HTML widget submitted user input (MJWhiteboard.submit) — already\n // validated, size-capped and not canceled (the host's cancelable WidgetSubmitting\n // event ran first). Surface it to the agent so it can react to quiz answers /\n // micro-form input it asked for.\n instance.WidgetSubmitted.subscribe((submit: WhiteboardWidgetSubmitEvent) => {\n // Durable awareness first (the note persists in the model's context)…\n this.Context?.SendContextNote(\n `[whiteboard] the user submitted input in widget \"${submit.Title || submit.ItemID}\": ${submit.DataJson}`);\n // …then make the model REACT — a submission is explicit user input the user is\n // waiting on; without this trigger, SendContextNote alone produces dead silence\n // (\"I clicked Submit and nothing happened\").\n this.Context?.RequestSpokenResponse?.(\n `The user just submitted input in the whiteboard widget \"${submit.Title || submit.ItemID}\": ${submit.DataJson}. ` +\n `React to it now in your own voice — acknowledge their choice and continue naturally.`);\n }),\n // AMBIENT widget telemetry (the injected recorder, NOT widget-authored script):\n // clicks / changes / typing summarized by the board. Pure background perception —\n // throttled per widget so chatty widgets don't flood the model's context, and framed\n // with do-not-respond etiquette (explicit MJWhiteboard.submit input arrives above).\n instance.WidgetInteraction.subscribe((interaction: WhiteboardWidgetInteractionEvent) => {\n this.onWidgetInteraction(interaction);\n }),\n // The board's Focus toggle — ask the shell to collapse/restore the main call column.\n instance.FocusModeChange.subscribe((focused: boolean) => {\n this.Context?.SetFocusMode(focused);\n }),\n // \"Save to artifacts\": snapshot the board as a first-class versioned artifact.\n instance.SaveToArtifactsRequested.subscribe(() => {\n void this.saveBoardAsArtifact();\n })\n );\n }\n\n public override UnbindSurface(): void {\n this.releaseSurface();\n }\n\n /**\n * Routes one ambient widget-interaction batch to the agent as a throttled background\n * context note: outside an open window the note goes out immediately and opens a\n * {@link WHITEBOARD_INTERACTION_NOTE_THROTTLE_MS} window; within the window the LATEST\n * event is stashed and a trailing-edge timer sends it when the window closes (one note\n * per widget per window, latest summary wins).\n */\n private onWidgetInteraction(interaction: WhiteboardWidgetInteractionEvent): void {\n const now = Date.now();\n const entry = this.interactionThrottles.get(interaction.ItemID);\n if (!entry || (entry.Timer === null && now - entry.LastSentAt >= WHITEBOARD_INTERACTION_NOTE_THROTTLE_MS)) {\n this.sendInteractionNote(interaction);\n this.interactionThrottles.set(interaction.ItemID, { LastSentAt: now, Timer: null, Pending: null });\n return;\n }\n entry.Pending = interaction; // latest wins within the window\n if (entry.Timer === null) {\n const wait = Math.max(0, entry.LastSentAt + WHITEBOARD_INTERACTION_NOTE_THROTTLE_MS - now);\n entry.Timer = setTimeout(() => {\n entry.Timer = null;\n const pending = entry.Pending;\n entry.Pending = null;\n if (pending) {\n entry.LastSentAt = Date.now();\n this.sendInteractionNote(pending);\n }\n }, wait);\n }\n }\n\n /** The ambient-note framing: background etiquette rides in the note itself (like scene deltas). */\n private sendInteractionNote(interaction: WhiteboardWidgetInteractionEvent): void {\n this.Context?.SendContextNote(\n `[whiteboard] ambient activity in widget \"${interaction.Title || interaction.ItemID}\" ` +\n '(background — do NOT respond unless it is significant or you are asked; ' +\n `explicit submissions arrive separately): ${interaction.Summary}`);\n }\n\n /** Cancels all pending ambient-note timers and resets the per-widget throttle windows. */\n private clearInteractionThrottles(): void {\n for (const entry of this.interactionThrottles.values()) {\n if (entry.Timer !== null) {\n clearTimeout(entry.Timer);\n }\n }\n this.interactionThrottles.clear();\n }\n\n /**\n * Persists the current board as a `MJ: Artifacts` snapshot via the host context\n * (best-effort; the host logs failures). On success the agent is told via a context\n * note so it can reference the saved artifact naturally.\n */\n private async saveBoardAsArtifact(): Promise<void> {\n const ctx = this.Context;\n if (!ctx) {\n return;\n }\n const now = new Date();\n const name = `Whiteboard — ${now.toLocaleDateString()} ${now.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}`;\n const artifactId = await ctx.SaveAsArtifact(name, this.State.ToJSON());\n if (artifactId) {\n ctx.SendContextNote(`[whiteboard] the user saved the current board as the artifact \"${name}\"`);\n }\n }\n\n /**\n * Executes one `Whiteboard_*` tool call LOCALLY. Prefers the live bound host (board\n * mutation + UI garnish); falls back to the pure engine function when no surface is\n * bound so the channel keeps working before the board is first shown.\n */\n public ApplyAgentTool(toolName: string, argsJson: string): string {\n let result: string;\n if (this.host) {\n result = this.host.ApplyAgentTool(toolName, argsJson);\n } else {\n result = ApplyWhiteboardAgentTool(this.State, toolName, argsJson);\n }\n // A SUCCESSFUL agent tool triggers exactly ONE immediate visual confirmation frame and a note\n // telling the model not to narrate its own change. A FAILED one must trigger neither: every\n // failure path returns `{ success: false, error }` (bad JSON args, unknown tool, per-tool\n // validation), and confirming it would tell the model its edit landed AND instruct it to stay\n // quiet about it — so the failure would vanish from the user's view while the model carried on.\n // It would also push a frame identical to the last one, since a failed tool changes nothing.\n if (toolSucceeded(result)) {\n void this.ConfirmVisualChange();\n }\n return result;\n }\n\n /** The board's serialized state of record (persisted under {@link ChannelName}). */\n public override SerializeState(): string | null {\n return this.State.ToJSON();\n }\n\n /**\n * Rehydrates a prior session's saved board into THIS session's state engine (in place —\n * the {@link State} instance and its subscriptions are preserved). Returns `true` on\n * success; malformed / incompatible JSON returns `false` and the board stays fresh\n * (never throws — {@link WhiteboardState.LoadFromJSON} is tolerant by contract).\n */\n public override RestoreState(stateJson: string): boolean {\n return this.State.LoadFromJSON(stateJson);\n }\n\n /** Keeps the board's \"Move to stage\" / \"Back to tab\" button true to where the host placed it. */\n public override OnSurfacePlacementChange(placement: MediaPlacement): void {\n this.host?.SetOnStage(placement === 'stage');\n }\n\n /**\n * Exit focus mode THROUGH the bound host (its own Focus button state stays in sync; it\n * re-emits `FocusModeChange(false)` → `Context.SetFocusMode(false)`). When no surface is\n * bound the overlay's defensive flag clear covers it.\n */\n public override RequestFocusExit(): void {\n if (this.host?.FocusMode) {\n this.host.ToggleFocus();\n }\n }\n\n public override Dispose(): void {\n this.stateChangedSub?.unsubscribe();\n this.stateChangedSub = null;\n super.Dispose(); // releases the surface binding, the visual pump + bridge, and the context\n }\n\n /** Unsubscribes surface outputs, cancels pending ambient notes and drops the host reference. */\n private releaseSurface(): void {\n for (const sub of this.surfaceSubs) {\n sub.unsubscribe();\n }\n this.surfaceSubs = [];\n this.clearInteractionThrottles();\n this.host = null;\n }\n}\n\n/**\n * Tree-shaking prevention: the whiteboard channel is resolved dynamically through the\n * ClassFactory (by the registry row's `ClientPluginClass` key), so this static call is\n * what keeps its `@RegisterClass` side effect from being eliminated by the bundler.\n * Called by `RealtimeSessionService` alongside the realtime-client driver Load calls.\n */\nexport function LoadRealtimeWhiteboardChannel(): void {\n // intentional no-op — the import side effect performs the registration\n}\n\n/** @deprecated Use {@link RasterizeSvgToJpegBase64}. */\nexport async function rasterizeSvgToJpegBase64(svg: string, width = 1280, height = 720): Promise<string | null> {\n return RasterizeSvgToJpegBase64(svg, width, height);\n}\n"]}
@@ -143,6 +143,8 @@ export declare class SearchPanelComponent implements OnInit, OnDestroy {
143
143
  ClearSearch(): void;
144
144
  /** @deprecated Use {@link ClearSearch}. */
145
145
  clearSearch(): void;
146
+ /** True when a message hit sits in a fork rather than in Main. */
147
+ IsInFork(result: SearchResult): boolean;
146
148
  /**
147
149
  * Select a result
148
150
  */
@@ -1 +1 @@
1
- {"version":3,"file":"search-panel.component.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/search/search-panel.component.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"search-panel.component.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/search/search-panel.component.ts"],"names":[],"mappings":"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"}