@memberjunction/ng-conversations 5.42.0 → 5.44.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 (351) hide show
  1. package/dist/lib/components/active-tasks/active-tasks-panel.component.d.ts +0 -1
  2. package/dist/lib/components/active-tasks/active-tasks-panel.component.d.ts.map +1 -1
  3. package/dist/lib/components/active-tasks/active-tasks-panel.component.js +56 -52
  4. package/dist/lib/components/active-tasks/active-tasks-panel.component.js.map +1 -1
  5. package/dist/lib/components/artifact/artifact-share-modal.component.js +37 -41
  6. package/dist/lib/components/artifact/artifact-share-modal.component.js.map +1 -1
  7. package/dist/lib/components/collection/collection-form-modal.component.d.ts.map +1 -1
  8. package/dist/lib/components/collection/collection-form-modal.component.js +10 -14
  9. package/dist/lib/components/collection/collection-form-modal.component.js.map +1 -1
  10. package/dist/lib/components/collection/collection-share-modal.component.js +41 -45
  11. package/dist/lib/components/collection/collection-share-modal.component.js.map +1 -1
  12. package/dist/lib/components/collection/collection-view.component.d.ts.map +1 -1
  13. package/dist/lib/components/collection/collection-view.component.js +22 -36
  14. package/dist/lib/components/collection/collection-view.component.js.map +1 -1
  15. package/dist/lib/components/collection/collections-full-view.component.d.ts +4 -0
  16. package/dist/lib/components/collection/collections-full-view.component.d.ts.map +1 -1
  17. package/dist/lib/components/collection/collections-full-view.component.js +134 -166
  18. package/dist/lib/components/collection/collections-full-view.component.js.map +1 -1
  19. package/dist/lib/components/conversation/conversation-chat-area.component.d.ts +73 -8
  20. package/dist/lib/components/conversation/conversation-chat-area.component.d.ts.map +1 -1
  21. package/dist/lib/components/conversation/conversation-chat-area.component.js +487 -123
  22. package/dist/lib/components/conversation/conversation-chat-area.component.js.map +1 -1
  23. package/dist/lib/components/conversation/pinned-messages-panel.component.js +6 -9
  24. package/dist/lib/components/conversation/pinned-messages-panel.component.js.map +1 -1
  25. package/dist/lib/components/library/library-full-view.component.d.ts.map +1 -1
  26. package/dist/lib/components/library/library-full-view.component.js +20 -24
  27. package/dist/lib/components/library/library-full-view.component.js.map +1 -1
  28. package/dist/lib/components/members/members-modal.component.d.ts.map +1 -1
  29. package/dist/lib/components/members/members-modal.component.js +10 -11
  30. package/dist/lib/components/members/members-modal.component.js.map +1 -1
  31. package/dist/lib/components/mention/mention-dropdown.component.js +65 -26
  32. package/dist/lib/components/mention/mention-dropdown.component.js.map +1 -1
  33. package/dist/lib/components/mention/mention-editor.component.d.ts.map +1 -1
  34. package/dist/lib/components/mention/mention-editor.component.js +31 -10
  35. package/dist/lib/components/mention/mention-editor.component.js.map +1 -1
  36. package/dist/lib/components/message/message-input-box.component.d.ts +11 -16
  37. package/dist/lib/components/message/message-input-box.component.d.ts.map +1 -1
  38. package/dist/lib/components/message/message-input-box.component.js +52 -46
  39. package/dist/lib/components/message/message-input-box.component.js.map +1 -1
  40. package/dist/lib/components/message/message-input.component.d.ts +83 -18
  41. package/dist/lib/components/message/message-input.component.d.ts.map +1 -1
  42. package/dist/lib/components/message/message-input.component.js +238 -151
  43. package/dist/lib/components/message/message-input.component.js.map +1 -1
  44. package/dist/lib/components/message/message-item.component.d.ts +15 -1
  45. package/dist/lib/components/message/message-item.component.d.ts.map +1 -1
  46. package/dist/lib/components/message/message-item.component.js +90 -15
  47. package/dist/lib/components/message/message-item.component.js.map +1 -1
  48. package/dist/lib/components/message/message-list.component.js +6 -9
  49. package/dist/lib/components/message/message-list.component.js.map +1 -1
  50. package/dist/lib/components/overlay/chat-overlay.component.d.ts +3 -0
  51. package/dist/lib/components/overlay/chat-overlay.component.d.ts.map +1 -1
  52. package/dist/lib/components/overlay/chat-overlay.component.js +9 -4
  53. package/dist/lib/components/overlay/chat-overlay.component.js.map +1 -1
  54. package/dist/lib/components/realtime/channels/base-realtime-channel-client.d.ts +45 -0
  55. package/dist/lib/components/realtime/channels/base-realtime-channel-client.d.ts.map +1 -1
  56. package/dist/lib/components/realtime/channels/base-realtime-channel-client.js +10 -0
  57. package/dist/lib/components/realtime/channels/base-realtime-channel-client.js.map +1 -1
  58. package/dist/lib/components/realtime/channels/client-context-channel.d.ts +46 -0
  59. package/dist/lib/components/realtime/channels/client-context-channel.d.ts.map +1 -0
  60. package/dist/lib/components/realtime/channels/client-context-channel.js +174 -0
  61. package/dist/lib/components/realtime/channels/client-context-channel.js.map +1 -0
  62. package/dist/lib/components/realtime/evidence-playback/realtime-evidence-playback.component.d.ts +123 -0
  63. package/dist/lib/components/realtime/evidence-playback/realtime-evidence-playback.component.d.ts.map +1 -0
  64. package/dist/lib/components/realtime/evidence-playback/realtime-evidence-playback.component.js +397 -0
  65. package/dist/lib/components/realtime/evidence-playback/realtime-evidence-playback.component.js.map +1 -0
  66. package/dist/lib/components/realtime/media/media-channel-state.d.ts +103 -0
  67. package/dist/lib/components/realtime/media/media-channel-state.d.ts.map +1 -0
  68. package/dist/lib/components/realtime/media/media-channel-state.js +143 -0
  69. package/dist/lib/components/realtime/media/media-channel-state.js.map +1 -0
  70. package/dist/lib/components/realtime/media/media-channel-tools.d.ts +24 -0
  71. package/dist/lib/components/realtime/media/media-channel-tools.d.ts.map +1 -0
  72. package/dist/lib/components/realtime/media/media-channel-tools.js +107 -0
  73. package/dist/lib/components/realtime/media/media-channel-tools.js.map +1 -0
  74. package/dist/lib/components/realtime/media/media-channel.d.ts +89 -0
  75. package/dist/lib/components/realtime/media/media-channel.d.ts.map +1 -0
  76. package/dist/lib/components/realtime/media/media-channel.js +253 -0
  77. package/dist/lib/components/realtime/media/media-channel.js.map +1 -0
  78. package/dist/lib/components/realtime/media/realtime-media-surface.component.d.ts +141 -0
  79. package/dist/lib/components/realtime/media/realtime-media-surface.component.d.ts.map +1 -0
  80. package/dist/lib/components/realtime/media/realtime-media-surface.component.js +574 -0
  81. package/dist/lib/components/realtime/media/realtime-media-surface.component.js.map +1 -0
  82. package/dist/lib/components/realtime/realtime-activity-rail.component.d.ts +59 -14
  83. package/dist/lib/components/realtime/realtime-activity-rail.component.d.ts.map +1 -1
  84. package/dist/lib/components/realtime/realtime-activity-rail.component.js +277 -74
  85. package/dist/lib/components/realtime/realtime-activity-rail.component.js.map +1 -1
  86. package/dist/lib/components/realtime/realtime-agent-banner.component.d.ts +28 -27
  87. package/dist/lib/components/realtime/realtime-agent-banner.component.d.ts.map +1 -1
  88. package/dist/lib/components/realtime/realtime-agent-banner.component.js +144 -143
  89. package/dist/lib/components/realtime/realtime-agent-banner.component.js.map +1 -1
  90. package/dist/lib/components/realtime/realtime-agent-picker.component.d.ts +12 -0
  91. package/dist/lib/components/realtime/realtime-agent-picker.component.d.ts.map +1 -1
  92. package/dist/lib/components/realtime/realtime-agent-picker.component.js +105 -43
  93. package/dist/lib/components/realtime/realtime-agent-picker.component.js.map +1 -1
  94. package/dist/lib/components/realtime/realtime-audio-visuals.d.ts +2 -2
  95. package/dist/lib/components/realtime/realtime-audio-visuals.d.ts.map +1 -1
  96. package/dist/lib/components/realtime/realtime-audio-visuals.js.map +1 -1
  97. package/dist/lib/components/realtime/realtime-composer.component.d.ts +41 -7
  98. package/dist/lib/components/realtime/realtime-composer.component.d.ts.map +1 -1
  99. package/dist/lib/components/realtime/realtime-composer.component.js +216 -102
  100. package/dist/lib/components/realtime/realtime-composer.component.js.map +1 -1
  101. package/dist/lib/components/realtime/realtime-delegation-card.component.d.ts +0 -2
  102. package/dist/lib/components/realtime/realtime-delegation-card.component.d.ts.map +1 -1
  103. package/dist/lib/components/realtime/realtime-delegation-card.component.js +67 -71
  104. package/dist/lib/components/realtime/realtime-delegation-card.component.js.map +1 -1
  105. package/dist/lib/components/realtime/realtime-session-overlay.component.d.ts +364 -44
  106. package/dist/lib/components/realtime/realtime-session-overlay.component.d.ts.map +1 -1
  107. package/dist/lib/components/realtime/realtime-session-overlay.component.js +839 -153
  108. package/dist/lib/components/realtime/realtime-session-overlay.component.js.map +1 -1
  109. package/dist/lib/components/realtime/realtime-session-state.d.ts +5 -5
  110. package/dist/lib/components/realtime/realtime-session-state.d.ts.map +1 -1
  111. package/dist/lib/components/realtime/realtime-session-state.js.map +1 -1
  112. package/dist/lib/components/realtime/realtime-surface-tab-style.d.ts +70 -0
  113. package/dist/lib/components/realtime/realtime-surface-tab-style.d.ts.map +1 -0
  114. package/dist/lib/components/realtime/realtime-surface-tab-style.js +115 -0
  115. package/dist/lib/components/realtime/realtime-surface-tab-style.js.map +1 -0
  116. package/dist/lib/components/realtime/realtime-surface-tabs.component.d.ts +55 -57
  117. package/dist/lib/components/realtime/realtime-surface-tabs.component.d.ts.map +1 -1
  118. package/dist/lib/components/realtime/realtime-surface-tabs.component.js +165 -143
  119. package/dist/lib/components/realtime/realtime-surface-tabs.component.js.map +1 -1
  120. package/dist/lib/components/realtime/realtime-surface-tabs.model.d.ts +80 -71
  121. package/dist/lib/components/realtime/realtime-surface-tabs.model.d.ts.map +1 -1
  122. package/dist/lib/components/realtime/realtime-surface-tabs.model.js +83 -113
  123. package/dist/lib/components/realtime/realtime-surface-tabs.model.js.map +1 -1
  124. package/dist/lib/components/realtime/realtime-ui-config.d.ts +270 -0
  125. package/dist/lib/components/realtime/realtime-ui-config.d.ts.map +1 -0
  126. package/dist/lib/components/realtime/realtime-ui-config.js +212 -0
  127. package/dist/lib/components/realtime/realtime-ui-config.js.map +1 -0
  128. package/dist/lib/components/search/search-panel.component.d.ts +2 -0
  129. package/dist/lib/components/search/search-panel.component.d.ts.map +1 -1
  130. package/dist/lib/components/search/search-panel.component.js +92 -101
  131. package/dist/lib/components/search/search-panel.component.js.map +1 -1
  132. package/dist/lib/components/share/share-modal.component.d.ts.map +1 -1
  133. package/dist/lib/components/share/share-modal.component.js +10 -11
  134. package/dist/lib/components/share/share-modal.component.js.map +1 -1
  135. package/dist/lib/components/shared/user-picker.component.d.ts.map +1 -1
  136. package/dist/lib/components/shared/user-picker.component.js +12 -15
  137. package/dist/lib/components/shared/user-picker.component.js.map +1 -1
  138. package/dist/lib/components/workspace/conversation-workspace.component.d.ts +5 -0
  139. package/dist/lib/components/workspace/conversation-workspace.component.d.ts.map +1 -1
  140. package/dist/lib/components/workspace/conversation-workspace.component.js +18 -7
  141. package/dist/lib/components/workspace/conversation-workspace.component.js.map +1 -1
  142. package/dist/lib/conversations.module.d.ts +29 -26
  143. package/dist/lib/conversations.module.d.ts.map +1 -1
  144. package/dist/lib/conversations.module.js +37 -6
  145. package/dist/lib/conversations.module.js.map +1 -1
  146. package/dist/lib/models/conversation-state.model.d.ts +6 -3
  147. package/dist/lib/models/conversation-state.model.d.ts.map +1 -1
  148. package/dist/lib/models/conversation-state.model.js.map +1 -1
  149. package/dist/lib/services/conversation-agent.service.d.ts +2 -2
  150. package/dist/lib/services/conversation-agent.service.d.ts.map +1 -1
  151. package/dist/lib/services/conversation-agent.service.js +6 -2
  152. package/dist/lib/services/conversation-agent.service.js.map +1 -1
  153. package/dist/lib/services/mention-autocomplete.service.d.ts +41 -5
  154. package/dist/lib/services/mention-autocomplete.service.d.ts.map +1 -1
  155. package/dist/lib/services/mention-autocomplete.service.js +143 -19
  156. package/dist/lib/services/mention-autocomplete.service.js.map +1 -1
  157. package/dist/lib/services/realtime-audio-recorder.d.ts +143 -0
  158. package/dist/lib/services/realtime-audio-recorder.d.ts.map +1 -0
  159. package/dist/lib/services/realtime-audio-recorder.js +379 -0
  160. package/dist/lib/services/realtime-audio-recorder.js.map +1 -0
  161. package/dist/lib/services/realtime-pcm-wav.d.ts +75 -0
  162. package/dist/lib/services/realtime-pcm-wav.d.ts.map +1 -0
  163. package/dist/lib/services/realtime-pcm-wav.js +205 -0
  164. package/dist/lib/services/realtime-pcm-wav.js.map +1 -0
  165. package/dist/lib/services/realtime-session-review.service.d.ts +28 -1
  166. package/dist/lib/services/realtime-session-review.service.d.ts.map +1 -1
  167. package/dist/lib/services/realtime-session-review.service.js +12 -3
  168. package/dist/lib/services/realtime-session-review.service.js.map +1 -1
  169. package/dist/lib/services/realtime-session.service.d.ts +210 -20
  170. package/dist/lib/services/realtime-session.service.d.ts.map +1 -1
  171. package/dist/lib/services/realtime-session.service.js +452 -21
  172. package/dist/lib/services/realtime-session.service.js.map +1 -1
  173. package/dist/lib/services/realtime-sessions-adapter.js +1 -1
  174. package/dist/lib/services/realtime-sessions-adapter.js.map +1 -1
  175. package/dist/lib/services/ui-command-handler.service.d.ts +7 -2
  176. package/dist/lib/services/ui-command-handler.service.d.ts.map +1 -1
  177. package/dist/lib/services/ui-command-handler.service.js +6 -2
  178. package/dist/lib/services/ui-command-handler.service.js.map +1 -1
  179. package/dist/lib/utils/plan-mode-preference.d.ts +62 -0
  180. package/dist/lib/utils/plan-mode-preference.d.ts.map +1 -0
  181. package/dist/lib/utils/plan-mode-preference.js +130 -0
  182. package/dist/lib/utils/plan-mode-preference.js.map +1 -0
  183. package/dist/public-api.d.ts +6 -0
  184. package/dist/public-api.d.ts.map +1 -1
  185. package/dist/public-api.js +8 -0
  186. package/dist/public-api.js.map +1 -1
  187. package/package.json +28 -26
  188. package/dist/__tests__/attachment-badge.test.d.ts +0 -2
  189. package/dist/__tests__/attachment-badge.test.d.ts.map +0 -1
  190. package/dist/__tests__/attachment-badge.test.js +0 -66
  191. package/dist/__tests__/attachment-badge.test.js.map +0 -1
  192. package/dist/__tests__/channel-optional-surface.test.d.ts +0 -2
  193. package/dist/__tests__/channel-optional-surface.test.d.ts.map +0 -1
  194. package/dist/__tests__/channel-optional-surface.test.js +0 -53
  195. package/dist/__tests__/channel-optional-surface.test.js.map +0 -1
  196. package/dist/__tests__/chat-events.test.d.ts +0 -14
  197. package/dist/__tests__/chat-events.test.d.ts.map +0 -1
  198. package/dist/__tests__/chat-events.test.js +0 -109
  199. package/dist/__tests__/chat-events.test.js.map +0 -1
  200. package/dist/__tests__/collections-full-view.test.d.ts +0 -2
  201. package/dist/__tests__/collections-full-view.test.d.ts.map +0 -1
  202. package/dist/__tests__/collections-full-view.test.js +0 -225
  203. package/dist/__tests__/collections-full-view.test.js.map +0 -1
  204. package/dist/__tests__/conversation-cache.test.d.ts +0 -2
  205. package/dist/__tests__/conversation-cache.test.d.ts.map +0 -1
  206. package/dist/__tests__/conversation-cache.test.js +0 -233
  207. package/dist/__tests__/conversation-cache.test.js.map +0 -1
  208. package/dist/__tests__/conversation-naming.test.d.ts +0 -2
  209. package/dist/__tests__/conversation-naming.test.d.ts.map +0 -1
  210. package/dist/__tests__/conversation-naming.test.js +0 -110
  211. package/dist/__tests__/conversation-naming.test.js.map +0 -1
  212. package/dist/__tests__/delegation-result-parser.test.d.ts +0 -2
  213. package/dist/__tests__/delegation-result-parser.test.d.ts.map +0 -1
  214. package/dist/__tests__/delegation-result-parser.test.js +0 -107
  215. package/dist/__tests__/delegation-result-parser.test.js.map +0 -1
  216. package/dist/__tests__/distinct-artifacts.test.d.ts +0 -2
  217. package/dist/__tests__/distinct-artifacts.test.d.ts.map +0 -1
  218. package/dist/__tests__/distinct-artifacts.test.js +0 -56
  219. package/dist/__tests__/distinct-artifacts.test.js.map +0 -1
  220. package/dist/__tests__/event-wiring.test.d.ts +0 -15
  221. package/dist/__tests__/event-wiring.test.d.ts.map +0 -1
  222. package/dist/__tests__/event-wiring.test.js +0 -100
  223. package/dist/__tests__/event-wiring.test.js.map +0 -1
  224. package/dist/__tests__/index.test.d.ts +0 -2
  225. package/dist/__tests__/index.test.d.ts.map +0 -1
  226. package/dist/__tests__/index.test.js +0 -7
  227. package/dist/__tests__/index.test.js.map +0 -1
  228. package/dist/__tests__/narration-template.test.d.ts +0 -2
  229. package/dist/__tests__/narration-template.test.d.ts.map +0 -1
  230. package/dist/__tests__/narration-template.test.js +0 -76
  231. package/dist/__tests__/narration-template.test.js.map +0 -1
  232. package/dist/__tests__/notification-model.test.d.ts +0 -2
  233. package/dist/__tests__/notification-model.test.d.ts.map +0 -1
  234. package/dist/__tests__/notification-model.test.js +0 -68
  235. package/dist/__tests__/notification-model.test.js.map +0 -1
  236. package/dist/__tests__/realtime-agent-picker-models.test.d.ts +0 -2
  237. package/dist/__tests__/realtime-agent-picker-models.test.d.ts.map +0 -1
  238. package/dist/__tests__/realtime-agent-picker-models.test.js +0 -49
  239. package/dist/__tests__/realtime-agent-picker-models.test.js.map +0 -1
  240. package/dist/__tests__/realtime-audio-visuals.test.d.ts +0 -2
  241. package/dist/__tests__/realtime-audio-visuals.test.d.ts.map +0 -1
  242. package/dist/__tests__/realtime-audio-visuals.test.js +0 -123
  243. package/dist/__tests__/realtime-audio-visuals.test.js.map +0 -1
  244. package/dist/__tests__/realtime-delegation-card-cancel.test.d.ts +0 -2
  245. package/dist/__tests__/realtime-delegation-card-cancel.test.d.ts.map +0 -1
  246. package/dist/__tests__/realtime-delegation-card-cancel.test.js +0 -48
  247. package/dist/__tests__/realtime-delegation-card-cancel.test.js.map +0 -1
  248. package/dist/__tests__/realtime-disclosure.test.d.ts +0 -2
  249. package/dist/__tests__/realtime-disclosure.test.d.ts.map +0 -1
  250. package/dist/__tests__/realtime-disclosure.test.js +0 -164
  251. package/dist/__tests__/realtime-disclosure.test.js.map +0 -1
  252. package/dist/__tests__/realtime-pairing.test.d.ts +0 -2
  253. package/dist/__tests__/realtime-pairing.test.d.ts.map +0 -1
  254. package/dist/__tests__/realtime-pairing.test.js +0 -207
  255. package/dist/__tests__/realtime-pairing.test.js.map +0 -1
  256. package/dist/__tests__/realtime-review-lifecycle.test.d.ts +0 -2
  257. package/dist/__tests__/realtime-review-lifecycle.test.d.ts.map +0 -1
  258. package/dist/__tests__/realtime-review-lifecycle.test.js +0 -154
  259. package/dist/__tests__/realtime-review-lifecycle.test.js.map +0 -1
  260. package/dist/__tests__/realtime-session-cancel-usage.test.d.ts +0 -2
  261. package/dist/__tests__/realtime-session-cancel-usage.test.d.ts.map +0 -1
  262. package/dist/__tests__/realtime-session-cancel-usage.test.js +0 -230
  263. package/dist/__tests__/realtime-session-cancel-usage.test.js.map +0 -1
  264. package/dist/__tests__/realtime-session-channels.test.d.ts +0 -2
  265. package/dist/__tests__/realtime-session-channels.test.d.ts.map +0 -1
  266. package/dist/__tests__/realtime-session-channels.test.js +0 -252
  267. package/dist/__tests__/realtime-session-channels.test.js.map +0 -1
  268. package/dist/__tests__/realtime-session-client-tools.test.d.ts +0 -2
  269. package/dist/__tests__/realtime-session-client-tools.test.d.ts.map +0 -1
  270. package/dist/__tests__/realtime-session-client-tools.test.js +0 -103
  271. package/dist/__tests__/realtime-session-client-tools.test.js.map +0 -1
  272. package/dist/__tests__/realtime-session-minimized.test.d.ts +0 -2
  273. package/dist/__tests__/realtime-session-minimized.test.d.ts.map +0 -1
  274. package/dist/__tests__/realtime-session-minimized.test.js +0 -32
  275. package/dist/__tests__/realtime-session-minimized.test.js.map +0 -1
  276. package/dist/__tests__/realtime-session-mint.test.d.ts +0 -2
  277. package/dist/__tests__/realtime-session-mint.test.d.ts.map +0 -1
  278. package/dist/__tests__/realtime-session-mint.test.js +0 -69
  279. package/dist/__tests__/realtime-session-mint.test.js.map +0 -1
  280. package/dist/__tests__/realtime-session-policy.test.d.ts +0 -2
  281. package/dist/__tests__/realtime-session-policy.test.d.ts.map +0 -1
  282. package/dist/__tests__/realtime-session-policy.test.js +0 -303
  283. package/dist/__tests__/realtime-session-policy.test.js.map +0 -1
  284. package/dist/__tests__/realtime-session-review.service.test.d.ts +0 -2
  285. package/dist/__tests__/realtime-session-review.service.test.d.ts.map +0 -1
  286. package/dist/__tests__/realtime-session-review.service.test.js +0 -743
  287. package/dist/__tests__/realtime-session-review.service.test.js.map +0 -1
  288. package/dist/__tests__/realtime-session-state.test.d.ts +0 -2
  289. package/dist/__tests__/realtime-session-state.test.d.ts.map +0 -1
  290. package/dist/__tests__/realtime-session-state.test.js +0 -83
  291. package/dist/__tests__/realtime-session-state.test.js.map +0 -1
  292. package/dist/__tests__/realtime-session-timeline-card.test.d.ts +0 -2
  293. package/dist/__tests__/realtime-session-timeline-card.test.d.ts.map +0 -1
  294. package/dist/__tests__/realtime-session-timeline-card.test.js +0 -106
  295. package/dist/__tests__/realtime-session-timeline-card.test.js.map +0 -1
  296. package/dist/__tests__/realtime-session-timeline.test.d.ts +0 -2
  297. package/dist/__tests__/realtime-session-timeline.test.d.ts.map +0 -1
  298. package/dist/__tests__/realtime-session-timeline.test.js +0 -142
  299. package/dist/__tests__/realtime-session-timeline.test.js.map +0 -1
  300. package/dist/__tests__/realtime-sessions-adapter.test.d.ts +0 -19
  301. package/dist/__tests__/realtime-sessions-adapter.test.d.ts.map +0 -1
  302. package/dist/__tests__/realtime-sessions-adapter.test.js +0 -188
  303. package/dist/__tests__/realtime-sessions-adapter.test.js.map +0 -1
  304. package/dist/__tests__/realtime-surface-panel-prefs.test.d.ts +0 -2
  305. package/dist/__tests__/realtime-surface-panel-prefs.test.d.ts.map +0 -1
  306. package/dist/__tests__/realtime-surface-panel-prefs.test.js +0 -100
  307. package/dist/__tests__/realtime-surface-panel-prefs.test.js.map +0 -1
  308. package/dist/__tests__/realtime-surface-tabs-model.test.d.ts +0 -2
  309. package/dist/__tests__/realtime-surface-tabs-model.test.d.ts.map +0 -1
  310. package/dist/__tests__/realtime-surface-tabs-model.test.js +0 -193
  311. package/dist/__tests__/realtime-surface-tabs-model.test.js.map +0 -1
  312. package/dist/__tests__/remote-browser-audio-player.test.d.ts +0 -2
  313. package/dist/__tests__/remote-browser-audio-player.test.d.ts.map +0 -1
  314. package/dist/__tests__/remote-browser-audio-player.test.js +0 -137
  315. package/dist/__tests__/remote-browser-audio-player.test.js.map +0 -1
  316. package/dist/__tests__/remote-browser-channel.test.d.ts +0 -2
  317. package/dist/__tests__/remote-browser-channel.test.d.ts.map +0 -1
  318. package/dist/__tests__/remote-browser-channel.test.js +0 -585
  319. package/dist/__tests__/remote-browser-channel.test.js.map +0 -1
  320. package/dist/__tests__/search-service.test.d.ts +0 -2
  321. package/dist/__tests__/search-service.test.d.ts.map +0 -1
  322. package/dist/__tests__/search-service.test.js +0 -114
  323. package/dist/__tests__/search-service.test.js.map +0 -1
  324. package/dist/__tests__/slot-defaults.test.d.ts +0 -24
  325. package/dist/__tests__/slot-defaults.test.d.ts.map +0 -1
  326. package/dist/__tests__/slot-defaults.test.js +0 -63
  327. package/dist/__tests__/slot-defaults.test.js.map +0 -1
  328. package/dist/__tests__/toast-service.test.d.ts +0 -2
  329. package/dist/__tests__/toast-service.test.d.ts.map +0 -1
  330. package/dist/__tests__/toast-service.test.js +0 -143
  331. package/dist/__tests__/toast-service.test.js.map +0 -1
  332. package/dist/__tests__/user-authorization.test.d.ts +0 -2
  333. package/dist/__tests__/user-authorization.test.d.ts.map +0 -1
  334. package/dist/__tests__/user-authorization.test.js +0 -97
  335. package/dist/__tests__/user-authorization.test.js.map +0 -1
  336. package/dist/__tests__/voice-session-narration.test.d.ts +0 -2
  337. package/dist/__tests__/voice-session-narration.test.d.ts.map +0 -1
  338. package/dist/__tests__/voice-session-narration.test.js +0 -609
  339. package/dist/__tests__/voice-session-narration.test.js.map +0 -1
  340. package/dist/__tests__/whiteboard-artifact-viewer.test.d.ts +0 -2
  341. package/dist/__tests__/whiteboard-artifact-viewer.test.d.ts.map +0 -1
  342. package/dist/__tests__/whiteboard-artifact-viewer.test.js +0 -101
  343. package/dist/__tests__/whiteboard-artifact-viewer.test.js.map +0 -1
  344. package/dist/__tests__/whiteboard-channel.test.d.ts +0 -2
  345. package/dist/__tests__/whiteboard-channel.test.d.ts.map +0 -1
  346. package/dist/__tests__/whiteboard-channel.test.js +0 -260
  347. package/dist/__tests__/whiteboard-channel.test.js.map +0 -1
  348. package/dist/__tests__/whiteboard-restore-state.test.d.ts +0 -2
  349. package/dist/__tests__/whiteboard-restore-state.test.d.ts.map +0 -1
  350. package/dist/__tests__/whiteboard-restore-state.test.js +0 -108
  351. package/dist/__tests__/whiteboard-restore-state.test.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"realtime-delegation-card-cancel.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/realtime-delegation-card-cancel.test.ts"],"names":[],"mappings":"AAEA,OAAO,mBAAmB,CAAC"}
@@ -1,48 +0,0 @@
1
- // Angular components in this package are partial-compiled — load the JIT compiler first
2
- // (same convention as the whiteboard component suites in this node test environment).
3
- import '@angular/compiler';
4
- import { describe, it, expect, vi } from 'vitest';
5
- import { RealtimeDelegationCardComponent } from '../lib/components/realtime/realtime-delegation-card.component';
6
- /**
7
- * The WORKING card's ✕ cancel affordance — the first hop of the explicit-cancel event
8
- * chain (card ✕ → thread re-emit → overlay → `RealtimeSessionService.CancelDelegation`).
9
- * Class-level tests (no TestBed): the card's emission contract is what the chain depends
10
- * on — the thread/overlay hops are template re-emits ((CancelRequested)="….emit($event)").
11
- */
12
- function workingCard(overrides = {}) {
13
- return {
14
- CallID: 'call-1',
15
- AgentName: 'Sage',
16
- LatestMessage: 'Looking things up',
17
- LatestStep: 'prompt_execution',
18
- Done: false,
19
- Success: false,
20
- StartedAt: Date.now(),
21
- ...overrides,
22
- };
23
- }
24
- /** A minimal MouseEvent stand-in whose stopPropagation is observable. */
25
- function fakeClick() {
26
- return { stopPropagation: vi.fn() };
27
- }
28
- describe('RealtimeDelegationCardComponent — ✕ cancel affordance (explicit user intent)', () => {
29
- it('emits CancelRequested with the call id for a WORKING card and stops propagation', () => {
30
- const component = new RealtimeDelegationCardComponent();
31
- component.Card = workingCard({ CallID: 'call-9' });
32
- const emitted = [];
33
- component.CancelRequested.subscribe((id) => emitted.push(id));
34
- const event = fakeClick();
35
- component.CancelWork(event);
36
- expect(emitted).toEqual(['call-9']);
37
- expect(event.stopPropagation).toHaveBeenCalled();
38
- });
39
- it('does NOT emit for a DONE card (the affordance only exists while work runs)', () => {
40
- const component = new RealtimeDelegationCardComponent();
41
- component.Card = workingCard({ Done: true, Success: true, Result: 'all set' });
42
- const emitted = [];
43
- component.CancelRequested.subscribe((id) => emitted.push(id));
44
- component.CancelWork(fakeClick());
45
- expect(emitted).toEqual([]);
46
- });
47
- });
48
- //# sourceMappingURL=realtime-delegation-card-cancel.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"realtime-delegation-card-cancel.test.js","sourceRoot":"","sources":["../../src/__tests__/realtime-delegation-card-cancel.test.ts"],"names":[],"mappings":"AAAA,wFAAwF;AACxF,sFAAsF;AACtF,OAAO,mBAAmB,CAAC;AAC3B,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAClD,OAAO,EAAE,+BAA+B,EAAE,MAAM,+DAA+D,CAAC;AAGhH;;;;;GAKG;AAEH,SAAS,WAAW,CAAC,YAA+C,EAAE;IACpE,OAAO;QACL,MAAM,EAAE,QAAQ;QAChB,SAAS,EAAE,MAAM;QACjB,aAAa,EAAE,mBAAmB;QAClC,UAAU,EAAE,kBAAkB;QAC9B,IAAI,EAAE,KAAK;QACX,OAAO,EAAE,KAAK;QACd,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;QACrB,GAAG,SAAS;KACb,CAAC;AACJ,CAAC;AAED,yEAAyE;AACzE,SAAS,SAAS;IAChB,OAAO,EAAE,eAAe,EAAE,EAAE,CAAC,EAAE,EAAE,EAA2E,CAAC;AAC/G,CAAC;AAED,QAAQ,CAAC,8EAA8E,EAAE,GAAG,EAAE;IAC5F,EAAE,CAAC,iFAAiF,EAAE,GAAG,EAAE;QACzF,MAAM,SAAS,GAAG,IAAI,+BAA+B,EAAE,CAAC;QACxD,SAAS,CAAC,IAAI,GAAG,WAAW,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC;QACnD,MAAM,OAAO,GAAa,EAAE,CAAC;QAC7B,SAAS,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC,EAAU,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;QAEtE,MAAM,KAAK,GAAG,SAAS,EAAE,CAAC;QAC1B,SAAS,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QAE5B,MAAM,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;QACpC,MAAM,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC,gBAAgB,EAAE,CAAC;IACnD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4EAA4E,EAAE,GAAG,EAAE;QACpF,MAAM,SAAS,GAAG,IAAI,+BAA+B,EAAE,CAAC;QACxD,SAAS,CAAC,IAAI,GAAG,WAAW,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;QAC/E,MAAM,OAAO,GAAa,EAAE,CAAC;QAC7B,SAAS,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC,EAAU,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;QAEtE,SAAS,CAAC,UAAU,CAAC,SAAS,EAAE,CAAC,CAAC;QAElC,MAAM,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAC9B,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["// Angular components in this package are partial-compiled — load the JIT compiler first\n// (same convention as the whiteboard component suites in this node test environment).\nimport '@angular/compiler';\nimport { describe, it, expect, vi } from 'vitest';\nimport { RealtimeDelegationCardComponent } from '../lib/components/realtime/realtime-delegation-card.component';\nimport { RealtimeDelegationCardVM } from '../lib/components/realtime/realtime-session-state';\n\n/**\n * The WORKING card's ✕ cancel affordance — the first hop of the explicit-cancel event\n * chain (card ✕ → thread re-emit → overlay → `RealtimeSessionService.CancelDelegation`).\n * Class-level tests (no TestBed): the card's emission contract is what the chain depends\n * on — the thread/overlay hops are template re-emits ((CancelRequested)=\"….emit($event)\").\n */\n\nfunction workingCard(overrides: Partial<RealtimeDelegationCardVM> = {}): RealtimeDelegationCardVM {\n return {\n CallID: 'call-1',\n AgentName: 'Sage',\n LatestMessage: 'Looking things up',\n LatestStep: 'prompt_execution',\n Done: false,\n Success: false,\n StartedAt: Date.now(),\n ...overrides,\n };\n}\n\n/** A minimal MouseEvent stand-in whose stopPropagation is observable. */\nfunction fakeClick(): MouseEvent & { stopPropagation: ReturnType<typeof vi.fn> } {\n return { stopPropagation: vi.fn() } as unknown as MouseEvent & { stopPropagation: ReturnType<typeof vi.fn> };\n}\n\ndescribe('RealtimeDelegationCardComponent — ✕ cancel affordance (explicit user intent)', () => {\n it('emits CancelRequested with the call id for a WORKING card and stops propagation', () => {\n const component = new RealtimeDelegationCardComponent();\n component.Card = workingCard({ CallID: 'call-9' });\n const emitted: string[] = [];\n component.CancelRequested.subscribe((id: string) => emitted.push(id));\n\n const event = fakeClick();\n component.CancelWork(event);\n\n expect(emitted).toEqual(['call-9']);\n expect(event.stopPropagation).toHaveBeenCalled();\n });\n\n it('does NOT emit for a DONE card (the affordance only exists while work runs)', () => {\n const component = new RealtimeDelegationCardComponent();\n component.Card = workingCard({ Done: true, Success: true, Result: 'all set' });\n const emitted: string[] = [];\n component.CancelRequested.subscribe((id: string) => emitted.push(id));\n\n component.CancelWork(fakeClick());\n\n expect(emitted).toEqual([]);\n });\n});\n"]}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=realtime-disclosure.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"realtime-disclosure.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/realtime-disclosure.test.ts"],"names":[],"mappings":""}
@@ -1,164 +0,0 @@
1
- /**
2
- * Unit tests for the realtime overlay's PROGRESSIVE DISCLOSURE engine — the
3
- * framework-free levels/milestones model behind the pure-audio-first call UX
4
- * (persisted per-user via UserInfoEngine under `mj.realtimeVoice.uxMilestones.v1`).
5
- */
6
- import { describe, it, expect } from 'vitest';
7
- import { ClampUxLevel, DefaultUxMilestones, EffectiveBaseLevel, ParseUxMilestones, RatchetedMilestones, RealtimeDisclosureModel, SerializeUxMilestones, REALTIME_UX_MAX_LEVEL, REALTIME_UX_PREF_KEY, REALTIME_UX_PRO_CALLS } from '../lib/components/realtime/realtime-disclosure';
8
- describe('pref key', () => {
9
- it('uses the versioned mj.* naming convention', () => {
10
- expect(REALTIME_UX_PREF_KEY).toBe('mj.realtimeVoice.uxMilestones.v1');
11
- });
12
- });
13
- describe('ClampUxLevel', () => {
14
- it('passes valid levels through and clamps the band edges', () => {
15
- expect(ClampUxLevel(0)).toBe(0);
16
- expect(ClampUxLevel(3)).toBe(3);
17
- expect(ClampUxLevel(-2)).toBe(0);
18
- expect(ClampUxLevel(9)).toBe(REALTIME_UX_MAX_LEVEL);
19
- });
20
- it('rounds fractional and zeroes non-finite levels', () => {
21
- expect(ClampUxLevel(2.6)).toBe(3);
22
- expect(ClampUxLevel(NaN)).toBe(0);
23
- expect(ClampUxLevel(Infinity)).toBe(0);
24
- });
25
- });
26
- describe('ParseUxMilestones / SerializeUxMilestones', () => {
27
- it('round-trips milestones', () => {
28
- const m = { Level: 3, Calls: 7, Density: 'pro' };
29
- expect(ParseUxMilestones(SerializeUxMilestones(m))).toEqual(m);
30
- });
31
- it.each([
32
- ['missing', undefined],
33
- ['null', null],
34
- ['blank', ''],
35
- ['malformed JSON', '{level:'],
36
- ['non-object', '"3"'],
37
- ['JSON null', 'null']
38
- ])('falls back to defaults (never throws) for %s', (_label, raw) => {
39
- expect(ParseUxMilestones(raw)).toEqual(DefaultUxMilestones());
40
- });
41
- it('repairs field-wise: bad level/calls/density fall back individually', () => {
42
- expect(ParseUxMilestones('{"level":"high","calls":2,"density":"standard"}'))
43
- .toEqual({ Level: 0, Calls: 2, Density: 'standard' });
44
- expect(ParseUxMilestones('{"level":3,"calls":-4,"density":"ultra"}'))
45
- .toEqual({ Level: 3, Calls: 0, Density: 'auto' });
46
- expect(ParseUxMilestones('{"level":99,"calls":1.7,"density":"simple"}'))
47
- .toEqual({ Level: REALTIME_UX_MAX_LEVEL, Calls: 2, Density: 'simple' });
48
- });
49
- });
50
- describe('EffectiveBaseLevel', () => {
51
- it('day one: a brand-new user starts at PURE AUDIO (level 0)', () => {
52
- expect(EffectiveBaseLevel(DefaultUxMilestones())).toBe(0);
53
- });
54
- it('auto density follows the earned ratchet', () => {
55
- expect(EffectiveBaseLevel({ Level: 2, Calls: 1, Density: 'auto' })).toBe(2);
56
- });
57
- it(`auto density promotes to the full console after ${REALTIME_UX_PRO_CALLS} completed calls`, () => {
58
- expect(EffectiveBaseLevel({ Level: 1, Calls: REALTIME_UX_PRO_CALLS, Density: 'auto' })).toBe(REALTIME_UX_MAX_LEVEL);
59
- expect(EffectiveBaseLevel({ Level: 1, Calls: REALTIME_UX_PRO_CALLS - 1, Density: 'auto' })).toBe(1);
60
- });
61
- it('manual density overrides win outright (the escape hatch)', () => {
62
- const earned = { Level: 4, Calls: 10, Density: 'simple' };
63
- expect(EffectiveBaseLevel(earned)).toBe(0);
64
- expect(EffectiveBaseLevel({ ...earned, Density: 'standard' })).toBe(2);
65
- expect(EffectiveBaseLevel({ Level: 0, Calls: 0, Density: 'pro' })).toBe(REALTIME_UX_MAX_LEVEL);
66
- });
67
- });
68
- describe('RatchetedMilestones (call end)', () => {
69
- it('increments calls and ratchets the level to the session peak', () => {
70
- expect(RatchetedMilestones({ Level: 1, Calls: 1, Density: 'auto' }, 3))
71
- .toEqual({ Level: 3, Calls: 2, Density: 'auto' });
72
- });
73
- it('a completed first call always earns at least level 1 (text next time)', () => {
74
- expect(RatchetedMilestones(DefaultUxMilestones(), 0))
75
- .toEqual({ Level: 1, Calls: 1, Density: 'auto' });
76
- });
77
- it('NEVER lowers the earned level (ratchet)', () => {
78
- expect(RatchetedMilestones({ Level: 4, Calls: 5, Density: 'auto' }, 0).Level).toBe(4);
79
- });
80
- it('preserves the density override', () => {
81
- expect(RatchetedMilestones({ Level: 0, Calls: 0, Density: 'simple' }, 2).Density).toBe('simple');
82
- });
83
- });
84
- describe('RealtimeDisclosureModel', () => {
85
- it('Load resets the session level to the effective base', () => {
86
- const m = new RealtimeDisclosureModel();
87
- m.Load(SerializeUxMilestones({ Level: 2, Calls: 1, Density: 'auto' }));
88
- expect(m.SessionLevel).toBe(2);
89
- expect(m.ShowThread).toBe(true);
90
- expect(m.ShowComposer).toBe(true);
91
- expect(m.ShowPanel).toBe(true);
92
- expect(m.PowerLevel).toBe(false);
93
- });
94
- it('day one exposes NOTHING beyond pure audio', () => {
95
- const m = new RealtimeDisclosureModel();
96
- m.Load(null);
97
- expect(m.SessionLevel).toBe(0);
98
- expect(m.ShowThread).toBe(false);
99
- expect(m.ShowComposer).toBe(false);
100
- expect(m.ShowPanel).toBe(false);
101
- expect(m.ShowGear).toBe(false);
102
- });
103
- it('Raise only raises — and reports whether anything changed', () => {
104
- const m = new RealtimeDisclosureModel();
105
- m.Load(null);
106
- expect(m.Raise('engaged')).toBe(true);
107
- expect(m.SessionLevel).toBe(2);
108
- expect(m.Raise('text')).toBe(false); // lower event after a higher one: no-op
109
- expect(m.SessionLevel).toBe(2);
110
- expect(m.Raise('channel')).toBe(true);
111
- expect(m.SessionLevel).toBe(3);
112
- });
113
- it('emits Changed$ on raises that change the level (and not on no-ops)', () => {
114
- const m = new RealtimeDisclosureModel();
115
- m.Load(null);
116
- let emissions = 0;
117
- m.Changed$.subscribe(() => emissions++);
118
- m.Raise('text');
119
- m.Raise('text');
120
- expect(emissions).toBe(1);
121
- });
122
- it('BeginSession resets the volatile level back to the base', () => {
123
- const m = new RealtimeDisclosureModel();
124
- m.Load(null);
125
- m.Raise('channel');
126
- m.BeginSession();
127
- expect(m.SessionLevel).toBe(0);
128
- });
129
- it('ReturnToPureAudio steps the volatile level back to 0 WITHOUT touching the ratchet', () => {
130
- const m = new RealtimeDisclosureModel();
131
- m.Load(SerializeUxMilestones({ Level: 2, Calls: 1, Density: 'auto' }));
132
- m.Raise('power');
133
- let emissions = 0;
134
- m.Changed$.subscribe(() => emissions++);
135
- m.ReturnToPureAudio();
136
- expect(m.SessionLevel).toBe(0);
137
- expect(m.ShowThread).toBe(false);
138
- expect(m.Milestones.Level).toBe(2); // the cross-session ratchet is untouched
139
- m.ReturnToPureAudio(); // already there — no extra emission
140
- expect(emissions).toBe(1);
141
- // the user can step back up afterward — the door swings both ways
142
- expect(m.Raise('text')).toBe(true);
143
- expect(m.SessionLevel).toBe(1);
144
- });
145
- it('SetDensity applies immediately — simple retracts even a mid-call console', () => {
146
- const m = new RealtimeDisclosureModel();
147
- m.Load(SerializeUxMilestones({ Level: 4, Calls: 9, Density: 'auto' }));
148
- expect(m.SessionLevel).toBe(4);
149
- m.SetDensity('simple');
150
- expect(m.SessionLevel).toBe(0);
151
- expect(m.Milestones.Density).toBe('simple');
152
- m.SetDensity('pro');
153
- expect(m.SessionLevel).toBe(REALTIME_UX_MAX_LEVEL);
154
- });
155
- it('RatchetOnSessionEnd replaces milestones and returns the persistable payload', () => {
156
- const m = new RealtimeDisclosureModel();
157
- m.Load(null);
158
- m.Raise('channel');
159
- const serialized = m.RatchetOnSessionEnd();
160
- expect(m.Milestones).toEqual({ Level: 3, Calls: 1, Density: 'auto' });
161
- expect(ParseUxMilestones(serialized)).toEqual(m.Milestones);
162
- });
163
- });
164
- //# sourceMappingURL=realtime-disclosure.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"realtime-disclosure.test.js","sourceRoot":"","sources":["../../src/__tests__/realtime-disclosure.test.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Unit tests for the realtime overlay's PROGRESSIVE DISCLOSURE engine — the\n * framework-free levels/milestones model behind the pure-audio-first call UX\n * (persisted per-user via UserInfoEngine under `mj.realtimeVoice.uxMilestones.v1`).\n */\nimport { describe, it, expect } from 'vitest';\nimport {\n ClampUxLevel,\n DefaultUxMilestones,\n EffectiveBaseLevel,\n ParseUxMilestones,\n RatchetedMilestones,\n RealtimeDisclosureModel,\n SerializeUxMilestones,\n REALTIME_UX_MAX_LEVEL,\n REALTIME_UX_PREF_KEY,\n REALTIME_UX_PRO_CALLS\n} from '../lib/components/realtime/realtime-disclosure';\n\ndescribe('pref key', () => {\n it('uses the versioned mj.* naming convention', () => {\n expect(REALTIME_UX_PREF_KEY).toBe('mj.realtimeVoice.uxMilestones.v1');\n });\n});\n\ndescribe('ClampUxLevel', () => {\n it('passes valid levels through and clamps the band edges', () => {\n expect(ClampUxLevel(0)).toBe(0);\n expect(ClampUxLevel(3)).toBe(3);\n expect(ClampUxLevel(-2)).toBe(0);\n expect(ClampUxLevel(9)).toBe(REALTIME_UX_MAX_LEVEL);\n });\n\n it('rounds fractional and zeroes non-finite levels', () => {\n expect(ClampUxLevel(2.6)).toBe(3);\n expect(ClampUxLevel(NaN)).toBe(0);\n expect(ClampUxLevel(Infinity)).toBe(0);\n });\n});\n\ndescribe('ParseUxMilestones / SerializeUxMilestones', () => {\n it('round-trips milestones', () => {\n const m = { Level: 3, Calls: 7, Density: 'pro' as const };\n expect(ParseUxMilestones(SerializeUxMilestones(m))).toEqual(m);\n });\n\n it.each([\n ['missing', undefined],\n ['null', null],\n ['blank', ''],\n ['malformed JSON', '{level:'],\n ['non-object', '\"3\"'],\n ['JSON null', 'null']\n ])('falls back to defaults (never throws) for %s', (_label, raw) => {\n expect(ParseUxMilestones(raw as string | null | undefined)).toEqual(DefaultUxMilestones());\n });\n\n it('repairs field-wise: bad level/calls/density fall back individually', () => {\n expect(ParseUxMilestones('{\"level\":\"high\",\"calls\":2,\"density\":\"standard\"}'))\n .toEqual({ Level: 0, Calls: 2, Density: 'standard' });\n expect(ParseUxMilestones('{\"level\":3,\"calls\":-4,\"density\":\"ultra\"}'))\n .toEqual({ Level: 3, Calls: 0, Density: 'auto' });\n expect(ParseUxMilestones('{\"level\":99,\"calls\":1.7,\"density\":\"simple\"}'))\n .toEqual({ Level: REALTIME_UX_MAX_LEVEL, Calls: 2, Density: 'simple' });\n });\n});\n\ndescribe('EffectiveBaseLevel', () => {\n it('day one: a brand-new user starts at PURE AUDIO (level 0)', () => {\n expect(EffectiveBaseLevel(DefaultUxMilestones())).toBe(0);\n });\n\n it('auto density follows the earned ratchet', () => {\n expect(EffectiveBaseLevel({ Level: 2, Calls: 1, Density: 'auto' })).toBe(2);\n });\n\n it(`auto density promotes to the full console after ${REALTIME_UX_PRO_CALLS} completed calls`, () => {\n expect(EffectiveBaseLevel({ Level: 1, Calls: REALTIME_UX_PRO_CALLS, Density: 'auto' })).toBe(REALTIME_UX_MAX_LEVEL);\n expect(EffectiveBaseLevel({ Level: 1, Calls: REALTIME_UX_PRO_CALLS - 1, Density: 'auto' })).toBe(1);\n });\n\n it('manual density overrides win outright (the escape hatch)', () => {\n const earned = { Level: 4, Calls: 10, Density: 'simple' as const };\n expect(EffectiveBaseLevel(earned)).toBe(0);\n expect(EffectiveBaseLevel({ ...earned, Density: 'standard' })).toBe(2);\n expect(EffectiveBaseLevel({ Level: 0, Calls: 0, Density: 'pro' })).toBe(REALTIME_UX_MAX_LEVEL);\n });\n});\n\ndescribe('RatchetedMilestones (call end)', () => {\n it('increments calls and ratchets the level to the session peak', () => {\n expect(RatchetedMilestones({ Level: 1, Calls: 1, Density: 'auto' }, 3))\n .toEqual({ Level: 3, Calls: 2, Density: 'auto' });\n });\n\n it('a completed first call always earns at least level 1 (text next time)', () => {\n expect(RatchetedMilestones(DefaultUxMilestones(), 0))\n .toEqual({ Level: 1, Calls: 1, Density: 'auto' });\n });\n\n it('NEVER lowers the earned level (ratchet)', () => {\n expect(RatchetedMilestones({ Level: 4, Calls: 5, Density: 'auto' }, 0).Level).toBe(4);\n });\n\n it('preserves the density override', () => {\n expect(RatchetedMilestones({ Level: 0, Calls: 0, Density: 'simple' }, 2).Density).toBe('simple');\n });\n});\n\ndescribe('RealtimeDisclosureModel', () => {\n it('Load resets the session level to the effective base', () => {\n const m = new RealtimeDisclosureModel();\n m.Load(SerializeUxMilestones({ Level: 2, Calls: 1, Density: 'auto' }));\n expect(m.SessionLevel).toBe(2);\n expect(m.ShowThread).toBe(true);\n expect(m.ShowComposer).toBe(true);\n expect(m.ShowPanel).toBe(true);\n expect(m.PowerLevel).toBe(false);\n });\n\n it('day one exposes NOTHING beyond pure audio', () => {\n const m = new RealtimeDisclosureModel();\n m.Load(null);\n expect(m.SessionLevel).toBe(0);\n expect(m.ShowThread).toBe(false);\n expect(m.ShowComposer).toBe(false);\n expect(m.ShowPanel).toBe(false);\n expect(m.ShowGear).toBe(false);\n });\n\n it('Raise only raises — and reports whether anything changed', () => {\n const m = new RealtimeDisclosureModel();\n m.Load(null);\n expect(m.Raise('engaged')).toBe(true);\n expect(m.SessionLevel).toBe(2);\n expect(m.Raise('text')).toBe(false); // lower event after a higher one: no-op\n expect(m.SessionLevel).toBe(2);\n expect(m.Raise('channel')).toBe(true);\n expect(m.SessionLevel).toBe(3);\n });\n\n it('emits Changed$ on raises that change the level (and not on no-ops)', () => {\n const m = new RealtimeDisclosureModel();\n m.Load(null);\n let emissions = 0;\n m.Changed$.subscribe(() => emissions++);\n m.Raise('text');\n m.Raise('text');\n expect(emissions).toBe(1);\n });\n\n it('BeginSession resets the volatile level back to the base', () => {\n const m = new RealtimeDisclosureModel();\n m.Load(null);\n m.Raise('channel');\n m.BeginSession();\n expect(m.SessionLevel).toBe(0);\n });\n\n it('ReturnToPureAudio steps the volatile level back to 0 WITHOUT touching the ratchet', () => {\n const m = new RealtimeDisclosureModel();\n m.Load(SerializeUxMilestones({ Level: 2, Calls: 1, Density: 'auto' }));\n m.Raise('power');\n let emissions = 0;\n m.Changed$.subscribe(() => emissions++);\n\n m.ReturnToPureAudio();\n expect(m.SessionLevel).toBe(0);\n expect(m.ShowThread).toBe(false);\n expect(m.Milestones.Level).toBe(2); // the cross-session ratchet is untouched\n m.ReturnToPureAudio(); // already there — no extra emission\n expect(emissions).toBe(1);\n\n // the user can step back up afterward — the door swings both ways\n expect(m.Raise('text')).toBe(true);\n expect(m.SessionLevel).toBe(1);\n });\n\n it('SetDensity applies immediately — simple retracts even a mid-call console', () => {\n const m = new RealtimeDisclosureModel();\n m.Load(SerializeUxMilestones({ Level: 4, Calls: 9, Density: 'auto' }));\n expect(m.SessionLevel).toBe(4);\n m.SetDensity('simple');\n expect(m.SessionLevel).toBe(0);\n expect(m.Milestones.Density).toBe('simple');\n m.SetDensity('pro');\n expect(m.SessionLevel).toBe(REALTIME_UX_MAX_LEVEL);\n });\n\n it('RatchetOnSessionEnd replaces milestones and returns the persistable payload', () => {\n const m = new RealtimeDisclosureModel();\n m.Load(null);\n m.Raise('channel');\n const serialized = m.RatchetOnSessionEnd();\n expect(m.Milestones).toEqual({ Level: 3, Calls: 1, Density: 'auto' });\n expect(ParseUxMilestones(serialized)).toEqual(m.Milestones);\n });\n});\n"]}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=realtime-pairing.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"realtime-pairing.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/realtime-pairing.test.ts"],"names":[],"mappings":""}
@@ -1,207 +0,0 @@
1
- import { describe, it, expect, vi, afterEach } from 'vitest';
2
- import { AIEngineBase } from '@memberjunction/ai-engine-base';
3
- import { BuildRealtimeConfigOverridesJson, ConstrainTargetsToPairings, DefaultPairedTargetId, FilterRealtimeCoAgents, LoadCoAgentPairings, PairingsAllowTarget, SortPairings, } from '../lib/services/realtime-pairing';
4
- /**
5
- * Pure co-agent pairing helpers — the client side of the `MJ: AI Agent Co Agents`
6
- * semantics: a co-agent with ZERO rows is universal (today's flow untouched); with rows,
7
- * its allowed targets are exactly those rows (Sequence order, IsDefault preselected).
8
- * Also covers the pinned `configOverridesJson` envelope builder and the Realtime-type
9
- * co-agent filter.
10
- */
11
- const CO_AGENT = 'C0000000-0000-0000-0000-000000000001';
12
- function pairing(overrides) {
13
- return {
14
- ID: `P-${overrides.TargetAgentID}`,
15
- CoAgentID: CO_AGENT,
16
- TargetAgent: null,
17
- IsDefault: false,
18
- Sequence: 0,
19
- Type: 'CoAgent',
20
- Status: 'Active',
21
- ...overrides,
22
- };
23
- }
24
- const TARGET_A = 'A0000000-0000-0000-0000-00000000000A';
25
- const TARGET_B = 'B0000000-0000-0000-0000-00000000000B';
26
- const TARGET_C = 'D0000000-0000-0000-0000-00000000000D';
27
- const agents = [
28
- { ID: TARGET_A, Name: 'Alpha' },
29
- { ID: TARGET_B, Name: 'Beta' },
30
- { ID: TARGET_C, Name: 'Gamma' },
31
- ];
32
- describe('ConstrainTargetsToPairings', () => {
33
- it('returns the candidates unchanged when there are zero pairing rows (universal co-agent)', () => {
34
- const result = ConstrainTargetsToPairings(agents, []);
35
- expect(result.map(a => a.ID)).toEqual([TARGET_A, TARGET_B, TARGET_C]);
36
- });
37
- it('constrains to exactly the paired targets, in pairing Sequence order', () => {
38
- const pairings = [
39
- pairing({ TargetAgentID: TARGET_C, Sequence: 2 }),
40
- pairing({ TargetAgentID: TARGET_B, Sequence: 1 }),
41
- ];
42
- const result = ConstrainTargetsToPairings(agents, pairings);
43
- expect(result.map(a => a.Name)).toEqual(['Beta', 'Gamma']);
44
- });
45
- it('silently drops paired targets the user cannot see/run (absent from the candidate list)', () => {
46
- const pairings = [
47
- pairing({ TargetAgentID: 'F0000000-0000-0000-0000-0000000000FF', Sequence: 1 }),
48
- pairing({ TargetAgentID: TARGET_A, Sequence: 2 }),
49
- ];
50
- const result = ConstrainTargetsToPairings(agents, pairings);
51
- expect(result.map(a => a.ID)).toEqual([TARGET_A]);
52
- });
53
- it('matches target ids across UUID casing and de-duplicates repeated targets', () => {
54
- const pairings = [
55
- pairing({ TargetAgentID: TARGET_B.toLowerCase(), Sequence: 1 }),
56
- pairing({ TargetAgentID: TARGET_B.toUpperCase(), Sequence: 2 }),
57
- ];
58
- const result = ConstrainTargetsToPairings(agents, pairings);
59
- expect(result.map(a => a.ID)).toEqual([TARGET_B]);
60
- });
61
- });
62
- describe('SortPairings', () => {
63
- it('orders by Sequence ascending with null sequences last, ties by target name', () => {
64
- const rows = [
65
- pairing({ TargetAgentID: TARGET_A, Sequence: null, TargetAgent: 'Alpha' }),
66
- pairing({ TargetAgentID: TARGET_C, Sequence: 1, TargetAgent: 'Gamma' }),
67
- pairing({ TargetAgentID: TARGET_B, Sequence: 1, TargetAgent: 'Beta' }),
68
- ];
69
- expect(SortPairings(rows).map(r => r.TargetAgentID)).toEqual([TARGET_B, TARGET_C, TARGET_A]);
70
- });
71
- it('does not mutate the input array', () => {
72
- const rows = [pairing({ TargetAgentID: TARGET_B, Sequence: 2 }), pairing({ TargetAgentID: TARGET_A, Sequence: 1 })];
73
- SortPairings(rows);
74
- expect(rows[0].TargetAgentID).toBe(TARGET_B);
75
- });
76
- });
77
- describe('DefaultPairedTargetId', () => {
78
- it('returns the IsDefault row target', () => {
79
- const pairings = [
80
- pairing({ TargetAgentID: TARGET_A, Sequence: 1 }),
81
- pairing({ TargetAgentID: TARGET_B, Sequence: 2, IsDefault: true }),
82
- ];
83
- expect(DefaultPairedTargetId(pairings)).toBe(TARGET_B);
84
- });
85
- it('returns the FIRST default in Sequence order when (defensively) more than one exists', () => {
86
- const pairings = [
87
- pairing({ TargetAgentID: TARGET_B, Sequence: 2, IsDefault: true }),
88
- pairing({ TargetAgentID: TARGET_A, Sequence: 1, IsDefault: true }),
89
- ];
90
- expect(DefaultPairedTargetId(pairings)).toBe(TARGET_A);
91
- });
92
- it('returns null when no row is marked default or there are no rows', () => {
93
- expect(DefaultPairedTargetId([pairing({ TargetAgentID: TARGET_A })])).toBeNull();
94
- expect(DefaultPairedTargetId([])).toBeNull();
95
- });
96
- });
97
- describe('PairingsAllowTarget', () => {
98
- it('always allows when there are zero rows (universal co-agent)', () => {
99
- expect(PairingsAllowTarget([], TARGET_A)).toBe(true);
100
- expect(PairingsAllowTarget([], null)).toBe(true);
101
- });
102
- it('allows only the paired targets when rows exist (UUID-casing safe)', () => {
103
- const pairings = [pairing({ TargetAgentID: TARGET_A })];
104
- expect(PairingsAllowTarget(pairings, TARGET_A.toLowerCase())).toBe(true);
105
- expect(PairingsAllowTarget(pairings, TARGET_B)).toBe(false);
106
- });
107
- it('never allows a missing target against a constrained co-agent', () => {
108
- expect(PairingsAllowTarget([pairing({ TargetAgentID: TARGET_A })], null)).toBe(false);
109
- expect(PairingsAllowTarget([pairing({ TargetAgentID: TARGET_A })], '')).toBe(false);
110
- });
111
- });
112
- describe('FilterRealtimeCoAgents', () => {
113
- it('keeps only agents whose Type is Realtime (trim + case-insensitive)', () => {
114
- const candidates = [
115
- { ID: '1', Type: 'Realtime' },
116
- { ID: '2', Type: ' realtime ' },
117
- { ID: '3', Type: 'Loop' },
118
- { ID: '4', Type: null },
119
- ];
120
- expect(FilterRealtimeCoAgents(candidates).map(a => a.ID)).toEqual(['1', '2']);
121
- });
122
- });
123
- describe('LoadCoAgentPairings', () => {
124
- afterEach(() => {
125
- vi.restoreAllMocks();
126
- });
127
- /**
128
- * Stubs the provider-scoped AIEngineBase the loader reads (suite convention: spy on the
129
- * static `GetProviderInstance`, the way other suites spy `AIEngineBase.Instance`). The
130
- * engine cache — not a RunView — is the only data surface the loader touches.
131
- */
132
- function engineReturning(rows) {
133
- const config = vi.fn(async () => {
134
- if (rows instanceof Error) {
135
- throw rows;
136
- }
137
- });
138
- const fakeEngine = {
139
- Config: config,
140
- get AgentCoAgents() {
141
- if (rows instanceof Error) {
142
- throw rows;
143
- }
144
- return rows;
145
- },
146
- };
147
- const getProviderInstance = vi
148
- .spyOn(AIEngineBase, 'GetProviderInstance')
149
- .mockReturnValue(fakeEngine);
150
- return { provider: {}, config, getProviderInstance };
151
- }
152
- it('reads the engine cache filtered to the co-agent (UUID-casing safe) and returns Sequence order', async () => {
153
- const { provider, config, getProviderInstance } = engineReturning([
154
- pairing({ TargetAgentID: TARGET_B, Sequence: 2, CoAgentID: CO_AGENT.toLowerCase() }),
155
- pairing({ TargetAgentID: TARGET_A, Sequence: 1 }),
156
- // Another co-agent's row — must be filtered out client-side.
157
- pairing({ TargetAgentID: TARGET_C, Sequence: 0, CoAgentID: 'E0000000-0000-0000-0000-0000000000EE' }),
158
- // Disabled row — ignored by resolution/pickers.
159
- pairing({ TargetAgentID: TARGET_C, Sequence: 0, Status: 'Disabled' }),
160
- // Reserved relationship type — ignored until its feature ships.
161
- pairing({ TargetAgentID: TARGET_C, Sequence: 0, Type: 'Peer' }),
162
- ]);
163
- const rows = await LoadCoAgentPairings(provider, CO_AGENT);
164
- expect(rows.map(r => r.TargetAgentID)).toEqual([TARGET_A, TARGET_B]);
165
- // Provider-scoped engine instance, lazily configured against the SAME provider.
166
- expect(getProviderInstance).toHaveBeenCalledWith(provider, AIEngineBase);
167
- expect(config).toHaveBeenCalledWith(false, undefined, provider);
168
- });
169
- it('returns plain projected rows carrying the pairing fields the UI consumes', async () => {
170
- const { provider } = engineReturning([
171
- pairing({ TargetAgentID: TARGET_A, Sequence: 3, IsDefault: true, TargetAgent: 'Alpha' }),
172
- ]);
173
- const rows = await LoadCoAgentPairings(provider, CO_AGENT);
174
- expect(rows).toEqual([
175
- {
176
- ID: `P-${TARGET_A}`,
177
- CoAgentID: CO_AGENT,
178
- TargetAgentID: TARGET_A,
179
- TargetAgent: 'Alpha',
180
- IsDefault: true,
181
- Sequence: 3,
182
- },
183
- ]);
184
- });
185
- it('degrades to an empty list (no constraint) when the engine load throws', async () => {
186
- const { provider } = engineReturning(new Error('offline'));
187
- await expect(LoadCoAgentPairings(provider, CO_AGENT)).resolves.toEqual([]);
188
- });
189
- it('returns an empty list without touching the engine when the co-agent id is blank', async () => {
190
- const { provider, getProviderInstance } = engineReturning([]);
191
- await expect(LoadCoAgentPairings(provider, ' ')).resolves.toEqual([]);
192
- expect(getProviderInstance).not.toHaveBeenCalled();
193
- });
194
- });
195
- describe('BuildRealtimeConfigOverridesJson', () => {
196
- it('returns null when nothing was overridden', () => {
197
- expect(BuildRealtimeConfigOverridesJson(null)).toBeNull();
198
- expect(BuildRealtimeConfigOverridesJson(undefined)).toBeNull();
199
- expect(BuildRealtimeConfigOverridesJson(' ')).toBeNull();
200
- });
201
- it('emits the pinned override envelope for an explicit model pick', () => {
202
- const json = BuildRealtimeConfigOverridesJson('model-77');
203
- expect(json).toBe('{"realtime":{"modelPreference":"model-77"}}');
204
- expect(JSON.parse(json)).toEqual({ realtime: { modelPreference: 'model-77' } });
205
- });
206
- });
207
- //# sourceMappingURL=realtime-pairing.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"realtime-pairing.test.js","sourceRoot":"","sources":["../../src/__tests__/realtime-pairing.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { describe, it, expect, vi, afterEach } from 'vitest';\nimport { IMetadataProvider } from '@memberjunction/core';\nimport { AIEngineBase } from '@memberjunction/ai-engine-base';\nimport {\n BuildRealtimeConfigOverridesJson,\n ConstrainTargetsToPairings,\n DefaultPairedTargetId,\n FilterRealtimeCoAgents,\n LoadCoAgentPairings,\n PairingsAllowTarget,\n SortPairings,\n RealtimePairedAgentRow,\n} from '../lib/services/realtime-pairing';\n\n/**\n * Pure co-agent pairing helpers — the client side of the `MJ: AI Agent Co Agents`\n * semantics: a co-agent with ZERO rows is universal (today's flow untouched); with rows,\n * its allowed targets are exactly those rows (Sequence order, IsDefault preselected).\n * Also covers the pinned `configOverridesJson` envelope builder and the Realtime-type\n * co-agent filter.\n */\n\nconst CO_AGENT = 'C0000000-0000-0000-0000-000000000001';\n\n/** The engine-cache row shape LoadCoAgentPairings filters on (the new AIAgentCoAgent contract). */\ninterface FakeCoAgentEngineRow extends RealtimePairedAgentRow {\n Type: 'CoAgent' | 'Peer';\n Status: 'Active' | 'Disabled';\n TargetAgentTypeID?: string | null;\n}\n\nfunction pairing(overrides: Partial<FakeCoAgentEngineRow> & { TargetAgentID: string }): FakeCoAgentEngineRow {\n return {\n ID: `P-${overrides.TargetAgentID}`,\n CoAgentID: CO_AGENT,\n TargetAgent: null,\n IsDefault: false,\n Sequence: 0,\n Type: 'CoAgent',\n Status: 'Active',\n ...overrides,\n };\n}\n\nconst TARGET_A = 'A0000000-0000-0000-0000-00000000000A';\nconst TARGET_B = 'B0000000-0000-0000-0000-00000000000B';\nconst TARGET_C = 'D0000000-0000-0000-0000-00000000000D';\n\ninterface FakeAgent { ID: string; Name: string }\nconst agents: FakeAgent[] = [\n { ID: TARGET_A, Name: 'Alpha' },\n { ID: TARGET_B, Name: 'Beta' },\n { ID: TARGET_C, Name: 'Gamma' },\n];\n\ndescribe('ConstrainTargetsToPairings', () => {\n it('returns the candidates unchanged when there are zero pairing rows (universal co-agent)', () => {\n const result = ConstrainTargetsToPairings(agents, []);\n expect(result.map(a => a.ID)).toEqual([TARGET_A, TARGET_B, TARGET_C]);\n });\n\n it('constrains to exactly the paired targets, in pairing Sequence order', () => {\n const pairings = [\n pairing({ TargetAgentID: TARGET_C, Sequence: 2 }),\n pairing({ TargetAgentID: TARGET_B, Sequence: 1 }),\n ];\n const result = ConstrainTargetsToPairings(agents, pairings);\n expect(result.map(a => a.Name)).toEqual(['Beta', 'Gamma']);\n });\n\n it('silently drops paired targets the user cannot see/run (absent from the candidate list)', () => {\n const pairings = [\n pairing({ TargetAgentID: 'F0000000-0000-0000-0000-0000000000FF', Sequence: 1 }),\n pairing({ TargetAgentID: TARGET_A, Sequence: 2 }),\n ];\n const result = ConstrainTargetsToPairings(agents, pairings);\n expect(result.map(a => a.ID)).toEqual([TARGET_A]);\n });\n\n it('matches target ids across UUID casing and de-duplicates repeated targets', () => {\n const pairings = [\n pairing({ TargetAgentID: TARGET_B.toLowerCase(), Sequence: 1 }),\n pairing({ TargetAgentID: TARGET_B.toUpperCase(), Sequence: 2 }),\n ];\n const result = ConstrainTargetsToPairings(agents, pairings);\n expect(result.map(a => a.ID)).toEqual([TARGET_B]);\n });\n});\n\ndescribe('SortPairings', () => {\n it('orders by Sequence ascending with null sequences last, ties by target name', () => {\n const rows = [\n pairing({ TargetAgentID: TARGET_A, Sequence: null, TargetAgent: 'Alpha' }),\n pairing({ TargetAgentID: TARGET_C, Sequence: 1, TargetAgent: 'Gamma' }),\n pairing({ TargetAgentID: TARGET_B, Sequence: 1, TargetAgent: 'Beta' }),\n ];\n expect(SortPairings(rows).map(r => r.TargetAgentID)).toEqual([TARGET_B, TARGET_C, TARGET_A]);\n });\n\n it('does not mutate the input array', () => {\n const rows = [pairing({ TargetAgentID: TARGET_B, Sequence: 2 }), pairing({ TargetAgentID: TARGET_A, Sequence: 1 })];\n SortPairings(rows);\n expect(rows[0].TargetAgentID).toBe(TARGET_B);\n });\n});\n\ndescribe('DefaultPairedTargetId', () => {\n it('returns the IsDefault row target', () => {\n const pairings = [\n pairing({ TargetAgentID: TARGET_A, Sequence: 1 }),\n pairing({ TargetAgentID: TARGET_B, Sequence: 2, IsDefault: true }),\n ];\n expect(DefaultPairedTargetId(pairings)).toBe(TARGET_B);\n });\n\n it('returns the FIRST default in Sequence order when (defensively) more than one exists', () => {\n const pairings = [\n pairing({ TargetAgentID: TARGET_B, Sequence: 2, IsDefault: true }),\n pairing({ TargetAgentID: TARGET_A, Sequence: 1, IsDefault: true }),\n ];\n expect(DefaultPairedTargetId(pairings)).toBe(TARGET_A);\n });\n\n it('returns null when no row is marked default or there are no rows', () => {\n expect(DefaultPairedTargetId([pairing({ TargetAgentID: TARGET_A })])).toBeNull();\n expect(DefaultPairedTargetId([])).toBeNull();\n });\n});\n\ndescribe('PairingsAllowTarget', () => {\n it('always allows when there are zero rows (universal co-agent)', () => {\n expect(PairingsAllowTarget([], TARGET_A)).toBe(true);\n expect(PairingsAllowTarget([], null)).toBe(true);\n });\n\n it('allows only the paired targets when rows exist (UUID-casing safe)', () => {\n const pairings = [pairing({ TargetAgentID: TARGET_A })];\n expect(PairingsAllowTarget(pairings, TARGET_A.toLowerCase())).toBe(true);\n expect(PairingsAllowTarget(pairings, TARGET_B)).toBe(false);\n });\n\n it('never allows a missing target against a constrained co-agent', () => {\n expect(PairingsAllowTarget([pairing({ TargetAgentID: TARGET_A })], null)).toBe(false);\n expect(PairingsAllowTarget([pairing({ TargetAgentID: TARGET_A })], '')).toBe(false);\n });\n});\n\ndescribe('FilterRealtimeCoAgents', () => {\n it('keeps only agents whose Type is Realtime (trim + case-insensitive)', () => {\n const candidates = [\n { ID: '1', Type: 'Realtime' },\n { ID: '2', Type: ' realtime ' },\n { ID: '3', Type: 'Loop' },\n { ID: '4', Type: null },\n ];\n expect(FilterRealtimeCoAgents(candidates).map(a => a.ID)).toEqual(['1', '2']);\n });\n});\n\ndescribe('LoadCoAgentPairings', () => {\n afterEach(() => {\n vi.restoreAllMocks();\n });\n\n /**\n * Stubs the provider-scoped AIEngineBase the loader reads (suite convention: spy on the\n * static `GetProviderInstance`, the way other suites spy `AIEngineBase.Instance`). The\n * engine cache — not a RunView — is the only data surface the loader touches.\n */\n function engineReturning(rows: FakeCoAgentEngineRow[] | Error): {\n provider: IMetadataProvider;\n config: ReturnType<typeof vi.fn>;\n getProviderInstance: ReturnType<typeof vi.spyOn>;\n } {\n const config = vi.fn(async () => {\n if (rows instanceof Error) {\n throw rows;\n }\n });\n const fakeEngine = {\n Config: config,\n get AgentCoAgents(): FakeCoAgentEngineRow[] {\n if (rows instanceof Error) {\n throw rows;\n }\n return rows;\n },\n };\n const getProviderInstance = vi\n .spyOn(AIEngineBase, 'GetProviderInstance')\n .mockReturnValue(fakeEngine as unknown as AIEngineBase);\n return { provider: {} as IMetadataProvider, config, getProviderInstance };\n }\n\n it('reads the engine cache filtered to the co-agent (UUID-casing safe) and returns Sequence order', async () => {\n const { provider, config, getProviderInstance } = engineReturning([\n pairing({ TargetAgentID: TARGET_B, Sequence: 2, CoAgentID: CO_AGENT.toLowerCase() }),\n pairing({ TargetAgentID: TARGET_A, Sequence: 1 }),\n // Another co-agent's row — must be filtered out client-side.\n pairing({ TargetAgentID: TARGET_C, Sequence: 0, CoAgentID: 'E0000000-0000-0000-0000-0000000000EE' }),\n // Disabled row — ignored by resolution/pickers.\n pairing({ TargetAgentID: TARGET_C, Sequence: 0, Status: 'Disabled' }),\n // Reserved relationship type — ignored until its feature ships.\n pairing({ TargetAgentID: TARGET_C, Sequence: 0, Type: 'Peer' }),\n ]);\n const rows = await LoadCoAgentPairings(provider, CO_AGENT);\n expect(rows.map(r => r.TargetAgentID)).toEqual([TARGET_A, TARGET_B]);\n // Provider-scoped engine instance, lazily configured against the SAME provider.\n expect(getProviderInstance).toHaveBeenCalledWith(provider, AIEngineBase);\n expect(config).toHaveBeenCalledWith(false, undefined, provider);\n });\n\n it('returns plain projected rows carrying the pairing fields the UI consumes', async () => {\n const { provider } = engineReturning([\n pairing({ TargetAgentID: TARGET_A, Sequence: 3, IsDefault: true, TargetAgent: 'Alpha' }),\n ]);\n const rows = await LoadCoAgentPairings(provider, CO_AGENT);\n expect(rows).toEqual([\n {\n ID: `P-${TARGET_A}`,\n CoAgentID: CO_AGENT,\n TargetAgentID: TARGET_A,\n TargetAgent: 'Alpha',\n IsDefault: true,\n Sequence: 3,\n },\n ]);\n });\n\n it('degrades to an empty list (no constraint) when the engine load throws', async () => {\n const { provider } = engineReturning(new Error('offline'));\n await expect(LoadCoAgentPairings(provider, CO_AGENT)).resolves.toEqual([]);\n });\n\n it('returns an empty list without touching the engine when the co-agent id is blank', async () => {\n const { provider, getProviderInstance } = engineReturning([]);\n await expect(LoadCoAgentPairings(provider, ' ')).resolves.toEqual([]);\n expect(getProviderInstance).not.toHaveBeenCalled();\n });\n});\n\ndescribe('BuildRealtimeConfigOverridesJson', () => {\n it('returns null when nothing was overridden', () => {\n expect(BuildRealtimeConfigOverridesJson(null)).toBeNull();\n expect(BuildRealtimeConfigOverridesJson(undefined)).toBeNull();\n expect(BuildRealtimeConfigOverridesJson(' ')).toBeNull();\n });\n\n it('emits the pinned override envelope for an explicit model pick', () => {\n const json = BuildRealtimeConfigOverridesJson('model-77');\n expect(json).toBe('{\"realtime\":{\"modelPreference\":\"model-77\"}}');\n expect(JSON.parse(json as string)).toEqual({ realtime: { modelPreference: 'model-77' } });\n });\n});\n"]}
@@ -1,2 +0,0 @@
1
- import '@angular/compiler';
2
- //# sourceMappingURL=realtime-review-lifecycle.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"realtime-review-lifecycle.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/realtime-review-lifecycle.test.ts"],"names":[],"mappings":"AAEA,OAAO,mBAAmB,CAAC"}