@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 @@
1
+ {"version":3,"file":"realtime-session-channels.test.js","sourceRoot":"","sources":["../../src/__tests__/realtime-session-channels.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { describe, it, expect, beforeEach, afterEach, vi, type MockInstance } from 'vitest';\nimport { AIEngineBase } from '@memberjunction/ai-engine-base';\nimport { RegisterClass } from '@memberjunction/global';\nimport { RealtimeToolDefinition } from '@memberjunction/ai';\nimport { RealtimeSessionService, RealtimeChannelFocusEvent } from '../lib/services/realtime-session.service';\nimport { BaseRealtimeChannelClient, RealtimeChannelContext } from '../lib/components/realtime/channels/base-realtime-channel-client';\n\n/**\n * INTERACTIVE-CHANNEL plumbing in the session service — the registry-driven plugin path:\n * `MJ: AI Agent Channels` rows → ClassFactory resolution by ClientPluginClass → per-session\n * plugin instances → tool aggregation + prefix-handler registration → debounced channel\n * saves → teardown flush + dispose. The service is channel-agnostic throughout; these tests\n * drive it with a FAKE channel plugin registered the same way real ones are.\n */\n\n/** The private surface the tests drive — no `any`, just the members under test. */\ninterface RealtimeSessionChannelInternals {\n client: FakeRealtimeClient | null;\n agentSessionId: string | null;\n startChannels(): Promise<RealtimeToolDefinition[]>;\n handleToolCall(call: { CallID: string; ToolName: string; ArgumentsJson: string }): Promise<void>;\n teardown(closeServerSession: boolean): Promise<void>;\n}\n\nclass FakeRealtimeClient {\n public ToolResults: Array<{ CallID: string; ResultJson: string }> = [];\n public SendToolResult(callId: string, resultJson: string): void {\n this.ToolResults.push({ CallID: callId, ResultJson: resultJson });\n }\n public SendContextNote(_text: string): void {\n // not under test here\n }\n public async Disconnect(): Promise<void> {\n // no-op for teardown\n }\n}\n\nfunction internals(service: RealtimeSessionService): RealtimeSessionChannelInternals {\n return service as unknown as RealtimeSessionChannelInternals;\n}\n\n/** A minimal surface stand-in (never instantiated by these node tests). */\nclass FakeSurface {}\n\n/**\n * A fake interactive-channel plugin, registered exactly like production plugins\n * (`@RegisterClass(BaseRealtimeChannelClient, '<ClientPluginClass>')`).\n */\n@RegisterClass(BaseRealtimeChannelClient, 'TestEchoChannel')\nclass TestEchoChannel extends BaseRealtimeChannelClient<FakeSurface> {\n public AppliedCalls: Array<{ ToolName: string; ArgsJson: string }> = [];\n public Disposed = false;\n public BoundSurface: FakeSurface | null = null;\n\n public get ChannelName(): string {\n return 'Echo';\n }\n public get ToolNamePrefix(): string {\n return 'Echo.';\n }\n public get TabTitle(): string {\n return 'Echo';\n }\n public get TabIcon(): string {\n return 'fa-solid fa-microphone';\n }\n public GetToolDefinitions(): RealtimeToolDefinition[] {\n return [\n { Name: 'Echo.Say', Description: 'Echo a phrase', ParametersSchema: { type: 'object' } },\n { Name: 'Echo.Clear', Description: 'Clear echoes', ParametersSchema: { type: 'object' } }\n ];\n }\n public GetSurfaceComponent(): import('@angular/core').Type<FakeSurface> {\n return FakeSurface;\n }\n public BindSurface(instance: FakeSurface): void {\n this.BoundSurface = instance;\n }\n public ApplyAgentTool(toolName: string, argsJson: string): string {\n this.AppliedCalls.push({ ToolName: toolName, ArgsJson: argsJson });\n return JSON.stringify({ success: true, echoed: toolName });\n }\n public override Dispose(): void {\n this.Disposed = true;\n super.Dispose();\n }\n\n /** Test seam: expose the host context the service handed us. */\n public get Ctx(): RealtimeChannelContext | null {\n return this.Context;\n }\n}\n\n/**\n * Stubs the provider-scoped AIEngineBase whose cached `AgentChannels` the service reads\n * (rows default to ACTIVE; pass `IsActive: false` to exercise the active-only filter).\n * `success = false` makes the engine load reject — the registry-failure degradation path.\n */\nfunction mockChannelRegistry(\n rows: Array<{ ID: string; Name: string; ClientPluginClass: string; IsActive?: boolean }>,\n success = true\n): ReturnType<typeof vi.fn> {\n const configFn = vi.fn(async () => {\n if (!success) {\n throw new Error('boom');\n }\n });\n const fakeEngine = {\n Config: configFn,\n get AgentChannels() {\n return rows.map(r => ({ IsActive: true, ...r }));\n }\n };\n vi.spyOn(AIEngineBase, 'GetProviderInstance').mockReturnValue(fakeEngine as unknown as AIEngineBase);\n return configFn;\n}\n\ndescribe('RealtimeSessionService — interactive-channel registry resolution', () => {\n let service: RealtimeSessionService;\n\n beforeEach(() => {\n service = new RealtimeSessionService();\n });\n\n afterEach(() => {\n vi.restoreAllMocks();\n });\n\n it('resolves ACTIVE registry rows into per-session plugin instances via the ClassFactory', async () => {\n const configFn = mockChannelRegistry([\n { ID: 'c1', Name: 'Echo', ClientPluginClass: 'TestEchoChannel' },\n // Inactive rows never become session plugins (parity with the old `IsActive = 1` filter).\n { ID: 'c2', Name: 'Dormant', ClientPluginClass: 'TestEchoChannel', IsActive: false }\n ]);\n\n await internals(service).startChannels();\n\n // Lazily configures the provider-scoped engine before reading the cached registry.\n expect(configFn).toHaveBeenCalledWith(false, undefined, service.Provider);\n expect(service.ActiveChannels).toHaveLength(1);\n expect(service.ActiveChannels[0]).toBeInstanceOf(TestEchoChannel);\n });\n\n it('creates a FRESH instance per session (plugins are not singletons)', async () => {\n mockChannelRegistry([{ ID: 'c1', Name: 'Echo', ClientPluginClass: 'TestEchoChannel' }]);\n await internals(service).startChannels();\n const first = service.ActiveChannels[0];\n\n await internals(service).startChannels();\n expect(service.ActiveChannels[0]).not.toBe(first);\n });\n\n it('skips rows whose ClientPluginClass has no registration (logged, never fatal)', async () => {\n const warn = vi.spyOn(console, 'warn').mockImplementation(() => undefined);\n mockChannelRegistry([\n { ID: 'c1', Name: 'Ghost', ClientPluginClass: 'NoSuchChannelPlugin' },\n { ID: 'c2', Name: 'Echo', ClientPluginClass: 'TestEchoChannel' }\n ]);\n\n await internals(service).startChannels();\n\n expect(service.ActiveChannels).toHaveLength(1);\n expect(service.ActiveChannels[0]).toBeInstanceOf(TestEchoChannel);\n expect(warn).toHaveBeenCalledWith(expect.stringContaining(\"No client plugin registered for channel 'Ghost'\"));\n });\n\n it('degrades to NO channels when the registry load fails (the voice session must proceed)', async () => {\n vi.spyOn(console, 'warn').mockImplementation(() => undefined);\n mockChannelRegistry([], false);\n\n const tools = await internals(service).startChannels();\n\n expect(tools).toEqual([]);\n expect(service.ActiveChannels).toEqual([]);\n });\n\n it('degrades to NO channels when the engine acquisition throws', async () => {\n vi.spyOn(console, 'warn').mockImplementation(() => undefined);\n vi.spyOn(AIEngineBase, 'GetProviderInstance').mockImplementation(() => {\n throw new Error('no provider');\n });\n\n const tools = await internals(service).startChannels();\n\n expect(tools).toEqual([]);\n expect(service.ActiveChannels).toEqual([]);\n });\n\n it('aggregates every plugin tool definition into the clientTools set for the mint', async () => {\n mockChannelRegistry([{ ID: 'c1', Name: 'Echo', ClientPluginClass: 'TestEchoChannel' }]);\n\n const tools = await internals(service).startChannels();\n\n expect(tools.map(t => t.Name)).toEqual(['Echo.Say', 'Echo.Clear']);\n });\n\n it('emits the resolved plugins on ActiveChannels$ (the overlay registers tabs from it)', async () => {\n mockChannelRegistry([{ ID: 'c1', Name: 'Echo', ClientPluginClass: 'TestEchoChannel' }]);\n const emissions: number[] = [];\n const sub = service.ActiveChannels$.subscribe(channels => emissions.push(channels.length));\n\n await internals(service).startChannels();\n\n sub.unsubscribe();\n expect(emissions).toEqual([0, 1]); // BehaviorSubject replay, then the resolved set\n });\n});\n\ndescribe('RealtimeSessionService — per-plugin tool routing + host context', () => {\n let service: RealtimeSessionService;\n let fakeClient: FakeRealtimeClient;\n let plugin: TestEchoChannel;\n\n beforeEach(async () => {\n service = new RealtimeSessionService();\n fakeClient = new FakeRealtimeClient();\n internals(service).client = fakeClient;\n mockChannelRegistry([{ ID: 'c1', Name: 'Echo', ClientPluginClass: 'TestEchoChannel' }]);\n await internals(service).startChannels();\n plugin = service.ActiveChannels[0] as TestEchoChannel;\n });\n\n afterEach(() => {\n vi.restoreAllMocks();\n });\n\n it('routes prefix-matched tool calls to the plugin and feeds its result back to the model', async () => {\n await internals(service).handleToolCall({ CallID: 'call-1', ToolName: 'Echo.Say', ArgumentsJson: '{\"phrase\":\"hi\"}' });\n\n expect(plugin.AppliedCalls).toEqual([{ ToolName: 'Echo.Say', ArgsJson: '{\"phrase\":\"hi\"}' }]);\n expect(fakeClient.ToolResults).toEqual([\n { CallID: 'call-1', ResultJson: JSON.stringify({ success: true, echoed: 'Echo.Say' }) }\n ]);\n });\n\n it('hands each plugin a context whose AgentName matches the session agent', () => {\n expect(plugin.Ctx?.AgentName).toBe(service.CurrentAgentName);\n });\n\n it('SetFocusMode rides ChannelFocus$ tagged with the requesting plugin', () => {\n const events: RealtimeChannelFocusEvent[] = [];\n const sub = service.ChannelFocus$.subscribe(e => events.push(e));\n\n plugin.Ctx?.SetFocusMode(true);\n plugin.Ctx?.SetFocusMode(false);\n\n sub.unsubscribe();\n expect(events).toEqual([\n { Channel: plugin, Focused: true },\n { Channel: plugin, Focused: false }\n ]);\n });\n});\n\ndescribe('RealtimeSessionService — debounced channel saves + teardown flush/dispose', () => {\n let service: RealtimeSessionService;\n let plugin: TestEchoChannel;\n let saveSpy: MockInstance<RealtimeSessionService['SaveChannelState']>;\n\n beforeEach(async () => {\n vi.useFakeTimers();\n service = new RealtimeSessionService();\n internals(service).agentSessionId = 'session-123';\n saveSpy = vi.spyOn(service, 'SaveChannelState').mockResolvedValue(true);\n mockChannelRegistry([{ ID: 'c1', Name: 'Echo', ClientPluginClass: 'TestEchoChannel' }]);\n await internals(service).startChannels();\n plugin = service.ActiveChannels[0] as TestEchoChannel;\n });\n\n afterEach(() => {\n vi.useRealTimers();\n vi.restoreAllMocks();\n });\n\n it('debounces RequestSave: a change burst becomes ONE save with the LATEST state', () => {\n plugin.Ctx?.RequestSave('{\"v\":1}');\n plugin.Ctx?.RequestSave('{\"v\":2}');\n plugin.Ctx?.RequestSave('{\"v\":3}');\n expect(saveSpy).not.toHaveBeenCalled();\n\n vi.advanceTimersByTime(3000);\n\n expect(saveSpy).toHaveBeenCalledTimes(1);\n expect(saveSpy).toHaveBeenCalledWith('Echo', '{\"v\":3}', 'session-123');\n });\n\n it('teardown FLUSHES a pending save immediately (captured session id) and disposes plugins', async () => {\n plugin.Ctx?.RequestSave('{\"final\":true}');\n\n await internals(service).teardown(false);\n\n expect(saveSpy).toHaveBeenCalledTimes(1);\n expect(saveSpy).toHaveBeenCalledWith('Echo', '{\"final\":true}', 'session-123');\n expect(plugin.Disposed).toBe(true);\n expect(service.ActiveChannels).toEqual([]);\n });\n\n it('teardown with nothing pending saves nothing but still disposes', async () => {\n await internals(service).teardown(false);\n\n expect(saveSpy).not.toHaveBeenCalled();\n expect(plugin.Disposed).toBe(true);\n });\n\n it('a Dispose error in one plugin is contained (teardown completes)', async () => {\n const error = vi.spyOn(console, 'error').mockImplementation(() => undefined);\n vi.spyOn(plugin, 'Dispose').mockImplementation(() => {\n throw new Error('plugin exploded');\n });\n\n await internals(service).teardown(false);\n\n expect(service.ActiveChannels).toEqual([]);\n expect(error).toHaveBeenCalledWith(expect.stringContaining(\"Channel 'Echo' Dispose failed\"), expect.any(Error));\n });\n});\n"]}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=realtime-session-client-tools.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"realtime-session-client-tools.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/realtime-session-client-tools.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,103 @@
1
+ import { describe, it, expect, beforeEach, vi } from 'vitest';
2
+ import { RealtimeSessionService } from '../lib/services/realtime-session.service';
3
+ class FakeRealtimeClient {
4
+ ToolResults = [];
5
+ ContextNotes = [];
6
+ SendToolResult(callId, resultJson) {
7
+ this.ToolResults.push({ CallID: callId, ResultJson: resultJson });
8
+ }
9
+ SendContextNote(text) {
10
+ this.ContextNotes.push(text);
11
+ }
12
+ }
13
+ function internals(service) {
14
+ return service;
15
+ }
16
+ describe('RealtimeSessionService — client-executed UI tool routing', () => {
17
+ let service;
18
+ let fakeClient;
19
+ beforeEach(() => {
20
+ service = new RealtimeSessionService();
21
+ fakeClient = new FakeRealtimeClient();
22
+ internals(service).client = fakeClient;
23
+ });
24
+ it('routes a prefix-matched tool call to the LOCAL handler and feeds its result back', async () => {
25
+ const handler = vi.fn((toolName, argsJson) => JSON.stringify({ success: true, summary: `${toolName}:${argsJson}` }));
26
+ service.RegisterClientToolHandler('Whiteboard_', handler);
27
+ await internals(service).handleToolCall({
28
+ CallID: 'call-1',
29
+ ToolName: 'Whiteboard_AddNote',
30
+ ArgumentsJson: '{"text":"hi"}'
31
+ });
32
+ expect(handler).toHaveBeenCalledWith('Whiteboard_AddNote', '{"text":"hi"}');
33
+ expect(fakeClient.ToolResults).toEqual([
34
+ { CallID: 'call-1', ResultJson: JSON.stringify({ success: true, summary: 'Whiteboard_AddNote:{"text":"hi"}' }) }
35
+ ]);
36
+ });
37
+ it('supports async handlers', async () => {
38
+ service.RegisterClientToolHandler('Whiteboard_', async () => '{"success":true}');
39
+ await internals(service).handleToolCall({ CallID: 'call-2', ToolName: 'Whiteboard_MoveItem', ArgumentsJson: '{}' });
40
+ expect(fakeClient.ToolResults).toEqual([{ CallID: 'call-2', ResultJson: '{"success":true}' }]);
41
+ });
42
+ it('wraps a thrown handler error as { success:false, error } so the model can narrate it', async () => {
43
+ service.RegisterClientToolHandler('Whiteboard_', () => {
44
+ throw new Error('board offline');
45
+ });
46
+ await internals(service).handleToolCall({ CallID: 'call-3', ToolName: 'Whiteboard_AddShape', ArgumentsJson: '{}' });
47
+ expect(fakeClient.ToolResults).toHaveLength(1);
48
+ expect(JSON.parse(fakeClient.ToolResults[0].ResultJson)).toEqual({ success: false, error: 'board offline' });
49
+ });
50
+ it('does NOT capture non-matching tool names (they take the server-relay path)', async () => {
51
+ const handler = vi.fn(() => '{"success":true}');
52
+ service.RegisterClientToolHandler('Whiteboard_', handler);
53
+ // No agentSessionId is minted, so the server path fails fast — the point is the
54
+ // local handler is never consulted and the model still receives an error result.
55
+ await internals(service).handleToolCall({ CallID: 'call-4', ToolName: 'invoke-target-agent', ArgumentsJson: '{}' });
56
+ expect(handler).not.toHaveBeenCalled();
57
+ expect(fakeClient.ToolResults).toHaveLength(1);
58
+ expect(JSON.parse(fakeClient.ToolResults[0].ResultJson)).toMatchObject({
59
+ error: expect.stringContaining('No active agent session')
60
+ });
61
+ });
62
+ it('UnregisterClientToolHandler removes the route — later calls fall through to the server path', async () => {
63
+ const handler = vi.fn(() => '{"success":true}');
64
+ service.RegisterClientToolHandler('Whiteboard_', handler);
65
+ service.UnregisterClientToolHandler('Whiteboard_');
66
+ await internals(service).handleToolCall({ CallID: 'call-5', ToolName: 'Whiteboard_AddNote', ArgumentsJson: '{}' });
67
+ expect(handler).not.toHaveBeenCalled();
68
+ expect(JSON.parse(fakeClient.ToolResults[0].ResultJson)).toMatchObject({
69
+ error: expect.stringContaining('No active agent session')
70
+ });
71
+ });
72
+ it('re-registering the same prefix replaces the handler', async () => {
73
+ service.RegisterClientToolHandler('Whiteboard_', () => '{"v":1}');
74
+ service.RegisterClientToolHandler('Whiteboard_', () => '{"v":2}');
75
+ await internals(service).handleToolCall({ CallID: 'call-6', ToolName: 'Whiteboard_AddText', ArgumentsJson: '{}' });
76
+ expect(fakeClient.ToolResults).toEqual([{ CallID: 'call-6', ResultJson: '{"v":2}' }]);
77
+ });
78
+ });
79
+ describe('RealtimeSessionService — SendContextNote guard', () => {
80
+ it('is a no-op when no session is live (no client / closed state)', () => {
81
+ const service = new RealtimeSessionService();
82
+ const fakeClient = new FakeRealtimeClient();
83
+ internals(service).client = fakeClient;
84
+ // ConnectionState is 'closed' by default — the note must NOT reach the client.
85
+ service.SendContextNote('[whiteboard] {"added":[]}');
86
+ expect(fakeClient.ContextNotes).toEqual([]);
87
+ });
88
+ it('ignores empty / whitespace-only notes', () => {
89
+ const service = new RealtimeSessionService();
90
+ const fakeClient = new FakeRealtimeClient();
91
+ internals(service).client = fakeClient;
92
+ service.SendContextNote(' ');
93
+ expect(fakeClient.ContextNotes).toEqual([]);
94
+ });
95
+ });
96
+ describe('RealtimeSessionService — SaveChannelState guards', () => {
97
+ it('returns false when no session id is available (live or explicit)', async () => {
98
+ const service = new RealtimeSessionService();
99
+ const saved = await service.SaveChannelState('Whiteboard', '{"items":[]}');
100
+ expect(saved).toBe(false);
101
+ });
102
+ });
103
+ //# sourceMappingURL=realtime-session-client-tools.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"realtime-session-client-tools.test.js","sourceRoot":"","sources":["../../src/__tests__/realtime-session-client-tools.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { describe, it, expect, beforeEach, vi } from 'vitest';\nimport { RealtimeSessionService } from '../lib/services/realtime-session.service';\n\n/**\n * CLIENT-EXECUTED UI TOOL routing (the live whiteboard's `Whiteboard_*` path).\n *\n * The registry + routing live behind the service's private tool-call handler, so these tests\n * reach it through a narrow typed seam: a fake realtime client capturing `SendToolResult`, and\n * direct invocation of `handleToolCall` with a synthetic provider tool-call frame.\n */\n\n/** The private surface the tests drive — no `any`, just the members under test. */\ninterface RealtimeSessionInternals {\n client: FakeRealtimeClient | null;\n handleToolCall(call: { CallID: string; ToolName: string; ArgumentsJson: string }): Promise<void>;\n}\n\nclass FakeRealtimeClient {\n public ToolResults: Array<{ CallID: string; ResultJson: string }> = [];\n public ContextNotes: string[] = [];\n public SendToolResult(callId: string, resultJson: string): void {\n this.ToolResults.push({ CallID: callId, ResultJson: resultJson });\n }\n public SendContextNote(text: string): void {\n this.ContextNotes.push(text);\n }\n}\n\nfunction internals(service: RealtimeSessionService): RealtimeSessionInternals {\n return service as unknown as RealtimeSessionInternals;\n}\n\ndescribe('RealtimeSessionService — client-executed UI tool routing', () => {\n let service: RealtimeSessionService;\n let fakeClient: FakeRealtimeClient;\n\n beforeEach(() => {\n service = new RealtimeSessionService();\n fakeClient = new FakeRealtimeClient();\n internals(service).client = fakeClient;\n });\n\n it('routes a prefix-matched tool call to the LOCAL handler and feeds its result back', async () => {\n const handler = vi.fn((toolName: string, argsJson: string) =>\n JSON.stringify({ success: true, summary: `${toolName}:${argsJson}` })\n );\n service.RegisterClientToolHandler('Whiteboard_', handler);\n\n await internals(service).handleToolCall({\n CallID: 'call-1',\n ToolName: 'Whiteboard_AddNote',\n ArgumentsJson: '{\"text\":\"hi\"}'\n });\n\n expect(handler).toHaveBeenCalledWith('Whiteboard_AddNote', '{\"text\":\"hi\"}');\n expect(fakeClient.ToolResults).toEqual([\n { CallID: 'call-1', ResultJson: JSON.stringify({ success: true, summary: 'Whiteboard_AddNote:{\"text\":\"hi\"}' }) }\n ]);\n });\n\n it('supports async handlers', async () => {\n service.RegisterClientToolHandler('Whiteboard_', async () => '{\"success\":true}');\n\n await internals(service).handleToolCall({ CallID: 'call-2', ToolName: 'Whiteboard_MoveItem', ArgumentsJson: '{}' });\n\n expect(fakeClient.ToolResults).toEqual([{ CallID: 'call-2', ResultJson: '{\"success\":true}' }]);\n });\n\n it('wraps a thrown handler error as { success:false, error } so the model can narrate it', async () => {\n service.RegisterClientToolHandler('Whiteboard_', () => {\n throw new Error('board offline');\n });\n\n await internals(service).handleToolCall({ CallID: 'call-3', ToolName: 'Whiteboard_AddShape', ArgumentsJson: '{}' });\n\n expect(fakeClient.ToolResults).toHaveLength(1);\n expect(JSON.parse(fakeClient.ToolResults[0].ResultJson)).toEqual({ success: false, error: 'board offline' });\n });\n\n it('does NOT capture non-matching tool names (they take the server-relay path)', async () => {\n const handler = vi.fn(() => '{\"success\":true}');\n service.RegisterClientToolHandler('Whiteboard_', handler);\n\n // No agentSessionId is minted, so the server path fails fast — the point is the\n // local handler is never consulted and the model still receives an error result.\n await internals(service).handleToolCall({ CallID: 'call-4', ToolName: 'invoke-target-agent', ArgumentsJson: '{}' });\n\n expect(handler).not.toHaveBeenCalled();\n expect(fakeClient.ToolResults).toHaveLength(1);\n expect(JSON.parse(fakeClient.ToolResults[0].ResultJson)).toMatchObject({\n error: expect.stringContaining('No active agent session')\n });\n });\n\n it('UnregisterClientToolHandler removes the route — later calls fall through to the server path', async () => {\n const handler = vi.fn(() => '{\"success\":true}');\n service.RegisterClientToolHandler('Whiteboard_', handler);\n service.UnregisterClientToolHandler('Whiteboard_');\n\n await internals(service).handleToolCall({ CallID: 'call-5', ToolName: 'Whiteboard_AddNote', ArgumentsJson: '{}' });\n\n expect(handler).not.toHaveBeenCalled();\n expect(JSON.parse(fakeClient.ToolResults[0].ResultJson)).toMatchObject({\n error: expect.stringContaining('No active agent session')\n });\n });\n\n it('re-registering the same prefix replaces the handler', async () => {\n service.RegisterClientToolHandler('Whiteboard_', () => '{\"v\":1}');\n service.RegisterClientToolHandler('Whiteboard_', () => '{\"v\":2}');\n\n await internals(service).handleToolCall({ CallID: 'call-6', ToolName: 'Whiteboard_AddText', ArgumentsJson: '{}' });\n\n expect(fakeClient.ToolResults).toEqual([{ CallID: 'call-6', ResultJson: '{\"v\":2}' }]);\n });\n});\n\ndescribe('RealtimeSessionService — SendContextNote guard', () => {\n it('is a no-op when no session is live (no client / closed state)', () => {\n const service = new RealtimeSessionService();\n const fakeClient = new FakeRealtimeClient();\n internals(service).client = fakeClient;\n\n // ConnectionState is 'closed' by default — the note must NOT reach the client.\n service.SendContextNote('[whiteboard] {\"added\":[]}');\n expect(fakeClient.ContextNotes).toEqual([]);\n });\n\n it('ignores empty / whitespace-only notes', () => {\n const service = new RealtimeSessionService();\n const fakeClient = new FakeRealtimeClient();\n internals(service).client = fakeClient;\n\n service.SendContextNote(' ');\n expect(fakeClient.ContextNotes).toEqual([]);\n });\n});\n\ndescribe('RealtimeSessionService — SaveChannelState guards', () => {\n it('returns false when no session id is available (live or explicit)', async () => {\n const service = new RealtimeSessionService();\n const saved = await service.SaveChannelState('Whiteboard', '{\"items\":[]}');\n expect(saved).toBe(false);\n });\n});\n"]}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=realtime-session-minimized.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"realtime-session-minimized.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/realtime-session-minimized.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,32 @@
1
+ import { describe, it, expect, beforeEach } from 'vitest';
2
+ import { RealtimeSessionService } from '../lib/services/realtime-session.service';
3
+ describe('RealtimeSessionService — Minimized$ presentation state', () => {
4
+ let service;
5
+ beforeEach(() => {
6
+ service = new RealtimeSessionService();
7
+ });
8
+ it('starts NOT minimized', () => {
9
+ expect(service.IsMinimized).toBe(false);
10
+ });
11
+ it('SetMinimized(true) flips the state and emits on Minimized$', () => {
12
+ const seen = [];
13
+ service.Minimized$.subscribe(v => seen.push(v));
14
+ service.SetMinimized(true);
15
+ expect(service.IsMinimized).toBe(true);
16
+ service.SetMinimized(false);
17
+ expect(service.IsMinimized).toBe(false);
18
+ expect(seen).toEqual([false, true, false]);
19
+ });
20
+ it('is idempotent — repeated same-value calls do not re-emit', () => {
21
+ const seen = [];
22
+ service.Minimized$.subscribe(v => seen.push(v));
23
+ service.SetMinimized(true);
24
+ service.SetMinimized(true);
25
+ service.SetMinimized(true);
26
+ expect(seen).toEqual([false, true]);
27
+ });
28
+ it('exposes no agent session id before a session is minted', () => {
29
+ expect(service.CurrentAgentSessionId).toBeNull();
30
+ });
31
+ });
32
+ //# sourceMappingURL=realtime-session-minimized.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"realtime-session-minimized.test.js","sourceRoot":"","sources":["../../src/__tests__/realtime-session-minimized.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAC1D,OAAO,EAAE,sBAAsB,EAAE,MAAM,0CAA0C,CAAC;AAElF,QAAQ,CAAC,wDAAwD,EAAE,GAAG,EAAE;IACtE,IAAI,OAA+B,CAAC;IAEpC,UAAU,CAAC,GAAG,EAAE;QACd,OAAO,GAAG,IAAI,sBAAsB,EAAE,CAAC;IACzC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sBAAsB,EAAE,GAAG,EAAE;QAC9B,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4DAA4D,EAAE,GAAG,EAAE;QACpE,MAAM,IAAI,GAAc,EAAE,CAAC;QAC3B,OAAO,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;QAEhD,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;QAC3B,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAEvC,OAAO,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;QAC5B,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAExC,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC;IAC7C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0DAA0D,EAAE,GAAG,EAAE;QAClE,MAAM,IAAI,GAAc,EAAE,CAAC;QAC3B,OAAO,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;QAEhD,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;QAC3B,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;QAC3B,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;QAE3B,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wDAAwD,EAAE,GAAG,EAAE;QAChE,MAAM,CAAC,OAAO,CAAC,qBAAqB,CAAC,CAAC,QAAQ,EAAE,CAAC;IACnD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { describe, it, expect, beforeEach } from 'vitest';\nimport { RealtimeSessionService } from '../lib/services/realtime-session.service';\n\ndescribe('RealtimeSessionService — Minimized$ presentation state', () => {\n let service: RealtimeSessionService;\n\n beforeEach(() => {\n service = new RealtimeSessionService();\n });\n\n it('starts NOT minimized', () => {\n expect(service.IsMinimized).toBe(false);\n });\n\n it('SetMinimized(true) flips the state and emits on Minimized$', () => {\n const seen: boolean[] = [];\n service.Minimized$.subscribe(v => seen.push(v));\n\n service.SetMinimized(true);\n expect(service.IsMinimized).toBe(true);\n\n service.SetMinimized(false);\n expect(service.IsMinimized).toBe(false);\n\n expect(seen).toEqual([false, true, false]);\n });\n\n it('is idempotent — repeated same-value calls do not re-emit', () => {\n const seen: boolean[] = [];\n service.Minimized$.subscribe(v => seen.push(v));\n\n service.SetMinimized(true);\n service.SetMinimized(true);\n service.SetMinimized(true);\n\n expect(seen).toEqual([false, true]);\n });\n\n it('exposes no agent session id before a session is minted', () => {\n expect(service.CurrentAgentSessionId).toBeNull();\n });\n});\n"]}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=realtime-session-mint.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"realtime-session-mint.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/realtime-session-mint.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,69 @@
1
+ import { describe, it, expect, beforeEach, vi } from 'vitest';
2
+ import { RealtimeSessionService } from '../lib/services/realtime-session.service';
3
+ function internals(service) {
4
+ return service;
5
+ }
6
+ const OK_RESULT = {
7
+ StartRealtimeClientSession: {
8
+ AgentSessionId: 'session-1',
9
+ ConversationId: 'conv-1',
10
+ Provider: 'openai',
11
+ Model: 'gpt-realtime',
12
+ EphemeralToken: 'ek_abc',
13
+ ExpiresAt: '2026-01-01T00:00:00Z',
14
+ SessionConfigJson: '{}'
15
+ }
16
+ };
17
+ describe('RealtimeSessionService — mintSession variable passthrough', () => {
18
+ let service;
19
+ let executeGQL;
20
+ beforeEach(() => {
21
+ service = new RealtimeSessionService();
22
+ executeGQL = vi.fn(async () => OK_RESULT);
23
+ // The service's gql() seam is just `this.Provider as GraphQLDataProvider` — a fake with
24
+ // ExecuteGQL is all the mint path touches.
25
+ service.Provider = { ExecuteGQL: executeGQL };
26
+ });
27
+ /** Returns the variables object the mutation was invoked with. */
28
+ async function mintAndGetVariables(coAgentId, preferredModelId, configOverridesJson) {
29
+ await internals(service).mintSession('target-1', 'conv-1', null, preferredModelId, null, coAgentId, configOverridesJson);
30
+ expect(executeGQL).toHaveBeenCalledTimes(1);
31
+ return executeGQL.mock.calls[0][1];
32
+ }
33
+ it('threads coAgentId into the mutation variables when supplied', async () => {
34
+ const variables = await mintAndGetVariables('co-explicit');
35
+ expect(variables['coAgentId']).toBe('co-explicit');
36
+ expect(variables['targetAgentId']).toBe('target-1');
37
+ });
38
+ it('sends coAgentId: null when omitted (server metadata drives the co-agent choice)', async () => {
39
+ const variables = await mintAndGetVariables();
40
+ expect(variables['coAgentId']).toBeNull();
41
+ });
42
+ it('declares $coAgentId in the mutation document and passes it to the field', async () => {
43
+ await mintAndGetVariables('co-explicit');
44
+ const mutation = executeGQL.mock.calls[0][0];
45
+ expect(mutation).toContain('$coAgentId: String');
46
+ expect(mutation).toContain('coAgentId: $coAgentId');
47
+ });
48
+ it('keeps the preferredModelId passthrough intact alongside coAgentId', async () => {
49
+ const variables = await mintAndGetVariables('co-explicit', 'model-77');
50
+ expect(variables['preferredModelId']).toBe('model-77');
51
+ expect(variables['coAgentId']).toBe('co-explicit');
52
+ });
53
+ it('threads configOverridesJson into the mutation variables when supplied', async () => {
54
+ const overrides = '{"realtime":{"modelPreference":"model-77"}}';
55
+ const variables = await mintAndGetVariables('co-explicit', 'model-77', overrides);
56
+ expect(variables['configOverridesJson']).toBe(overrides);
57
+ });
58
+ it('sends configOverridesJson: null when omitted (server defaults — today\'s behavior)', async () => {
59
+ const variables = await mintAndGetVariables();
60
+ expect(variables['configOverridesJson']).toBeNull();
61
+ });
62
+ it('declares $configOverridesJson in the mutation document and passes it to the field', async () => {
63
+ await mintAndGetVariables(null, null, '{"realtime":{}}');
64
+ const mutation = executeGQL.mock.calls[0][0];
65
+ expect(mutation).toContain('$configOverridesJson: String');
66
+ expect(mutation).toContain('configOverridesJson: $configOverridesJson');
67
+ });
68
+ });
69
+ //# sourceMappingURL=realtime-session-mint.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"realtime-session-mint.test.js","sourceRoot":"","sources":["../../src/__tests__/realtime-session-mint.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { describe, it, expect, beforeEach, vi } from 'vitest';\nimport { IMetadataProvider } from '@memberjunction/core';\nimport { RealtimeSessionService } from '../lib/services/realtime-session.service';\n\n/**\n * Session-mint passthrough — verifies the `StartRealtimeClientSession` mutation variables the\n * service sends, in particular the optional `coAgentId` (highest-precedence step of the server's\n * co-agent resolution chain) and the optional `configOverridesJson` (authorization-gated session\n * config overrides, e.g. `{\"realtime\":{\"modelPreference\":…}}`) alongside the previously-added\n * `preferredModelId`.\n *\n * The mint path lives behind the private `mintSession` method, reached through a narrow typed\n * seam (same approach as the client-tools suite) with the service's `Provider` swapped for a\n * fake whose `ExecuteGQL` captures the mutation + variables.\n */\n\n/** The private surface under test — no `any`, just the member driven by the suite. */\ninterface RealtimeSessionInternals {\n mintSession(\n targetAgentId: string,\n conversationId?: string | null,\n lastSessionId?: string | null,\n preferredModelId?: string | null,\n clientTools?: Array<{ Name: string; Description: string; ParametersSchema: object }> | null,\n coAgentId?: string | null,\n configOverridesJson?: string | null\n ): Promise<unknown>;\n}\n\nfunction internals(service: RealtimeSessionService): RealtimeSessionInternals {\n return service as unknown as RealtimeSessionInternals;\n}\n\nconst OK_RESULT = {\n StartRealtimeClientSession: {\n AgentSessionId: 'session-1',\n ConversationId: 'conv-1',\n Provider: 'openai',\n Model: 'gpt-realtime',\n EphemeralToken: 'ek_abc',\n ExpiresAt: '2026-01-01T00:00:00Z',\n SessionConfigJson: '{}'\n }\n};\n\ndescribe('RealtimeSessionService — mintSession variable passthrough', () => {\n let service: RealtimeSessionService;\n let executeGQL: ReturnType<typeof vi.fn>;\n\n beforeEach(() => {\n service = new RealtimeSessionService();\n executeGQL = vi.fn(async () => OK_RESULT);\n // The service's gql() seam is just `this.Provider as GraphQLDataProvider` — a fake with\n // ExecuteGQL is all the mint path touches.\n service.Provider = { ExecuteGQL: executeGQL } as unknown as IMetadataProvider;\n });\n\n /** Returns the variables object the mutation was invoked with. */\n async function mintAndGetVariables(\n coAgentId?: string | null,\n preferredModelId?: string | null,\n configOverridesJson?: string | null\n ): Promise<Record<string, unknown>> {\n await internals(service).mintSession('target-1', 'conv-1', null, preferredModelId, null, coAgentId, configOverridesJson);\n expect(executeGQL).toHaveBeenCalledTimes(1);\n return executeGQL.mock.calls[0][1] as Record<string, unknown>;\n }\n\n it('threads coAgentId into the mutation variables when supplied', async () => {\n const variables = await mintAndGetVariables('co-explicit');\n expect(variables['coAgentId']).toBe('co-explicit');\n expect(variables['targetAgentId']).toBe('target-1');\n });\n\n it('sends coAgentId: null when omitted (server metadata drives the co-agent choice)', async () => {\n const variables = await mintAndGetVariables();\n expect(variables['coAgentId']).toBeNull();\n });\n\n it('declares $coAgentId in the mutation document and passes it to the field', async () => {\n await mintAndGetVariables('co-explicit');\n const mutation = executeGQL.mock.calls[0][0] as string;\n expect(mutation).toContain('$coAgentId: String');\n expect(mutation).toContain('coAgentId: $coAgentId');\n });\n\n it('keeps the preferredModelId passthrough intact alongside coAgentId', async () => {\n const variables = await mintAndGetVariables('co-explicit', 'model-77');\n expect(variables['preferredModelId']).toBe('model-77');\n expect(variables['coAgentId']).toBe('co-explicit');\n });\n\n it('threads configOverridesJson into the mutation variables when supplied', async () => {\n const overrides = '{\"realtime\":{\"modelPreference\":\"model-77\"}}';\n const variables = await mintAndGetVariables('co-explicit', 'model-77', overrides);\n expect(variables['configOverridesJson']).toBe(overrides);\n });\n\n it('sends configOverridesJson: null when omitted (server defaults — today\\'s behavior)', async () => {\n const variables = await mintAndGetVariables();\n expect(variables['configOverridesJson']).toBeNull();\n });\n\n it('declares $configOverridesJson in the mutation document and passes it to the field', async () => {\n await mintAndGetVariables(null, null, '{\"realtime\":{}}');\n const mutation = executeGQL.mock.calls[0][0] as string;\n expect(mutation).toContain('$configOverridesJson: String');\n expect(mutation).toContain('configOverridesJson: $configOverridesJson');\n });\n});\n"]}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=realtime-session-policy.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"realtime-session-policy.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/realtime-session-policy.test.ts"],"names":[],"mappings":""}