@memberjunction/ng-conversations 5.40.2 → 5.41.0

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 (378) hide show
  1. package/README.md +57 -0
  2. package/dist/__tests__/channel-optional-surface.test.d.ts +2 -0
  3. package/dist/__tests__/channel-optional-surface.test.d.ts.map +1 -0
  4. package/dist/__tests__/channel-optional-surface.test.js +53 -0
  5. package/dist/__tests__/channel-optional-surface.test.js.map +1 -0
  6. package/dist/__tests__/chat-events.test.d.ts +14 -0
  7. package/dist/__tests__/chat-events.test.d.ts.map +1 -0
  8. package/dist/__tests__/chat-events.test.js +109 -0
  9. package/dist/__tests__/chat-events.test.js.map +1 -0
  10. package/dist/__tests__/conversation-naming.test.d.ts +2 -0
  11. package/dist/__tests__/conversation-naming.test.d.ts.map +1 -0
  12. package/dist/__tests__/conversation-naming.test.js +110 -0
  13. package/dist/__tests__/conversation-naming.test.js.map +1 -0
  14. package/dist/__tests__/delegation-result-parser.test.d.ts +2 -0
  15. package/dist/__tests__/delegation-result-parser.test.d.ts.map +1 -0
  16. package/dist/__tests__/delegation-result-parser.test.js +107 -0
  17. package/dist/__tests__/delegation-result-parser.test.js.map +1 -0
  18. package/dist/__tests__/event-wiring.test.d.ts +15 -0
  19. package/dist/__tests__/event-wiring.test.d.ts.map +1 -0
  20. package/dist/__tests__/event-wiring.test.js +100 -0
  21. package/dist/__tests__/event-wiring.test.js.map +1 -0
  22. package/dist/__tests__/narration-template.test.d.ts +2 -0
  23. package/dist/__tests__/narration-template.test.d.ts.map +1 -0
  24. package/dist/__tests__/narration-template.test.js +76 -0
  25. package/dist/__tests__/narration-template.test.js.map +1 -0
  26. package/dist/__tests__/realtime-agent-picker-models.test.d.ts +2 -0
  27. package/dist/__tests__/realtime-agent-picker-models.test.d.ts.map +1 -0
  28. package/dist/__tests__/realtime-agent-picker-models.test.js +49 -0
  29. package/dist/__tests__/realtime-agent-picker-models.test.js.map +1 -0
  30. package/dist/__tests__/realtime-audio-visuals.test.d.ts +2 -0
  31. package/dist/__tests__/realtime-audio-visuals.test.d.ts.map +1 -0
  32. package/dist/__tests__/realtime-audio-visuals.test.js +123 -0
  33. package/dist/__tests__/realtime-audio-visuals.test.js.map +1 -0
  34. package/dist/__tests__/realtime-delegation-card-cancel.test.d.ts +2 -0
  35. package/dist/__tests__/realtime-delegation-card-cancel.test.d.ts.map +1 -0
  36. package/dist/__tests__/realtime-delegation-card-cancel.test.js +48 -0
  37. package/dist/__tests__/realtime-delegation-card-cancel.test.js.map +1 -0
  38. package/dist/__tests__/realtime-disclosure.test.d.ts +2 -0
  39. package/dist/__tests__/realtime-disclosure.test.d.ts.map +1 -0
  40. package/dist/__tests__/realtime-disclosure.test.js +164 -0
  41. package/dist/__tests__/realtime-disclosure.test.js.map +1 -0
  42. package/dist/__tests__/realtime-pairing.test.d.ts +2 -0
  43. package/dist/__tests__/realtime-pairing.test.d.ts.map +1 -0
  44. package/dist/__tests__/realtime-pairing.test.js +207 -0
  45. package/dist/__tests__/realtime-pairing.test.js.map +1 -0
  46. package/dist/__tests__/realtime-review-lifecycle.test.d.ts +2 -0
  47. package/dist/__tests__/realtime-review-lifecycle.test.d.ts.map +1 -0
  48. package/dist/__tests__/realtime-review-lifecycle.test.js +154 -0
  49. package/dist/__tests__/realtime-review-lifecycle.test.js.map +1 -0
  50. package/dist/__tests__/realtime-session-cancel-usage.test.d.ts +2 -0
  51. package/dist/__tests__/realtime-session-cancel-usage.test.d.ts.map +1 -0
  52. package/dist/__tests__/realtime-session-cancel-usage.test.js +230 -0
  53. package/dist/__tests__/realtime-session-cancel-usage.test.js.map +1 -0
  54. package/dist/__tests__/realtime-session-channels.test.d.ts +2 -0
  55. package/dist/__tests__/realtime-session-channels.test.d.ts.map +1 -0
  56. package/dist/__tests__/realtime-session-channels.test.js +252 -0
  57. package/dist/__tests__/realtime-session-channels.test.js.map +1 -0
  58. package/dist/__tests__/realtime-session-client-tools.test.d.ts +2 -0
  59. package/dist/__tests__/realtime-session-client-tools.test.d.ts.map +1 -0
  60. package/dist/__tests__/realtime-session-client-tools.test.js +103 -0
  61. package/dist/__tests__/realtime-session-client-tools.test.js.map +1 -0
  62. package/dist/__tests__/realtime-session-minimized.test.d.ts +2 -0
  63. package/dist/__tests__/realtime-session-minimized.test.d.ts.map +1 -0
  64. package/dist/__tests__/realtime-session-minimized.test.js +32 -0
  65. package/dist/__tests__/realtime-session-minimized.test.js.map +1 -0
  66. package/dist/__tests__/realtime-session-mint.test.d.ts +2 -0
  67. package/dist/__tests__/realtime-session-mint.test.d.ts.map +1 -0
  68. package/dist/__tests__/realtime-session-mint.test.js +69 -0
  69. package/dist/__tests__/realtime-session-mint.test.js.map +1 -0
  70. package/dist/__tests__/realtime-session-policy.test.d.ts +2 -0
  71. package/dist/__tests__/realtime-session-policy.test.d.ts.map +1 -0
  72. package/dist/__tests__/realtime-session-policy.test.js +303 -0
  73. package/dist/__tests__/realtime-session-policy.test.js.map +1 -0
  74. package/dist/__tests__/realtime-session-review.service.test.d.ts +2 -0
  75. package/dist/__tests__/realtime-session-review.service.test.d.ts.map +1 -0
  76. package/dist/__tests__/realtime-session-review.service.test.js +743 -0
  77. package/dist/__tests__/realtime-session-review.service.test.js.map +1 -0
  78. package/dist/__tests__/realtime-session-state.test.d.ts +2 -0
  79. package/dist/__tests__/realtime-session-state.test.d.ts.map +1 -0
  80. package/dist/__tests__/realtime-session-state.test.js +83 -0
  81. package/dist/__tests__/realtime-session-state.test.js.map +1 -0
  82. package/dist/__tests__/realtime-session-timeline-card.test.d.ts +2 -0
  83. package/dist/__tests__/realtime-session-timeline-card.test.d.ts.map +1 -0
  84. package/dist/__tests__/realtime-session-timeline-card.test.js +106 -0
  85. package/dist/__tests__/realtime-session-timeline-card.test.js.map +1 -0
  86. package/dist/__tests__/realtime-session-timeline.test.d.ts +2 -0
  87. package/dist/__tests__/realtime-session-timeline.test.d.ts.map +1 -0
  88. package/dist/__tests__/realtime-session-timeline.test.js +142 -0
  89. package/dist/__tests__/realtime-session-timeline.test.js.map +1 -0
  90. package/dist/__tests__/realtime-sessions-adapter.test.d.ts +19 -0
  91. package/dist/__tests__/realtime-sessions-adapter.test.d.ts.map +1 -0
  92. package/dist/__tests__/realtime-sessions-adapter.test.js +188 -0
  93. package/dist/__tests__/realtime-sessions-adapter.test.js.map +1 -0
  94. package/dist/__tests__/realtime-surface-panel-prefs.test.d.ts +2 -0
  95. package/dist/__tests__/realtime-surface-panel-prefs.test.d.ts.map +1 -0
  96. package/dist/__tests__/realtime-surface-panel-prefs.test.js +100 -0
  97. package/dist/__tests__/realtime-surface-panel-prefs.test.js.map +1 -0
  98. package/dist/__tests__/realtime-surface-tabs-model.test.d.ts +2 -0
  99. package/dist/__tests__/realtime-surface-tabs-model.test.d.ts.map +1 -0
  100. package/dist/__tests__/realtime-surface-tabs-model.test.js +193 -0
  101. package/dist/__tests__/realtime-surface-tabs-model.test.js.map +1 -0
  102. package/dist/__tests__/remote-browser-audio-player.test.d.ts +2 -0
  103. package/dist/__tests__/remote-browser-audio-player.test.d.ts.map +1 -0
  104. package/dist/__tests__/remote-browser-audio-player.test.js +137 -0
  105. package/dist/__tests__/remote-browser-audio-player.test.js.map +1 -0
  106. package/dist/__tests__/remote-browser-channel.test.d.ts +2 -0
  107. package/dist/__tests__/remote-browser-channel.test.d.ts.map +1 -0
  108. package/dist/__tests__/remote-browser-channel.test.js +423 -0
  109. package/dist/__tests__/remote-browser-channel.test.js.map +1 -0
  110. package/dist/__tests__/slot-defaults.test.d.ts +24 -0
  111. package/dist/__tests__/slot-defaults.test.d.ts.map +1 -0
  112. package/dist/__tests__/slot-defaults.test.js +63 -0
  113. package/dist/__tests__/slot-defaults.test.js.map +1 -0
  114. package/dist/__tests__/user-authorization.test.d.ts +2 -0
  115. package/dist/__tests__/user-authorization.test.d.ts.map +1 -0
  116. package/dist/__tests__/user-authorization.test.js +97 -0
  117. package/dist/__tests__/user-authorization.test.js.map +1 -0
  118. package/dist/__tests__/voice-session-narration.test.d.ts +2 -0
  119. package/dist/__tests__/voice-session-narration.test.d.ts.map +1 -0
  120. package/dist/__tests__/voice-session-narration.test.js +609 -0
  121. package/dist/__tests__/voice-session-narration.test.js.map +1 -0
  122. package/dist/__tests__/whiteboard-artifact-viewer.test.d.ts +2 -0
  123. package/dist/__tests__/whiteboard-artifact-viewer.test.d.ts.map +1 -0
  124. package/dist/__tests__/whiteboard-artifact-viewer.test.js +101 -0
  125. package/dist/__tests__/whiteboard-artifact-viewer.test.js.map +1 -0
  126. package/dist/__tests__/whiteboard-channel.test.d.ts +2 -0
  127. package/dist/__tests__/whiteboard-channel.test.d.ts.map +1 -0
  128. package/dist/__tests__/whiteboard-channel.test.js +260 -0
  129. package/dist/__tests__/whiteboard-channel.test.js.map +1 -0
  130. package/dist/__tests__/whiteboard-restore-state.test.d.ts +2 -0
  131. package/dist/__tests__/whiteboard-restore-state.test.d.ts.map +1 -0
  132. package/dist/__tests__/whiteboard-restore-state.test.js +108 -0
  133. package/dist/__tests__/whiteboard-restore-state.test.js.map +1 -0
  134. package/dist/lib/components/conversation/conversation-chat-area.component.d.ts +205 -3
  135. package/dist/lib/components/conversation/conversation-chat-area.component.d.ts.map +1 -1
  136. package/dist/lib/components/conversation/conversation-chat-area.component.js +911 -342
  137. package/dist/lib/components/conversation/conversation-chat-area.component.js.map +1 -1
  138. package/dist/lib/components/mention/mention-dropdown.component.js +35 -17
  139. package/dist/lib/components/mention/mention-dropdown.component.js.map +1 -1
  140. package/dist/lib/components/mention/mention-editor.component.d.ts +4 -0
  141. package/dist/lib/components/mention/mention-editor.component.d.ts.map +1 -1
  142. package/dist/lib/components/mention/mention-editor.component.js +43 -19
  143. package/dist/lib/components/mention/mention-editor.component.js.map +1 -1
  144. package/dist/lib/components/message/message-input-box.component.d.ts +17 -1
  145. package/dist/lib/components/message/message-input-box.component.d.ts.map +1 -1
  146. package/dist/lib/components/message/message-input-box.component.js +73 -15
  147. package/dist/lib/components/message/message-input-box.component.js.map +1 -1
  148. package/dist/lib/components/message/message-input.component.d.ts +142 -6
  149. package/dist/lib/components/message/message-input.component.d.ts.map +1 -1
  150. package/dist/lib/components/message/message-input.component.js +328 -82
  151. package/dist/lib/components/message/message-input.component.js.map +1 -1
  152. package/dist/lib/components/message/message-item.component.d.ts +28 -3
  153. package/dist/lib/components/message/message-item.component.d.ts.map +1 -1
  154. package/dist/lib/components/message/message-item.component.js +180 -108
  155. package/dist/lib/components/message/message-item.component.js.map +1 -1
  156. package/dist/lib/components/message/message-list.component.d.ts +81 -2
  157. package/dist/lib/components/message/message-list.component.d.ts.map +1 -1
  158. package/dist/lib/components/message/message-list.component.js +252 -87
  159. package/dist/lib/components/message/message-list.component.js.map +1 -1
  160. package/dist/lib/components/realtime/channels/base-realtime-channel-client.d.ts +282 -0
  161. package/dist/lib/components/realtime/channels/base-realtime-channel-client.d.ts.map +1 -0
  162. package/dist/lib/components/realtime/channels/base-realtime-channel-client.js +158 -0
  163. package/dist/lib/components/realtime/channels/base-realtime-channel-client.js.map +1 -0
  164. package/dist/lib/components/realtime/channels/channel-onboarding-panel.component.d.ts +25 -0
  165. package/dist/lib/components/realtime/channels/channel-onboarding-panel.component.d.ts.map +1 -0
  166. package/dist/lib/components/realtime/channels/channel-onboarding-panel.component.js +140 -0
  167. package/dist/lib/components/realtime/channels/channel-onboarding-panel.component.js.map +1 -0
  168. package/dist/lib/components/realtime/channels/realtime-channel-pane.component.d.ts +35 -0
  169. package/dist/lib/components/realtime/channels/realtime-channel-pane.component.d.ts.map +1 -0
  170. package/dist/lib/components/realtime/channels/realtime-channel-pane.component.js +58 -0
  171. package/dist/lib/components/realtime/channels/realtime-channel-pane.component.js.map +1 -0
  172. package/dist/lib/components/realtime/realtime-activity-rail.component.d.ts +63 -0
  173. package/dist/lib/components/realtime/realtime-activity-rail.component.d.ts.map +1 -0
  174. package/dist/lib/components/realtime/realtime-activity-rail.component.js +260 -0
  175. package/dist/lib/components/realtime/realtime-activity-rail.component.js.map +1 -0
  176. package/dist/lib/components/realtime/realtime-agent-banner.component.d.ts +117 -0
  177. package/dist/lib/components/realtime/realtime-agent-banner.component.d.ts.map +1 -0
  178. package/dist/lib/components/realtime/realtime-agent-banner.component.js +504 -0
  179. package/dist/lib/components/realtime/realtime-agent-banner.component.js.map +1 -0
  180. package/dist/lib/components/realtime/realtime-agent-picker.component.d.ts +168 -0
  181. package/dist/lib/components/realtime/realtime-agent-picker.component.d.ts.map +1 -0
  182. package/dist/lib/components/realtime/realtime-agent-picker.component.js +556 -0
  183. package/dist/lib/components/realtime/realtime-agent-picker.component.js.map +1 -0
  184. package/dist/lib/components/realtime/realtime-audio-visuals.d.ts +97 -0
  185. package/dist/lib/components/realtime/realtime-audio-visuals.d.ts.map +1 -0
  186. package/dist/lib/components/realtime/realtime-audio-visuals.js +139 -0
  187. package/dist/lib/components/realtime/realtime-audio-visuals.js.map +1 -0
  188. package/dist/lib/components/realtime/realtime-channel-strip.component.d.ts +29 -0
  189. package/dist/lib/components/realtime/realtime-channel-strip.component.d.ts.map +1 -0
  190. package/dist/lib/components/realtime/realtime-channel-strip.component.js +69 -0
  191. package/dist/lib/components/realtime/realtime-channel-strip.component.js.map +1 -0
  192. package/dist/lib/components/realtime/realtime-composer.component.d.ts +65 -0
  193. package/dist/lib/components/realtime/realtime-composer.component.d.ts.map +1 -0
  194. package/dist/lib/components/realtime/realtime-composer.component.js +256 -0
  195. package/dist/lib/components/realtime/realtime-composer.component.js.map +1 -0
  196. package/dist/lib/components/realtime/realtime-delegation-card.component.d.ts +71 -0
  197. package/dist/lib/components/realtime/realtime-delegation-card.component.d.ts.map +1 -0
  198. package/dist/lib/components/realtime/realtime-delegation-card.component.js +324 -0
  199. package/dist/lib/components/realtime/realtime-delegation-card.component.js.map +1 -0
  200. package/dist/lib/components/realtime/realtime-disclosure.d.ts +135 -0
  201. package/dist/lib/components/realtime/realtime-disclosure.d.ts.map +1 -0
  202. package/dist/lib/components/realtime/realtime-disclosure.js +188 -0
  203. package/dist/lib/components/realtime/realtime-disclosure.js.map +1 -0
  204. package/dist/lib/components/realtime/realtime-session-overlay.component.d.ts +491 -0
  205. package/dist/lib/components/realtime/realtime-session-overlay.component.d.ts.map +1 -0
  206. package/dist/lib/components/realtime/realtime-session-overlay.component.js +1274 -0
  207. package/dist/lib/components/realtime/realtime-session-overlay.component.js.map +1 -0
  208. package/dist/lib/components/realtime/realtime-session-state.d.ts +191 -0
  209. package/dist/lib/components/realtime/realtime-session-state.d.ts.map +1 -0
  210. package/dist/lib/components/realtime/realtime-session-state.js +244 -0
  211. package/dist/lib/components/realtime/realtime-session-state.js.map +1 -0
  212. package/dist/lib/components/realtime/realtime-session-thread.component.d.ts +56 -0
  213. package/dist/lib/components/realtime/realtime-session-thread.component.d.ts.map +1 -0
  214. package/dist/lib/components/realtime/realtime-session-thread.component.js +246 -0
  215. package/dist/lib/components/realtime/realtime-session-thread.component.js.map +1 -0
  216. package/dist/lib/components/realtime/realtime-session-timeline-card.component.d.ts +51 -0
  217. package/dist/lib/components/realtime/realtime-session-timeline-card.component.d.ts.map +1 -0
  218. package/dist/lib/components/realtime/realtime-session-timeline-card.component.js +193 -0
  219. package/dist/lib/components/realtime/realtime-session-timeline-card.component.js.map +1 -0
  220. package/dist/lib/components/realtime/realtime-surface-panel-prefs.d.ts +77 -0
  221. package/dist/lib/components/realtime/realtime-surface-panel-prefs.d.ts.map +1 -0
  222. package/dist/lib/components/realtime/realtime-surface-panel-prefs.js +114 -0
  223. package/dist/lib/components/realtime/realtime-surface-panel-prefs.js.map +1 -0
  224. package/dist/lib/components/realtime/realtime-surface-tabs.component.d.ts +173 -0
  225. package/dist/lib/components/realtime/realtime-surface-tabs.component.d.ts.map +1 -0
  226. package/dist/lib/components/realtime/realtime-surface-tabs.component.js +496 -0
  227. package/dist/lib/components/realtime/realtime-surface-tabs.component.js.map +1 -0
  228. package/dist/lib/components/realtime/realtime-surface-tabs.model.d.ts +181 -0
  229. package/dist/lib/components/realtime/realtime-surface-tabs.model.d.ts.map +1 -0
  230. package/dist/lib/components/realtime/realtime-surface-tabs.model.js +223 -0
  231. package/dist/lib/components/realtime/realtime-surface-tabs.model.js.map +1 -0
  232. package/dist/lib/components/realtime/remote-browser/remote-browser-audio-player.d.ts +163 -0
  233. package/dist/lib/components/realtime/remote-browser/remote-browser-audio-player.d.ts.map +1 -0
  234. package/dist/lib/components/realtime/remote-browser/remote-browser-audio-player.js +309 -0
  235. package/dist/lib/components/realtime/remote-browser/remote-browser-audio-player.js.map +1 -0
  236. package/dist/lib/components/realtime/remote-browser/remote-browser-channel.d.ts +168 -0
  237. package/dist/lib/components/realtime/remote-browser/remote-browser-channel.d.ts.map +1 -0
  238. package/dist/lib/components/realtime/remote-browser/remote-browser-channel.js +524 -0
  239. package/dist/lib/components/realtime/remote-browser/remote-browser-channel.js.map +1 -0
  240. package/dist/lib/components/realtime/remote-browser/remote-browser-surface.component.d.ts +346 -0
  241. package/dist/lib/components/realtime/remote-browser/remote-browser-surface.component.d.ts.map +1 -0
  242. package/dist/lib/components/realtime/remote-browser/remote-browser-surface.component.js +851 -0
  243. package/dist/lib/components/realtime/remote-browser/remote-browser-surface.component.js.map +1 -0
  244. package/dist/lib/components/realtime/remote-browser/remote-browser-tools.d.ts +86 -0
  245. package/dist/lib/components/realtime/remote-browser/remote-browser-tools.d.ts.map +1 -0
  246. package/dist/lib/components/realtime/remote-browser/remote-browser-tools.js +210 -0
  247. package/dist/lib/components/realtime/remote-browser/remote-browser-tools.js.map +1 -0
  248. package/dist/lib/components/realtime/whiteboard/whiteboard-artifact-viewer.component.d.ts +48 -0
  249. package/dist/lib/components/realtime/whiteboard/whiteboard-artifact-viewer.component.d.ts.map +1 -0
  250. package/dist/lib/components/realtime/whiteboard/whiteboard-artifact-viewer.component.js +180 -0
  251. package/dist/lib/components/realtime/whiteboard/whiteboard-artifact-viewer.component.js.map +1 -0
  252. package/dist/lib/components/realtime/whiteboard/whiteboard-channel.d.ts +119 -0
  253. package/dist/lib/components/realtime/whiteboard/whiteboard-channel.d.ts.map +1 -0
  254. package/dist/lib/components/realtime/whiteboard/whiteboard-channel.js +274 -0
  255. package/dist/lib/components/realtime/whiteboard/whiteboard-channel.js.map +1 -0
  256. package/dist/lib/components/slots/mj-chat-agent-presence-default.component.d.ts +11 -0
  257. package/dist/lib/components/slots/mj-chat-agent-presence-default.component.d.ts.map +1 -0
  258. package/dist/lib/components/slots/mj-chat-agent-presence-default.component.js +98 -0
  259. package/dist/lib/components/slots/mj-chat-agent-presence-default.component.js.map +1 -0
  260. package/dist/lib/components/slots/mj-chat-demonstration-surface-default.component.d.ts +9 -0
  261. package/dist/lib/components/slots/mj-chat-demonstration-surface-default.component.d.ts.map +1 -0
  262. package/dist/lib/components/slots/mj-chat-demonstration-surface-default.component.js +35 -0
  263. package/dist/lib/components/slots/mj-chat-demonstration-surface-default.component.js.map +1 -0
  264. package/dist/lib/components/slots/mj-chat-empty-state-default.component.d.ts +28 -0
  265. package/dist/lib/components/slots/mj-chat-empty-state-default.component.d.ts.map +1 -0
  266. package/dist/lib/components/slots/mj-chat-empty-state-default.component.js +104 -0
  267. package/dist/lib/components/slots/mj-chat-empty-state-default.component.js.map +1 -0
  268. package/dist/lib/components/slots/mj-chat-header-default.component.d.ts +11 -0
  269. package/dist/lib/components/slots/mj-chat-header-default.component.d.ts.map +1 -0
  270. package/dist/lib/components/slots/mj-chat-header-default.component.js +103 -0
  271. package/dist/lib/components/slots/mj-chat-header-default.component.js.map +1 -0
  272. package/dist/lib/components/slots/mj-chat-message-bubble-default.component.d.ts +15 -0
  273. package/dist/lib/components/slots/mj-chat-message-bubble-default.component.d.ts.map +1 -0
  274. package/dist/lib/components/slots/mj-chat-message-bubble-default.component.js +73 -0
  275. package/dist/lib/components/slots/mj-chat-message-bubble-default.component.js.map +1 -0
  276. package/dist/lib/components/slots/mj-chat-message-extra-default.component.d.ts +9 -0
  277. package/dist/lib/components/slots/mj-chat-message-extra-default.component.d.ts.map +1 -0
  278. package/dist/lib/components/slots/mj-chat-message-extra-default.component.js +34 -0
  279. package/dist/lib/components/slots/mj-chat-message-extra-default.component.js.map +1 -0
  280. package/dist/lib/components/slots/slot-interfaces.d.ts +95 -0
  281. package/dist/lib/components/slots/slot-interfaces.d.ts.map +1 -0
  282. package/dist/lib/components/slots/slot-interfaces.js +18 -0
  283. package/dist/lib/components/slots/slot-interfaces.js.map +1 -0
  284. package/dist/lib/components/workspace/conversation-workspace.component.d.ts +11 -0
  285. package/dist/lib/components/workspace/conversation-workspace.component.d.ts.map +1 -1
  286. package/dist/lib/components/workspace/conversation-workspace.component.js +28 -4
  287. package/dist/lib/components/workspace/conversation-workspace.component.js.map +1 -1
  288. package/dist/lib/conversations.module.d.ts +12 -1
  289. package/dist/lib/conversations.module.d.ts.map +1 -1
  290. package/dist/lib/conversations.module.js +93 -5
  291. package/dist/lib/conversations.module.js.map +1 -1
  292. package/dist/lib/directives/chat-slot.directive.d.ts +44 -0
  293. package/dist/lib/directives/chat-slot.directive.d.ts.map +1 -0
  294. package/dist/lib/directives/chat-slot.directive.js +54 -0
  295. package/dist/lib/directives/chat-slot.directive.js.map +1 -0
  296. package/dist/lib/events/chat-events.d.ts +137 -0
  297. package/dist/lib/events/chat-events.d.ts.map +1 -0
  298. package/dist/lib/events/chat-events.js +189 -0
  299. package/dist/lib/events/chat-events.js.map +1 -0
  300. package/dist/lib/models/conversation-state.model.d.ts +2 -1
  301. package/dist/lib/models/conversation-state.model.d.ts.map +1 -1
  302. package/dist/lib/models/conversation-state.model.js.map +1 -1
  303. package/dist/lib/services/artifact-state.service.d.ts.map +1 -1
  304. package/dist/lib/services/artifact-state.service.js +23 -6
  305. package/dist/lib/services/artifact-state.service.js.map +1 -1
  306. package/dist/lib/services/conversation-agent.service.d.ts +60 -74
  307. package/dist/lib/services/conversation-agent.service.d.ts.map +1 -1
  308. package/dist/lib/services/conversation-agent.service.js +100 -313
  309. package/dist/lib/services/conversation-agent.service.js.map +1 -1
  310. package/dist/lib/services/conversation-bridge.service.d.ts +11 -70
  311. package/dist/lib/services/conversation-bridge.service.d.ts.map +1 -1
  312. package/dist/lib/services/conversation-bridge.service.js +51 -85
  313. package/dist/lib/services/conversation-bridge.service.js.map +1 -1
  314. package/dist/lib/services/conversation-naming.d.ts +63 -0
  315. package/dist/lib/services/conversation-naming.d.ts.map +1 -0
  316. package/dist/lib/services/conversation-naming.js +58 -0
  317. package/dist/lib/services/conversation-naming.js.map +1 -0
  318. package/dist/lib/services/conversation-streaming.service.d.ts +24 -154
  319. package/dist/lib/services/conversation-streaming.service.d.ts.map +1 -1
  320. package/dist/lib/services/conversation-streaming.service.js +39 -361
  321. package/dist/lib/services/conversation-streaming.service.js.map +1 -1
  322. package/dist/lib/services/conversations-runtime-bootstrap.service.d.ts +10 -0
  323. package/dist/lib/services/conversations-runtime-bootstrap.service.d.ts.map +1 -0
  324. package/dist/lib/services/conversations-runtime-bootstrap.service.js +104 -0
  325. package/dist/lib/services/conversations-runtime-bootstrap.service.js.map +1 -0
  326. package/dist/lib/services/delegation-result-parser.d.ts +45 -0
  327. package/dist/lib/services/delegation-result-parser.d.ts.map +1 -0
  328. package/dist/lib/services/delegation-result-parser.js +48 -0
  329. package/dist/lib/services/delegation-result-parser.js.map +1 -0
  330. package/dist/lib/services/mention-autocomplete.service.d.ts +19 -4
  331. package/dist/lib/services/mention-autocomplete.service.d.ts.map +1 -1
  332. package/dist/lib/services/mention-autocomplete.service.js +65 -4
  333. package/dist/lib/services/mention-autocomplete.service.js.map +1 -1
  334. package/dist/lib/services/mention-parser.service.d.ts +8 -53
  335. package/dist/lib/services/mention-parser.service.d.ts.map +1 -1
  336. package/dist/lib/services/mention-parser.service.js +32 -243
  337. package/dist/lib/services/mention-parser.service.js.map +1 -1
  338. package/dist/lib/services/narration-template.d.ts +42 -0
  339. package/dist/lib/services/narration-template.d.ts.map +1 -0
  340. package/dist/lib/services/narration-template.js +73 -0
  341. package/dist/lib/services/narration-template.js.map +1 -0
  342. package/dist/lib/services/realtime-pairing.d.ts +120 -0
  343. package/dist/lib/services/realtime-pairing.d.ts.map +1 -0
  344. package/dist/lib/services/realtime-pairing.js +150 -0
  345. package/dist/lib/services/realtime-pairing.js.map +1 -0
  346. package/dist/lib/services/realtime-session-review.service.d.ts +233 -0
  347. package/dist/lib/services/realtime-session-review.service.d.ts.map +1 -0
  348. package/dist/lib/services/realtime-session-review.service.js +417 -0
  349. package/dist/lib/services/realtime-session-review.service.js.map +1 -0
  350. package/dist/lib/services/realtime-session.service.d.ts +739 -0
  351. package/dist/lib/services/realtime-session.service.d.ts.map +1 -0
  352. package/dist/lib/services/realtime-session.service.js +1647 -0
  353. package/dist/lib/services/realtime-session.service.js.map +1 -0
  354. package/dist/lib/services/realtime-sessions-adapter.d.ts +54 -0
  355. package/dist/lib/services/realtime-sessions-adapter.d.ts.map +1 -0
  356. package/dist/lib/services/realtime-sessions-adapter.js +154 -0
  357. package/dist/lib/services/realtime-sessions-adapter.js.map +1 -0
  358. package/dist/lib/services/user-authorization.d.ts +67 -0
  359. package/dist/lib/services/user-authorization.d.ts.map +1 -0
  360. package/dist/lib/services/user-authorization.js +66 -0
  361. package/dist/lib/services/user-authorization.js.map +1 -0
  362. package/dist/lib/utils/realtime-session-timeline.d.ts +84 -0
  363. package/dist/lib/utils/realtime-session-timeline.d.ts.map +1 -0
  364. package/dist/lib/utils/realtime-session-timeline.js +94 -0
  365. package/dist/lib/utils/realtime-session-timeline.js.map +1 -0
  366. package/dist/public-api.d.ts +41 -0
  367. package/dist/public-api.d.ts.map +1 -1
  368. package/dist/public-api.js +50 -0
  369. package/dist/public-api.js.map +1 -1
  370. package/package.json +27 -24
  371. package/dist/__tests__/conversation-bridge.service.test.d.ts +0 -2
  372. package/dist/__tests__/conversation-bridge.service.test.d.ts.map +0 -1
  373. package/dist/__tests__/conversation-bridge.service.test.js +0 -98
  374. package/dist/__tests__/conversation-bridge.service.test.js.map +0 -1
  375. package/dist/__tests__/mention-parser.test.d.ts +0 -2
  376. package/dist/__tests__/mention-parser.test.d.ts.map +0 -1
  377. package/dist/__tests__/mention-parser.test.js +0 -154
  378. package/dist/__tests__/mention-parser.test.js.map +0 -1
@@ -0,0 +1,180 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
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
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var WhiteboardArtifactViewerComponent_1;
8
+ import { Component } from '@angular/core';
9
+ import { DataSnapshot } from '@memberjunction/core';
10
+ import { RegisterClass } from '@memberjunction/global';
11
+ import { BaseArtifactViewerPluginComponent } from '@memberjunction/ng-artifacts';
12
+ import { BuildWhiteboardExportHtml, BuildWhiteboardExportSvg, ParseBoardStateJson, WhiteboardSnapshotComponent } from '@memberjunction/ng-whiteboard';
13
+ import * as i0 from "@angular/core";
14
+ /**
15
+ * ARTIFACT VIEWER PLUGIN for saved whiteboards — renders the session-channel board
16
+ * artifact (a {@link WhiteboardState.ToJSON} payload) as a read-only snapshot with the
17
+ * same export affordances the live board offers (Download HTML / Download SVG / Print).
18
+ *
19
+ * Resolved dynamically by the artifact plugin host via the MJ ClassFactory (keyed by the
20
+ * artifact type's DriverClass), which instantiates the class ONCE with a bare `new` to
21
+ * discover the component type — so this class must stay constructible outside an Angular
22
+ * injection context (no `inject()` field initializers, no constructor DI).
23
+ */
24
+ let WhiteboardArtifactViewerComponent = class WhiteboardArtifactViewerComponent extends BaseArtifactViewerPluginComponent {
25
+ static { WhiteboardArtifactViewerComponent_1 = this; }
26
+ /** Memoized parse — keyed by the raw content string so version switches re-parse. */
27
+ parsedForJson = null;
28
+ parsedState = null;
29
+ /** Raw board payload fed to the snapshot component (setter-driven re-parse there). */
30
+ get ContentJson() {
31
+ return this.getRawContent() ?? '';
32
+ }
33
+ /** Rehydrated board engine for export/snapshot duty (null when content is malformed). */
34
+ get BoardState() {
35
+ const json = this.getRawContent();
36
+ if (json !== this.parsedForJson) {
37
+ this.parsedForJson = json;
38
+ this.parsedState = ParseBoardStateJson(json);
39
+ }
40
+ return this.parsedState;
41
+ }
42
+ get HasBoard() {
43
+ return this.BoardState !== null;
44
+ }
45
+ get hasDisplayContent() {
46
+ return this.HasBoard;
47
+ }
48
+ GetCurrentStateSnapshot() {
49
+ const state = this.BoardState;
50
+ if (!state) {
51
+ return null;
52
+ }
53
+ const scene = state.BuildSceneSummary();
54
+ const snap = new DataSnapshot();
55
+ snap.title = this.getDisplayTitle() ?? 'Whiteboard';
56
+ snap.interpretation = scene.summary;
57
+ snap.custom = { elementCounts: scene.counts };
58
+ return snap;
59
+ }
60
+ // ────────────────────────────────────────────── export actions (live-board parity)
61
+ /** Download the board as one self-contained HTML document. */
62
+ OnDownloadHtml() {
63
+ const state = this.BoardState;
64
+ if (!state) {
65
+ return;
66
+ }
67
+ this.downloadBlob(this.buildExportHtml(state), 'text/html', `whiteboard-${WhiteboardArtifactViewerComponent_1.exportDateStamp()}.html`);
68
+ }
69
+ /** Download the board as a standalone SVG document. */
70
+ OnDownloadSvg() {
71
+ const state = this.BoardState;
72
+ if (!state) {
73
+ return;
74
+ }
75
+ this.downloadBlob(BuildWhiteboardExportSvg(state), 'image/svg+xml', `whiteboard-${WhiteboardArtifactViewerComponent_1.exportDateStamp()}.svg`);
76
+ }
77
+ /**
78
+ * Print the board: open a blank window, write the self-contained export document and
79
+ * invoke the print dialog (same precedent as the live board host's print path). When
80
+ * the popup is blocked this is a logged no-op — nothing breaks, the user can retry.
81
+ */
82
+ OnPrint() {
83
+ const state = this.BoardState;
84
+ if (!state) {
85
+ return;
86
+ }
87
+ const printWindow = window.open('about:blank', '_blank');
88
+ if (!printWindow) {
89
+ console.warn('Whiteboard print: popup was blocked — allow popups for this site and retry.');
90
+ return;
91
+ }
92
+ printWindow.document.write(this.buildExportHtml(state));
93
+ printWindow.document.close();
94
+ printWindow.focus();
95
+ // let the document lay out before invoking the dialog (artifact-viewer precedent)
96
+ setTimeout(() => printWindow.print(), 250);
97
+ }
98
+ buildExportHtml(state) {
99
+ return BuildWhiteboardExportHtml(state, {
100
+ Title: this.getDisplayTitle() ?? 'Whiteboard',
101
+ AgentName: 'Agent',
102
+ GeneratedAt: new Date().toLocaleString()
103
+ });
104
+ }
105
+ downloadBlob(content, mimeType, fileName) {
106
+ const url = URL.createObjectURL(new Blob([content], { type: mimeType }));
107
+ const anchor = document.createElement('a');
108
+ anchor.href = url;
109
+ anchor.download = fileName;
110
+ anchor.click();
111
+ URL.revokeObjectURL(url);
112
+ }
113
+ static exportDateStamp() {
114
+ return new Date().toISOString().slice(0, 10);
115
+ }
116
+ static ɵfac = /*@__PURE__*/ (() => { let ɵWhiteboardArtifactViewerComponent_BaseFactory; return function WhiteboardArtifactViewerComponent_Factory(__ngFactoryType__) { return (ɵWhiteboardArtifactViewerComponent_BaseFactory || (ɵWhiteboardArtifactViewerComponent_BaseFactory = i0.ɵɵgetInheritedFactory(WhiteboardArtifactViewerComponent)))(__ngFactoryType__ || WhiteboardArtifactViewerComponent); }; })();
117
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: WhiteboardArtifactViewerComponent, selectors: [["mj-whiteboard-artifact-viewer"]], features: [i0.ɵɵInheritDefinitionFeature], decls: 12, vars: 8, consts: [[1, "wb-artifact-toolbar"], ["type", "button", "title", "Download as HTML", 1, "wb-tool-btn", 3, "click", "disabled"], ["aria-hidden", "true", 1, "fa-solid", "fa-file-code"], ["type", "button", "title", "Download as SVG", 1, "wb-tool-btn", 3, "click", "disabled"], ["aria-hidden", "true", 1, "fa-solid", "fa-bezier-curve"], ["type", "button", "title", "Print board", 1, "wb-tool-btn", 3, "click", "disabled"], ["aria-hidden", "true", 1, "fa-solid", "fa-print"], [1, "wb-artifact-board", 3, "StateJson"]], template: function WhiteboardArtifactViewerComponent_Template(rf, ctx) { if (rf & 1) {
118
+ i0.ɵɵelementStart(0, "div")(1, "div", 0)(2, "button", 1);
119
+ i0.ɵɵlistener("click", function WhiteboardArtifactViewerComponent_Template_button_click_2_listener() { return ctx.OnDownloadHtml(); });
120
+ i0.ɵɵelement(3, "i", 2);
121
+ i0.ɵɵtext(4, " HTML ");
122
+ i0.ɵɵelementEnd();
123
+ i0.ɵɵelementStart(5, "button", 3);
124
+ i0.ɵɵlistener("click", function WhiteboardArtifactViewerComponent_Template_button_click_5_listener() { return ctx.OnDownloadSvg(); });
125
+ i0.ɵɵelement(6, "i", 4);
126
+ i0.ɵɵtext(7, " SVG ");
127
+ i0.ɵɵelementEnd();
128
+ i0.ɵɵelementStart(8, "button", 5);
129
+ i0.ɵɵlistener("click", function WhiteboardArtifactViewerComponent_Template_button_click_8_listener() { return ctx.OnPrint(); });
130
+ i0.ɵɵelement(9, "i", 6);
131
+ i0.ɵɵtext(10, " Print ");
132
+ i0.ɵɵelementEnd()();
133
+ i0.ɵɵelement(11, "mj-whiteboard-snapshot", 7);
134
+ i0.ɵɵelementEnd();
135
+ } if (rf & 2) {
136
+ i0.ɵɵclassMap("wb-artifact-viewer " + (ctx.cssClass || ""));
137
+ i0.ɵɵstyleProp("height", ctx.height || null);
138
+ i0.ɵɵadvance(2);
139
+ i0.ɵɵproperty("disabled", !ctx.HasBoard);
140
+ i0.ɵɵadvance(3);
141
+ i0.ɵɵproperty("disabled", !ctx.HasBoard);
142
+ i0.ɵɵadvance(3);
143
+ i0.ɵɵproperty("disabled", !ctx.HasBoard);
144
+ i0.ɵɵadvance(3);
145
+ i0.ɵɵproperty("StateJson", ctx.ContentJson);
146
+ } }, dependencies: [WhiteboardSnapshotComponent], styles: ["[_nghost-%COMP%] {\n display: flex;\n flex-direction: column;\n flex: 1;\n height: 100%;\n min-height: 0;\n }\n .wb-artifact-viewer[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n flex: 1;\n height: 100%;\n min-height: 0;\n }\n .wb-artifact-toolbar[_ngcontent-%COMP%] {\n display: flex;\n justify-content: flex-end;\n align-items: center;\n gap: 8px;\n padding: 8px;\n flex-shrink: 0;\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n }\n .wb-tool-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 5px 11px;\n font-size: 12px;\n cursor: pointer;\n color: var(--mj-text-secondary);\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-sm, 4px);\n }\n .wb-tool-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-bg-surface-hover);\n border-color: var(--mj-border-strong);\n color: var(--mj-text-primary);\n }\n .wb-tool-btn[_ngcontent-%COMP%]:disabled {\n color: var(--mj-text-disabled);\n cursor: default;\n }\n .wb-artifact-board[_ngcontent-%COMP%] {\n flex: 1;\n min-height: 0;\n }"] });
147
+ };
148
+ WhiteboardArtifactViewerComponent = WhiteboardArtifactViewerComponent_1 = __decorate([
149
+ RegisterClass(BaseArtifactViewerPluginComponent, 'WhiteboardArtifactViewerPlugin')
150
+ ], WhiteboardArtifactViewerComponent);
151
+ export { WhiteboardArtifactViewerComponent };
152
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(WhiteboardArtifactViewerComponent, [{
153
+ type: Component,
154
+ args: [{ standalone: true, selector: 'mj-whiteboard-artifact-viewer', imports: [WhiteboardSnapshotComponent], template: `
155
+ <div [class]="'wb-artifact-viewer ' + (cssClass || '')" [style.height]="height || null">
156
+ <div class="wb-artifact-toolbar">
157
+ <button type="button" class="wb-tool-btn" title="Download as HTML" [disabled]="!HasBoard" (click)="OnDownloadHtml()">
158
+ <i class="fa-solid fa-file-code" aria-hidden="true"></i> HTML
159
+ </button>
160
+ <button type="button" class="wb-tool-btn" title="Download as SVG" [disabled]="!HasBoard" (click)="OnDownloadSvg()">
161
+ <i class="fa-solid fa-bezier-curve" aria-hidden="true"></i> SVG
162
+ </button>
163
+ <button type="button" class="wb-tool-btn" title="Print board" [disabled]="!HasBoard" (click)="OnPrint()">
164
+ <i class="fa-solid fa-print" aria-hidden="true"></i> Print
165
+ </button>
166
+ </div>
167
+ <mj-whiteboard-snapshot class="wb-artifact-board" [StateJson]="ContentJson" />
168
+ </div>
169
+ `, styles: ["\n :host {\n display: flex;\n flex-direction: column;\n flex: 1;\n height: 100%;\n min-height: 0;\n }\n .wb-artifact-viewer {\n display: flex;\n flex-direction: column;\n flex: 1;\n height: 100%;\n min-height: 0;\n }\n .wb-artifact-toolbar {\n display: flex;\n justify-content: flex-end;\n align-items: center;\n gap: 8px;\n padding: 8px;\n flex-shrink: 0;\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n }\n .wb-tool-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 5px 11px;\n font-size: 12px;\n cursor: pointer;\n color: var(--mj-text-secondary);\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-sm, 4px);\n }\n .wb-tool-btn:hover:not(:disabled) {\n background: var(--mj-bg-surface-hover);\n border-color: var(--mj-border-strong);\n color: var(--mj-text-primary);\n }\n .wb-tool-btn:disabled {\n color: var(--mj-text-disabled);\n cursor: default;\n }\n .wb-artifact-board {\n flex: 1;\n min-height: 0;\n }\n "] }]
170
+ }], null, null); })();
171
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(WhiteboardArtifactViewerComponent, { className: "WhiteboardArtifactViewerComponent", filePath: "src/lib/components/realtime/whiteboard/whiteboard-artifact-viewer.component.ts", lineNumber: 93 }); })();
172
+ /**
173
+ * Tree-shaking prevention: the plugin is resolved dynamically through the MJ ClassFactory
174
+ * (keyed by the artifact type's DriverClass), so this static call keeps the @RegisterClass
175
+ * side effect from being eliminated by the bundler.
176
+ */
177
+ export function LoadWhiteboardArtifactViewer() {
178
+ // intentional no-op — the import side effect performs the registration
179
+ }
180
+ //# sourceMappingURL=whiteboard-artifact-viewer.component.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"whiteboard-artifact-viewer.component.js","sourceRoot":"","sources":["../../../../../src/lib/components/realtime/whiteboard/whiteboard-artifact-viewer.component.ts"],"names":[],"mappings":";;;;;;;AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,iCAAiC,EAAE,MAAM,8BAA8B,CAAC;AACjF,OAAO,EACL,yBAAyB,EAAE,wBAAwB,EAAE,mBAAmB,EACxE,2BAA2B,EAC5B,MAAM,+BAA+B,CAAC;;AAEvC;;;;;;;;;GASG;AA0EI,IAAM,iCAAiC,GAAvC,MAAM,iCAAkC,SAAQ,iCAAiC;;IACtF,qFAAqF;IAC7E,aAAa,GAAkB,IAAI,CAAC;IACpC,WAAW,GAA2B,IAAI,CAAC;IAEnD,sFAAsF;IACtF,IAAW,WAAW;QACpB,OAAO,IAAI,CAAC,aAAa,EAAE,IAAI,EAAE,CAAC;IACpC,CAAC;IAED,yFAAyF;IACzF,IAAW,UAAU;QACnB,MAAM,IAAI,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;QAClC,IAAI,IAAI,KAAK,IAAI,CAAC,aAAa,EAAE,CAAC;YAChC,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;YAC1B,IAAI,CAAC,WAAW,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC;QAC/C,CAAC;QACD,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;IAED,IAAW,QAAQ;QACjB,OAAO,IAAI,CAAC,UAAU,KAAK,IAAI,CAAC;IAClC,CAAC;IAED,IAAoB,iBAAiB;QACnC,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;IAEe,uBAAuB;QACrC,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC;QAC9B,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,KAAK,GAAG,KAAK,CAAC,iBAAiB,EAAE,CAAC;QACxC,MAAM,IAAI,GAAG,IAAI,YAAY,EAAE,CAAC;QAChC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,eAAe,EAAE,IAAI,YAAY,CAAC;QACpD,IAAI,CAAC,cAAc,GAAG,KAAK,CAAC,OAAO,CAAC;QACpC,IAAI,CAAC,MAAM,GAAG,EAAE,aAAa,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC;QAC9C,OAAO,IAAI,CAAC;IACd,CAAC;IAED,oFAAoF;IAEpF,8DAA8D;IACvD,cAAc;QACnB,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC;QAC9B,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO;QACT,CAAC;QACD,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,EAAE,WAAW,EAAE,cAAc,mCAAiC,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC;IACxI,CAAC;IAED,uDAAuD;IAChD,aAAa;QAClB,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC;QAC9B,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO;QACT,CAAC;QACD,IAAI,CAAC,YAAY,CAAC,wBAAwB,CAAC,KAAK,CAAC,EAAE,eAAe,EAAE,cAAc,mCAAiC,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC;IAC/I,CAAC;IAED;;;;OAIG;IACI,OAAO;QACZ,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC;QAC9B,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO;QACT,CAAC;QACD,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAC;QACzD,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,OAAO,CAAC,IAAI,CAAC,6EAA6E,CAAC,CAAC;YAC5F,OAAO;QACT,CAAC;QACD,WAAW,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC;QACxD,WAAW,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;QAC7B,WAAW,CAAC,KAAK,EAAE,CAAC;QACpB,kFAAkF;QAClF,UAAU,CAAC,GAAG,EAAE,CAAC,WAAW,CAAC,KAAK,EAAE,EAAE,GAAG,CAAC,CAAC;IAC7C,CAAC;IAEO,eAAe,CAAC,KAAsB;QAC5C,OAAO,yBAAyB,CAAC,KAAK,EAAE;YACtC,KAAK,EAAE,IAAI,CAAC,eAAe,EAAE,IAAI,YAAY;YAC7C,SAAS,EAAE,OAAO;YAClB,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC,cAAc,EAAE;SACzC,CAAC,CAAC;IACL,CAAC;IAEO,YAAY,CAAC,OAAe,EAAE,QAAgB,EAAE,QAAgB;QACtE,MAAM,GAAG,GAAG,GAAG,CAAC,eAAe,CAAC,IAAI,IAAI,CAAC,CAAC,OAAO,CAAC,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC;QACzE,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;QAC3C,MAAM,CAAC,IAAI,GAAG,GAAG,CAAC;QAClB,MAAM,CAAC,QAAQ,GAAG,QAAQ,CAAC;QAC3B,MAAM,CAAC,KAAK,EAAE,CAAC;QACf,GAAG,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC;IAC3B,CAAC;IAEO,MAAM,CAAC,eAAe;QAC5B,OAAO,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAC/C,CAAC;iTAtGU,iCAAiC,yBAAjC,iCAAiC;6DAAjC,iCAAiC;YAlEtC,AADF,AADF,2BAAwF,aACrD,gBACsF;YAA3B,8GAAS,oBAAgB,IAAC;YAClH,uBAAwD;YAAC,sBAC3D;YAAA,iBAAS;YACT,iCAAmH;YAA1B,8GAAS,mBAAe,IAAC;YAChH,uBAA2D;YAAC,qBAC9D;YAAA,iBAAS;YACT,iCAAyG;YAApB,8GAAS,aAAS,IAAC;YACtG,uBAAoD;YAAC,wBACvD;YACF,AADE,iBAAS,EACL;YACN,6CAA8E;YAChF,iBAAM;;YAbD,2DAAkD;YAAC,4CAA+B;YAEhB,eAAsB;YAAtB,wCAAsB;YAGvB,eAAsB;YAAtB,wCAAsB;YAG1B,eAAsB;YAAtB,wCAAsB;YAIpC,eAAyB;YAAzB,2CAAyB;4BAdrE,2BAA2B;;AAsE1B,iCAAiC;IAD7C,aAAa,CAAC,iCAAiC,EAAE,gCAAgC,CAAC;GACtE,iCAAiC,CAuG7C;;iFAvGY,iCAAiC;cAzE7C,SAAS;6BACI,IAAI,YACN,+BAA+B,WAChC,CAAC,2BAA2B,CAAC,YAC5B;;;;;;;;;;;;;;;GAeT;;kFAsDU,iCAAiC;AAyG9C;;;;GAIG;AACH,MAAM,UAAU,4BAA4B;IAC1C,uEAAuE;AACzE,CAAC","sourcesContent":["import { Component } from '@angular/core';\nimport { DataSnapshot } from '@memberjunction/core';\nimport { RegisterClass } from '@memberjunction/global';\nimport { BaseArtifactViewerPluginComponent } from '@memberjunction/ng-artifacts';\nimport {\n BuildWhiteboardExportHtml, BuildWhiteboardExportSvg, ParseBoardStateJson,\n WhiteboardSnapshotComponent, WhiteboardState\n} from '@memberjunction/ng-whiteboard';\n\n/**\n * ARTIFACT VIEWER PLUGIN for saved whiteboards — renders the session-channel board\n * artifact (a {@link WhiteboardState.ToJSON} payload) as a read-only snapshot with the\n * same export affordances the live board offers (Download HTML / Download SVG / Print).\n *\n * Resolved dynamically by the artifact plugin host via the MJ ClassFactory (keyed by the\n * artifact type's DriverClass), which instantiates the class ONCE with a bare `new` to\n * discover the component type — so this class must stay constructible outside an Angular\n * injection context (no `inject()` field initializers, no constructor DI).\n */\n@Component({\n standalone: true,\n selector: 'mj-whiteboard-artifact-viewer',\n imports: [WhiteboardSnapshotComponent],\n template: `\n <div [class]=\"'wb-artifact-viewer ' + (cssClass || '')\" [style.height]=\"height || null\">\n <div class=\"wb-artifact-toolbar\">\n <button type=\"button\" class=\"wb-tool-btn\" title=\"Download as HTML\" [disabled]=\"!HasBoard\" (click)=\"OnDownloadHtml()\">\n <i class=\"fa-solid fa-file-code\" aria-hidden=\"true\"></i> HTML\n </button>\n <button type=\"button\" class=\"wb-tool-btn\" title=\"Download as SVG\" [disabled]=\"!HasBoard\" (click)=\"OnDownloadSvg()\">\n <i class=\"fa-solid fa-bezier-curve\" aria-hidden=\"true\"></i> SVG\n </button>\n <button type=\"button\" class=\"wb-tool-btn\" title=\"Print board\" [disabled]=\"!HasBoard\" (click)=\"OnPrint()\">\n <i class=\"fa-solid fa-print\" aria-hidden=\"true\"></i> Print\n </button>\n </div>\n <mj-whiteboard-snapshot class=\"wb-artifact-board\" [StateJson]=\"ContentJson\" />\n </div>\n `,\n styles: [`\n :host {\n display: flex;\n flex-direction: column;\n flex: 1;\n height: 100%;\n min-height: 0;\n }\n .wb-artifact-viewer {\n display: flex;\n flex-direction: column;\n flex: 1;\n height: 100%;\n min-height: 0;\n }\n .wb-artifact-toolbar {\n display: flex;\n justify-content: flex-end;\n align-items: center;\n gap: 8px;\n padding: 8px;\n flex-shrink: 0;\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n }\n .wb-tool-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 5px 11px;\n font-size: 12px;\n cursor: pointer;\n color: var(--mj-text-secondary);\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-sm, 4px);\n }\n .wb-tool-btn:hover:not(:disabled) {\n background: var(--mj-bg-surface-hover);\n border-color: var(--mj-border-strong);\n color: var(--mj-text-primary);\n }\n .wb-tool-btn:disabled {\n color: var(--mj-text-disabled);\n cursor: default;\n }\n .wb-artifact-board {\n flex: 1;\n min-height: 0;\n }\n `]\n})\n@RegisterClass(BaseArtifactViewerPluginComponent, 'WhiteboardArtifactViewerPlugin')\nexport class WhiteboardArtifactViewerComponent extends BaseArtifactViewerPluginComponent {\n /** Memoized parse — keyed by the raw content string so version switches re-parse. */\n private parsedForJson: string | null = null;\n private parsedState: WhiteboardState | null = null;\n\n /** Raw board payload fed to the snapshot component (setter-driven re-parse there). */\n public get ContentJson(): string {\n return this.getRawContent() ?? '';\n }\n\n /** Rehydrated board engine for export/snapshot duty (null when content is malformed). */\n public get BoardState(): WhiteboardState | null {\n const json = this.getRawContent();\n if (json !== this.parsedForJson) {\n this.parsedForJson = json;\n this.parsedState = ParseBoardStateJson(json);\n }\n return this.parsedState;\n }\n\n public get HasBoard(): boolean {\n return this.BoardState !== null;\n }\n\n public override get hasDisplayContent(): boolean {\n return this.HasBoard;\n }\n\n public override GetCurrentStateSnapshot(): DataSnapshot | null {\n const state = this.BoardState;\n if (!state) {\n return null;\n }\n const scene = state.BuildSceneSummary();\n const snap = new DataSnapshot();\n snap.title = this.getDisplayTitle() ?? 'Whiteboard';\n snap.interpretation = scene.summary;\n snap.custom = { elementCounts: scene.counts };\n return snap;\n }\n\n // ────────────────────────────────────────────── export actions (live-board parity)\n\n /** Download the board as one self-contained HTML document. */\n public OnDownloadHtml(): void {\n const state = this.BoardState;\n if (!state) {\n return;\n }\n this.downloadBlob(this.buildExportHtml(state), 'text/html', `whiteboard-${WhiteboardArtifactViewerComponent.exportDateStamp()}.html`);\n }\n\n /** Download the board as a standalone SVG document. */\n public OnDownloadSvg(): void {\n const state = this.BoardState;\n if (!state) {\n return;\n }\n this.downloadBlob(BuildWhiteboardExportSvg(state), 'image/svg+xml', `whiteboard-${WhiteboardArtifactViewerComponent.exportDateStamp()}.svg`);\n }\n\n /**\n * Print the board: open a blank window, write the self-contained export document and\n * invoke the print dialog (same precedent as the live board host's print path). When\n * the popup is blocked this is a logged no-op — nothing breaks, the user can retry.\n */\n public OnPrint(): void {\n const state = this.BoardState;\n if (!state) {\n return;\n }\n const printWindow = window.open('about:blank', '_blank');\n if (!printWindow) {\n console.warn('Whiteboard print: popup was blocked — allow popups for this site and retry.');\n return;\n }\n printWindow.document.write(this.buildExportHtml(state));\n printWindow.document.close();\n printWindow.focus();\n // let the document lay out before invoking the dialog (artifact-viewer precedent)\n setTimeout(() => printWindow.print(), 250);\n }\n\n private buildExportHtml(state: WhiteboardState): string {\n return BuildWhiteboardExportHtml(state, {\n Title: this.getDisplayTitle() ?? 'Whiteboard',\n AgentName: 'Agent',\n GeneratedAt: new Date().toLocaleString()\n });\n }\n\n private downloadBlob(content: string, mimeType: string, fileName: string): void {\n const url = URL.createObjectURL(new Blob([content], { type: mimeType }));\n const anchor = document.createElement('a');\n anchor.href = url;\n anchor.download = fileName;\n anchor.click();\n URL.revokeObjectURL(url);\n }\n\n private static exportDateStamp(): string {\n return new Date().toISOString().slice(0, 10);\n }\n}\n\n/**\n * Tree-shaking prevention: the plugin is resolved dynamically through the MJ ClassFactory\n * (keyed by the artifact type's DriverClass), so this static call keeps the @RegisterClass\n * side effect from being eliminated by the bundler.\n */\nexport function LoadWhiteboardArtifactViewer(): void {\n // intentional no-op — the import side effect performs the registration\n}\n"]}
@@ -0,0 +1,119 @@
1
+ import type { Type } from '@angular/core';
2
+ import { RealtimeToolDefinition } from '@memberjunction/ai';
3
+ import { BaseRealtimeChannelClient, ChannelOnboardingDetails } from '../channels/base-realtime-channel-client';
4
+ import { RealtimeWhiteboardHostComponent, WhiteboardState } from '@memberjunction/ng-whiteboard';
5
+ /**
6
+ * Per-widget throttle window for AMBIENT interaction context notes: at most one note per
7
+ * widget per this many ms — within the window the LATEST summary wins (chatty widgets
8
+ * collapse to one trailing-edge note instead of flooding the model's context).
9
+ */
10
+ export declare const WHITEBOARD_INTERACTION_NOTE_THROTTLE_MS = 4000;
11
+ /**
12
+ * The LIVE WHITEBOARD as a pluggable interactive channel — the canonical
13
+ * {@link BaseRealtimeChannelClient} implementation, resolved from the `MJ: AI Agent
14
+ * Channels` registry row whose `ClientPluginClass` is `'RealtimeWhiteboardChannel'`.
15
+ *
16
+ * One instance per session (created via ClassFactory at session start). It owns the
17
+ * board's {@link WhiteboardState} engine and contributes the channel's full contract:
18
+ *
19
+ * - **Action**: the `Whiteboard_*` client-executed tool set
20
+ * ({@link WHITEBOARD_TOOL_DEFINITIONS}); {@link ApplyAgentTool} prefers the BOUND host
21
+ * component (board mutation + violet pop-in / toast / presence-cursor garnish) and
22
+ * falls back to the pure {@link ApplyWhiteboardAgentTool} engine call when no surface
23
+ * is bound (e.g. the surface panel is collapsed) — the channel keeps working, just
24
+ * without the garnish.
25
+ * - **Perception**: {@link BindSurface} subscribes the host's coalesced (750 ms)
26
+ * `SceneDelta` stream and pipes each delta into the live model's context as a
27
+ * `[whiteboard]` background note; the agent-undo toast click flows the same way.
28
+ * - **Surface**: {@link RealtimeWhiteboardHostComponent}, created dynamically by the
29
+ * overlay's channel tab; the host's Focus toggle rides `Context.SetFocusMode` so the
30
+ * shell can collapse/restore the main call column.
31
+ * - **State of record**: every board mutation (user edits AND agent tool calls) requests
32
+ * a save of {@link WhiteboardState.ToJSON} under channel name `'Whiteboard'` — the
33
+ * host debounces and flushes at teardown.
34
+ *
35
+ * A PRIOR session's persisted board is restored through {@link RestoreState} (invoked by
36
+ * the session host after Initialize, before any surface binding): the saved JSON is
37
+ * rehydrated IN PLACE into the same {@link WhiteboardState} instance, so the save
38
+ * subscription and any later surface binding keep pointing at one engine. Malformed or
39
+ * incompatible payloads are tolerated — the board simply starts fresh.
40
+ */
41
+ export declare class RealtimeWhiteboardChannel extends BaseRealtimeChannelClient<RealtimeWhiteboardHostComponent> {
42
+ /** The board's state of record — created fresh with the plugin (one per session). */
43
+ readonly State: WhiteboardState;
44
+ /** The live bound surface, when the channel tab's pane is instantiated. */
45
+ private host;
46
+ /** Output subscriptions on the bound surface (SceneDelta / AgentUndo / FocusModeChange). */
47
+ private surfaceSubs;
48
+ /** Board-mutation subscription driving the debounced state-of-record save. */
49
+ private stateChangedSub;
50
+ /** Per-widget ambient-interaction note throttles (ItemID → window state). */
51
+ private interactionThrottles;
52
+ get ChannelName(): string;
53
+ get ToolNamePrefix(): string;
54
+ get TabTitle(): string;
55
+ get TabIcon(): string;
56
+ GetToolDefinitions(): RealtimeToolDefinition[];
57
+ GetSurfaceComponent(): Type<RealtimeWhiteboardHostComponent>;
58
+ /** First-run intro shown the first time the user opens the Whiteboard tab (once per user). */
59
+ GetOnboardingDetails(): ChannelOnboardingDetails;
60
+ /** Persist the board (host-debounced) on EVERY board mutation — user edits AND agent tools. */
61
+ protected OnInitialize(): void;
62
+ /**
63
+ * Wires the dynamically-created board host: inputs (shared state engine + agent name)
64
+ * are set BEFORE the component's first change detection, and the perception/garnish
65
+ * outputs are subscribed back into the host context — the overlay never sees any of it.
66
+ */
67
+ BindSurface(instance: RealtimeWhiteboardHostComponent): void;
68
+ UnbindSurface(): void;
69
+ /**
70
+ * Routes one ambient widget-interaction batch to the agent as a throttled background
71
+ * context note: outside an open window the note goes out immediately and opens a
72
+ * {@link WHITEBOARD_INTERACTION_NOTE_THROTTLE_MS} window; within the window the LATEST
73
+ * event is stashed and a trailing-edge timer sends it when the window closes (one note
74
+ * per widget per window, latest summary wins).
75
+ */
76
+ private onWidgetInteraction;
77
+ /** The ambient-note framing: background etiquette rides in the note itself (like scene deltas). */
78
+ private sendInteractionNote;
79
+ /** Cancels all pending ambient-note timers and resets the per-widget throttle windows. */
80
+ private clearInteractionThrottles;
81
+ /**
82
+ * Persists the current board as a `MJ: Artifacts` snapshot via the host context
83
+ * (best-effort; the host logs failures). On success the agent is told via a context
84
+ * note so it can reference the saved artifact naturally.
85
+ */
86
+ private saveBoardAsArtifact;
87
+ /**
88
+ * Executes one `Whiteboard_*` tool call LOCALLY. Prefers the live bound host (board
89
+ * mutation + UI garnish); falls back to the pure engine function when no surface is
90
+ * bound so the channel keeps working with the pane collapsed.
91
+ */
92
+ ApplyAgentTool(toolName: string, argsJson: string): string;
93
+ /** The board's serialized state of record (persisted under {@link ChannelName}). */
94
+ SerializeState(): string | null;
95
+ /**
96
+ * Rehydrates a prior session's saved board into THIS session's state engine (in place —
97
+ * the {@link State} instance and its subscriptions are preserved). Returns `true` on
98
+ * success; malformed / incompatible JSON returns `false` and the board stays fresh
99
+ * (never throws — {@link WhiteboardState.LoadFromJSON} is tolerant by contract).
100
+ */
101
+ RestoreState(stateJson: string): boolean;
102
+ /**
103
+ * Exit focus mode THROUGH the bound host (its own Focus button state stays in sync; it
104
+ * re-emits `FocusModeChange(false)` → `Context.SetFocusMode(false)`). When no surface is
105
+ * bound the overlay's defensive flag clear covers it.
106
+ */
107
+ RequestFocusExit(): void;
108
+ Dispose(): void;
109
+ /** Unsubscribes surface outputs, cancels pending ambient notes and drops the host reference. */
110
+ private releaseSurface;
111
+ }
112
+ /**
113
+ * Tree-shaking prevention: the whiteboard channel is resolved dynamically through the
114
+ * ClassFactory (by the registry row's `ClientPluginClass` key), so this static call is
115
+ * what keeps its `@RegisterClass` side effect from being eliminated by the bundler.
116
+ * Called by `RealtimeSessionService` alongside the realtime-client driver Load calls.
117
+ */
118
+ export declare function LoadRealtimeWhiteboardChannel(): void;
119
+ //# sourceMappingURL=whiteboard-channel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"whiteboard-channel.d.ts","sourceRoot":"","sources":["../../../../../src/lib/components/realtime/whiteboard/whiteboard-channel.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAG1C,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,yBAAyB,EAAE,wBAAwB,EAAE,MAAM,0CAA0C,CAAC;AAC/G,OAAO,EACqB,+BAA+B,EACjC,eAAe,EACxC,MAAM,+BAA+B,CAAC;AAEvC;;;;GAIG;AACH,eAAO,MAAM,uCAAuC,OAAO,CAAC;AAY5D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,qBACa,yBAA0B,SAAQ,yBAAyB,CAAC,+BAA+B,CAAC;IACvG,qFAAqF;IACrF,SAAgB,KAAK,kBAAyB;IAE9C,2EAA2E;IAC3E,OAAO,CAAC,IAAI,CAAgD;IAC5D,4FAA4F;IAC5F,OAAO,CAAC,WAAW,CAAsB;IACzC,8EAA8E;IAC9E,OAAO,CAAC,eAAe,CAA6B;IACpD,6EAA6E;IAC7E,OAAO,CAAC,oBAAoB,CAA+C;IAE3E,IAAW,WAAW,IAAI,MAAM,CAE/B;IAED,IAAW,cAAc,IAAI,MAAM,CAElC;IAED,IAAW,QAAQ,IAAI,MAAM,CAE5B;IAED,IAAW,OAAO,IAAI,MAAM,CAE3B;IAEM,kBAAkB,IAAI,sBAAsB,EAAE;IAIrC,mBAAmB,IAAI,IAAI,CAAC,+BAA+B,CAAC;IAI5E,8FAA8F;IAC9E,oBAAoB,IAAI,wBAAwB;IAehE,+FAA+F;cAC5E,YAAY,IAAI,IAAI;IAMvC;;;;OAIG;IACI,WAAW,CAAC,QAAQ,EAAE,+BAA+B,GAAG,IAAI;IAqDnD,aAAa,IAAI,IAAI;IAIrC;;;;;;OAMG;IACH,OAAO,CAAC,mBAAmB;IAuB3B,mGAAmG;IACnG,OAAO,CAAC,mBAAmB;IAO3B,0FAA0F;IAC1F,OAAO,CAAC,yBAAyB;IASjC;;;;OAIG;YACW,mBAAmB;IAajC;;;;OAIG;IACI,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM;IAOjE,oFAAoF;IACpE,cAAc,IAAI,MAAM,GAAG,IAAI;IAI/C;;;;;OAKG;IACa,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;IAIxD;;;;OAIG;IACa,gBAAgB,IAAI,IAAI;IAMxB,OAAO,IAAI,IAAI;IAM/B,gGAAgG;IAChG,OAAO,CAAC,cAAc;CAQvB;AAED;;;;;GAKG;AACH,wBAAgB,6BAA6B,IAAI,IAAI,CAEpD"}
@@ -0,0 +1,274 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
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
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ import { RegisterClass } from '@memberjunction/global';
8
+ import { BaseRealtimeChannelClient } from '../channels/base-realtime-channel-client';
9
+ import { ApplyWhiteboardAgentTool, RealtimeWhiteboardHostComponent, WHITEBOARD_TOOL_DEFINITIONS, WHITEBOARD_TOOL_PREFIX, WhiteboardState } from '@memberjunction/ng-whiteboard';
10
+ /**
11
+ * Per-widget throttle window for AMBIENT interaction context notes: at most one note per
12
+ * widget per this many ms — within the window the LATEST summary wins (chatty widgets
13
+ * collapse to one trailing-edge note instead of flooding the model's context).
14
+ */
15
+ export const WHITEBOARD_INTERACTION_NOTE_THROTTLE_MS = 4000;
16
+ /**
17
+ * The LIVE WHITEBOARD as a pluggable interactive channel — the canonical
18
+ * {@link BaseRealtimeChannelClient} implementation, resolved from the `MJ: AI Agent
19
+ * Channels` registry row whose `ClientPluginClass` is `'RealtimeWhiteboardChannel'`.
20
+ *
21
+ * One instance per session (created via ClassFactory at session start). It owns the
22
+ * board's {@link WhiteboardState} engine and contributes the channel's full contract:
23
+ *
24
+ * - **Action**: the `Whiteboard_*` client-executed tool set
25
+ * ({@link WHITEBOARD_TOOL_DEFINITIONS}); {@link ApplyAgentTool} prefers the BOUND host
26
+ * component (board mutation + violet pop-in / toast / presence-cursor garnish) and
27
+ * falls back to the pure {@link ApplyWhiteboardAgentTool} engine call when no surface
28
+ * is bound (e.g. the surface panel is collapsed) — the channel keeps working, just
29
+ * without the garnish.
30
+ * - **Perception**: {@link BindSurface} subscribes the host's coalesced (750 ms)
31
+ * `SceneDelta` stream and pipes each delta into the live model's context as a
32
+ * `[whiteboard]` background note; the agent-undo toast click flows the same way.
33
+ * - **Surface**: {@link RealtimeWhiteboardHostComponent}, created dynamically by the
34
+ * overlay's channel tab; the host's Focus toggle rides `Context.SetFocusMode` so the
35
+ * shell can collapse/restore the main call column.
36
+ * - **State of record**: every board mutation (user edits AND agent tool calls) requests
37
+ * a save of {@link WhiteboardState.ToJSON} under channel name `'Whiteboard'` — the
38
+ * host debounces and flushes at teardown.
39
+ *
40
+ * A PRIOR session's persisted board is restored through {@link RestoreState} (invoked by
41
+ * the session host after Initialize, before any surface binding): the saved JSON is
42
+ * rehydrated IN PLACE into the same {@link WhiteboardState} instance, so the save
43
+ * subscription and any later surface binding keep pointing at one engine. Malformed or
44
+ * incompatible payloads are tolerated — the board simply starts fresh.
45
+ */
46
+ let RealtimeWhiteboardChannel = class RealtimeWhiteboardChannel extends BaseRealtimeChannelClient {
47
+ /** The board's state of record — created fresh with the plugin (one per session). */
48
+ State = new WhiteboardState();
49
+ /** The live bound surface, when the channel tab's pane is instantiated. */
50
+ host = null;
51
+ /** Output subscriptions on the bound surface (SceneDelta / AgentUndo / FocusModeChange). */
52
+ surfaceSubs = [];
53
+ /** Board-mutation subscription driving the debounced state-of-record save. */
54
+ stateChangedSub = null;
55
+ /** Per-widget ambient-interaction note throttles (ItemID → window state). */
56
+ interactionThrottles = new Map();
57
+ get ChannelName() {
58
+ return 'Whiteboard';
59
+ }
60
+ get ToolNamePrefix() {
61
+ return WHITEBOARD_TOOL_PREFIX;
62
+ }
63
+ get TabTitle() {
64
+ return 'Whiteboard';
65
+ }
66
+ get TabIcon() {
67
+ return 'fa-solid fa-chalkboard';
68
+ }
69
+ GetToolDefinitions() {
70
+ return WHITEBOARD_TOOL_DEFINITIONS;
71
+ }
72
+ GetSurfaceComponent() {
73
+ return RealtimeWhiteboardHostComponent;
74
+ }
75
+ /** First-run intro shown the first time the user opens the Whiteboard tab (once per user). */
76
+ GetOnboardingDetails() {
77
+ return {
78
+ Heading: 'Whiteboard',
79
+ Description: 'A shared canvas the agent can sketch, write and annotate on live during the call — ' +
80
+ 'whatever it draws appears here instantly, and anything you add is something it can see too.',
81
+ Tips: [
82
+ 'Watch the board fill in as you talk — the agent updates it in real time.',
83
+ 'Add your own notes or shapes; the agent perceives your edits and can build on them.',
84
+ 'Use Focus to give the board the whole screen, and save it to artifacts to keep it.'
85
+ ],
86
+ IconClass: 'fa-solid fa-chalkboard'
87
+ };
88
+ }
89
+ /** Persist the board (host-debounced) on EVERY board mutation — user edits AND agent tools. */
90
+ OnInitialize() {
91
+ this.stateChangedSub = this.State.Changed$.subscribe(() => {
92
+ this.Context?.RequestSave(this.State.ToJSON());
93
+ });
94
+ }
95
+ /**
96
+ * Wires the dynamically-created board host: inputs (shared state engine + agent name)
97
+ * are set BEFORE the component's first change detection, and the perception/garnish
98
+ * outputs are subscribed back into the host context — the overlay never sees any of it.
99
+ */
100
+ BindSurface(instance) {
101
+ this.releaseSurface();
102
+ this.host = instance;
103
+ instance.State = this.State;
104
+ instance.AgentName = this.Context?.AgentName ?? 'Agent';
105
+ this.surfaceSubs.push(
106
+ // The board's coalesced scene delta — the perception feed the agent "sees".
107
+ instance.SceneDelta.subscribe((deltaJson) => {
108
+ // Background PERCEPTION, not conversation: the model sees every user edit without
109
+ // being told, but must not narrate minor changes — only react when something is
110
+ // significant (or when asked). The etiquette rides in the note itself so any
111
+ // realtime model gets it regardless of system-prompt sync state.
112
+ this.Context?.SendContextNote('[whiteboard] board update (background context — do NOT comment on minor edits; ' +
113
+ 'only mention it if the change is significant to the discussion): ' + deltaJson);
114
+ }),
115
+ // The user clicked Undo on the agent-action toast (the undo already applied locally).
116
+ instance.AgentUndo.subscribe(() => {
117
+ this.Context?.SendContextNote('[whiteboard] user undid your last change');
118
+ }),
119
+ // A sandboxed HTML widget submitted user input (MJWhiteboard.submit) — already
120
+ // validated, size-capped and not canceled (the host's cancelable WidgetSubmitting
121
+ // event ran first). Surface it to the agent so it can react to quiz answers /
122
+ // micro-form input it asked for.
123
+ instance.WidgetSubmitted.subscribe((submit) => {
124
+ // Durable awareness first (the note persists in the model's context)…
125
+ this.Context?.SendContextNote(`[whiteboard] the user submitted input in widget "${submit.Title || submit.ItemID}": ${submit.DataJson}`);
126
+ // …then make the model REACT — a submission is explicit user input the user is
127
+ // waiting on; without this trigger, SendContextNote alone produces dead silence
128
+ // ("I clicked Submit and nothing happened").
129
+ this.Context?.RequestSpokenResponse?.(`The user just submitted input in the whiteboard widget "${submit.Title || submit.ItemID}": ${submit.DataJson}. ` +
130
+ `React to it now in your own voice — acknowledge their choice and continue naturally.`);
131
+ }),
132
+ // AMBIENT widget telemetry (the injected recorder, NOT widget-authored script):
133
+ // clicks / changes / typing summarized by the board. Pure background perception —
134
+ // throttled per widget so chatty widgets don't flood the model's context, and framed
135
+ // with do-not-respond etiquette (explicit MJWhiteboard.submit input arrives above).
136
+ instance.WidgetInteraction.subscribe((interaction) => {
137
+ this.onWidgetInteraction(interaction);
138
+ }),
139
+ // The board's Focus toggle — ask the shell to collapse/restore the main call column.
140
+ instance.FocusModeChange.subscribe((focused) => {
141
+ this.Context?.SetFocusMode(focused);
142
+ }),
143
+ // "Save to artifacts": snapshot the board as a first-class versioned artifact.
144
+ instance.SaveToArtifactsRequested.subscribe(() => {
145
+ void this.saveBoardAsArtifact();
146
+ }));
147
+ }
148
+ UnbindSurface() {
149
+ this.releaseSurface();
150
+ }
151
+ /**
152
+ * Routes one ambient widget-interaction batch to the agent as a throttled background
153
+ * context note: outside an open window the note goes out immediately and opens a
154
+ * {@link WHITEBOARD_INTERACTION_NOTE_THROTTLE_MS} window; within the window the LATEST
155
+ * event is stashed and a trailing-edge timer sends it when the window closes (one note
156
+ * per widget per window, latest summary wins).
157
+ */
158
+ onWidgetInteraction(interaction) {
159
+ const now = Date.now();
160
+ const entry = this.interactionThrottles.get(interaction.ItemID);
161
+ if (!entry || (entry.Timer === null && now - entry.LastSentAt >= WHITEBOARD_INTERACTION_NOTE_THROTTLE_MS)) {
162
+ this.sendInteractionNote(interaction);
163
+ this.interactionThrottles.set(interaction.ItemID, { LastSentAt: now, Timer: null, Pending: null });
164
+ return;
165
+ }
166
+ entry.Pending = interaction; // latest wins within the window
167
+ if (entry.Timer === null) {
168
+ const wait = Math.max(0, entry.LastSentAt + WHITEBOARD_INTERACTION_NOTE_THROTTLE_MS - now);
169
+ entry.Timer = setTimeout(() => {
170
+ entry.Timer = null;
171
+ const pending = entry.Pending;
172
+ entry.Pending = null;
173
+ if (pending) {
174
+ entry.LastSentAt = Date.now();
175
+ this.sendInteractionNote(pending);
176
+ }
177
+ }, wait);
178
+ }
179
+ }
180
+ /** The ambient-note framing: background etiquette rides in the note itself (like scene deltas). */
181
+ sendInteractionNote(interaction) {
182
+ this.Context?.SendContextNote(`[whiteboard] ambient activity in widget "${interaction.Title || interaction.ItemID}" ` +
183
+ '(background — do NOT respond unless it is significant or you are asked; ' +
184
+ `explicit submissions arrive separately): ${interaction.Summary}`);
185
+ }
186
+ /** Cancels all pending ambient-note timers and resets the per-widget throttle windows. */
187
+ clearInteractionThrottles() {
188
+ for (const entry of this.interactionThrottles.values()) {
189
+ if (entry.Timer !== null) {
190
+ clearTimeout(entry.Timer);
191
+ }
192
+ }
193
+ this.interactionThrottles.clear();
194
+ }
195
+ /**
196
+ * Persists the current board as a `MJ: Artifacts` snapshot via the host context
197
+ * (best-effort; the host logs failures). On success the agent is told via a context
198
+ * note so it can reference the saved artifact naturally.
199
+ */
200
+ async saveBoardAsArtifact() {
201
+ const ctx = this.Context;
202
+ if (!ctx) {
203
+ return;
204
+ }
205
+ const now = new Date();
206
+ const name = `Whiteboard — ${now.toLocaleDateString()} ${now.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}`;
207
+ const artifactId = await ctx.SaveAsArtifact(name, this.State.ToJSON());
208
+ if (artifactId) {
209
+ ctx.SendContextNote(`[whiteboard] the user saved the current board as the artifact "${name}"`);
210
+ }
211
+ }
212
+ /**
213
+ * Executes one `Whiteboard_*` tool call LOCALLY. Prefers the live bound host (board
214
+ * mutation + UI garnish); falls back to the pure engine function when no surface is
215
+ * bound so the channel keeps working with the pane collapsed.
216
+ */
217
+ ApplyAgentTool(toolName, argsJson) {
218
+ if (this.host) {
219
+ return this.host.ApplyAgentTool(toolName, argsJson);
220
+ }
221
+ return ApplyWhiteboardAgentTool(this.State, toolName, argsJson);
222
+ }
223
+ /** The board's serialized state of record (persisted under {@link ChannelName}). */
224
+ SerializeState() {
225
+ return this.State.ToJSON();
226
+ }
227
+ /**
228
+ * Rehydrates a prior session's saved board into THIS session's state engine (in place —
229
+ * the {@link State} instance and its subscriptions are preserved). Returns `true` on
230
+ * success; malformed / incompatible JSON returns `false` and the board stays fresh
231
+ * (never throws — {@link WhiteboardState.LoadFromJSON} is tolerant by contract).
232
+ */
233
+ RestoreState(stateJson) {
234
+ return this.State.LoadFromJSON(stateJson);
235
+ }
236
+ /**
237
+ * Exit focus mode THROUGH the bound host (its own Focus button state stays in sync; it
238
+ * re-emits `FocusModeChange(false)` → `Context.SetFocusMode(false)`). When no surface is
239
+ * bound the overlay's defensive flag clear covers it.
240
+ */
241
+ RequestFocusExit() {
242
+ if (this.host?.FocusMode) {
243
+ this.host.ToggleFocus();
244
+ }
245
+ }
246
+ Dispose() {
247
+ this.stateChangedSub?.unsubscribe();
248
+ this.stateChangedSub = null;
249
+ super.Dispose(); // releases the surface binding + context
250
+ }
251
+ /** Unsubscribes surface outputs, cancels pending ambient notes and drops the host reference. */
252
+ releaseSurface() {
253
+ for (const sub of this.surfaceSubs) {
254
+ sub.unsubscribe();
255
+ }
256
+ this.surfaceSubs = [];
257
+ this.clearInteractionThrottles();
258
+ this.host = null;
259
+ }
260
+ };
261
+ RealtimeWhiteboardChannel = __decorate([
262
+ RegisterClass(BaseRealtimeChannelClient, 'RealtimeWhiteboardChannel')
263
+ ], RealtimeWhiteboardChannel);
264
+ export { RealtimeWhiteboardChannel };
265
+ /**
266
+ * Tree-shaking prevention: the whiteboard channel is resolved dynamically through the
267
+ * ClassFactory (by the registry row's `ClientPluginClass` key), so this static call is
268
+ * what keeps its `@RegisterClass` side effect from being eliminated by the bundler.
269
+ * Called by `RealtimeSessionService` alongside the realtime-client driver Load calls.
270
+ */
271
+ export function LoadRealtimeWhiteboardChannel() {
272
+ // intentional no-op — the import side effect performs the registration
273
+ }
274
+ //# sourceMappingURL=whiteboard-channel.js.map