@memberjunction/ng-conversations 5.43.0 → 5.45.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 (405) 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.d.ts +3 -1
  6. package/dist/lib/components/artifact/artifact-share-modal.component.d.ts.map +1 -1
  7. package/dist/lib/components/artifact/artifact-share-modal.component.js +52 -52
  8. package/dist/lib/components/artifact/artifact-share-modal.component.js.map +1 -1
  9. package/dist/lib/components/collection/collection-form-modal.component.d.ts.map +1 -1
  10. package/dist/lib/components/collection/collection-form-modal.component.js +10 -14
  11. package/dist/lib/components/collection/collection-form-modal.component.js.map +1 -1
  12. package/dist/lib/components/collection/collection-share-modal.component.d.ts +3 -1
  13. package/dist/lib/components/collection/collection-share-modal.component.d.ts.map +1 -1
  14. package/dist/lib/components/collection/collection-share-modal.component.js +56 -56
  15. package/dist/lib/components/collection/collection-share-modal.component.js.map +1 -1
  16. package/dist/lib/components/collection/collection-tree.component.d.ts +3 -1
  17. package/dist/lib/components/collection/collection-tree.component.d.ts.map +1 -1
  18. package/dist/lib/components/collection/collection-tree.component.js +10 -7
  19. package/dist/lib/components/collection/collection-tree.component.js.map +1 -1
  20. package/dist/lib/components/collection/collection-view.component.d.ts +3 -1
  21. package/dist/lib/components/collection/collection-view.component.d.ts.map +1 -1
  22. package/dist/lib/components/collection/collection-view.component.js +29 -41
  23. package/dist/lib/components/collection/collection-view.component.js.map +1 -1
  24. package/dist/lib/components/collection/collections-full-view.component.d.ts +4 -0
  25. package/dist/lib/components/collection/collections-full-view.component.d.ts.map +1 -1
  26. package/dist/lib/components/collection/collections-full-view.component.js +134 -166
  27. package/dist/lib/components/collection/collections-full-view.component.js.map +1 -1
  28. package/dist/lib/components/composer/ai-composer.component.d.ts +103 -0
  29. package/dist/lib/components/composer/ai-composer.component.d.ts.map +1 -0
  30. package/dist/lib/components/composer/ai-composer.component.js +263 -0
  31. package/dist/lib/components/composer/ai-composer.component.js.map +1 -0
  32. package/dist/lib/components/conversation/conversation-chat-area.component.d.ts +76 -12
  33. package/dist/lib/components/conversation/conversation-chat-area.component.d.ts.map +1 -1
  34. package/dist/lib/components/conversation/conversation-chat-area.component.js +522 -158
  35. package/dist/lib/components/conversation/conversation-chat-area.component.js.map +1 -1
  36. package/dist/lib/components/conversation/conversation-empty-state.component.d.ts +1 -1
  37. package/dist/lib/components/conversation/conversation-empty-state.component.d.ts.map +1 -1
  38. package/dist/lib/components/conversation/conversation-empty-state.component.js.map +1 -1
  39. package/dist/lib/components/conversation/pinned-messages-panel.component.js +6 -9
  40. package/dist/lib/components/conversation/pinned-messages-panel.component.js.map +1 -1
  41. package/dist/lib/components/library/library-full-view.component.d.ts.map +1 -1
  42. package/dist/lib/components/library/library-full-view.component.js +20 -24
  43. package/dist/lib/components/library/library-full-view.component.js.map +1 -1
  44. package/dist/lib/components/members/members-modal.component.d.ts.map +1 -1
  45. package/dist/lib/components/members/members-modal.component.js +10 -11
  46. package/dist/lib/components/members/members-modal.component.js.map +1 -1
  47. package/dist/lib/components/message/message-input.component.d.ts +87 -23
  48. package/dist/lib/components/message/message-input.component.d.ts.map +1 -1
  49. package/dist/lib/components/message/message-input.component.js +245 -158
  50. package/dist/lib/components/message/message-input.component.js.map +1 -1
  51. package/dist/lib/components/message/message-item.component.d.ts +11 -3
  52. package/dist/lib/components/message/message-item.component.d.ts.map +1 -1
  53. package/dist/lib/components/message/message-item.component.js +73 -21
  54. package/dist/lib/components/message/message-item.component.js.map +1 -1
  55. package/dist/lib/components/message/message-list.component.js +6 -9
  56. package/dist/lib/components/message/message-list.component.js.map +1 -1
  57. package/dist/lib/components/overlay/chat-overlay.component.d.ts +4 -1
  58. package/dist/lib/components/overlay/chat-overlay.component.d.ts.map +1 -1
  59. package/dist/lib/components/overlay/chat-overlay.component.js +9 -4
  60. package/dist/lib/components/overlay/chat-overlay.component.js.map +1 -1
  61. package/dist/lib/components/realtime/channels/base-realtime-channel-client.d.ts +45 -0
  62. package/dist/lib/components/realtime/channels/base-realtime-channel-client.d.ts.map +1 -1
  63. package/dist/lib/components/realtime/channels/base-realtime-channel-client.js +10 -0
  64. package/dist/lib/components/realtime/channels/base-realtime-channel-client.js.map +1 -1
  65. package/dist/lib/components/realtime/channels/client-context-channel.d.ts +46 -0
  66. package/dist/lib/components/realtime/channels/client-context-channel.d.ts.map +1 -0
  67. package/dist/lib/components/realtime/channels/client-context-channel.js +174 -0
  68. package/dist/lib/components/realtime/channels/client-context-channel.js.map +1 -0
  69. package/dist/lib/components/realtime/evidence-playback/realtime-evidence-playback.component.d.ts +123 -0
  70. package/dist/lib/components/realtime/evidence-playback/realtime-evidence-playback.component.d.ts.map +1 -0
  71. package/dist/lib/components/realtime/evidence-playback/realtime-evidence-playback.component.js +397 -0
  72. package/dist/lib/components/realtime/evidence-playback/realtime-evidence-playback.component.js.map +1 -0
  73. package/dist/lib/components/realtime/media/media-channel-state.d.ts +103 -0
  74. package/dist/lib/components/realtime/media/media-channel-state.d.ts.map +1 -0
  75. package/dist/lib/components/realtime/media/media-channel-state.js +143 -0
  76. package/dist/lib/components/realtime/media/media-channel-state.js.map +1 -0
  77. package/dist/lib/components/realtime/media/media-channel-tools.d.ts +24 -0
  78. package/dist/lib/components/realtime/media/media-channel-tools.d.ts.map +1 -0
  79. package/dist/lib/components/realtime/media/media-channel-tools.js +107 -0
  80. package/dist/lib/components/realtime/media/media-channel-tools.js.map +1 -0
  81. package/dist/lib/components/realtime/media/media-channel.d.ts +89 -0
  82. package/dist/lib/components/realtime/media/media-channel.d.ts.map +1 -0
  83. package/dist/lib/components/realtime/media/media-channel.js +253 -0
  84. package/dist/lib/components/realtime/media/media-channel.js.map +1 -0
  85. package/dist/lib/components/realtime/media/realtime-media-surface.component.d.ts +141 -0
  86. package/dist/lib/components/realtime/media/realtime-media-surface.component.d.ts.map +1 -0
  87. package/dist/lib/components/realtime/media/realtime-media-surface.component.js +574 -0
  88. package/dist/lib/components/realtime/media/realtime-media-surface.component.js.map +1 -0
  89. package/dist/lib/components/realtime/realtime-activity-rail.component.d.ts +59 -14
  90. package/dist/lib/components/realtime/realtime-activity-rail.component.d.ts.map +1 -1
  91. package/dist/lib/components/realtime/realtime-activity-rail.component.js +277 -74
  92. package/dist/lib/components/realtime/realtime-activity-rail.component.js.map +1 -1
  93. package/dist/lib/components/realtime/realtime-agent-banner.component.d.ts +28 -27
  94. package/dist/lib/components/realtime/realtime-agent-banner.component.d.ts.map +1 -1
  95. package/dist/lib/components/realtime/realtime-agent-banner.component.js +144 -143
  96. package/dist/lib/components/realtime/realtime-agent-banner.component.js.map +1 -1
  97. package/dist/lib/components/realtime/realtime-agent-picker.component.d.ts +12 -0
  98. package/dist/lib/components/realtime/realtime-agent-picker.component.d.ts.map +1 -1
  99. package/dist/lib/components/realtime/realtime-agent-picker.component.js +105 -43
  100. package/dist/lib/components/realtime/realtime-agent-picker.component.js.map +1 -1
  101. package/dist/lib/components/realtime/realtime-audio-visuals.d.ts +2 -2
  102. package/dist/lib/components/realtime/realtime-audio-visuals.d.ts.map +1 -1
  103. package/dist/lib/components/realtime/realtime-audio-visuals.js.map +1 -1
  104. package/dist/lib/components/realtime/realtime-composer.component.d.ts +41 -7
  105. package/dist/lib/components/realtime/realtime-composer.component.d.ts.map +1 -1
  106. package/dist/lib/components/realtime/realtime-composer.component.js +216 -102
  107. package/dist/lib/components/realtime/realtime-composer.component.js.map +1 -1
  108. package/dist/lib/components/realtime/realtime-delegation-card.component.d.ts +0 -2
  109. package/dist/lib/components/realtime/realtime-delegation-card.component.d.ts.map +1 -1
  110. package/dist/lib/components/realtime/realtime-delegation-card.component.js +67 -71
  111. package/dist/lib/components/realtime/realtime-delegation-card.component.js.map +1 -1
  112. package/dist/lib/components/realtime/realtime-session-overlay.component.d.ts +364 -44
  113. package/dist/lib/components/realtime/realtime-session-overlay.component.d.ts.map +1 -1
  114. package/dist/lib/components/realtime/realtime-session-overlay.component.js +839 -153
  115. package/dist/lib/components/realtime/realtime-session-overlay.component.js.map +1 -1
  116. package/dist/lib/components/realtime/realtime-session-state.d.ts +5 -5
  117. package/dist/lib/components/realtime/realtime-session-state.d.ts.map +1 -1
  118. package/dist/lib/components/realtime/realtime-session-state.js.map +1 -1
  119. package/dist/lib/components/realtime/realtime-surface-tab-style.d.ts +70 -0
  120. package/dist/lib/components/realtime/realtime-surface-tab-style.d.ts.map +1 -0
  121. package/dist/lib/components/realtime/realtime-surface-tab-style.js +115 -0
  122. package/dist/lib/components/realtime/realtime-surface-tab-style.js.map +1 -0
  123. package/dist/lib/components/realtime/realtime-surface-tabs.component.d.ts +55 -57
  124. package/dist/lib/components/realtime/realtime-surface-tabs.component.d.ts.map +1 -1
  125. package/dist/lib/components/realtime/realtime-surface-tabs.component.js +165 -143
  126. package/dist/lib/components/realtime/realtime-surface-tabs.component.js.map +1 -1
  127. package/dist/lib/components/realtime/realtime-surface-tabs.model.d.ts +80 -71
  128. package/dist/lib/components/realtime/realtime-surface-tabs.model.d.ts.map +1 -1
  129. package/dist/lib/components/realtime/realtime-surface-tabs.model.js +83 -113
  130. package/dist/lib/components/realtime/realtime-surface-tabs.model.js.map +1 -1
  131. package/dist/lib/components/realtime/realtime-ui-config.d.ts +270 -0
  132. package/dist/lib/components/realtime/realtime-ui-config.d.ts.map +1 -0
  133. package/dist/lib/components/realtime/realtime-ui-config.js +212 -0
  134. package/dist/lib/components/realtime/realtime-ui-config.js.map +1 -0
  135. package/dist/lib/components/search/search-panel.component.d.ts +2 -0
  136. package/dist/lib/components/search/search-panel.component.d.ts.map +1 -1
  137. package/dist/lib/components/search/search-panel.component.js +92 -101
  138. package/dist/lib/components/search/search-panel.component.js.map +1 -1
  139. package/dist/lib/components/share/share-modal.component.d.ts.map +1 -1
  140. package/dist/lib/components/share/share-modal.component.js +10 -11
  141. package/dist/lib/components/share/share-modal.component.js.map +1 -1
  142. package/dist/lib/components/shared/user-picker.component.d.ts.map +1 -1
  143. package/dist/lib/components/shared/user-picker.component.js +12 -15
  144. package/dist/lib/components/shared/user-picker.component.js.map +1 -1
  145. package/dist/lib/components/sidebar/conversation-sidebar.component.d.ts +11 -3
  146. package/dist/lib/components/sidebar/conversation-sidebar.component.d.ts.map +1 -1
  147. package/dist/lib/components/sidebar/conversation-sidebar.component.js +34 -10
  148. package/dist/lib/components/sidebar/conversation-sidebar.component.js.map +1 -1
  149. package/dist/lib/components/sidebar/routines-section.component.d.ts +73 -0
  150. package/dist/lib/components/sidebar/routines-section.component.d.ts.map +1 -0
  151. package/dist/lib/components/sidebar/routines-section.component.js +211 -0
  152. package/dist/lib/components/sidebar/routines-section.component.js.map +1 -0
  153. package/dist/lib/components/tasks/tasks-dropdown.component.d.ts +12 -0
  154. package/dist/lib/components/tasks/tasks-dropdown.component.d.ts.map +1 -1
  155. package/dist/lib/components/tasks/tasks-dropdown.component.js +37 -1
  156. package/dist/lib/components/tasks/tasks-dropdown.component.js.map +1 -1
  157. package/dist/lib/components/workspace/conversation-workspace.component.d.ts +16 -5
  158. package/dist/lib/components/workspace/conversation-workspace.component.d.ts.map +1 -1
  159. package/dist/lib/components/workspace/conversation-workspace.component.js +51 -31
  160. package/dist/lib/components/workspace/conversation-workspace.component.js.map +1 -1
  161. package/dist/lib/composer-plugins/agent-mention.provider.d.ts +16 -0
  162. package/dist/lib/composer-plugins/agent-mention.provider.d.ts.map +1 -0
  163. package/dist/lib/composer-plugins/agent-mention.provider.js +28 -0
  164. package/dist/lib/composer-plugins/agent-mention.provider.js.map +1 -0
  165. package/dist/lib/composer-plugins/base-conversation-mention.provider.d.ts +20 -0
  166. package/dist/lib/composer-plugins/base-conversation-mention.provider.d.ts.map +1 -0
  167. package/dist/lib/composer-plugins/base-conversation-mention.provider.js +32 -0
  168. package/dist/lib/composer-plugins/base-conversation-mention.provider.js.map +1 -0
  169. package/dist/lib/composer-plugins/load-composer-plugins.d.ts +9 -0
  170. package/dist/lib/composer-plugins/load-composer-plugins.d.ts.map +1 -0
  171. package/dist/lib/composer-plugins/load-composer-plugins.js +17 -0
  172. package/dist/lib/composer-plugins/load-composer-plugins.js.map +1 -0
  173. package/dist/lib/composer-plugins/record-mention.provider.d.ts +14 -0
  174. package/dist/lib/composer-plugins/record-mention.provider.d.ts.map +1 -0
  175. package/dist/lib/composer-plugins/record-mention.provider.js +26 -0
  176. package/dist/lib/composer-plugins/record-mention.provider.js.map +1 -0
  177. package/dist/lib/composer-plugins/skill-command.provider.d.ts +15 -0
  178. package/dist/lib/composer-plugins/skill-command.provider.d.ts.map +1 -0
  179. package/dist/lib/composer-plugins/skill-command.provider.js +27 -0
  180. package/dist/lib/composer-plugins/skill-command.provider.js.map +1 -0
  181. package/dist/lib/conversations.module.d.ts +68 -64
  182. package/dist/lib/conversations.module.d.ts.map +1 -1
  183. package/dist/lib/conversations.module.js +69 -18
  184. package/dist/lib/conversations.module.js.map +1 -1
  185. package/dist/lib/models/conversation-state.model.d.ts +6 -3
  186. package/dist/lib/models/conversation-state.model.d.ts.map +1 -1
  187. package/dist/lib/models/conversation-state.model.js.map +1 -1
  188. package/dist/lib/services/conversation-agent.service.d.ts +9 -2
  189. package/dist/lib/services/conversation-agent.service.d.ts.map +1 -1
  190. package/dist/lib/services/conversation-agent.service.js +26 -2
  191. package/dist/lib/services/conversation-agent.service.js.map +1 -1
  192. package/dist/lib/services/conversation-attachment.service.d.ts +1 -1
  193. package/dist/lib/services/conversation-attachment.service.d.ts.map +1 -1
  194. package/dist/lib/services/conversation-attachment.service.js.map +1 -1
  195. package/dist/lib/services/mention-autocomplete.service.d.ts +42 -19
  196. package/dist/lib/services/mention-autocomplete.service.d.ts.map +1 -1
  197. package/dist/lib/services/mention-autocomplete.service.js +113 -18
  198. package/dist/lib/services/mention-autocomplete.service.js.map +1 -1
  199. package/dist/lib/services/realtime-audio-recorder.d.ts +143 -0
  200. package/dist/lib/services/realtime-audio-recorder.d.ts.map +1 -0
  201. package/dist/lib/services/realtime-audio-recorder.js +379 -0
  202. package/dist/lib/services/realtime-audio-recorder.js.map +1 -0
  203. package/dist/lib/services/realtime-pcm-wav.d.ts +75 -0
  204. package/dist/lib/services/realtime-pcm-wav.d.ts.map +1 -0
  205. package/dist/lib/services/realtime-pcm-wav.js +205 -0
  206. package/dist/lib/services/realtime-pcm-wav.js.map +1 -0
  207. package/dist/lib/services/realtime-session-review.service.d.ts +28 -1
  208. package/dist/lib/services/realtime-session-review.service.d.ts.map +1 -1
  209. package/dist/lib/services/realtime-session-review.service.js +12 -3
  210. package/dist/lib/services/realtime-session-review.service.js.map +1 -1
  211. package/dist/lib/services/realtime-session.service.d.ts +210 -20
  212. package/dist/lib/services/realtime-session.service.d.ts.map +1 -1
  213. package/dist/lib/services/realtime-session.service.js +452 -21
  214. package/dist/lib/services/realtime-session.service.js.map +1 -1
  215. package/dist/lib/services/realtime-sessions-adapter.js +1 -1
  216. package/dist/lib/services/realtime-sessions-adapter.js.map +1 -1
  217. package/dist/lib/services/ui-command-handler.service.d.ts +7 -2
  218. package/dist/lib/services/ui-command-handler.service.d.ts.map +1 -1
  219. package/dist/lib/services/ui-command-handler.service.js +6 -2
  220. package/dist/lib/services/ui-command-handler.service.js.map +1 -1
  221. package/dist/lib/utils/plan-mode-preference.d.ts +62 -0
  222. package/dist/lib/utils/plan-mode-preference.d.ts.map +1 -0
  223. package/dist/lib/utils/plan-mode-preference.js +130 -0
  224. package/dist/lib/utils/plan-mode-preference.js.map +1 -0
  225. package/dist/public-api.d.ts +29 -3
  226. package/dist/public-api.d.ts.map +1 -1
  227. package/dist/public-api.js +46 -3
  228. package/dist/public-api.js.map +1 -1
  229. package/package.json +30 -26
  230. package/dist/__tests__/attachment-badge.test.d.ts +0 -2
  231. package/dist/__tests__/attachment-badge.test.d.ts.map +0 -1
  232. package/dist/__tests__/attachment-badge.test.js +0 -66
  233. package/dist/__tests__/attachment-badge.test.js.map +0 -1
  234. package/dist/__tests__/channel-optional-surface.test.d.ts +0 -2
  235. package/dist/__tests__/channel-optional-surface.test.d.ts.map +0 -1
  236. package/dist/__tests__/channel-optional-surface.test.js +0 -53
  237. package/dist/__tests__/channel-optional-surface.test.js.map +0 -1
  238. package/dist/__tests__/chat-events.test.d.ts +0 -14
  239. package/dist/__tests__/chat-events.test.d.ts.map +0 -1
  240. package/dist/__tests__/chat-events.test.js +0 -109
  241. package/dist/__tests__/chat-events.test.js.map +0 -1
  242. package/dist/__tests__/collections-full-view.test.d.ts +0 -2
  243. package/dist/__tests__/collections-full-view.test.d.ts.map +0 -1
  244. package/dist/__tests__/collections-full-view.test.js +0 -225
  245. package/dist/__tests__/collections-full-view.test.js.map +0 -1
  246. package/dist/__tests__/conversation-cache.test.d.ts +0 -2
  247. package/dist/__tests__/conversation-cache.test.d.ts.map +0 -1
  248. package/dist/__tests__/conversation-cache.test.js +0 -233
  249. package/dist/__tests__/conversation-cache.test.js.map +0 -1
  250. package/dist/__tests__/conversation-naming.test.d.ts +0 -2
  251. package/dist/__tests__/conversation-naming.test.d.ts.map +0 -1
  252. package/dist/__tests__/conversation-naming.test.js +0 -110
  253. package/dist/__tests__/conversation-naming.test.js.map +0 -1
  254. package/dist/__tests__/delegation-result-parser.test.d.ts +0 -2
  255. package/dist/__tests__/delegation-result-parser.test.d.ts.map +0 -1
  256. package/dist/__tests__/delegation-result-parser.test.js +0 -107
  257. package/dist/__tests__/delegation-result-parser.test.js.map +0 -1
  258. package/dist/__tests__/distinct-artifacts.test.d.ts +0 -2
  259. package/dist/__tests__/distinct-artifacts.test.d.ts.map +0 -1
  260. package/dist/__tests__/distinct-artifacts.test.js +0 -56
  261. package/dist/__tests__/distinct-artifacts.test.js.map +0 -1
  262. package/dist/__tests__/event-wiring.test.d.ts +0 -15
  263. package/dist/__tests__/event-wiring.test.d.ts.map +0 -1
  264. package/dist/__tests__/event-wiring.test.js +0 -100
  265. package/dist/__tests__/event-wiring.test.js.map +0 -1
  266. package/dist/__tests__/index.test.d.ts +0 -2
  267. package/dist/__tests__/index.test.d.ts.map +0 -1
  268. package/dist/__tests__/index.test.js +0 -7
  269. package/dist/__tests__/index.test.js.map +0 -1
  270. package/dist/__tests__/narration-template.test.d.ts +0 -2
  271. package/dist/__tests__/narration-template.test.d.ts.map +0 -1
  272. package/dist/__tests__/narration-template.test.js +0 -76
  273. package/dist/__tests__/narration-template.test.js.map +0 -1
  274. package/dist/__tests__/notification-model.test.d.ts +0 -2
  275. package/dist/__tests__/notification-model.test.d.ts.map +0 -1
  276. package/dist/__tests__/notification-model.test.js +0 -68
  277. package/dist/__tests__/notification-model.test.js.map +0 -1
  278. package/dist/__tests__/realtime-agent-picker-models.test.d.ts +0 -2
  279. package/dist/__tests__/realtime-agent-picker-models.test.d.ts.map +0 -1
  280. package/dist/__tests__/realtime-agent-picker-models.test.js +0 -49
  281. package/dist/__tests__/realtime-agent-picker-models.test.js.map +0 -1
  282. package/dist/__tests__/realtime-audio-visuals.test.d.ts +0 -2
  283. package/dist/__tests__/realtime-audio-visuals.test.d.ts.map +0 -1
  284. package/dist/__tests__/realtime-audio-visuals.test.js +0 -123
  285. package/dist/__tests__/realtime-audio-visuals.test.js.map +0 -1
  286. package/dist/__tests__/realtime-delegation-card-cancel.test.d.ts +0 -2
  287. package/dist/__tests__/realtime-delegation-card-cancel.test.d.ts.map +0 -1
  288. package/dist/__tests__/realtime-delegation-card-cancel.test.js +0 -48
  289. package/dist/__tests__/realtime-delegation-card-cancel.test.js.map +0 -1
  290. package/dist/__tests__/realtime-disclosure.test.d.ts +0 -2
  291. package/dist/__tests__/realtime-disclosure.test.d.ts.map +0 -1
  292. package/dist/__tests__/realtime-disclosure.test.js +0 -164
  293. package/dist/__tests__/realtime-disclosure.test.js.map +0 -1
  294. package/dist/__tests__/realtime-pairing.test.d.ts +0 -2
  295. package/dist/__tests__/realtime-pairing.test.d.ts.map +0 -1
  296. package/dist/__tests__/realtime-pairing.test.js +0 -207
  297. package/dist/__tests__/realtime-pairing.test.js.map +0 -1
  298. package/dist/__tests__/realtime-review-lifecycle.test.d.ts +0 -2
  299. package/dist/__tests__/realtime-review-lifecycle.test.d.ts.map +0 -1
  300. package/dist/__tests__/realtime-review-lifecycle.test.js +0 -154
  301. package/dist/__tests__/realtime-review-lifecycle.test.js.map +0 -1
  302. package/dist/__tests__/realtime-session-cancel-usage.test.d.ts +0 -2
  303. package/dist/__tests__/realtime-session-cancel-usage.test.d.ts.map +0 -1
  304. package/dist/__tests__/realtime-session-cancel-usage.test.js +0 -230
  305. package/dist/__tests__/realtime-session-cancel-usage.test.js.map +0 -1
  306. package/dist/__tests__/realtime-session-channels.test.d.ts +0 -2
  307. package/dist/__tests__/realtime-session-channels.test.d.ts.map +0 -1
  308. package/dist/__tests__/realtime-session-channels.test.js +0 -252
  309. package/dist/__tests__/realtime-session-channels.test.js.map +0 -1
  310. package/dist/__tests__/realtime-session-client-tools.test.d.ts +0 -2
  311. package/dist/__tests__/realtime-session-client-tools.test.d.ts.map +0 -1
  312. package/dist/__tests__/realtime-session-client-tools.test.js +0 -103
  313. package/dist/__tests__/realtime-session-client-tools.test.js.map +0 -1
  314. package/dist/__tests__/realtime-session-minimized.test.d.ts +0 -2
  315. package/dist/__tests__/realtime-session-minimized.test.d.ts.map +0 -1
  316. package/dist/__tests__/realtime-session-minimized.test.js +0 -32
  317. package/dist/__tests__/realtime-session-minimized.test.js.map +0 -1
  318. package/dist/__tests__/realtime-session-mint.test.d.ts +0 -2
  319. package/dist/__tests__/realtime-session-mint.test.d.ts.map +0 -1
  320. package/dist/__tests__/realtime-session-mint.test.js +0 -69
  321. package/dist/__tests__/realtime-session-mint.test.js.map +0 -1
  322. package/dist/__tests__/realtime-session-policy.test.d.ts +0 -2
  323. package/dist/__tests__/realtime-session-policy.test.d.ts.map +0 -1
  324. package/dist/__tests__/realtime-session-policy.test.js +0 -303
  325. package/dist/__tests__/realtime-session-policy.test.js.map +0 -1
  326. package/dist/__tests__/realtime-session-review.service.test.d.ts +0 -2
  327. package/dist/__tests__/realtime-session-review.service.test.d.ts.map +0 -1
  328. package/dist/__tests__/realtime-session-review.service.test.js +0 -743
  329. package/dist/__tests__/realtime-session-review.service.test.js.map +0 -1
  330. package/dist/__tests__/realtime-session-state.test.d.ts +0 -2
  331. package/dist/__tests__/realtime-session-state.test.d.ts.map +0 -1
  332. package/dist/__tests__/realtime-session-state.test.js +0 -83
  333. package/dist/__tests__/realtime-session-state.test.js.map +0 -1
  334. package/dist/__tests__/realtime-session-timeline-card.test.d.ts +0 -2
  335. package/dist/__tests__/realtime-session-timeline-card.test.d.ts.map +0 -1
  336. package/dist/__tests__/realtime-session-timeline-card.test.js +0 -106
  337. package/dist/__tests__/realtime-session-timeline-card.test.js.map +0 -1
  338. package/dist/__tests__/realtime-session-timeline.test.d.ts +0 -2
  339. package/dist/__tests__/realtime-session-timeline.test.d.ts.map +0 -1
  340. package/dist/__tests__/realtime-session-timeline.test.js +0 -142
  341. package/dist/__tests__/realtime-session-timeline.test.js.map +0 -1
  342. package/dist/__tests__/realtime-sessions-adapter.test.d.ts +0 -19
  343. package/dist/__tests__/realtime-sessions-adapter.test.d.ts.map +0 -1
  344. package/dist/__tests__/realtime-sessions-adapter.test.js +0 -188
  345. package/dist/__tests__/realtime-sessions-adapter.test.js.map +0 -1
  346. package/dist/__tests__/realtime-surface-panel-prefs.test.d.ts +0 -2
  347. package/dist/__tests__/realtime-surface-panel-prefs.test.d.ts.map +0 -1
  348. package/dist/__tests__/realtime-surface-panel-prefs.test.js +0 -100
  349. package/dist/__tests__/realtime-surface-panel-prefs.test.js.map +0 -1
  350. package/dist/__tests__/realtime-surface-tabs-model.test.d.ts +0 -2
  351. package/dist/__tests__/realtime-surface-tabs-model.test.d.ts.map +0 -1
  352. package/dist/__tests__/realtime-surface-tabs-model.test.js +0 -193
  353. package/dist/__tests__/realtime-surface-tabs-model.test.js.map +0 -1
  354. package/dist/__tests__/remote-browser-audio-player.test.d.ts +0 -2
  355. package/dist/__tests__/remote-browser-audio-player.test.d.ts.map +0 -1
  356. package/dist/__tests__/remote-browser-audio-player.test.js +0 -137
  357. package/dist/__tests__/remote-browser-audio-player.test.js.map +0 -1
  358. package/dist/__tests__/remote-browser-channel.test.d.ts +0 -2
  359. package/dist/__tests__/remote-browser-channel.test.d.ts.map +0 -1
  360. package/dist/__tests__/remote-browser-channel.test.js +0 -585
  361. package/dist/__tests__/remote-browser-channel.test.js.map +0 -1
  362. package/dist/__tests__/search-service.test.d.ts +0 -2
  363. package/dist/__tests__/search-service.test.d.ts.map +0 -1
  364. package/dist/__tests__/search-service.test.js +0 -114
  365. package/dist/__tests__/search-service.test.js.map +0 -1
  366. package/dist/__tests__/slot-defaults.test.d.ts +0 -24
  367. package/dist/__tests__/slot-defaults.test.d.ts.map +0 -1
  368. package/dist/__tests__/slot-defaults.test.js +0 -63
  369. package/dist/__tests__/slot-defaults.test.js.map +0 -1
  370. package/dist/__tests__/toast-service.test.d.ts +0 -2
  371. package/dist/__tests__/toast-service.test.d.ts.map +0 -1
  372. package/dist/__tests__/toast-service.test.js +0 -143
  373. package/dist/__tests__/toast-service.test.js.map +0 -1
  374. package/dist/__tests__/user-authorization.test.d.ts +0 -2
  375. package/dist/__tests__/user-authorization.test.d.ts.map +0 -1
  376. package/dist/__tests__/user-authorization.test.js +0 -97
  377. package/dist/__tests__/user-authorization.test.js.map +0 -1
  378. package/dist/__tests__/voice-session-narration.test.d.ts +0 -2
  379. package/dist/__tests__/voice-session-narration.test.d.ts.map +0 -1
  380. package/dist/__tests__/voice-session-narration.test.js +0 -609
  381. package/dist/__tests__/voice-session-narration.test.js.map +0 -1
  382. package/dist/__tests__/whiteboard-artifact-viewer.test.d.ts +0 -2
  383. package/dist/__tests__/whiteboard-artifact-viewer.test.d.ts.map +0 -1
  384. package/dist/__tests__/whiteboard-artifact-viewer.test.js +0 -101
  385. package/dist/__tests__/whiteboard-artifact-viewer.test.js.map +0 -1
  386. package/dist/__tests__/whiteboard-channel.test.d.ts +0 -2
  387. package/dist/__tests__/whiteboard-channel.test.d.ts.map +0 -1
  388. package/dist/__tests__/whiteboard-channel.test.js +0 -260
  389. package/dist/__tests__/whiteboard-channel.test.js.map +0 -1
  390. package/dist/__tests__/whiteboard-restore-state.test.d.ts +0 -2
  391. package/dist/__tests__/whiteboard-restore-state.test.d.ts.map +0 -1
  392. package/dist/__tests__/whiteboard-restore-state.test.js +0 -108
  393. package/dist/__tests__/whiteboard-restore-state.test.js.map +0 -1
  394. package/dist/lib/components/mention/mention-dropdown.component.d.ts +0 -53
  395. package/dist/lib/components/mention/mention-dropdown.component.d.ts.map +0 -1
  396. package/dist/lib/components/mention/mention-dropdown.component.js +0 -276
  397. package/dist/lib/components/mention/mention-dropdown.component.js.map +0 -1
  398. package/dist/lib/components/mention/mention-editor.component.d.ts +0 -256
  399. package/dist/lib/components/mention/mention-editor.component.d.ts.map +0 -1
  400. package/dist/lib/components/mention/mention-editor.component.js +0 -1233
  401. package/dist/lib/components/mention/mention-editor.component.js.map +0 -1
  402. package/dist/lib/components/message/message-input-box.component.d.ts +0 -137
  403. package/dist/lib/components/message/message-input-box.component.d.ts.map +0 -1
  404. package/dist/lib/components/message/message-input-box.component.js +0 -321
  405. package/dist/lib/components/message/message-input-box.component.js.map +0 -1
@@ -6,6 +6,8 @@ import { GraphQLDataProvider } from '@memberjunction/graphql-dataprovider';
6
6
  import { GenerateAndApplyConversationName } from '../../services/conversation-naming';
7
7
  import { AIEngineBase } from '@memberjunction/ai-engine-base';
8
8
  import { ConversationUtility } from '@memberjunction/ai-core-plus';
9
+ import { MentionAutocompleteService } from '../../services/mention-autocomplete.service';
10
+ import { PlanModePreference } from '../../utils/plan-mode-preference';
9
11
  import { MJNotificationService } from '@memberjunction/ng-notifications';
10
12
  import { BuildRealtimeConfigOverridesJson, FilterRealtimeCoAgents, LoadCoAgentPairings, PairingsAllowTarget } from '../../services/realtime-pairing';
11
13
  import { UUIDsEqual } from '@memberjunction/global';
@@ -17,16 +19,16 @@ import * as i4 from "../../services/data-cache.service";
17
19
  import * as i5 from "../../services/active-tasks.service";
18
20
  import * as i6 from "../../services/conversation-streaming.service";
19
21
  import * as i7 from "../../services/mention-parser.service";
20
- import * as i8 from "../../services/mention-autocomplete.service";
21
- import * as i9 from "../../services/conversation-attachment.service";
22
- import * as i10 from "../../services/conversation-bridge.service";
23
- import * as i11 from "../../services/realtime-session.service";
22
+ import * as i8 from "../../services/conversation-attachment.service";
23
+ import * as i9 from "../../services/conversation-bridge.service";
24
+ import * as i10 from "../../services/realtime-session.service";
25
+ import * as i11 from "@angular/cdk/overlay";
24
26
  import * as i12 from "../realtime/realtime-agent-picker.component";
25
- import * as i13 from "./message-input-box.component";
27
+ import * as i13 from "../composer/ai-composer.component";
26
28
  const _c0 = ["inputBox"];
27
- function MessageInputComponent_Conditional_1_Template(rf, ctx) { if (rf & 1) {
28
- i0.ɵɵelementStart(0, "div", 2);
29
- i0.ɵɵelement(1, "i", 5);
29
+ function MessageInputComponent_Conditional_2_Template(rf, ctx) { if (rf & 1) {
30
+ i0.ɵɵelementStart(0, "div", 3);
31
+ i0.ɵɵelement(1, "i", 6);
30
32
  i0.ɵɵelementStart(2, "span");
31
33
  i0.ɵɵtext(3);
32
34
  i0.ɵɵelementEnd()();
@@ -35,10 +37,10 @@ function MessageInputComponent_Conditional_1_Template(rf, ctx) { if (rf & 1) {
35
37
  i0.ɵɵadvance(3);
36
38
  i0.ɵɵtextInterpolate(ctx_r1.processingMessage);
37
39
  } }
38
- function MessageInputComponent_Conditional_4_Template(rf, ctx) { if (rf & 1) {
40
+ function MessageInputComponent_ng_template_5_Template(rf, ctx) { if (rf & 1) {
39
41
  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.ɵɵelementStart(0, "mj-realtime-agent-picker", 7);
43
+ i0.ɵɵlistener("AgentPicked", function MessageInputComponent_ng_template_5_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_ng_template_5_Template_mj_realtime_agent_picker_Cancelled_0_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onRealtimeAgentPickerCancelled()); });
42
44
  i0.ɵɵelementEnd();
43
45
  } if (rf & 2) {
44
46
  const ctx_r1 = i0.ɵɵnextContext();
@@ -52,10 +54,9 @@ export class MessageInputComponent extends BaseAngularComponent {
52
54
  activeTasks;
53
55
  streamingService;
54
56
  mentionParser;
55
- mentionAutocomplete;
56
57
  attachmentService;
57
58
  bridge;
58
- voiceSession;
59
+ realtimeSession;
59
60
  // Default artifact type ID for JSON (when agent doesn't specify DefaultArtifactTypeID)
60
61
  JSON_ARTIFACT_TYPE_ID = 'ae674c7e-ea0d-49ea-89e4-0649f5eb20d4';
61
62
  conversationId;
@@ -74,6 +75,40 @@ export class MessageInputComponent extends BaseAngularComponent {
74
75
  agentRunsByDetailId; // Pre-loaded agent run data for performance
75
76
  emptyStateMode = false; // When true, emits emptyStateSubmit instead of creating messages directly
76
77
  appContext = null; // Application context for AI agent awareness
78
+ /**
79
+ * Plan Mode toggle state — sticky PER CONVERSATION, OFF by default (no behavior change unless
80
+ * the user turns it on). When on, the user's next message(s) in THIS conversation request Plan
81
+ * Mode: the routed root agent must present a plan for approval before executing Actions/
82
+ * Sub-Agents. The toggle is always shown and the server enforces the `AIAgent.SupportsPlanMode`
83
+ * capability — a plan-mode request to an agent that doesn't support it simply no-ops the gate
84
+ * (see resolvePlanModeGate), so we don't need to resolve "the current agent" client-side.
85
+ *
86
+ * IMPORTANT: this is a GETTER over {@link PlanModePreference} (UserInfoEngine-backed), NOT a
87
+ * local field. The composer is mounted in multiple places at once (empty-state, chat-area,
88
+ * thread panel) — a local boolean per instance goes stale the moment another instance toggles.
89
+ * On the new-conversation composer (no conversationId yet) the value lives in a pending bucket
90
+ * that transfers to the real conversation on its first message. Approving a plan turns the
91
+ * conversation's flag OFF automatically (see message-item's plan-decision handling).
92
+ */
93
+ get PlanModeEnabled() {
94
+ return PlanModePreference.IsEnabled(this.conversationId);
95
+ }
96
+ /**
97
+ * Skill IDs the user requested via `/skill-name` mentions in the message being routed. Collected
98
+ * once per send from the composer's mention chips and forwarded to every agent-invocation path so
99
+ * whichever agent handles the message receives them as `RequestedSkillIDs`. The server intersects
100
+ * them with the agent's accepted skills AND the user's Run permission before any activate, so a
101
+ * skill the user can't run (or the agent doesn't accept) is silently dropped. Reset each send.
102
+ */
103
+ _pendingRequestedSkillIDs = [];
104
+ /**
105
+ * Collects the skill IDs from `/skill` mention chips currently in the composer. Called at the
106
+ * start of routing so the value is stable for the whole message dispatch.
107
+ */
108
+ collectRequestedSkillIDs() {
109
+ const chipData = this.inputBox?.getMentionChipsData() || [];
110
+ return chipData.filter(chip => chip.type === 'skill').map(chip => chip.id);
111
+ }
77
112
  /**
78
113
  * Optional default agent ID for the conversation. When set, the FIRST
79
114
  * message routes directly to this agent — skipping Sage's default
@@ -124,6 +159,8 @@ export class MessageInputComponent extends BaseAngularComponent {
124
159
  _initialMessage = null;
125
160
  _initialAttachments = null;
126
161
  _isComponentReady = false; // Track if component is ready to send
162
+ /** Conversation this input has already auto-sent its pending first message for. */
163
+ _autoSentForConversationId = null;
127
164
  set initialMessage(value) {
128
165
  // Handle case where an object with {text, attachments} is passed instead of just a string
129
166
  // This can happen if there's a type mismatch in the binding chain
@@ -164,6 +201,13 @@ export class MessageInputComponent extends BaseAngularComponent {
164
201
  if (this.streamingService && value && value.length > 0) {
165
202
  this.reconnectInProgressMessages();
166
203
  }
204
+ else if (this.streamingService) {
205
+ // Empty/undefined — e.g. this input was backgrounded by a conversation swap
206
+ // ([] is bound to non-active inputs). Drop any streaming callbacks so a hidden
207
+ // input isn't left subscribed; reconnectInProgressMessages re-registers when it
208
+ // becomes active again with a non-empty list.
209
+ this.unregisterAllCallbacks();
210
+ }
167
211
  }
168
212
  get inProgressMessageIds() {
169
213
  return this._inProgressMessageIds;
@@ -191,16 +235,21 @@ export class MessageInputComponent extends BaseAngularComponent {
191
235
  * the underlying `processMessage` errored.
192
236
  */
193
237
  afterAgentTurn = new EventEmitter();
238
+ // conversationId is carried on every agent-lifecycle event so the parent chat-area can drop
239
+ // events emitted by a BACKGROUND conversation's (hidden, still-streaming) input after the user
240
+ // has swapped conversations — preventing cross-conversation state/cache bleed. Sourced from the
241
+ // ConversationDetail entity's ConversationID (the captured, immutable value), never this.conversationId.
194
242
  agentRunDetected = new EventEmitter();
195
243
  agentRunUpdate = new EventEmitter(); // Emits when agent run data updates during progress
196
244
  messageComplete = new EventEmitter(); // Emits when message completes (success or error)
197
245
  artifactCreated = new EventEmitter();
198
246
  conversationRenamed = new EventEmitter();
199
247
  intentCheckStarted = new EventEmitter(); // Emits when intent checking starts
200
- intentCheckCompleted = new EventEmitter(); // Emits when intent checking completes
248
+ intentCheckCompleted = new EventEmitter(); // Emits when intent checking completes (carries conversationId so the parent can drop a background conversation's completion after a swap — symmetric with intentCheckStarted)
249
+ initialMessageAutoSendStarted = new EventEmitter(); // Emitted when this input latches the pending first message for auto-send
250
+ initialMessageAutoSendFailed = new EventEmitter(); // Emitted when a latched pending first message fails before messageSent
201
251
  emptyStateSubmit = new EventEmitter(); // Emitted when in emptyStateMode
202
252
  uploadStateChanged = new EventEmitter(); // Emits when attachment upload state changes
203
- artifactPickerRequested = new EventEmitter(); // Emits when user clicks "Attach Artifact"
204
253
  inputBox;
205
254
  messageText = '';
206
255
  isSending = false;
@@ -216,7 +265,9 @@ export class MessageInputComponent extends BaseAngularComponent {
216
265
  // Track pending attachments from the input box
217
266
  pendingAttachments = [];
218
267
  engine = ConversationEngine.Instance;
219
- constructor(dialogService, toastService, agentService, dataCache, activeTasks, streamingService, mentionParser, mentionAutocomplete, attachmentService, bridge, voiceSession) {
268
+ // Shared AI mention/suggestion engine (BaseSingleton same instance the composer plugins use)
269
+ mentionAutocomplete = MentionAutocompleteService.Instance;
270
+ constructor(dialogService, toastService, agentService, dataCache, activeTasks, streamingService, mentionParser, attachmentService, bridge, realtimeSession) {
220
271
  super();
221
272
  this.dialogService = dialogService;
222
273
  this.toastService = toastService;
@@ -225,15 +276,14 @@ export class MessageInputComponent extends BaseAngularComponent {
225
276
  this.activeTasks = activeTasks;
226
277
  this.streamingService = streamingService;
227
278
  this.mentionParser = mentionParser;
228
- this.mentionAutocomplete = mentionAutocomplete;
229
279
  this.attachmentService = attachmentService;
230
280
  this.bridge = bridge;
231
- this.voiceSession = voiceSession;
281
+ this.realtimeSession = realtimeSession;
232
282
  }
233
283
  // ── Voice session (Realtime Co-Agent) ───────────────────────────────
234
284
  /** True while a live voice session is active — drives the overlay + mic state. */
235
285
  voiceActive = false;
236
- voiceActiveSub;
286
+ realtimeActiveSub;
237
287
  async ngOnInit() {
238
288
  // Bind provider-aware services to this component's provider.
239
289
  const p = this.ProviderToUse;
@@ -241,12 +291,15 @@ export class MessageInputComponent extends BaseAngularComponent {
241
291
  this.dataCache.Provider = p;
242
292
  this.activeTasks.Provider = p;
243
293
  this.attachmentService.Provider = p;
244
- this.voiceSession.Provider = p;
294
+ this.realtimeSession.Provider = p;
245
295
  // Reflect the live voice-session Active flag into a local field for the template.
246
- this.voiceActiveSub = this.voiceSession.Active$.subscribe(active => {
296
+ this.realtimeActiveSub = this.realtimeSession.Active$.subscribe(active => {
247
297
  this.voiceActive = active;
248
298
  });
249
299
  this.converationManagerAgent = await this.agentService.getConversationManagerAgent();
300
+ // Warm UserInfoEngine so the PlanModeEnabled getter has the cached settings available
301
+ // (no-op when already loaded; failure just leaves the toggle at its default OFF).
302
+ PlanModePreference.Warm();
250
303
  // Initialize mention autocomplete (needed for parsing mentions in messages)
251
304
  await this.mentionAutocomplete.initialize(this.currentUser);
252
305
  // Reconnect to any in-progress messages for streaming updates (via global streaming service)
@@ -276,22 +329,34 @@ export class MessageInputComponent extends BaseAngularComponent {
276
329
  triggerInitialSend() {
277
330
  const message = this._initialMessage;
278
331
  const attachments = this._initialAttachments;
332
+ const hasContent = !!message || !!(attachments && attachments.length > 0);
333
+ if (!hasContent || !this.conversationId || UUIDsEqual(this._autoSentForConversationId, this.conversationId)) {
334
+ return;
335
+ }
336
+ this._autoSentForConversationId = this.conversationId;
279
337
  // Set pending attachments before sending
280
338
  if (attachments && attachments.length > 0) {
281
339
  this.pendingAttachments = [...attachments];
282
340
  }
341
+ Promise.resolve().then(() => {
342
+ this.initialMessageAutoSendStarted.emit({ conversationId: this.conversationId });
343
+ });
283
344
  // Use setTimeout to ensure we're outside of change detection cycle
284
- setTimeout(() => {
285
- this.sendMessageWithText(message || '');
345
+ setTimeout(async () => {
346
+ const sent = await this.sendMessageWithText(message || '');
347
+ if (!sent) {
348
+ this._autoSentForConversationId = null;
349
+ this.initialMessageAutoSendFailed.emit({ conversationId: this.conversationId });
350
+ }
286
351
  }, 100);
287
352
  }
288
353
  ngOnDestroy() {
289
354
  // Unregister all streaming callbacks
290
355
  this.unregisterAllCallbacks();
291
- this.voiceActiveSub?.unsubscribe();
356
+ this.realtimeActiveSub?.unsubscribe();
292
357
  // If the user navigates away mid-call, tear the session down.
293
- if (this.voiceSession.IsActive) {
294
- void this.voiceSession.EndVoiceSession();
358
+ if (this.realtimeSession.IsActive) {
359
+ void this.realtimeSession.EndRealtimeSession();
295
360
  }
296
361
  }
297
362
  /**
@@ -311,7 +376,7 @@ export class MessageInputComponent extends BaseAngularComponent {
311
376
  ?? null;
312
377
  }
313
378
  /** True when the mic button should be enabled (have an agent + not disabled). */
314
- get canStartVoice() {
379
+ get canStartRealtime() {
315
380
  return !this.disabled && !this.voiceActive && !!this.resolveCurrentAgentId();
316
381
  }
317
382
  /**
@@ -319,7 +384,7 @@ export class MessageInputComponent extends BaseAngularComponent {
319
384
  * owns the conversation's routing context) and passed to RealtimeSessionService at
320
385
  * session start so the chat-area-hosted overlay can read it from the service.
321
386
  */
322
- resolveVoiceAgentName() {
387
+ resolveRealtimeAgentName() {
323
388
  const agentId = this.resolveCurrentAgentId();
324
389
  if (agentId) {
325
390
  const match = this.mentionAutocomplete
@@ -333,6 +398,17 @@ export class MessageInputComponent extends BaseAngularComponent {
333
398
  }
334
399
  /** True while the "Start a voice call with…" agent picker popover is open. */
335
400
  showRealtimeAgentPicker = false;
401
+ /**
402
+ * CDK connected-overlay positions for the voice agent picker. Preferred: open UPWARD,
403
+ * right edge aligned to the composer's right edge (matching the old absolute placement).
404
+ * Fallback: open downward when there isn't room above. Because the popover renders in the
405
+ * body-level CDK overlay container (with `cdkConnectedOverlayPush`), it escapes the chat
406
+ * overlay's `overflow: hidden` border and can never clip at the top of a narrow overlay.
407
+ */
408
+ pickerOverlayPositions = [
409
+ { originX: 'end', originY: 'top', overlayX: 'end', overlayY: 'bottom', offsetY: -8 },
410
+ { originX: 'end', originY: 'bottom', overlayX: 'end', overlayY: 'top', offsetY: 8 },
411
+ ];
336
412
  /**
337
413
  * `MJ: User Settings` key persisting the user's co-agent choice for realtime calls
338
414
  * (server-side, cross-device — never localStorage). Stored shape: `{"coAgentId":
@@ -346,7 +422,7 @@ export class MessageInputComponent extends BaseAngularComponent {
346
422
  voicePickerDefaultCoAgentId = null;
347
423
  /**
348
424
  * Agents the voice picker offers — the same cached set the @mention
349
- * autocomplete and {@link resolveVoiceAgentName} use, so the picker can
425
+ * autocomplete and {@link resolveRealtimeAgentName} use, so the picker can
350
426
  * never offer an agent the conversation couldn't otherwise route to.
351
427
  */
352
428
  get voicePickerAgents() {
@@ -378,8 +454,8 @@ export class MessageInputComponent extends BaseAngularComponent {
378
454
  * the user never chose — so show a compact agent picker instead and start
379
455
  * with whichever agent they pick.
380
456
  */
381
- async onStartVoice() {
382
- if (!this.canStartVoice) {
457
+ async onStartRealtime() {
458
+ if (!this.canStartRealtime) {
383
459
  return;
384
460
  }
385
461
  // New/empty conversation (no prior agent turn): let the user choose who
@@ -395,7 +471,7 @@ export class MessageInputComponent extends BaseAngularComponent {
395
471
  return;
396
472
  }
397
473
  const coAgentId = await this.resolveInstantCoAgentId(targetAgentId);
398
- await this.startVoiceWithAgent(targetAgentId, this.resolveVoiceAgentName(), null, coAgentId);
474
+ await this.startRealtimeWithAgent(targetAgentId, this.resolveRealtimeAgentName(), null, coAgentId);
399
475
  }
400
476
  /**
401
477
  * Caret-next-to-the-phone click: open the agent/co-agent/model picker ON DEMAND, even
@@ -405,15 +481,15 @@ export class MessageInputComponent extends BaseAngularComponent {
405
481
  * choice one click away. Falls through to the instant path when there is nothing to
406
482
  * pick from.
407
483
  */
408
- async onVoiceOptions() {
409
- if (!this.canStartVoice) {
484
+ async onRealtimeOptions() {
485
+ if (!this.canStartRealtime) {
410
486
  return;
411
487
  }
412
488
  if (this.voicePickerAgents.length > 0) {
413
489
  await this.openRealtimeAgentPicker();
414
490
  return;
415
491
  }
416
- void this.onStartVoice();
492
+ void this.onStartRealtime();
417
493
  }
418
494
  /** Loads the persisted co-agent preference, then shows the picker (pref preselected). */
419
495
  async openRealtimeAgentPicker() {
@@ -424,7 +500,7 @@ export class MessageInputComponent extends BaseAngularComponent {
424
500
  async onRealtimeAgentPicked(pick) {
425
501
  this.showRealtimeAgentPicker = false;
426
502
  this.persistCoAgentChoice(pick.CoAgentId);
427
- await this.startVoiceWithAgent(pick.Agent.ID, pick.Agent.Name || this.resolveVoiceAgentName(), pick.PreferredModelId, pick.CoAgentId, BuildRealtimeConfigOverridesJson(pick.PreferredModelId, pick.PreferredVoice));
503
+ await this.startRealtimeWithAgent(pick.Agent.ID, pick.Agent.Name || this.resolveRealtimeAgentName(), pick.PreferredModelId, pick.CoAgentId, BuildRealtimeConfigOverridesJson(pick.PreferredModelId, pick.PreferredVoice), pick.RecordingConsent);
428
504
  }
429
505
  /**
430
506
  * Reads the persisted co-agent preference from `MJ: User Settings` (via
@@ -493,9 +569,13 @@ export class MessageInputComponent extends BaseAngularComponent {
493
569
  * passed here — the session service resolves the active channel plugins from the
494
570
  * `MJ: AI Agent Channels` registry and aggregates their tool sets at mint itself.
495
571
  */
496
- async startVoiceWithAgent(agentId, agentName, preferredModelId, coAgentId, configOverridesJson) {
572
+ async startRealtimeWithAgent(agentId, agentName, preferredModelId, coAgentId, configOverridesJson, recordingConsent) {
497
573
  try {
498
- await this.voiceSession.StartVoiceSession(agentId, this.conversationId, null, agentName, preferredModelId ?? null, null, coAgentId ?? null, configOverridesJson ?? null);
574
+ await this.realtimeSession.StartRealtimeSession(agentId, this.conversationId, null, agentName, preferredModelId ?? null, null, coAgentId ?? null, configOverridesJson ?? null, recordingConsent ?? null, null,
575
+ // App awareness: the app the session runs in + the live app-context snapshot (where the
576
+ // user is, what they see, capability manifest) — drives the server-side app cascade + the
577
+ // mint-time prompt injection, and seeds the ClientContextChannel's streaming.
578
+ this.applicationId, this.appContext);
499
579
  }
500
580
  catch (error) {
501
581
  console.error('Failed to start voice session:', error);
@@ -613,12 +693,6 @@ export class MessageInputComponent extends BaseAngularComponent {
613
693
  onAttachmentError(error) {
614
694
  this.toastService.error(error);
615
695
  }
616
- /**
617
- * Handle artifact picker request — bubble up to parent
618
- */
619
- onArtifactPickerRequested() {
620
- this.artifactPickerRequested.emit();
621
- }
622
696
  /**
623
697
  * Handle text submitted from the input box
624
698
  */
@@ -698,6 +772,16 @@ export class MessageInputComponent extends BaseAngularComponent {
698
772
  this.isSending = false;
699
773
  }
700
774
  }
775
+ /**
776
+ * Toggle sticky Plan Mode for THIS conversation (or the pending-new bucket on the
777
+ * new-conversation composer). Writes through {@link PlanModePreference} — the
778
+ * {@link PlanModeEnabled} getter reads the same cached setting, so ALL live composer
779
+ * instances flip together, and the value survives component recreation and sessions
780
+ * until the user turns it off or approves a plan.
781
+ */
782
+ TogglePlanMode() {
783
+ PlanModePreference.Set(this.conversationId, !this.PlanModeEnabled);
784
+ }
701
785
  async onSend() {
702
786
  if (!this.canSend)
703
787
  return;
@@ -748,10 +832,10 @@ export class MessageInputComponent extends BaseAngularComponent {
748
832
  const hasText = text && text.trim().length > 0;
749
833
  const hasAttachments = merged.length > 0;
750
834
  if (!hasText && !hasAttachments) {
751
- return;
835
+ return false;
752
836
  }
753
837
  if (this.isSending) {
754
- return;
838
+ return false;
755
839
  }
756
840
  this.isSending = true;
757
841
  const attachmentsToSave = merged;
@@ -798,7 +882,7 @@ export class MessageInputComponent extends BaseAngularComponent {
798
882
  console.error('Failed to roll back conversation detail after attachment rejection:', rollbackErr);
799
883
  }
800
884
  this.isSending = false;
801
- return;
885
+ return false;
802
886
  }
803
887
  }
804
888
  // Clear pending attachments after successful send
@@ -812,13 +896,16 @@ export class MessageInputComponent extends BaseAngularComponent {
812
896
  const mentionResult = this.parseMentionsFromMessage(detail.Message);
813
897
  const isFirstMessage = this.conversationHistory.length === 0;
814
898
  await this.routeMessage(detail, mentionResult, isFirstMessage);
899
+ return true;
815
900
  }
816
901
  else {
817
902
  this.handleSendFailure(detail);
903
+ return false;
818
904
  }
819
905
  }
820
906
  catch (error) {
821
907
  this.handleSendError(error);
908
+ return false;
822
909
  }
823
910
  finally {
824
911
  this.isSending = false;
@@ -876,6 +963,21 @@ export class MessageInputComponent extends BaseAngularComponent {
876
963
  * default agent > Sage fallback.
877
964
  */
878
965
  async routeMessage(messageDetail, mentionResult, isFirstMessage) {
966
+ // A Plan Mode choice made on the new-conversation composer (no conversation yet) lives in a
967
+ // pending bucket — the FIRST routed message claims it onto the real conversation so the
968
+ // toggle carries across the empty-state → chat-area transition without bleeding into other
969
+ // conversations.
970
+ if (isFirstMessage && messageDetail.ConversationID) {
971
+ PlanModePreference.ClaimPendingNew(messageDetail.ConversationID);
972
+ }
973
+ // Snapshot user-requested skills once, before any routing branch, so every invocation path
974
+ // forwards the same set for this message. Derived from the SAVED MESSAGE TEXT via the shared
975
+ // MentionParser (`@{"type":"skill",…}` JSON mentions — same encoding as @agent/#entity), so the
976
+ // source of truth is the message itself, not composer DOM state. Chip-DOM read is the fallback
977
+ // for any path where the parsed result isn't available.
978
+ this._pendingRequestedSkillIDs = mentionResult.skillMentions?.length
979
+ ? mentionResult.skillMentions.map(m => m.id)
980
+ : this.collectRequestedSkillIDs();
879
981
  // Priority 1: Direct @mention
880
982
  if (mentionResult.agentMention) {
881
983
  await this.handleDirectMention(messageDetail, mentionResult.agentMention, isFirstMessage);
@@ -912,10 +1014,10 @@ export class MessageInputComponent extends BaseAngularComponent {
912
1014
  if (sageConfigPreset) {
913
1015
  // User explicitly @mentioned Sage with a config - use the shared execution helper directly
914
1016
  // Pass the already-found config preset to avoid redundant history search
915
- await this.executeRouteWithNaming(() => this.executeAgentContinuation(messageDetail, this.converationManagerAgent.ID, this.converationManagerAgent.Name || 'Sage', this.conversationId, null, // Sage doesn't use payload continuity
1017
+ await this.executeRouteWithNaming(() => this.executeAgentContinuation(messageDetail, this.converationManagerAgent.ID, this.converationManagerAgent.Name || 'Sage', messageDetail.ConversationID, null, // Sage doesn't use payload continuity
916
1018
  null, // Sage doesn't use artifact info
917
1019
  sageConfigPreset // Pass the already-found config preset
918
- ), messageDetail.Message, isFirstMessage);
1020
+ ), messageDetail.Message, isFirstMessage, messageDetail.ConversationID);
919
1021
  return;
920
1022
  }
921
1023
  }
@@ -938,7 +1040,7 @@ export class MessageInputComponent extends BaseAngularComponent {
938
1040
  if (agentMention.configurationId) {
939
1041
  //console.log(`🎯 Agent mention has configuration ID: ${agentMention.configurationId}`);
940
1042
  }
941
- await this.executeRouteWithNaming(() => this.invokeAgentDirectly(messageDetail, agentMention, this.conversationId), messageDetail.Message, isFirstMessage);
1043
+ await this.executeRouteWithNaming(() => this.invokeAgentDirectly(messageDetail, agentMention, messageDetail.ConversationID), messageDetail.Message, isFirstMessage, messageDetail.ConversationID);
942
1044
  }
943
1045
  /**
944
1046
  * Handles routing when there's a previous non-Sage agent in the conversation.
@@ -982,14 +1084,14 @@ export class MessageInputComponent extends BaseAngularComponent {
982
1084
  // );
983
1085
  // }
984
1086
  // Always continue with the previous agent — user can @mention another agent to switch.
985
- await this.executeRouteWithNaming(() => this.continueWithAgent(messageDetail, lastAgentId, this.conversationId, undefined // artifact version targeting unavailable without intent check
986
- ), messageDetail.Message, isFirstMessage);
1087
+ await this.executeRouteWithNaming(() => this.continueWithAgent(messageDetail, lastAgentId, messageDetail.ConversationID, undefined // artifact version targeting unavailable without intent check
1088
+ ), messageDetail.Message, isFirstMessage, messageDetail.ConversationID);
987
1089
  }
988
1090
  /**
989
1091
  * Handles routing when there's no previous agent context
990
1092
  */
991
1093
  async handleNoAgentContext(messageDetail, mentionResult, isFirstMessage) {
992
- await this.executeRouteWithNaming(() => this.processMessageThroughAgent(messageDetail, mentionResult), messageDetail.Message, isFirstMessage);
1094
+ await this.executeRouteWithNaming(() => this.processMessageThroughAgent(messageDetail, mentionResult), messageDetail.Message, isFirstMessage, messageDetail.ConversationID);
993
1095
  }
994
1096
  /**
995
1097
  * Finds the last agent ID that isn't Sage
@@ -1019,7 +1121,7 @@ export class MessageInputComponent extends BaseAngularComponent {
1019
1121
  };
1020
1122
  }
1021
1123
  // Emit event to show temporary "Analyzing intent..." message in conversation
1022
- this.intentCheckStarted.emit();
1124
+ this.intentCheckStarted.emit({ conversationId: this.conversationId });
1023
1125
  try {
1024
1126
  // Build context from pre-loaded maps (if available)
1025
1127
  if (!this.artifactsByDetailId || !this.agentRunsByDetailId) {
@@ -1038,7 +1140,7 @@ export class MessageInputComponent extends BaseAngularComponent {
1038
1140
  }
1039
1141
  finally {
1040
1142
  // Emit event to remove temporary intent checking message
1041
- this.intentCheckCompleted.emit();
1143
+ this.intentCheckCompleted.emit({ conversationId: this.conversationId });
1042
1144
  }
1043
1145
  }
1044
1146
  /**
@@ -1047,11 +1149,11 @@ export class MessageInputComponent extends BaseAngularComponent {
1047
1149
  * IMPORTANT: Conversation naming runs asynchronously in the background and does NOT
1048
1150
  * block the agent invocation. This prevents UI blocking if naming times out.
1049
1151
  */
1050
- async executeRouteWithNaming(routeFunction, userMessage, isFirstMessage) {
1152
+ async executeRouteWithNaming(routeFunction, userMessage, isFirstMessage, conversationId) {
1051
1153
  if (isFirstMessage) {
1052
1154
  // Fire conversation naming in background (don't await)
1053
1155
  // This prevents 2+ minute UI blocking if naming times out
1054
- this.nameConversation(userMessage);
1156
+ this.nameConversation(userMessage, conversationId);
1055
1157
  // Execute route immediately (don't wait for naming)
1056
1158
  await routeFunction();
1057
1159
  }
@@ -1126,6 +1228,7 @@ export class MessageInputComponent extends BaseAngularComponent {
1126
1228
  // This contains live timestamps, status, and other fields that change during execution
1127
1229
  if (progressAgentRun || progressAgentRunId) {
1128
1230
  this.agentRunUpdate.emit({
1231
+ conversationId: conversationDetail.ConversationID,
1129
1232
  conversationDetailId: conversationDetail.ID,
1130
1233
  agentRun: progressAgentRun,
1131
1234
  agentRunId: progressAgentRunId
@@ -1135,6 +1238,7 @@ export class MessageInputComponent extends BaseAngularComponent {
1135
1238
  // Fallback: If we don't have the full object but have the ID, emit agentRunDetected
1136
1239
  // This will trigger a database query to load the agent run
1137
1240
  this.agentRunDetected.emit({
1241
+ conversationId: conversationDetail.ConversationID,
1138
1242
  conversationDetailId: conversationDetail.ID,
1139
1243
  agentRunId: progressAgentRunId
1140
1244
  });
@@ -1184,7 +1288,7 @@ export class MessageInputComponent extends BaseAngularComponent {
1184
1288
  status: 'Evaluating message...',
1185
1289
  relatedMessageId: userMessage.ID,
1186
1290
  conversationDetailId: conversationManagerMessage.ID,
1187
- conversationId: this.conversationId,
1291
+ conversationId,
1188
1292
  conversationName: this.conversationName
1189
1293
  });
1190
1294
  // ── PR 2c follow-up: Before/After cancelable event wiring ──
@@ -1206,7 +1310,8 @@ export class MessageInputComponent extends BaseAngularComponent {
1206
1310
  }
1207
1311
  return;
1208
1312
  }
1209
- const result = await this.agentService.processMessage(conversationId, userMessage, this.conversationHistory, conversationManagerMessage.ID, this.createProgressCallback(conversationManagerMessage, 'Sage'), this.appContext);
1313
+ const result = await this.agentService.processMessage(conversationId, userMessage, this.conversationHistory, conversationManagerMessage.ID, this.createProgressCallback(conversationManagerMessage, 'Sage'), this.appContext, this.PlanModeEnabled, // per-request Plan Mode toggle
1314
+ this._pendingRequestedSkillIDs);
1210
1315
  // Emit afterAgentTurn on the happy path only — the error/failure branch
1211
1316
  // immediately below handles its own cleanup and skips this emit.
1212
1317
  if (result && result.success) {
@@ -1228,7 +1333,7 @@ export class MessageInputComponent extends BaseAngularComponent {
1228
1333
  }
1229
1334
  // Stage 2: Check for task graph (multi-step orchestration)
1230
1335
  if (result.payload?.taskGraph) {
1231
- await this.handleTaskGraphExecution(userMessage, result, this.conversationId, conversationManagerMessage);
1336
+ await this.handleTaskGraphExecution(userMessage, result, conversationId, conversationManagerMessage);
1232
1337
  // Remove CM from active tasks
1233
1338
  if (taskId) {
1234
1339
  // Task removed in markMessageComplete() - this.activeTasks.remove(taskId);
@@ -1237,7 +1342,7 @@ export class MessageInputComponent extends BaseAngularComponent {
1237
1342
  // Stage 3: Check for sub-agent invocation (single-step delegation)
1238
1343
  else if (result.agentRun.FinalStep === 'Success' && result.payload?.invokeAgent) {
1239
1344
  // Reuse the existing conversationManagerMessage instead of creating new ones
1240
- await this.handleSubAgentInvocation(userMessage, result, this.conversationId, conversationManagerMessage);
1345
+ await this.handleSubAgentInvocation(userMessage, result, conversationId, conversationManagerMessage);
1241
1346
  // Remove CM from active tasks
1242
1347
  if (taskId) {
1243
1348
  // Task removed in markMessageComplete() - this.activeTasks.remove(taskId);
@@ -1252,13 +1357,7 @@ export class MessageInputComponent extends BaseAngularComponent {
1252
1357
  // Handle artifacts if any (but NOT task graphs - those are intermediate work products)
1253
1358
  // Server already created artifacts - just emit event to trigger UI reload
1254
1359
  if (result.payload && Object.keys(result.payload).length > 0) {
1255
- this.artifactCreated.emit({
1256
- artifactId: '',
1257
- versionId: '',
1258
- versionNumber: 0,
1259
- conversationDetailId: conversationManagerMessage.ID,
1260
- name: ''
1261
- });
1360
+ this.emitArtifactReload(conversationManagerMessage);
1262
1361
  this.messageSent.emit(conversationManagerMessage);
1263
1362
  }
1264
1363
  await this.updateConversationDetail(userMessage, userMessage.Message, 'Complete');
@@ -1290,7 +1389,7 @@ export class MessageInputComponent extends BaseAngularComponent {
1290
1389
  // use update helper to ensure that if there is a race condition with more streaming updates we don't allow that to override this final message
1291
1390
  await this.updateConversationDetail(conversationManagerMessage, conversationManagerMessage.Message, 'Complete', result);
1292
1391
  this.messageSent.emit(conversationManagerMessage);
1293
- await this.handleSilentObservation(userMessage, this.conversationId);
1392
+ await this.handleSilentObservation(userMessage, conversationId);
1294
1393
  // Clean up completion timestamp after delay
1295
1394
  this.cleanupCompletionTimestamp(conversationManagerMessage.ID);
1296
1395
  }
@@ -1418,13 +1517,7 @@ export class MessageInputComponent extends BaseAngularComponent {
1418
1517
  // Trigger artifact reload for this message
1419
1518
  // Artifacts were created on server during task execution and linked to this message
1420
1519
  // This event triggers the parent component to reload artifacts from the database
1421
- this.artifactCreated.emit({
1422
- artifactId: '', // Placeholder - reload will fetch actual artifacts from DB
1423
- versionId: '',
1424
- versionNumber: 1,
1425
- conversationDetailId: taskExecutionMessage.ID,
1426
- name: ''
1427
- });
1520
+ this.emitArtifactReload(taskExecutionMessage);
1428
1521
  // Unregister streaming callback (task complete)
1429
1522
  const callback = this.registeredCallbacks.get(taskExecutionMessage.ID);
1430
1523
  if (callback) {
@@ -1441,13 +1534,7 @@ export class MessageInputComponent extends BaseAngularComponent {
1441
1534
  taskExecutionMessage.Error = String(error);
1442
1535
  await this.updateConversationDetail(taskExecutionMessage, `❌ **${workflowName}** - Error: ${String(error)}`, 'Error');
1443
1536
  // Trigger artifact reload even on error - partial artifacts may have been created
1444
- this.artifactCreated.emit({
1445
- artifactId: '',
1446
- versionId: '',
1447
- versionNumber: 1,
1448
- conversationDetailId: taskExecutionMessage.ID,
1449
- name: ''
1450
- });
1537
+ this.emitArtifactReload(taskExecutionMessage);
1451
1538
  // Unregister streaming callback (task failed)
1452
1539
  const callback = this.registeredCallbacks.get(taskExecutionMessage.ID);
1453
1540
  if (callback) {
@@ -1592,7 +1679,7 @@ export class MessageInputComponent extends BaseAngularComponent {
1592
1679
  status: 'Starting...',
1593
1680
  relatedMessageId: userMessage.ID,
1594
1681
  conversationDetailId: agentResponseMessage.ID,
1595
- conversationId: this.conversationId,
1682
+ conversationId,
1596
1683
  conversationName: this.conversationName
1597
1684
  });
1598
1685
  // Load previous payload if agent has been invoked before
@@ -1604,7 +1691,9 @@ export class MessageInputComponent extends BaseAngularComponent {
1604
1691
  // Invoke agent with merged payload
1605
1692
  const agentResult = await this.agentService.invokeSubAgent(agentName, conversationId, userMessage, this.conversationHistory, task.description || task.name, agentResponseMessage.ID, mergedPayload, // Pass merged payload for continuity
1606
1693
  this.createProgressCallback(agentResponseMessage, agentName), artifactInfo?.artifactId, artifactInfo?.versionId, undefined, // configurationPresetId not used in this path
1607
- this.appContext);
1694
+ this.appContext, // Embedder-supplied app/form context
1695
+ this.PlanModeEnabled, // per-request Plan Mode toggle
1696
+ this._pendingRequestedSkillIDs);
1608
1697
  // Task will be removed automatically in markMessageComplete() when status changes to Complete/Error
1609
1698
  // DO NOT remove here - allows UI to show task during entire execution
1610
1699
  if (agentResult && agentResult.success) {
@@ -1612,13 +1701,7 @@ export class MessageInputComponent extends BaseAngularComponent {
1612
1701
  await this.updateConversationDetail(agentResponseMessage, agentResult.agentRun?.Message || `✅ **${agentName}** completed`, 'Complete', agentResult);
1613
1702
  // Server created artifacts - emit event to trigger UI reload
1614
1703
  if (agentResult.payload && Object.keys(agentResult.payload).length > 0) {
1615
- this.artifactCreated.emit({
1616
- artifactId: '',
1617
- versionId: '',
1618
- versionNumber: 0,
1619
- conversationDetailId: agentResponseMessage.ID,
1620
- name: ''
1621
- });
1704
+ this.emitArtifactReload(agentResponseMessage);
1622
1705
  console.log('🎨 Server created artifact from single task execution');
1623
1706
  this.messageSent.emit(agentResponseMessage);
1624
1707
  }
@@ -1670,7 +1753,7 @@ export class MessageInputComponent extends BaseAngularComponent {
1670
1753
  status: 'Starting...',
1671
1754
  relatedMessageId: userMessage.ID,
1672
1755
  conversationDetailId: agentResponseMessage.ID,
1673
- conversationId: this.conversationId,
1756
+ conversationId,
1674
1757
  conversationName: this.conversationName
1675
1758
  });
1676
1759
  // Load previous payload if agent has been invoked before
@@ -1684,7 +1767,9 @@ export class MessageInputComponent extends BaseAngularComponent {
1684
1767
  // Invoke the sub-agent with progress callback
1685
1768
  const subResult = await this.agentService.invokeSubAgent(agentName, conversationId, userMessage, this.conversationHistory, reasoning, agentResponseMessage.ID, previousPayload, // Pass previous payload for continuity
1686
1769
  this.createProgressCallback(agentResponseMessage, agentName), artifactInfo?.artifactId, artifactInfo?.versionId, configurationPresetId, // Pass configuration from previous @mention for continuity
1687
- this.appContext);
1770
+ this.appContext, // Embedder-supplied app/form context
1771
+ this.PlanModeEnabled, // per-request Plan Mode toggle
1772
+ this._pendingRequestedSkillIDs);
1688
1773
  // Task will be removed automatically in markMessageComplete() when status changes to Complete/Error
1689
1774
  // DO NOT remove here - allows UI to show task during entire execution
1690
1775
  if (subResult && subResult.success) {
@@ -1697,13 +1782,7 @@ export class MessageInputComponent extends BaseAngularComponent {
1697
1782
  // Always emit artifactCreated to trigger UI reload — the server may have created
1698
1783
  // artifacts even when the result payload is empty (e.g., remote stage server).
1699
1784
  // onArtifactCreated will reload from DB and discover any artifacts that exist.
1700
- this.artifactCreated.emit({
1701
- artifactId: '',
1702
- versionId: '',
1703
- versionNumber: 0,
1704
- conversationDetailId: agentResponseMessage.ID,
1705
- name: ''
1706
- });
1785
+ this.emitArtifactReload(agentResponseMessage);
1707
1786
  this.messageSent.emit(agentResponseMessage);
1708
1787
  // Mark user message as complete
1709
1788
  await this.updateConversationDetail(userMessage, userMessage.Message, 'Complete');
@@ -1717,7 +1796,9 @@ export class MessageInputComponent extends BaseAngularComponent {
1717
1796
  // Retry the sub-agent (reuse previously loaded payload and config from first attempt)
1718
1797
  const retryResult = await this.agentService.invokeSubAgent(agentName, conversationId, userMessage, this.conversationHistory, reasoning, agentResponseMessage.ID, previousPayload, // Pass same payload as first attempt
1719
1798
  this.createProgressCallback(agentResponseMessage, `${agentName} (retry)`), artifactInfo?.artifactId, artifactInfo?.versionId, configurationPresetId, // Pass same config as first attempt
1720
- this.appContext);
1799
+ this.appContext, // Embedder-supplied app/form context
1800
+ this.PlanModeEnabled, // per-request Plan Mode toggle
1801
+ this._pendingRequestedSkillIDs);
1721
1802
  if (retryResult && retryResult.success) {
1722
1803
  // Retry succeeded - update the same message
1723
1804
  if (retryResult.agentRun.AgentID) {
@@ -1725,13 +1806,7 @@ export class MessageInputComponent extends BaseAngularComponent {
1725
1806
  }
1726
1807
  await this.updateConversationDetail(agentResponseMessage, retryResult.agentRun?.Message || `✅ **${agentName}** completed`, 'Complete', retryResult);
1727
1808
  // Always emit artifactCreated to trigger UI reload (same as initial attempt)
1728
- this.artifactCreated.emit({
1729
- artifactId: '',
1730
- versionId: '',
1731
- versionNumber: 0,
1732
- conversationDetailId: agentResponseMessage.ID,
1733
- name: ''
1734
- });
1809
+ this.emitArtifactReload(agentResponseMessage);
1735
1810
  this.messageSent.emit(agentResponseMessage);
1736
1811
  await this.updateConversationDetail(userMessage, userMessage.Message, 'Complete');
1737
1812
  }
@@ -1820,13 +1895,15 @@ export class MessageInputComponent extends BaseAngularComponent {
1820
1895
  status: 'Processing refinement...',
1821
1896
  relatedMessageId: userMessage.ID,
1822
1897
  conversationDetailId: statusMessage.ID,
1823
- conversationId: this.conversationId,
1898
+ conversationId,
1824
1899
  conversationName: this.conversationName
1825
1900
  });
1826
1901
  try {
1827
1902
  // Invoke the agent with the previous payload
1828
1903
  const continuityResult = await this.agentService.invokeSubAgent(agentName, conversationId, userMessage, this.conversationHistory, 'Continuing previous work based on user feedback', statusMessage.ID, previousPayload, this.createProgressCallback(statusMessage, agentName), previousArtifactInfo?.artifactId, previousArtifactInfo?.versionId, undefined, // configurationPresetId not used in this path
1829
- this.appContext);
1904
+ this.appContext, // Embedder-supplied app/form context
1905
+ this.PlanModeEnabled, // per-request Plan Mode toggle
1906
+ this._pendingRequestedSkillIDs);
1830
1907
  // Remove from active tasks
1831
1908
  // Task removed in markMessageComplete() - this.activeTasks.remove(taskId);
1832
1909
  if (continuityResult && continuityResult.success) {
@@ -1843,13 +1920,7 @@ export class MessageInputComponent extends BaseAngularComponent {
1843
1920
  this.messageSent.emit(agentResponseMessage);
1844
1921
  // Server created artifacts (handles versioning automatically) - emit event to trigger UI reload
1845
1922
  if (continuityResult.payload && Object.keys(continuityResult.payload).length > 0) {
1846
- this.artifactCreated.emit({
1847
- artifactId: '',
1848
- versionId: '',
1849
- versionNumber: 0,
1850
- conversationDetailId: agentResponseMessage.ID,
1851
- name: ''
1852
- });
1923
+ this.emitArtifactReload(agentResponseMessage);
1853
1924
  console.log('🎨 Server created artifact (versioned) from agent continuity');
1854
1925
  this.messageSent.emit(agentResponseMessage);
1855
1926
  }
@@ -1883,7 +1954,7 @@ export class MessageInputComponent extends BaseAngularComponent {
1883
1954
  status: 'Processing...',
1884
1955
  relatedMessageId: userMessage.ID,
1885
1956
  conversationDetailId: userMessage.ID,
1886
- conversationId: this.conversationId,
1957
+ conversationId,
1887
1958
  conversationName: this.conversationName
1888
1959
  });
1889
1960
  // Declare agentResponseMessage outside try block so it's accessible in catch
@@ -1918,7 +1989,9 @@ export class MessageInputComponent extends BaseAngularComponent {
1918
1989
  // Invoke the agent directly
1919
1990
  const result = await this.agentService.invokeSubAgent(agentName, conversationId, userMessage, this.conversationHistory, `User mentioned agent directly with @${agentName}`, agentResponseMessage.ID, previousPayload, // Pass previous payload for continuity
1920
1991
  this.createProgressCallback(agentResponseMessage, agentName), artifactInfo?.artifactId, artifactInfo?.versionId, agentMention.configurationId, // Pass configuration preset ID
1921
- this.appContext);
1992
+ this.appContext, // Embedder-supplied app/form context
1993
+ this.PlanModeEnabled, // per-request Plan Mode toggle
1994
+ this._pendingRequestedSkillIDs);
1922
1995
  // Remove from active tasks
1923
1996
  // Task removed in markMessageComplete() - this.activeTasks.remove(taskId);
1924
1997
  if (result && result.success) {
@@ -1941,13 +2014,7 @@ export class MessageInputComponent extends BaseAngularComponent {
1941
2014
  await this.updateConversationDetail(agentResponseMessage, result.agentRun?.Message || `✅ **${agentName}** completed`, 'Complete', result);
1942
2015
  // Server created artifacts - emit event to trigger UI reload
1943
2016
  if (result.payload && Object.keys(result.payload).length > 0) {
1944
- this.artifactCreated.emit({
1945
- artifactId: '',
1946
- versionId: '',
1947
- versionNumber: 0,
1948
- conversationDetailId: agentResponseMessage.ID,
1949
- name: ''
1950
- });
2017
+ this.emitArtifactReload(agentResponseMessage);
1951
2018
  this.messageSent.emit(agentResponseMessage);
1952
2019
  }
1953
2020
  // Mark user message as complete
@@ -1983,7 +2050,7 @@ export class MessageInputComponent extends BaseAngularComponent {
1983
2050
  const agent = AIEngineBase.Instance.Agents.find(a => UUIDsEqual(a.ID, agentId));
1984
2051
  if (!agent) {
1985
2052
  console.warn('⚠️ Could not load agent for continuation - falling back to Sage');
1986
- await this.processMessageThroughAgent(userMessage, { mentions: [], agentMention: null, userMentions: [], entityMentions: [] });
2053
+ await this.processMessageThroughAgent(userMessage, { mentions: [], agentMention: null, userMentions: [], entityMentions: [], skillMentions: [] });
1987
2054
  return;
1988
2055
  }
1989
2056
  const agentName = agent.Name || 'Agent';
@@ -2115,7 +2182,7 @@ export class MessageInputComponent extends BaseAngularComponent {
2115
2182
  status: 'Processing...',
2116
2183
  relatedMessageId: userMessage.ID,
2117
2184
  conversationDetailId: userMessage.ID,
2118
- conversationId: this.conversationId,
2185
+ conversationId,
2119
2186
  conversationName: this.conversationName
2120
2187
  });
2121
2188
  // Declare agentResponseMessage outside try block so it's accessible in catch
@@ -2145,7 +2212,9 @@ export class MessageInputComponent extends BaseAngularComponent {
2145
2212
  // `processMessage`.
2146
2213
  const result = await this.agentService.invokeSubAgent(agentName, conversationId, userMessage, this.conversationHistory, 'Continuing previous conversation with user', agentResponseMessage.ID, previousPayload, // Pass previous OUTPUT artifact payload for continuity
2147
2214
  this.createProgressCallback(agentResponseMessage, agentName), previousArtifactInfo?.artifactId, previousArtifactInfo?.versionId, configurationId, // Pass configuration for continuity
2148
- this.appContext);
2215
+ this.appContext, // Embedder-supplied app/form context
2216
+ this.PlanModeEnabled, // per-request Plan Mode toggle
2217
+ this._pendingRequestedSkillIDs);
2149
2218
  // Remove from active tasks
2150
2219
  // Task removed in markMessageComplete() - this.activeTasks.remove(taskId);
2151
2220
  if (result && result.success) {
@@ -2153,13 +2222,7 @@ export class MessageInputComponent extends BaseAngularComponent {
2153
2222
  await this.updateConversationDetail(agentResponseMessage, result.agentRun?.Message || `✅ **${agentName}** completed`, 'Complete', result);
2154
2223
  // Server created artifacts (handles versioning) - emit event to trigger UI reload
2155
2224
  if (result.payload && Object.keys(result.payload).length > 0) {
2156
- this.artifactCreated.emit({
2157
- artifactId: '',
2158
- versionId: '',
2159
- versionNumber: 0,
2160
- conversationDetailId: agentResponseMessage.ID,
2161
- name: ''
2162
- });
2225
+ this.emitArtifactReload(agentResponseMessage);
2163
2226
  this.messageSent.emit(agentResponseMessage);
2164
2227
  }
2165
2228
  // Mark user message as complete
@@ -2189,11 +2252,13 @@ export class MessageInputComponent extends BaseAngularComponent {
2189
2252
  * session path uses. This wrapper keeps the composer-specific concerns local:
2190
2253
  * mention stripping and the sidebar rename animation event.
2191
2254
  */
2192
- async nameConversation(message) {
2255
+ async nameConversation(message, conversationId) {
2193
2256
  // Convert message to plain text (strips JSON-encoded mentions like @{"id":"...","name":"Sage"} to @Sage)
2194
2257
  const plainTextMessage = this.mentionParser.toPlainText(message, this.mentionAutocomplete.getAvailableAgents(), this.mentionAutocomplete.getAvailableUsers());
2258
+ // Use the captured conversationId (not this.conversationId): naming runs fire-and-forget
2259
+ // in the background, so the user may have swapped conversations before it resolves.
2195
2260
  const result = await GenerateAndApplyConversationName({
2196
- ConversationId: this.conversationId,
2261
+ ConversationId: conversationId,
2197
2262
  MessageText: plainTextMessage,
2198
2263
  Provider: this.ProviderToUse,
2199
2264
  CurrentUser: this.currentUser
@@ -2201,7 +2266,7 @@ export class MessageInputComponent extends BaseAngularComponent {
2201
2266
  if (result) {
2202
2267
  // Emit event for animation in conversation list
2203
2268
  this.conversationRenamed.emit({
2204
- conversationId: this.conversationId,
2269
+ conversationId,
2205
2270
  name: result.Name,
2206
2271
  description: result.Description
2207
2272
  });
@@ -2245,10 +2310,28 @@ export class MessageInputComponent extends BaseAngularComponent {
2245
2310
  }
2246
2311
  // Emit completion event to parent so it can refresh agent run data
2247
2312
  this.messageComplete.emit({
2313
+ conversationId: conversationDetail.ConversationID,
2248
2314
  conversationDetailId: conversationDetail.ID,
2249
2315
  agentId: conversationDetail.AgentID || undefined
2250
2316
  });
2251
2317
  }
2318
+ /**
2319
+ * Emit an artifact-reload signal for {@link detail}. The artifact metadata fields are
2320
+ * placeholders — the parent reloads the real artifacts from the DB; the only fields it
2321
+ * consumes are conversationDetailId and conversationId (the latter lets it drop events from
2322
+ * a background conversation after a conversation swap). conversationId is taken from the
2323
+ * detail entity's immutable ConversationID, never this.conversationId.
2324
+ */
2325
+ emitArtifactReload(detail) {
2326
+ this.artifactCreated.emit({
2327
+ conversationId: detail.ConversationID,
2328
+ artifactId: '',
2329
+ versionId: '',
2330
+ versionNumber: 0,
2331
+ conversationDetailId: detail.ID,
2332
+ name: ''
2333
+ });
2334
+ }
2252
2335
  /**
2253
2336
  * Cleans up completion timestamps for completed messages (prevents memory leak)
2254
2337
  */
@@ -2258,36 +2341,38 @@ export class MessageInputComponent extends BaseAngularComponent {
2258
2341
  this.completionTimestamps.delete(conversationDetailId);
2259
2342
  }, 5000); // 5 seconds should be more than enough
2260
2343
  }
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)); };
2344
+ 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.ConversationAttachmentService), i0.ɵɵdirectiveInject(i9.ConversationBridgeService), i0.ɵɵdirectiveInject(i10.RealtimeSessionService)); };
2262
2345
  static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: MessageInputComponent, selectors: [["mj-message-input"]], viewQuery: function MessageInputComponent_Query(rf, ctx) { if (rf & 1) {
2263
2346
  i0.ɵɵviewQuery(_c0, 5);
2264
2347
  } if (rf & 2) {
2265
2348
  let _t;
2266
2349
  i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.inputBox = _t.first);
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) {
2350
+ } }, 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", initialMessageAutoSendStarted: "initialMessageAutoSendStarted", initialMessageAutoSendFailed: "initialMessageAutoSendFailed", emptyStateSubmit: "emptyStateSubmit", uploadStateChanged: "uploadStateChanged" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature, i0.ɵɵNgOnChangesFeature], decls: 6, vars: 23, consts: [["pickerOrigin", "cdkOverlayOrigin"], ["inputBox", ""], ["cdkOverlayOrigin", "", 1, "message-input-wrapper"], [1, "processing-indicator"], [3, "valueChange", "textSubmitted", "attachmentsChanged", "attachmentError", "voiceRequested", "voiceOptionsRequested", "planModeToggle", "placeholder", "disabled", "showCharacterCount", "enableMentions", "enableAttachments", "maxAttachments", "maxAttachmentSizeBytes", "acceptedFileTypes", "currentUser", "Provider", "rows", "enableRealtime", "voiceActive", "canStartRealtime", "enablePlanMode", "planModeActive", "value"], ["cdkConnectedOverlay", "", "cdkConnectedOverlayBackdropClass", "cdk-overlay-transparent-backdrop", 3, "backdropClick", "detach", "cdkConnectedOverlayOrigin", "cdkConnectedOverlayOpen", "cdkConnectedOverlayPositions", "cdkConnectedOverlayPush", "cdkConnectedOverlayHasBackdrop"], [1, "fas", "fa-circle-notch", "fa-spin"], [3, "AgentPicked", "Cancelled", "Provider", "Agents", "DefaultAgentId", "CoAgents", "DefaultCoAgentId"]], template: function MessageInputComponent_Template(rf, ctx) { if (rf & 1) {
2268
2351
  const _r1 = i0.ɵɵgetCurrentView();
2269
- i0.ɵɵelementStart(0, "div", 1);
2270
- i0.ɵɵconditionalCreate(1, MessageInputComponent_Conditional_1_Template, 4, 1, "div", 2);
2271
- i0.ɵɵelementStart(2, "mj-message-input-box", 3, 0);
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); });
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()); });
2352
+ i0.ɵɵelementStart(0, "div", 2, 0);
2353
+ i0.ɵɵconditionalCreate(2, MessageInputComponent_Conditional_2_Template, 4, 1, "div", 3);
2354
+ i0.ɵɵelementStart(3, "mj-ai-composer", 4, 1);
2355
+ i0.ɵɵtwoWayListener("valueChange", function MessageInputComponent_Template_mj_ai_composer_valueChange_3_listener($event) { i0.ɵɵrestoreView(_r1); i0.ɵɵtwoWayBindingSet(ctx.messageText, $event) || (ctx.messageText = $event); return i0.ɵɵresetView($event); });
2356
+ i0.ɵɵlistener("textSubmitted", function MessageInputComponent_Template_mj_ai_composer_textSubmitted_3_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onTextSubmitted($event)); })("attachmentsChanged", function MessageInputComponent_Template_mj_ai_composer_attachmentsChanged_3_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onAttachmentsChanged($event)); })("attachmentError", function MessageInputComponent_Template_mj_ai_composer_attachmentError_3_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onAttachmentError($event)); })("voiceRequested", function MessageInputComponent_Template_mj_ai_composer_voiceRequested_3_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onStartRealtime()); })("voiceOptionsRequested", function MessageInputComponent_Template_mj_ai_composer_voiceOptionsRequested_3_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onRealtimeOptions()); })("planModeToggle", function MessageInputComponent_Template_mj_ai_composer_planModeToggle_3_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.TogglePlanMode()); });
2274
2357
  i0.ɵɵelementEnd();
2275
- i0.ɵɵconditionalCreate(4, MessageInputComponent_Conditional_4_Template, 1, 5, "mj-realtime-agent-picker", 4);
2358
+ i0.ɵɵtemplate(5, MessageInputComponent_ng_template_5_Template, 1, 5, "ng-template", 5);
2359
+ i0.ɵɵlistener("backdropClick", function MessageInputComponent_Template_ng_template_backdropClick_5_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onRealtimeAgentPickerCancelled()); })("detach", function MessageInputComponent_Template_ng_template_detach_5_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onRealtimeAgentPickerCancelled()); });
2276
2360
  i0.ɵɵelementEnd();
2277
2361
  } if (rf & 2) {
2362
+ const pickerOrigin_r4 = i0.ɵɵreference(1);
2363
+ i0.ɵɵadvance(2);
2364
+ i0.ɵɵconditional(ctx.isProcessing ? 2 : -1);
2278
2365
  i0.ɵɵadvance();
2279
- i0.ɵɵconditional(ctx.isProcessing ? 1 : -1);
2280
- i0.ɵɵadvance();
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);
2366
+ 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)("Provider", ctx.Provider)("rows", 3)("enableRealtime", true)("voiceActive", ctx.voiceActive)("canStartRealtime", ctx.canStartRealtime)("enablePlanMode", true)("planModeActive", ctx.PlanModeEnabled);
2282
2367
  i0.ɵɵtwoWayProperty("value", ctx.messageText);
2283
2368
  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}"] });
2369
+ i0.ɵɵproperty("cdkConnectedOverlayOrigin", pickerOrigin_r4)("cdkConnectedOverlayOpen", ctx.showRealtimeAgentPicker)("cdkConnectedOverlayPositions", ctx.pickerOverlayPositions)("cdkConnectedOverlayPush", true)("cdkConnectedOverlayHasBackdrop", true);
2370
+ } }, dependencies: [i11.CdkConnectedOverlay, i11.CdkOverlayOrigin, i12.RealtimeAgentPickerComponent, i13.AiComposerComponent], styles: [".message-input-wrapper[_ngcontent-%COMP%] {\n position: relative;\n width: 100%;\n}\n\n\n\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}"] });
2286
2371
  }
2287
2372
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MessageInputComponent, [{
2288
2373
  type: Component,
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: [{
2374
+ args: [{ standalone: false, selector: 'mj-message-input', template: "<div class=\"message-input-wrapper\" cdkOverlayOrigin #pickerOrigin=\"cdkOverlayOrigin\">\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 <!-- AI composer (mic + Plan Mode buttons live in its in-composer toolbar): wraps the\n generic mj-message-input-box with the '@' agent / '#' record / '/' skill trigger\n plugins built in \u2014 all three on by default, preserving the standard chat behavior. -->\n <mj-ai-composer\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 [Provider]=\"Provider\"\n [rows]=\"3\"\n [enableRealtime]=\"true\"\n [voiceActive]=\"voiceActive\"\n [canStartRealtime]=\"canStartRealtime\"\n [enablePlanMode]=\"true\"\n [planModeActive]=\"PlanModeEnabled\"\n [(value)]=\"messageText\"\n (textSubmitted)=\"onTextSubmitted($event)\"\n (attachmentsChanged)=\"onAttachmentsChanged($event)\"\n (attachmentError)=\"onAttachmentError($event)\"\n (voiceRequested)=\"onStartRealtime()\"\n (voiceOptionsRequested)=\"onRealtimeOptions()\"\n (planModeToggle)=\"TogglePlanMode()\">\n </mj-ai-composer>\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). Rendered in a body-level CDK overlay anchored above the\n composer so it POPS OUT of the chat overlay's clipping border instead of being cut\n off at the top of a narrow (~390px) overlay. -->\n <ng-template\n cdkConnectedOverlay\n [cdkConnectedOverlayOrigin]=\"pickerOrigin\"\n [cdkConnectedOverlayOpen]=\"showRealtimeAgentPicker\"\n [cdkConnectedOverlayPositions]=\"pickerOverlayPositions\"\n [cdkConnectedOverlayPush]=\"true\"\n [cdkConnectedOverlayHasBackdrop]=\"true\"\n cdkConnectedOverlayBackdropClass=\"cdk-overlay-transparent-backdrop\"\n (backdropClick)=\"onRealtimeAgentPickerCancelled()\"\n (detach)=\"onRealtimeAgentPickerCancelled()\">\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 </ng-template>\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/* Plan Mode moved into the in-composer toolbar (message-input-box) as a toggle icon button\n next to the attachment/voice buttons \u2014 see .plan-mode-button-icon there. */\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"] }]
2375
+ }], () => [{ type: i1.DialogService }, { type: i2.ToastService }, { type: i3.ConversationAgentService }, { type: i4.DataCacheService }, { type: i5.ActiveTasksService }, { type: i6.ConversationStreamingService }, { type: i7.MentionParserService }, { type: i8.ConversationAttachmentService }, { type: i9.ConversationBridgeService }, { type: i10.RealtimeSessionService }], { conversationId: [{
2291
2376
  type: Input
2292
2377
  }], conversationName: [{
2293
2378
  type: Input
@@ -2357,15 +2442,17 @@ export class MessageInputComponent extends BaseAngularComponent {
2357
2442
  type: Output
2358
2443
  }], intentCheckCompleted: [{
2359
2444
  type: Output
2445
+ }], initialMessageAutoSendStarted: [{
2446
+ type: Output
2447
+ }], initialMessageAutoSendFailed: [{
2448
+ type: Output
2360
2449
  }], emptyStateSubmit: [{
2361
2450
  type: Output
2362
2451
  }], uploadStateChanged: [{
2363
2452
  type: Output
2364
- }], artifactPickerRequested: [{
2365
- type: Output
2366
2453
  }], inputBox: [{
2367
2454
  type: ViewChild,
2368
2455
  args: ['inputBox']
2369
2456
  }] }); })();
2370
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(MessageInputComponent, { className: "MessageInputComponent", filePath: "src/lib/components/message/message-input.component.ts", lineNumber: 43 }); })();
2457
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(MessageInputComponent, { className: "MessageInputComponent", filePath: "src/lib/components/message/message-input.component.ts", lineNumber: 45 }); })();
2371
2458
  //# sourceMappingURL=message-input.component.js.map