@memberjunction/ng-conversations 5.40.1 → 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
@@ -1,11 +1,14 @@
1
1
  import { Component, Input, Output, EventEmitter, ViewChild } from '@angular/core';
2
2
  import { BaseAngularComponent } from '@memberjunction/ng-base-types';
3
- import { MJEnvironmentEntityExtended, ConversationEngine } from '@memberjunction/core-entities';
4
- import { GraphQLDataProvider, GraphQLAIClient } from '@memberjunction/graphql-dataprovider';
3
+ import { MJEnvironmentEntityExtended, ConversationEngine, UserInfoEngine } from '@memberjunction/core-entities';
4
+ import { BeforeAgentTurnEventArgs, AfterAgentTurnEventArgs } from '../../events/chat-events';
5
+ import { GraphQLDataProvider } from '@memberjunction/graphql-dataprovider';
6
+ import { GenerateAndApplyConversationName } from '../../services/conversation-naming';
5
7
  import { AIEngineBase } from '@memberjunction/ai-engine-base';
6
8
  import { ConversationUtility } from '@memberjunction/ai-core-plus';
7
9
  import { MJNotificationService } from '@memberjunction/ng-notifications';
8
- import { UUIDsEqual, CleanAndParseJSON } from '@memberjunction/global';
10
+ import { BuildRealtimeConfigOverridesJson, FilterRealtimeCoAgents, LoadCoAgentPairings, PairingsAllowTarget } from '../../services/realtime-pairing';
11
+ import { UUIDsEqual } from '@memberjunction/global';
9
12
  import * as i0 from "@angular/core";
10
13
  import * as i1 from "../../services/dialog.service";
11
14
  import * as i2 from "../../services/toast.service";
@@ -17,11 +20,13 @@ import * as i7 from "../../services/mention-parser.service";
17
20
  import * as i8 from "../../services/mention-autocomplete.service";
18
21
  import * as i9 from "../../services/conversation-attachment.service";
19
22
  import * as i10 from "../../services/conversation-bridge.service";
20
- import * as i11 from "./message-input-box.component";
23
+ import * as i11 from "../../services/realtime-session.service";
24
+ import * as i12 from "../realtime/realtime-agent-picker.component";
25
+ import * as i13 from "./message-input-box.component";
21
26
  const _c0 = ["inputBox"];
22
27
  function MessageInputComponent_Conditional_1_Template(rf, ctx) { if (rf & 1) {
23
28
  i0.ɵɵelementStart(0, "div", 2);
24
- i0.ɵɵelement(1, "i", 4);
29
+ i0.ɵɵelement(1, "i", 5);
25
30
  i0.ɵɵelementStart(2, "span");
26
31
  i0.ɵɵtext(3);
27
32
  i0.ɵɵelementEnd()();
@@ -30,6 +35,15 @@ function MessageInputComponent_Conditional_1_Template(rf, ctx) { if (rf & 1) {
30
35
  i0.ɵɵadvance(3);
31
36
  i0.ɵɵtextInterpolate(ctx_r1.processingMessage);
32
37
  } }
38
+ function MessageInputComponent_Conditional_4_Template(rf, ctx) { if (rf & 1) {
39
+ const _r3 = i0.ɵɵgetCurrentView();
40
+ i0.ɵɵelementStart(0, "mj-realtime-agent-picker", 6);
41
+ i0.ɵɵlistener("AgentPicked", function MessageInputComponent_Conditional_4_Template_mj_realtime_agent_picker_AgentPicked_0_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onRealtimeAgentPicked($event)); })("Cancelled", function MessageInputComponent_Conditional_4_Template_mj_realtime_agent_picker_Cancelled_0_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onRealtimeAgentPickerCancelled()); });
42
+ i0.ɵɵelementEnd();
43
+ } if (rf & 2) {
44
+ const ctx_r1 = i0.ɵɵnextContext();
45
+ i0.ɵɵproperty("Provider", ctx_r1.Provider)("Agents", ctx_r1.voicePickerAgents)("DefaultAgentId", ctx_r1.voicePickerDefaultAgentId)("CoAgents", ctx_r1.voicePickerCoAgents)("DefaultCoAgentId", ctx_r1.voicePickerDefaultCoAgentId);
46
+ } }
33
47
  export class MessageInputComponent extends BaseAngularComponent {
34
48
  dialogService;
35
49
  toastService;
@@ -41,6 +55,7 @@ export class MessageInputComponent extends BaseAngularComponent {
41
55
  mentionAutocomplete;
42
56
  attachmentService;
43
57
  bridge;
58
+ voiceSession;
44
59
  // Default artifact type ID for JSON (when agent doesn't specify DefaultArtifactTypeID)
45
60
  JSON_ARTIFACT_TYPE_ID = 'ae674c7e-ea0d-49ea-89e4-0649f5eb20d4';
46
61
  conversationId;
@@ -153,8 +168,29 @@ export class MessageInputComponent extends BaseAngularComponent {
153
168
  get inProgressMessageIds() {
154
169
  return this._inProgressMessageIds;
155
170
  }
171
+ /**
172
+ * Application context for the current conversation. Threaded through from the
173
+ * chat-area component for inclusion in the {@link beforeAgentTurn} event payload —
174
+ * lets listeners reason about which app's chat surface is invoking the agent.
175
+ * Optional; defaults to null for surfaces with no app context.
176
+ */
177
+ applicationId = null;
156
178
  messageSent = new EventEmitter();
157
179
  agentResponse = new EventEmitter();
180
+ /**
181
+ * Cancelable — fired BEFORE `agentService.processMessage()` is called for a user turn.
182
+ * Listeners may set `event.Cancel = true` to halt the agent invocation (e.g., a
183
+ * client-side guardrail blocking the turn). When canceled, the corresponding
184
+ * {@link afterAgentTurn} event is NOT fired and the running task is cleared.
185
+ * Follows MJ's established Before/After cancelable event pattern.
186
+ */
187
+ beforeAgentTurn = new EventEmitter();
188
+ /**
189
+ * Fired AFTER a successful agent turn completes. Carries the agent run id and the
190
+ * full agent result. Not fired when {@link beforeAgentTurn} was canceled or when
191
+ * the underlying `processMessage` errored.
192
+ */
193
+ afterAgentTurn = new EventEmitter();
158
194
  agentRunDetected = new EventEmitter();
159
195
  agentRunUpdate = new EventEmitter(); // Emits when agent run data updates during progress
160
196
  messageComplete = new EventEmitter(); // Emits when message completes (success or error)
@@ -180,7 +216,7 @@ export class MessageInputComponent extends BaseAngularComponent {
180
216
  // Track pending attachments from the input box
181
217
  pendingAttachments = [];
182
218
  engine = ConversationEngine.Instance;
183
- constructor(dialogService, toastService, agentService, dataCache, activeTasks, streamingService, mentionParser, mentionAutocomplete, attachmentService, bridge) {
219
+ constructor(dialogService, toastService, agentService, dataCache, activeTasks, streamingService, mentionParser, mentionAutocomplete, attachmentService, bridge, voiceSession) {
184
220
  super();
185
221
  this.dialogService = dialogService;
186
222
  this.toastService = toastService;
@@ -192,7 +228,12 @@ export class MessageInputComponent extends BaseAngularComponent {
192
228
  this.mentionAutocomplete = mentionAutocomplete;
193
229
  this.attachmentService = attachmentService;
194
230
  this.bridge = bridge;
231
+ this.voiceSession = voiceSession;
195
232
  }
233
+ // ── Voice session (Realtime Co-Agent) ───────────────────────────────
234
+ /** True while a live voice session is active — drives the overlay + mic state. */
235
+ voiceActive = false;
236
+ voiceActiveSub;
196
237
  async ngOnInit() {
197
238
  // Bind provider-aware services to this component's provider.
198
239
  const p = this.ProviderToUse;
@@ -200,6 +241,11 @@ export class MessageInputComponent extends BaseAngularComponent {
200
241
  this.dataCache.Provider = p;
201
242
  this.activeTasks.Provider = p;
202
243
  this.attachmentService.Provider = p;
244
+ this.voiceSession.Provider = p;
245
+ // Reflect the live voice-session Active flag into a local field for the template.
246
+ this.voiceActiveSub = this.voiceSession.Active$.subscribe(active => {
247
+ this.voiceActive = active;
248
+ });
203
249
  this.converationManagerAgent = await this.agentService.getConversationManagerAgent();
204
250
  // Initialize mention autocomplete (needed for parsing mentions in messages)
205
251
  await this.mentionAutocomplete.initialize(this.currentUser);
@@ -242,6 +288,219 @@ export class MessageInputComponent extends BaseAngularComponent {
242
288
  ngOnDestroy() {
243
289
  // Unregister all streaming callbacks
244
290
  this.unregisterAllCallbacks();
291
+ this.voiceActiveSub?.unsubscribe();
292
+ // If the user navigates away mid-call, tear the session down.
293
+ if (this.voiceSession.IsActive) {
294
+ void this.voiceSession.EndVoiceSession();
295
+ }
296
+ }
297
+ /**
298
+ * Resolve the agent the voice session should front for THIS conversation.
299
+ * Mirrors the routing precedence used for text turns ({@link routeMessage}):
300
+ * 1. last non-Sage agent (continuity)
301
+ * 2. per-conversation pinned default
302
+ * 3. embedder-supplied default
303
+ * 4. Sage fallback
304
+ * Returns null only if Sage itself failed to load.
305
+ */
306
+ resolveCurrentAgentId() {
307
+ return this.findLastNonSageAgentId()
308
+ ?? this.conversationDefaultAgentId
309
+ ?? this.defaultAgentId
310
+ ?? this.converationManagerAgent?.ID
311
+ ?? null;
312
+ }
313
+ /** True when the mic button should be enabled (have an agent + not disabled). */
314
+ get canStartVoice() {
315
+ return !this.disabled && !this.voiceActive && !!this.resolveCurrentAgentId();
316
+ }
317
+ /**
318
+ * Display name of the agent the voice session fronts. Resolved here (this component
319
+ * owns the conversation's routing context) and passed to RealtimeSessionService at
320
+ * session start so the chat-area-hosted overlay can read it from the service.
321
+ */
322
+ resolveVoiceAgentName() {
323
+ const agentId = this.resolveCurrentAgentId();
324
+ if (agentId) {
325
+ const match = this.mentionAutocomplete
326
+ .getAvailableAgents()
327
+ .find(a => UUIDsEqual(a.ID, agentId));
328
+ if (match?.Name) {
329
+ return match.Name;
330
+ }
331
+ }
332
+ return this.converationManagerAgent?.Name ?? 'Sage';
333
+ }
334
+ /** True while the "Start a voice call with…" agent picker popover is open. */
335
+ showRealtimeAgentPicker = false;
336
+ /**
337
+ * `MJ: User Settings` key persisting the user's co-agent choice for realtime calls
338
+ * (server-side, cross-device — never localStorage). Stored shape: `{"coAgentId":
339
+ * string | null}` — `null` is an explicit "Auto" choice that overwrites an older pick.
340
+ */
341
+ static CoAgentPrefKey = 'mj.realtimeVoice.coAgent.v1';
342
+ /**
343
+ * The persisted co-agent preference, loaded just before the picker opens (and read by
344
+ * the instant-start path). `null` = no preference / explicit "Auto".
345
+ */
346
+ voicePickerDefaultCoAgentId = null;
347
+ /**
348
+ * Agents the voice picker offers — the same cached set the @mention
349
+ * autocomplete and {@link resolveVoiceAgentName} use, so the picker can
350
+ * never offer an agent the conversation couldn't otherwise route to.
351
+ */
352
+ get voicePickerAgents() {
353
+ return this.mentionAutocomplete.getAvailableAgents();
354
+ }
355
+ /**
356
+ * The ACTIVE Realtime-type co-agent candidates — the same run-permission-filtered
357
+ * cached set as {@link voicePickerAgents}, narrowed to the Realtime agent type. The
358
+ * picker shows its co-agent selector only when more than one exists.
359
+ */
360
+ get voicePickerCoAgents() {
361
+ return FilterRealtimeCoAgents(this.mentionAutocomplete.getAvailableAgents());
362
+ }
363
+ /** The agent the default resolution would call — preselected in the picker. */
364
+ get voicePickerDefaultAgentId() {
365
+ return this.resolveCurrentAgentId();
366
+ }
367
+ /**
368
+ * Start a real-time voice session fronting the conversation's current agent.
369
+ * Client-direct: the RealtimeSessionService mints an ephemeral token and connects
370
+ * the browser straight to the realtime provider over WebRTC. The "call mode"
371
+ * overlay itself is hosted by the conversation chat area (driven by Active$).
372
+ *
373
+ * NEW vs EXISTING conversation:
374
+ * - When an agent has already participated (a prior non-Sage AI turn exists),
375
+ * start immediately with the resolved agent — zero added friction.
376
+ * - When the conversation has NO prior agent participation (new / empty
377
+ * conversation), the resolution would silently fall through to a default
378
+ * the user never chose — so show a compact agent picker instead and start
379
+ * with whichever agent they pick.
380
+ */
381
+ async onStartVoice() {
382
+ if (!this.canStartVoice) {
383
+ return;
384
+ }
385
+ // New/empty conversation (no prior agent turn): let the user choose who
386
+ // to call. Falls through to the immediate path if the agent cache is
387
+ // empty (nothing to pick from — the resolved default is the only option).
388
+ if (!this.findLastNonSageAgentId() && this.voicePickerAgents.length > 0) {
389
+ await this.openRealtimeAgentPicker();
390
+ return;
391
+ }
392
+ const targetAgentId = this.resolveCurrentAgentId();
393
+ if (!targetAgentId) {
394
+ this.toastService.error('No agent available for a voice session.');
395
+ return;
396
+ }
397
+ const coAgentId = await this.resolveInstantCoAgentId(targetAgentId);
398
+ await this.startVoiceWithAgent(targetAgentId, this.resolveVoiceAgentName(), null, coAgentId);
399
+ }
400
+ /**
401
+ * Caret-next-to-the-phone click: open the agent/co-agent/model picker ON DEMAND, even
402
+ * when the conversation already has agent history (where the plain phone click
403
+ * instant-starts). The resolved agent is preselected, so "open → Start" matches the
404
+ * instant path while keeping the co-agent (and, for authorized users, voice-model)
405
+ * choice one click away. Falls through to the instant path when there is nothing to
406
+ * pick from.
407
+ */
408
+ async onVoiceOptions() {
409
+ if (!this.canStartVoice) {
410
+ return;
411
+ }
412
+ if (this.voicePickerAgents.length > 0) {
413
+ await this.openRealtimeAgentPicker();
414
+ return;
415
+ }
416
+ void this.onStartVoice();
417
+ }
418
+ /** Loads the persisted co-agent preference, then shows the picker (pref preselected). */
419
+ async openRealtimeAgentPicker() {
420
+ this.voicePickerDefaultCoAgentId = await this.loadPersistedCoAgentId();
421
+ this.showRealtimeAgentPicker = true;
422
+ }
423
+ /** User confirmed an agent (+ optional co-agent / voice model) in the voice picker — start the call. */
424
+ async onRealtimeAgentPicked(pick) {
425
+ this.showRealtimeAgentPicker = false;
426
+ this.persistCoAgentChoice(pick.CoAgentId);
427
+ await this.startVoiceWithAgent(pick.Agent.ID, pick.Agent.Name || this.resolveVoiceAgentName(), pick.PreferredModelId, pick.CoAgentId, BuildRealtimeConfigOverridesJson(pick.PreferredModelId));
428
+ }
429
+ /**
430
+ * Reads the persisted co-agent preference from `MJ: User Settings` (via
431
+ * `UserInfoEngine`'s cached settings). Defensive: any failure or malformed payload
432
+ * resolves to `null` (Auto — the server's co-agent resolution chain).
433
+ */
434
+ async loadPersistedCoAgentId() {
435
+ try {
436
+ await UserInfoEngine.Instance.Config();
437
+ const raw = UserInfoEngine.Instance.GetSetting(MessageInputComponent.CoAgentPrefKey);
438
+ if (!raw) {
439
+ return null;
440
+ }
441
+ const parsed = JSON.parse(raw);
442
+ return typeof parsed.coAgentId === 'string' && parsed.coAgentId.length > 0 ? parsed.coAgentId : null;
443
+ }
444
+ catch {
445
+ return null;
446
+ }
447
+ }
448
+ /** Persists the user's co-agent choice (including explicit "Auto" = null) cross-device. */
449
+ persistCoAgentChoice(coAgentId) {
450
+ try {
451
+ UserInfoEngine.Instance.SetSettingDebounced(MessageInputComponent.CoAgentPrefKey, JSON.stringify({ coAgentId: coAgentId ?? null }));
452
+ }
453
+ catch (error) {
454
+ console.warn('[MessageInput] Failed to persist co-agent preference:', error);
455
+ }
456
+ }
457
+ /**
458
+ * Co-agent for the INSTANT start path (plain phone click, no picker): the persisted
459
+ * preference is honored when it's still a valid candidate AND its pairing rows (if
460
+ * any) allow the resolved target. Anything else falls back to `null` — the server's
461
+ * co-agent resolution chain — so a stale/deactivated/incompatible preference can never
462
+ * block the friction-free start (pairings constrain a chosen co-agent; they never
463
+ * mandate one).
464
+ */
465
+ async resolveInstantCoAgentId(targetAgentId) {
466
+ const preferred = await this.loadPersistedCoAgentId();
467
+ if (!preferred) {
468
+ return null;
469
+ }
470
+ const isValidCandidate = this.voicePickerCoAgents.some(a => UUIDsEqual(a.ID, preferred));
471
+ if (!isValidCandidate) {
472
+ return null;
473
+ }
474
+ const pairings = await LoadCoAgentPairings(this.ProviderToUse, preferred);
475
+ return PairingsAllowTarget(pairings, targetAgentId) ? preferred : null;
476
+ }
477
+ /** User dismissed the voice picker without starting a call. */
478
+ onRealtimeAgentPickerCancelled() {
479
+ this.showRealtimeAgentPicker = false;
480
+ }
481
+ /**
482
+ * Shared session-start path for both the immediate (existing conversation)
483
+ * and picker (new conversation / caret options) flows. The agent NAME is passed
484
+ * through to RealtimeSessionService so the chat-area-hosted overlay banner (AgentName$)
485
+ * shows who the call fronts without re-resolving. An explicit voice-model choice
486
+ * (authorization-gated, picker only) rides along as `preferredModelId` — the server
487
+ * uses exactly that model or fails with a clear reason (no silent fallback) — and is
488
+ * mirrored into `configOverridesJson` (`{"realtime":{"modelPreference":…}}`, the
489
+ * pinned override envelope). An explicit co-agent choice (picker pick or persisted
490
+ * preference) rides along as `coAgentId`.
491
+ *
492
+ * Interactive-channel tools (e.g. the live whiteboard's `Whiteboard_*` set) are NOT
493
+ * passed here — the session service resolves the active channel plugins from the
494
+ * `MJ: AI Agent Channels` registry and aggregates their tool sets at mint itself.
495
+ */
496
+ async startVoiceWithAgent(agentId, agentName, preferredModelId, coAgentId, configOverridesJson) {
497
+ try {
498
+ await this.voiceSession.StartVoiceSession(agentId, this.conversationId, null, agentName, preferredModelId ?? null, null, coAgentId ?? null, configOverridesJson ?? null);
499
+ }
500
+ catch (error) {
501
+ console.error('Failed to start voice session:', error);
502
+ this.toastService.error('Could not start the voice session.');
503
+ }
245
504
  }
246
505
  /**
247
506
  * Focus the message input textarea
@@ -928,7 +1187,31 @@ export class MessageInputComponent extends BaseAngularComponent {
928
1187
  conversationId: this.conversationId,
929
1188
  conversationName: this.conversationName
930
1189
  });
1190
+ // ── PR 2c follow-up: Before/After cancelable event wiring ──
1191
+ // Emit beforeAgentTurn so consumers can veto the turn (rate-limit, guardrail,
1192
+ // confirm-dialog, etc.). Cancel propagates synchronously through the chat-area
1193
+ // re-emit binding, so by the time .emit() returns, event.Cancel reflects every
1194
+ // subscriber's final answer.
1195
+ const beforeEvent = new BeforeAgentTurnEventArgs(conversationId, userMessage.Message ?? '', this.applicationId);
1196
+ this.beforeAgentTurn.emit(beforeEvent);
1197
+ if (beforeEvent.Cancel) {
1198
+ // Mark the conversation-manager message as canceled + clear its task so the
1199
+ // UI doesn't show a forever-pending spinner. afterAgentTurn is NOT emitted.
1200
+ await this.updateConversationDetail(conversationManagerMessage, beforeEvent.CancelReason ?? '⛔ Turn canceled before agent invocation', 'Error');
1201
+ await this.updateConversationDetail(userMessage, userMessage.Message, 'Complete');
1202
+ this.cleanupCompletionTimestamp(conversationManagerMessage.ID);
1203
+ if (taskId) {
1204
+ this.activeTasks.remove(taskId);
1205
+ taskId = null;
1206
+ }
1207
+ return;
1208
+ }
931
1209
  const result = await this.agentService.processMessage(conversationId, userMessage, this.conversationHistory, conversationManagerMessage.ID, this.createProgressCallback(conversationManagerMessage, 'Sage'), this.appContext);
1210
+ // Emit afterAgentTurn on the happy path only — the error/failure branch
1211
+ // immediately below handles its own cleanup and skips this emit.
1212
+ if (result && result.success) {
1213
+ this.afterAgentTurn.emit(new AfterAgentTurnEventArgs(conversationId, (result.agentRun?.ID ?? ''), result));
1214
+ }
932
1215
  // Task will be removed automatically in markMessageComplete()
933
1216
  // DO NOT remove here - agent may still be streaming/processing
934
1217
  taskId = null; // Clear reference but don't remove from service
@@ -1700,7 +1983,7 @@ export class MessageInputComponent extends BaseAngularComponent {
1700
1983
  const agent = AIEngineBase.Instance.Agents.find(a => UUIDsEqual(a.ID, agentId));
1701
1984
  if (!agent) {
1702
1985
  console.warn('⚠️ Could not load agent for continuation - falling back to Sage');
1703
- await this.processMessageThroughAgent(userMessage, { mentions: [], agentMention: null, userMentions: [] });
1986
+ await this.processMessageThroughAgent(userMessage, { mentions: [], agentMention: null, userMentions: [], entityMentions: [] });
1704
1987
  return;
1705
1988
  }
1706
1989
  const agentName = agent.Name || 'Agent';
@@ -1901,75 +2184,28 @@ export class MessageInputComponent extends BaseAngularComponent {
1901
2184
  }
1902
2185
  }
1903
2186
  /**
1904
- * Name the conversation based on the first message using GraphQL AI client
1905
- *
1906
- * IMPORTANT: This runs asynchronously in the background and has a 30-second timeout
1907
- * to prevent long delays. Failures are logged but don't affect the user experience.
2187
+ * Names the conversation from its first message via the SHARED naming helper
2188
+ * ({@link GenerateAndApplyConversationName}) — the same implementation the realtime
2189
+ * session path uses. This wrapper keeps the composer-specific concerns local:
2190
+ * mention stripping and the sidebar rename animation event.
1908
2191
  */
1909
2192
  async nameConversation(message) {
1910
- try {
1911
- // Load the Name Conversation prompt to get its ID
1912
- await AIEngineBase.Instance.Config(false);
1913
- const p = AIEngineBase.Instance.Prompts.find(pr => pr.Name === 'Name Conversation');
1914
- if (!p) {
1915
- console.warn('⚠️ Name Conversation prompt not found');
1916
- return;
1917
- }
1918
- const promptId = p.ID;
1919
- // Use GraphQL AI client to run the prompt (same client as agent)
1920
- const provider = this.ProviderToUse;
1921
- if (!provider) {
1922
- console.warn('⚠️ GraphQLDataProvider not available');
1923
- return;
1924
- }
1925
- // Convert message to plain text (strips JSON-encoded mentions like @{"id":"...","name":"Sage"} to @Sage)
1926
- const plainTextMessage = this.mentionParser.toPlainText(message, this.mentionAutocomplete.getAvailableAgents(), this.mentionAutocomplete.getAvailableUsers());
1927
- const aiClient = new GraphQLAIClient(provider);
1928
- // Add 30-second timeout to prevent long delays
1929
- // If this times out, the conversation will keep its default name
1930
- const timeoutPromise = new Promise((_, reject) => {
1931
- setTimeout(() => reject(new Error('Conversation naming timed out after 30 seconds')), 30000);
2193
+ // Convert message to plain text (strips JSON-encoded mentions like @{"id":"...","name":"Sage"} to @Sage)
2194
+ const plainTextMessage = this.mentionParser.toPlainText(message, this.mentionAutocomplete.getAvailableAgents(), this.mentionAutocomplete.getAvailableUsers());
2195
+ const result = await GenerateAndApplyConversationName({
2196
+ ConversationId: this.conversationId,
2197
+ MessageText: plainTextMessage,
2198
+ Provider: this.ProviderToUse,
2199
+ CurrentUser: this.currentUser
2200
+ });
2201
+ if (result) {
2202
+ // Emit event for animation in conversation list
2203
+ this.conversationRenamed.emit({
2204
+ conversationId: this.conversationId,
2205
+ name: result.Name,
2206
+ description: result.Description
1932
2207
  });
1933
- const result = await Promise.race([
1934
- aiClient.RunAIPrompt({
1935
- promptId: promptId,
1936
- messages: [{ role: 'user', content: plainTextMessage }],
1937
- }),
1938
- timeoutPromise
1939
- ]);
1940
- if (result && result.success && (result.parsedResult || result.output)) {
1941
- // Use parsedResult if available, otherwise clean and parse output
1942
- // (CleanAndParseJSON handles markdown code blocks like ```json ... ```)
1943
- const parsed = result.parsedResult ||
1944
- (result.output ? CleanAndParseJSON(result.output) : null);
1945
- if (parsed) {
1946
- const { name, description } = parsed;
1947
- if (name) {
1948
- // Update the conversation name and description in database AND state immediately
1949
- await this.engine.SaveConversation(this.conversationId, { Name: name, Description: description || '' }, this.currentUser);
1950
- // Emit event for animation in conversation list
1951
- this.conversationRenamed.emit({
1952
- conversationId: this.conversationId,
1953
- name: name,
1954
- description: description || ''
1955
- });
1956
- console.log(`✅ Conversation renamed to: "${name}"`);
1957
- }
1958
- }
1959
- }
1960
- else {
1961
- console.warn('⚠️ Failed to generate conversation name - using default');
1962
- }
1963
- }
1964
- catch (error) {
1965
- // Log timeout or other errors but don't disrupt user experience
1966
- if (error instanceof Error && error.message.includes('timed out')) {
1967
- console.warn('⏱️ Conversation naming timed out - conversation will keep default name');
1968
- }
1969
- else {
1970
- console.error('❌ Error naming conversation:', error);
1971
- }
1972
- // Don't show error to user - naming failures should be silent
2208
+ console.log(`✅ Conversation renamed to: "${result.Name}"`);
1973
2209
  }
1974
2210
  }
1975
2211
  /**
@@ -2022,32 +2258,36 @@ export class MessageInputComponent extends BaseAngularComponent {
2022
2258
  this.completionTimestamps.delete(conversationDetailId);
2023
2259
  }, 5000); // 5 seconds should be more than enough
2024
2260
  }
2025
- static ɵfac = function MessageInputComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || MessageInputComponent)(i0.ɵɵdirectiveInject(i1.DialogService), i0.ɵɵdirectiveInject(i2.ToastService), i0.ɵɵdirectiveInject(i3.ConversationAgentService), i0.ɵɵdirectiveInject(i4.DataCacheService), i0.ɵɵdirectiveInject(i5.ActiveTasksService), i0.ɵɵdirectiveInject(i6.ConversationStreamingService), i0.ɵɵdirectiveInject(i7.MentionParserService), i0.ɵɵdirectiveInject(i8.MentionAutocompleteService), i0.ɵɵdirectiveInject(i9.ConversationAttachmentService), i0.ɵɵdirectiveInject(i10.ConversationBridgeService)); };
2261
+ static ɵfac = function MessageInputComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || MessageInputComponent)(i0.ɵɵdirectiveInject(i1.DialogService), i0.ɵɵdirectiveInject(i2.ToastService), i0.ɵɵdirectiveInject(i3.ConversationAgentService), i0.ɵɵdirectiveInject(i4.DataCacheService), i0.ɵɵdirectiveInject(i5.ActiveTasksService), i0.ɵɵdirectiveInject(i6.ConversationStreamingService), i0.ɵɵdirectiveInject(i7.MentionParserService), i0.ɵɵdirectiveInject(i8.MentionAutocompleteService), i0.ɵɵdirectiveInject(i9.ConversationAttachmentService), i0.ɵɵdirectiveInject(i10.ConversationBridgeService), i0.ɵɵdirectiveInject(i11.RealtimeSessionService)); };
2026
2262
  static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: MessageInputComponent, selectors: [["mj-message-input"]], viewQuery: function MessageInputComponent_Query(rf, ctx) { if (rf & 1) {
2027
2263
  i0.ɵɵviewQuery(_c0, 5);
2028
2264
  } if (rf & 2) {
2029
2265
  let _t;
2030
2266
  i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.inputBox = _t.first);
2031
- } }, inputs: { conversationId: "conversationId", conversationName: "conversationName", currentUser: "currentUser", disabled: "disabled", placeholder: "placeholder", parentMessageId: "parentMessageId", enableAttachments: "enableAttachments", enableMentions: "enableMentions", maxAttachments: "maxAttachments", maxAttachmentSizeBytes: "maxAttachmentSizeBytes", acceptedFileTypes: "acceptedFileTypes", artifactsByDetailId: "artifactsByDetailId", systemArtifactsByDetailId: "systemArtifactsByDetailId", agentRunsByDetailId: "agentRunsByDetailId", emptyStateMode: "emptyStateMode", appContext: "appContext", defaultAgentId: "defaultAgentId", conversationDefaultAgentId: "conversationDefaultAgentId", agentConfigurationPresetId: "agentConfigurationPresetId", initialMessage: "initialMessage", initialAttachments: "initialAttachments", conversationHistory: "conversationHistory", inProgressMessageIds: "inProgressMessageIds" }, outputs: { messageSent: "messageSent", agentResponse: "agentResponse", agentRunDetected: "agentRunDetected", agentRunUpdate: "agentRunUpdate", messageComplete: "messageComplete", artifactCreated: "artifactCreated", conversationRenamed: "conversationRenamed", intentCheckStarted: "intentCheckStarted", intentCheckCompleted: "intentCheckCompleted", emptyStateSubmit: "emptyStateSubmit", uploadStateChanged: "uploadStateChanged", artifactPickerRequested: "artifactPickerRequested" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature, i0.ɵɵNgOnChangesFeature], decls: 4, vars: 12, consts: [["inputBox", ""], [1, "message-input-wrapper"], [1, "processing-indicator"], [3, "valueChange", "textSubmitted", "attachmentsChanged", "attachmentError", "artifactPickerRequested", "placeholder", "disabled", "showCharacterCount", "enableMentions", "enableAttachments", "maxAttachments", "maxAttachmentSizeBytes", "acceptedFileTypes", "currentUser", "rows", "value"], [1, "fas", "fa-circle-notch", "fa-spin"]], template: function MessageInputComponent_Template(rf, ctx) { if (rf & 1) {
2267
+ } }, inputs: { conversationId: "conversationId", conversationName: "conversationName", currentUser: "currentUser", disabled: "disabled", placeholder: "placeholder", parentMessageId: "parentMessageId", enableAttachments: "enableAttachments", enableMentions: "enableMentions", maxAttachments: "maxAttachments", maxAttachmentSizeBytes: "maxAttachmentSizeBytes", acceptedFileTypes: "acceptedFileTypes", artifactsByDetailId: "artifactsByDetailId", systemArtifactsByDetailId: "systemArtifactsByDetailId", agentRunsByDetailId: "agentRunsByDetailId", emptyStateMode: "emptyStateMode", appContext: "appContext", defaultAgentId: "defaultAgentId", conversationDefaultAgentId: "conversationDefaultAgentId", agentConfigurationPresetId: "agentConfigurationPresetId", initialMessage: "initialMessage", initialAttachments: "initialAttachments", conversationHistory: "conversationHistory", inProgressMessageIds: "inProgressMessageIds", applicationId: "applicationId" }, outputs: { messageSent: "messageSent", agentResponse: "agentResponse", beforeAgentTurn: "beforeAgentTurn", afterAgentTurn: "afterAgentTurn", agentRunDetected: "agentRunDetected", agentRunUpdate: "agentRunUpdate", messageComplete: "messageComplete", artifactCreated: "artifactCreated", conversationRenamed: "conversationRenamed", intentCheckStarted: "intentCheckStarted", intentCheckCompleted: "intentCheckCompleted", emptyStateSubmit: "emptyStateSubmit", uploadStateChanged: "uploadStateChanged", artifactPickerRequested: "artifactPickerRequested" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature, i0.ɵɵNgOnChangesFeature], decls: 5, vars: 16, consts: [["inputBox", ""], [1, "message-input-wrapper"], [1, "processing-indicator"], [3, "valueChange", "textSubmitted", "attachmentsChanged", "attachmentError", "artifactPickerRequested", "voiceRequested", "voiceOptionsRequested", "placeholder", "disabled", "showCharacterCount", "enableMentions", "enableAttachments", "maxAttachments", "maxAttachmentSizeBytes", "acceptedFileTypes", "currentUser", "rows", "enableVoice", "voiceActive", "canStartVoice", "value"], [3, "Provider", "Agents", "DefaultAgentId", "CoAgents", "DefaultCoAgentId"], [1, "fas", "fa-circle-notch", "fa-spin"], [3, "AgentPicked", "Cancelled", "Provider", "Agents", "DefaultAgentId", "CoAgents", "DefaultCoAgentId"]], template: function MessageInputComponent_Template(rf, ctx) { if (rf & 1) {
2032
2268
  const _r1 = i0.ɵɵgetCurrentView();
2033
2269
  i0.ɵɵelementStart(0, "div", 1);
2034
2270
  i0.ɵɵconditionalCreate(1, MessageInputComponent_Conditional_1_Template, 4, 1, "div", 2);
2035
2271
  i0.ɵɵelementStart(2, "mj-message-input-box", 3, 0);
2036
2272
  i0.ɵɵtwoWayListener("valueChange", function MessageInputComponent_Template_mj_message_input_box_valueChange_2_listener($event) { i0.ɵɵrestoreView(_r1); i0.ɵɵtwoWayBindingSet(ctx.messageText, $event) || (ctx.messageText = $event); return i0.ɵɵresetView($event); });
2037
- i0.ɵɵlistener("textSubmitted", function MessageInputComponent_Template_mj_message_input_box_textSubmitted_2_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onTextSubmitted($event)); })("attachmentsChanged", function MessageInputComponent_Template_mj_message_input_box_attachmentsChanged_2_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onAttachmentsChanged($event)); })("attachmentError", function MessageInputComponent_Template_mj_message_input_box_attachmentError_2_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onAttachmentError($event)); })("artifactPickerRequested", function MessageInputComponent_Template_mj_message_input_box_artifactPickerRequested_2_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onArtifactPickerRequested()); });
2038
- i0.ɵɵelementEnd()();
2273
+ i0.ɵɵlistener("textSubmitted", function MessageInputComponent_Template_mj_message_input_box_textSubmitted_2_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onTextSubmitted($event)); })("attachmentsChanged", function MessageInputComponent_Template_mj_message_input_box_attachmentsChanged_2_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onAttachmentsChanged($event)); })("attachmentError", function MessageInputComponent_Template_mj_message_input_box_attachmentError_2_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onAttachmentError($event)); })("artifactPickerRequested", function MessageInputComponent_Template_mj_message_input_box_artifactPickerRequested_2_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onArtifactPickerRequested()); })("voiceRequested", function MessageInputComponent_Template_mj_message_input_box_voiceRequested_2_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onStartVoice()); })("voiceOptionsRequested", function MessageInputComponent_Template_mj_message_input_box_voiceOptionsRequested_2_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onVoiceOptions()); });
2274
+ i0.ɵɵelementEnd();
2275
+ i0.ɵɵconditionalCreate(4, MessageInputComponent_Conditional_4_Template, 1, 5, "mj-realtime-agent-picker", 4);
2276
+ i0.ɵɵelementEnd();
2039
2277
  } if (rf & 2) {
2040
2278
  i0.ɵɵadvance();
2041
2279
  i0.ɵɵconditional(ctx.isProcessing ? 1 : -1);
2042
2280
  i0.ɵɵadvance();
2043
- i0.ɵɵproperty("placeholder", ctx.placeholder)("disabled", ctx.disabled || ctx.isProcessing)("showCharacterCount", false)("enableMentions", ctx.enableMentions)("enableAttachments", ctx.enableAttachments)("maxAttachments", ctx.maxAttachments)("maxAttachmentSizeBytes", ctx.maxAttachmentSizeBytes)("acceptedFileTypes", ctx.acceptedFileTypes)("currentUser", ctx.currentUser)("rows", 3);
2281
+ i0.ɵɵproperty("placeholder", ctx.placeholder)("disabled", ctx.disabled || ctx.isProcessing)("showCharacterCount", false)("enableMentions", ctx.enableMentions)("enableAttachments", ctx.enableAttachments)("maxAttachments", ctx.maxAttachments)("maxAttachmentSizeBytes", ctx.maxAttachmentSizeBytes)("acceptedFileTypes", ctx.acceptedFileTypes)("currentUser", ctx.currentUser)("rows", 3)("enableVoice", true)("voiceActive", ctx.voiceActive)("canStartVoice", ctx.canStartVoice);
2044
2282
  i0.ɵɵtwoWayProperty("value", ctx.messageText);
2045
- } }, dependencies: [i11.MessageInputBoxComponent], styles: [".message-input-wrapper[_ngcontent-%COMP%] {\n position: relative;\n width: 100%;\n}\n\n.processing-indicator[_ngcontent-%COMP%] {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n display: flex;\n align-items: center;\n gap: 0.5rem;\n padding: 0.75rem 1.25rem;\n background: color-mix(in srgb, var(--mj-bg-surface-card) 95%, transparent);\n border-radius: 8px;\n box-shadow: var(--mj-shadow-sm);\n z-index: 10;\n pointer-events: none;\n}\n.processing-indicator[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n.processing-indicator[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n font-size: 0.9rem;\n color: var(--mj-text-primary);\n}"] });
2283
+ i0.ɵɵadvance(2);
2284
+ i0.ɵɵconditional(ctx.showRealtimeAgentPicker ? 4 : -1);
2285
+ } }, dependencies: [i12.RealtimeAgentPickerComponent, i13.MessageInputBoxComponent], styles: [".message-input-wrapper[_ngcontent-%COMP%] {\n position: relative;\n width: 100%;\n}\n\n.processing-indicator[_ngcontent-%COMP%] {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n display: flex;\n align-items: center;\n gap: 0.5rem;\n padding: 0.75rem 1.25rem;\n background: color-mix(in srgb, var(--mj-bg-surface-card) 95%, transparent);\n border-radius: 8px;\n box-shadow: var(--mj-shadow-sm);\n z-index: 10;\n pointer-events: none;\n}\n.processing-indicator[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n.processing-indicator[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n font-size: 0.9rem;\n color: var(--mj-text-primary);\n}"] });
2046
2286
  }
2047
2287
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MessageInputComponent, [{
2048
2288
  type: Component,
2049
- args: [{ standalone: false, selector: 'mj-message-input', template: "<div class=\"message-input-wrapper\">\n <!-- Processing Indicator Overlay -->\n @if (isProcessing) {\n <div class=\"processing-indicator\">\n <i class=\"fas fa-circle-notch fa-spin\"></i>\n <span>{{ processingMessage }}</span>\n </div>\n }\n\n <!-- Message Input Box -->\n <mj-message-input-box\n #inputBox\n [placeholder]=\"placeholder\"\n [disabled]=\"disabled || isProcessing\"\n [showCharacterCount]=\"false\"\n [enableMentions]=\"enableMentions\"\n [enableAttachments]=\"enableAttachments\"\n [maxAttachments]=\"maxAttachments\"\n [maxAttachmentSizeBytes]=\"maxAttachmentSizeBytes\"\n [acceptedFileTypes]=\"acceptedFileTypes\"\n [currentUser]=\"currentUser\"\n [rows]=\"3\"\n [(value)]=\"messageText\"\n (textSubmitted)=\"onTextSubmitted($event)\"\n (attachmentsChanged)=\"onAttachmentsChanged($event)\"\n (attachmentError)=\"onAttachmentError($event)\"\n (artifactPickerRequested)=\"onArtifactPickerRequested()\">\n </mj-message-input-box>\n</div>", styles: [".message-input-wrapper {\n position: relative;\n width: 100%;\n}\n\n.processing-indicator {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n display: flex;\n align-items: center;\n gap: 0.5rem;\n padding: 0.75rem 1.25rem;\n background: color-mix(in srgb, var(--mj-bg-surface-card) 95%, transparent);\n border-radius: 8px;\n box-shadow: var(--mj-shadow-sm);\n z-index: 10;\n pointer-events: none;\n}\n.processing-indicator i {\n color: var(--mj-brand-primary);\n}\n.processing-indicator span {\n font-size: 0.9rem;\n color: var(--mj-text-primary);\n}\n"] }]
2050
- }], () => [{ type: i1.DialogService }, { type: i2.ToastService }, { type: i3.ConversationAgentService }, { type: i4.DataCacheService }, { type: i5.ActiveTasksService }, { type: i6.ConversationStreamingService }, { type: i7.MentionParserService }, { type: i8.MentionAutocompleteService }, { type: i9.ConversationAttachmentService }, { type: i10.ConversationBridgeService }], { conversationId: [{
2289
+ args: [{ standalone: false, selector: 'mj-message-input', template: "<div class=\"message-input-wrapper\">\n <!-- Processing Indicator Overlay -->\n @if (isProcessing) {\n <div class=\"processing-indicator\">\n <i class=\"fas fa-circle-notch fa-spin\"></i>\n <span>{{ processingMessage }}</span>\n </div>\n }\n\n <!-- Message Input Box (mic button lives in its in-composer toolbar) -->\n <mj-message-input-box\n #inputBox\n [placeholder]=\"placeholder\"\n [disabled]=\"disabled || isProcessing\"\n [showCharacterCount]=\"false\"\n [enableMentions]=\"enableMentions\"\n [enableAttachments]=\"enableAttachments\"\n [maxAttachments]=\"maxAttachments\"\n [maxAttachmentSizeBytes]=\"maxAttachmentSizeBytes\"\n [acceptedFileTypes]=\"acceptedFileTypes\"\n [currentUser]=\"currentUser\"\n [rows]=\"3\"\n [enableVoice]=\"true\"\n [voiceActive]=\"voiceActive\"\n [canStartVoice]=\"canStartVoice\"\n [(value)]=\"messageText\"\n (textSubmitted)=\"onTextSubmitted($event)\"\n (attachmentsChanged)=\"onAttachmentsChanged($event)\"\n (attachmentError)=\"onAttachmentError($event)\"\n (artifactPickerRequested)=\"onArtifactPickerRequested()\"\n (voiceRequested)=\"onStartVoice()\"\n (voiceOptionsRequested)=\"onVoiceOptions()\">\n </mj-message-input-box>\n\n <!-- Voice agent/co-agent/model picker \u2014 shown when starting a call on a conversation\n with NO prior agent participation, or on demand via the caret next to the phone\n button (any conversation). Anchored above the composer. -->\n @if (showRealtimeAgentPicker) {\n <mj-realtime-agent-picker\n [Provider]=\"Provider\"\n [Agents]=\"voicePickerAgents\"\n [DefaultAgentId]=\"voicePickerDefaultAgentId\"\n [CoAgents]=\"voicePickerCoAgents\"\n [DefaultCoAgentId]=\"voicePickerDefaultCoAgentId\"\n (AgentPicked)=\"onRealtimeAgentPicked($event)\"\n (Cancelled)=\"onRealtimeAgentPickerCancelled()\">\n </mj-realtime-agent-picker>\n }\n</div>\n\n<!-- The voice \"call mode\" overlay is hosted by <mj-conversation-chat-area> (it fills the\n whole conversation panel in place); this component only owns the trigger wiring. -->\n", styles: [".message-input-wrapper {\n position: relative;\n width: 100%;\n}\n\n.processing-indicator {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n display: flex;\n align-items: center;\n gap: 0.5rem;\n padding: 0.75rem 1.25rem;\n background: color-mix(in srgb, var(--mj-bg-surface-card) 95%, transparent);\n border-radius: 8px;\n box-shadow: var(--mj-shadow-sm);\n z-index: 10;\n pointer-events: none;\n}\n.processing-indicator i {\n color: var(--mj-brand-primary);\n}\n.processing-indicator span {\n font-size: 0.9rem;\n color: var(--mj-text-primary);\n}\n"] }]
2290
+ }], () => [{ type: i1.DialogService }, { type: i2.ToastService }, { type: i3.ConversationAgentService }, { type: i4.DataCacheService }, { type: i5.ActiveTasksService }, { type: i6.ConversationStreamingService }, { type: i7.MentionParserService }, { type: i8.MentionAutocompleteService }, { type: i9.ConversationAttachmentService }, { type: i10.ConversationBridgeService }, { type: i11.RealtimeSessionService }], { conversationId: [{
2051
2291
  type: Input
2052
2292
  }], conversationName: [{
2053
2293
  type: Input
@@ -2093,10 +2333,16 @@ export class MessageInputComponent extends BaseAngularComponent {
2093
2333
  type: Input
2094
2334
  }], inProgressMessageIds: [{
2095
2335
  type: Input
2336
+ }], applicationId: [{
2337
+ type: Input
2096
2338
  }], messageSent: [{
2097
2339
  type: Output
2098
2340
  }], agentResponse: [{
2099
2341
  type: Output
2342
+ }], beforeAgentTurn: [{
2343
+ type: Output
2344
+ }], afterAgentTurn: [{
2345
+ type: Output
2100
2346
  }], agentRunDetected: [{
2101
2347
  type: Output
2102
2348
  }], agentRunUpdate: [{
@@ -2121,5 +2367,5 @@ export class MessageInputComponent extends BaseAngularComponent {
2121
2367
  type: ViewChild,
2122
2368
  args: ['inputBox']
2123
2369
  }] }); })();
2124
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(MessageInputComponent, { className: "MessageInputComponent", filePath: "src/lib/components/message/message-input.component.ts", lineNumber: 33 }); })();
2370
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(MessageInputComponent, { className: "MessageInputComponent", filePath: "src/lib/components/message/message-input.component.ts", lineNumber: 43 }); })();
2125
2371
  //# sourceMappingURL=message-input.component.js.map