@memberjunction/ng-conversations 6.2.0-edge.5 → 6.2.0-edge.7

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 (164) hide show
  1. package/dist/lib/components/attachment/image-viewer.component.d.ts +3 -1
  2. package/dist/lib/components/attachment/image-viewer.component.d.ts.map +1 -1
  3. package/dist/lib/components/attachment/image-viewer.component.js +5 -1
  4. package/dist/lib/components/attachment/image-viewer.component.js.map +1 -1
  5. package/dist/lib/components/collection/collection-view.component.d.ts.map +1 -1
  6. package/dist/lib/components/collection/collection-view.component.js +1 -0
  7. package/dist/lib/components/collection/collection-view.component.js.map +1 -1
  8. package/dist/lib/components/conversation/conversation-chat-area.component.d.ts +188 -9
  9. package/dist/lib/components/conversation/conversation-chat-area.component.d.ts.map +1 -1
  10. package/dist/lib/components/conversation/conversation-chat-area.component.js +1333 -464
  11. package/dist/lib/components/conversation/conversation-chat-area.component.js.map +1 -1
  12. package/dist/lib/components/conversation/conversation-mode-picker.component.js +2 -2
  13. package/dist/lib/components/conversation/conversation-mode-picker.component.js.map +1 -1
  14. package/dist/lib/components/conversation/conversation-remote-browser-controller.d.ts +109 -0
  15. package/dist/lib/components/conversation/conversation-remote-browser-controller.d.ts.map +1 -0
  16. package/dist/lib/components/conversation/conversation-remote-browser-controller.js +298 -0
  17. package/dist/lib/components/conversation/conversation-remote-browser-controller.js.map +1 -0
  18. package/dist/lib/components/message/agent-handoff-card.component.d.ts +102 -0
  19. package/dist/lib/components/message/agent-handoff-card.component.d.ts.map +1 -0
  20. package/dist/lib/components/message/agent-handoff-card.component.js +439 -0
  21. package/dist/lib/components/message/agent-handoff-card.component.js.map +1 -0
  22. package/dist/lib/components/message/message-input.component.d.ts +126 -59
  23. package/dist/lib/components/message/message-input.component.d.ts.map +1 -1
  24. package/dist/lib/components/message/message-input.component.js +559 -554
  25. package/dist/lib/components/message/message-input.component.js.map +1 -1
  26. package/dist/lib/components/message/message-item.component.d.ts +34 -2
  27. package/dist/lib/components/message/message-item.component.d.ts.map +1 -1
  28. package/dist/lib/components/message/message-item.component.js +678 -520
  29. package/dist/lib/components/message/message-item.component.js.map +1 -1
  30. package/dist/lib/components/message/message-list.component.d.ts +13 -1
  31. package/dist/lib/components/message/message-list.component.d.ts.map +1 -1
  32. package/dist/lib/components/message/message-list.component.js +92 -39
  33. package/dist/lib/components/message/message-list.component.js.map +1 -1
  34. package/dist/lib/components/overlay/chat-overlay.component.d.ts +19 -0
  35. package/dist/lib/components/overlay/chat-overlay.component.d.ts.map +1 -1
  36. package/dist/lib/components/overlay/chat-overlay.component.js +125 -13
  37. package/dist/lib/components/overlay/chat-overlay.component.js.map +1 -1
  38. package/dist/lib/components/project/project-form-modal.component.js +2 -2
  39. package/dist/lib/components/project/project-form-modal.component.js.map +1 -1
  40. package/dist/lib/components/realtime/interactive-component/run-view-component-artifact-source.js +1 -1
  41. package/dist/lib/components/realtime/interactive-component/run-view-component-artifact-source.js.map +1 -1
  42. package/dist/lib/components/realtime/media/media-channel-state.d.ts +5 -0
  43. package/dist/lib/components/realtime/media/media-channel-state.d.ts.map +1 -1
  44. package/dist/lib/components/realtime/media/media-channel-state.js +27 -1
  45. package/dist/lib/components/realtime/media/media-channel-state.js.map +1 -1
  46. package/dist/lib/components/realtime/media/media-channel.d.ts.map +1 -1
  47. package/dist/lib/components/realtime/media/media-channel.js +7 -2
  48. package/dist/lib/components/realtime/media/media-channel.js.map +1 -1
  49. package/dist/lib/components/realtime/media/realtime-media-surface.component.d.ts +19 -2
  50. package/dist/lib/components/realtime/media/realtime-media-surface.component.d.ts.map +1 -1
  51. package/dist/lib/components/realtime/media/realtime-media-surface.component.js +59 -10
  52. package/dist/lib/components/realtime/media/realtime-media-surface.component.js.map +1 -1
  53. package/dist/lib/components/realtime/realtime-agent-banner.component.d.ts +22 -6
  54. package/dist/lib/components/realtime/realtime-agent-banner.component.d.ts.map +1 -1
  55. package/dist/lib/components/realtime/realtime-agent-banner.component.js +160 -98
  56. package/dist/lib/components/realtime/realtime-agent-banner.component.js.map +1 -1
  57. package/dist/lib/components/realtime/realtime-call-failure-notice.d.ts +13 -0
  58. package/dist/lib/components/realtime/realtime-call-failure-notice.d.ts.map +1 -0
  59. package/dist/lib/components/realtime/realtime-call-failure-notice.js +21 -0
  60. package/dist/lib/components/realtime/realtime-call-failure-notice.js.map +1 -0
  61. package/dist/lib/components/realtime/realtime-composer.component.d.ts +26 -3
  62. package/dist/lib/components/realtime/realtime-composer.component.d.ts.map +1 -1
  63. package/dist/lib/components/realtime/realtime-composer.component.js +226 -120
  64. package/dist/lib/components/realtime/realtime-composer.component.js.map +1 -1
  65. package/dist/lib/components/realtime/realtime-session-overlay.component.d.ts +73 -16
  66. package/dist/lib/components/realtime/realtime-session-overlay.component.d.ts.map +1 -1
  67. package/dist/lib/components/realtime/realtime-session-overlay.component.js +219 -108
  68. package/dist/lib/components/realtime/realtime-session-overlay.component.js.map +1 -1
  69. package/dist/lib/components/realtime/realtime-ui-config.d.ts +9 -12
  70. package/dist/lib/components/realtime/realtime-ui-config.d.ts.map +1 -1
  71. package/dist/lib/components/realtime/realtime-ui-config.js +38 -18
  72. package/dist/lib/components/realtime/realtime-ui-config.js.map +1 -1
  73. package/dist/lib/components/realtime/remote-browser/remote-browser-channel.d.ts.map +1 -1
  74. package/dist/lib/components/realtime/remote-browser/remote-browser-channel.js +34 -5
  75. package/dist/lib/components/realtime/remote-browser/remote-browser-channel.js.map +1 -1
  76. package/dist/lib/components/realtime/remote-browser/remote-browser-tools.d.ts +8 -2
  77. package/dist/lib/components/realtime/remote-browser/remote-browser-tools.d.ts.map +1 -1
  78. package/dist/lib/components/realtime/remote-browser/remote-browser-tools.js +51 -10
  79. package/dist/lib/components/realtime/remote-browser/remote-browser-tools.js.map +1 -1
  80. package/dist/lib/components/realtime/whiteboard/whiteboard-channel-config.d.ts +46 -0
  81. package/dist/lib/components/realtime/whiteboard/whiteboard-channel-config.d.ts.map +1 -0
  82. package/dist/lib/components/realtime/whiteboard/whiteboard-channel-config.js +64 -0
  83. package/dist/lib/components/realtime/whiteboard/whiteboard-channel-config.js.map +1 -0
  84. package/dist/lib/components/realtime/whiteboard/whiteboard-channel.d.ts +131 -9
  85. package/dist/lib/components/realtime/whiteboard/whiteboard-channel.d.ts.map +1 -1
  86. package/dist/lib/components/realtime/whiteboard/whiteboard-channel.js +347 -38
  87. package/dist/lib/components/realtime/whiteboard/whiteboard-channel.js.map +1 -1
  88. package/dist/lib/conversations.module.d.ts +2 -1
  89. package/dist/lib/conversations.module.d.ts.map +1 -1
  90. package/dist/lib/conversations.module.js +9 -4
  91. package/dist/lib/conversations.module.js.map +1 -1
  92. package/dist/lib/events/chat-events.d.ts +5 -4
  93. package/dist/lib/events/chat-events.d.ts.map +1 -1
  94. package/dist/lib/events/chat-events.js +2 -2
  95. package/dist/lib/events/chat-events.js.map +1 -1
  96. package/dist/lib/models/agent-turn.model.d.ts +11 -7
  97. package/dist/lib/models/agent-turn.model.d.ts.map +1 -1
  98. package/dist/lib/models/agent-turn.model.js.map +1 -1
  99. package/dist/lib/services/active-tasks.service.d.ts +5 -0
  100. package/dist/lib/services/active-tasks.service.d.ts.map +1 -1
  101. package/dist/lib/services/active-tasks.service.js +16 -0
  102. package/dist/lib/services/active-tasks.service.js.map +1 -1
  103. package/dist/lib/services/agent-state.service.d.ts.map +1 -1
  104. package/dist/lib/services/agent-state.service.js +7 -1
  105. package/dist/lib/services/agent-state.service.js.map +1 -1
  106. package/dist/lib/services/artifact-permission.service.d.ts.map +1 -1
  107. package/dist/lib/services/artifact-permission.service.js +2 -0
  108. package/dist/lib/services/artifact-permission.service.js.map +1 -1
  109. package/dist/lib/services/artifact-state.service.d.ts.map +1 -1
  110. package/dist/lib/services/artifact-state.service.js +1 -0
  111. package/dist/lib/services/artifact-state.service.js.map +1 -1
  112. package/dist/lib/services/collection-permission.service.d.ts.map +1 -1
  113. package/dist/lib/services/collection-permission.service.js +1 -0
  114. package/dist/lib/services/collection-permission.service.js.map +1 -1
  115. package/dist/lib/services/conversation-agent.service.d.ts +38 -16
  116. package/dist/lib/services/conversation-agent.service.d.ts.map +1 -1
  117. package/dist/lib/services/conversation-agent.service.js +57 -71
  118. package/dist/lib/services/conversation-agent.service.js.map +1 -1
  119. package/dist/lib/services/conversation-detail-window.store.d.ts +5 -0
  120. package/dist/lib/services/conversation-detail-window.store.d.ts.map +1 -1
  121. package/dist/lib/services/conversation-detail-window.store.js +52 -5
  122. package/dist/lib/services/conversation-detail-window.store.js.map +1 -1
  123. package/dist/lib/services/realtime-session-review.service.d.ts +2 -1
  124. package/dist/lib/services/realtime-session-review.service.d.ts.map +1 -1
  125. package/dist/lib/services/realtime-session-review.service.js.map +1 -1
  126. package/dist/lib/services/realtime-session.service.d.ts.map +1 -1
  127. package/dist/lib/services/realtime-session.service.js +2 -1
  128. package/dist/lib/services/realtime-session.service.js.map +1 -1
  129. package/dist/lib/services/search.service.d.ts.map +1 -1
  130. package/dist/lib/services/search.service.js +1 -0
  131. package/dist/lib/services/search.service.js.map +1 -1
  132. package/dist/lib/utils/agent-failure-display.d.ts +14 -0
  133. package/dist/lib/utils/agent-failure-display.d.ts.map +1 -0
  134. package/dist/lib/utils/agent-failure-display.js +26 -0
  135. package/dist/lib/utils/agent-failure-display.js.map +1 -0
  136. package/dist/lib/utils/agent-handoff-map.d.ts +52 -0
  137. package/dist/lib/utils/agent-handoff-map.d.ts.map +1 -0
  138. package/dist/lib/utils/agent-handoff-map.js +270 -0
  139. package/dist/lib/utils/agent-handoff-map.js.map +1 -0
  140. package/dist/lib/utils/agent-turn-routing.d.ts +62 -7
  141. package/dist/lib/utils/agent-turn-routing.d.ts.map +1 -1
  142. package/dist/lib/utils/agent-turn-routing.js +147 -6
  143. package/dist/lib/utils/agent-turn-routing.js.map +1 -1
  144. package/dist/lib/utils/decision-routing.d.ts +17 -9
  145. package/dist/lib/utils/decision-routing.d.ts.map +1 -1
  146. package/dist/lib/utils/decision-routing.js +23 -14
  147. package/dist/lib/utils/decision-routing.js.map +1 -1
  148. package/dist/lib/utils/message-list-order.d.ts +13 -0
  149. package/dist/lib/utils/message-list-order.d.ts.map +1 -0
  150. package/dist/lib/utils/message-list-order.js +31 -0
  151. package/dist/lib/utils/message-list-order.js.map +1 -0
  152. package/dist/lib/utils/pin-state.d.ts +11 -0
  153. package/dist/lib/utils/pin-state.d.ts.map +1 -0
  154. package/dist/lib/utils/pin-state.js +9 -0
  155. package/dist/lib/utils/pin-state.js.map +1 -0
  156. package/dist/lib/utils/thread-replies.d.ts +34 -0
  157. package/dist/lib/utils/thread-replies.d.ts.map +1 -0
  158. package/dist/lib/utils/thread-replies.js +49 -0
  159. package/dist/lib/utils/thread-replies.js.map +1 -0
  160. package/dist/public-api.d.ts +6 -0
  161. package/dist/public-api.d.ts.map +1 -1
  162. package/dist/public-api.js +6 -0
  163. package/dist/public-api.js.map +1 -1
  164. package/package.json +36 -36
@@ -4,6 +4,7 @@ import { RunView, CompositeKey, LogStatusEx } from '@memberjunction/core';
4
4
  import { ArtifactMetadataEngine, ConversationEngine, ShouldReplaceDetailAgentRun, CONVERSATIONS_FORK_AUTHORIZATION, CONVERSATIONS_FORKING_SETTING_KEY, UserInfoEngine, WorkflowSaveOperation } from '@memberjunction/core-entities';
5
5
  import { ConversationUtility } from "@memberjunction/ai-core-plus";
6
6
  import { AIEngineBase } from '@memberjunction/ai-engine-base';
7
+ import { GraphQLDataProvider } from '@memberjunction/graphql-dataprovider';
7
8
  import { ConversationDetailWindowStore } from '../../services/conversation-detail-window.store';
8
9
  import { MentionAutocompleteService } from '../../services/mention-autocomplete.service';
9
10
  import { MJResourcePermissionShareAdapter } from '@memberjunction/ng-resource-permissions';
@@ -22,15 +23,23 @@ import { RealtimeSessionReviewService } from '../../services/realtime-session-re
22
23
  import { GenerateAndApplyConversationName, GenerateAndApplyForkName, SaveForkName } from '../../services/conversation-naming';
23
24
  import { CollectRealtimeSessionIDs, MapRealtimeSessionMeta, REALTIME_SESSION_META_FIELDS } from '../../utils/realtime-session-timeline';
24
25
  import { ResolveDateJumpTarget, CombineDateJumpOutcome, DescribeDateJumpOutcome, DATE_JUMP_MAX_PAGES } from '../../utils/date-jump';
26
+ import { CompareMessagesByCreatedAt, UpsertMessageById } from '../../utils/message-list-order';
27
+ import { SavePinState } from '../../utils/pin-state';
25
28
  import { InjectFrameZone } from '../../util/frame-zone';
26
29
  import { MessageListComponent } from '../message/message-list.component';
27
30
  import { IsForkPointOrEarlier } from '../../utils/conversation-branching';
28
31
  import { BackLabelOf, BuildForkBreadcrumbs, BuildForkHeaderPath, BuildForkMarkerText, BuildForkComposerHint, BuildForkViewLayout, BuildViewForkChipMap, CanForkFrom, FindLatestTurn, FirstOwnRowID, ForkDependsOnRows, IsRowInOpenView, MAIN_COMPOSER_PLACEHOLDER, MAIN_OPEN_VIEW, ParentForkIdOf, ReadBranchIdOf, SameOpenView, SplitForkRows, TurnRowsAfter, FORK_COMPOSER_PLACEHOLDER, ForkInitials, ForkKindIcon, DRAFT_FORK_TITLE } from '../../utils/conversation-forks';
29
32
  import { DecideArtifactPanelAction, SnapshotArtifactVersions } from '../../utils/artifact-panel-action';
30
- import { NormalizeUUID, UUIDsEqual, UUIDSet, IndexByUUID, IsValidUUID } from '@memberjunction/global';
33
+ import { GetThreadReplyRoots } from '../../utils/thread-replies';
34
+ import { NormalizeUUID, UUIDsEqual, UUIDSet, UUIDMap, IndexByUUID, IsValidUUID } from '@memberjunction/global';
35
+ import { AgentAccentVar } from '../message/agent-handoff-card.component';
36
+ import { BuildHandoffsByDetailId, LoadHandoffStepsForRuns, } from '../../utils/agent-handoff-map';
37
+ import { FindContinuityAgentMessage } from '../../utils/agent-turn-routing';
31
38
  // PR 2c — Widget extension surface
32
39
  import { ChatSlotDirective } from '../../directives/chat-slot.directive';
33
40
  import { ConversationCallStartOptions } from '../realtime/capture/realtime-capture-channel';
41
+ import { ConversationRemoteBrowserController } from './conversation-remote-browser-controller';
42
+ import { DescribeCallFailureNotice } from '../realtime/realtime-call-failure-notice';
34
43
  import { BeforeToolInvokedEventArgs, AfterToolInvokedEventArgs, BeforeStopClickedEventArgs, AfterStopClickedEventArgs, SessionStartedEventArgs, SessionChannelStateChangedEventArgs, SessionEndedEventArgs, } from '../../events/chat-events';
35
44
  import * as i0 from "@angular/core";
36
45
  import * as i1 from "../../services/agent-state.service";
@@ -56,50 +65,52 @@ import * as i20 from "../collection/artifact-collection-picker-modal.component";
56
65
  import * as i21 from "../artifact/artifact-share-modal.component";
57
66
  import * as i22 from "../slots/mj-chat-agent-presence-default.component";
58
67
  import * as i23 from "../realtime/realtime-session-overlay.component";
59
- import * as i24 from "../message/message-list.component";
60
- import * as i25 from "../message/message-input.component";
61
- import * as i26 from "./conversation-empty-state.component";
62
- import * as i27 from "./conversation-agent-picker.component";
63
- import * as i28 from "./conversation-mode-picker.component";
64
- import * as i29 from "../project/project-selector.component";
65
- import * as i30 from "../members/members-modal.component";
66
- import * as i31 from "../export/export-modal.component";
67
- import * as i32 from "../attachment/image-viewer.component";
68
- import * as i33 from "./pinned-messages-panel.component";
69
- import * as i34 from "./forks-popover.component";
68
+ import * as i24 from "../realtime/remote-browser/remote-browser-surface.component";
69
+ import * as i25 from "../message/message-list.component";
70
+ import * as i26 from "../message/message-input.component";
71
+ import * as i27 from "./conversation-empty-state.component";
72
+ import * as i28 from "./conversation-agent-picker.component";
73
+ import * as i29 from "./conversation-mode-picker.component";
74
+ import * as i30 from "../project/project-selector.component";
75
+ import * as i31 from "../members/members-modal.component";
76
+ import * as i32 from "../export/export-modal.component";
77
+ import * as i33 from "../attachment/image-viewer.component";
78
+ import * as i34 from "./pinned-messages-panel.component";
79
+ import * as i35 from "./forks-popover.component";
70
80
  const _c0 = ["scrollContainer"];
71
- const _c1 = ["titleNameInput"];
72
- const _c2 = ["titleRenameButton"];
73
- const _c3 = ["forksButton"];
74
- const _c4 = ["messageInput"];
75
- const _c5 = (a0, a1, a2, a3, a4) => ({ $implicit: a0, state: a1, agentName: a2, avatarUrl: a3, mode: a4 });
76
- const _c6 = (a0, a1, a2, a3, a4) => ({ $implicit: a0, conversationTitle: a1, sharedBy: a2, artifactCount: a3, showArtifactIndicator: a4 });
77
- const _c7 = (a0, a1, a2) => ({ $implicit: a0, conversationId: a1, isProcessing: a2 });
78
- const _c8 = (a0, a1, a2) => ({ $implicit: a0, content: a1, visible: a2 });
79
- const _c9 = () => [];
80
- const _c10 = (a0, a1, a2, a3) => ({ $implicit: a0, greeting: a1, subtext: a2, suggestedPrompts: a3 });
81
- const _c11 = (a0, a1, a2) => ({ $implicit: a0, ConversationId: a1, IsProcessing: a2 });
82
- const _forTrack0 = ($index, $item) => $item.conversationId;
81
+ const _c1 = ["conversationRemoteBrowserSurface"];
82
+ const _c2 = ["titleNameInput"];
83
+ const _c3 = ["titleRenameButton"];
84
+ const _c4 = ["forksButton"];
85
+ const _c5 = ["messageInput"];
86
+ const _c6 = (a0, a1, a2, a3, a4) => ({ $implicit: a0, state: a1, agentName: a2, avatarUrl: a3, mode: a4 });
87
+ const _c7 = (a0, a1, a2, a3, a4) => ({ $implicit: a0, conversationTitle: a1, sharedBy: a2, artifactCount: a3, showArtifactIndicator: a4 });
88
+ const _c8 = (a0, a1, a2) => ({ $implicit: a0, conversationId: a1, isProcessing: a2 });
89
+ const _c9 = (a0, a1, a2) => ({ $implicit: a0, content: a1, visible: a2 });
90
+ const _c10 = () => [];
91
+ const _c11 = (a0, a1, a2, a3) => ({ $implicit: a0, greeting: a1, subtext: a2, suggestedPrompts: a3 });
92
+ const _c12 = (a0, a1, a2) => ({ $implicit: a0, ConversationId: a1, IsProcessing: a2 });
93
+ function _forTrack0($index, $item) { return this.NormalizeCachedInputId($item.conversationId); }
83
94
  const _forTrack1 = ($index, $item) => $item.artifactId;
84
95
  const _forTrack2 = ($index, $item) => $item.versionId;
85
96
  function ConversationChatAreaComponent_Conditional_1_Conditional_1_ng_container_0_Template(rf, ctx) { if (rf & 1) {
86
97
  i0.ɵɵelementContainer(0);
87
98
  } }
88
99
  function ConversationChatAreaComponent_Conditional_1_Conditional_1_Template(rf, ctx) { if (rf & 1) {
89
- i0.ɵɵtemplate(0, ConversationChatAreaComponent_Conditional_1_Conditional_1_ng_container_0_Template, 1, 0, "ng-container", 28);
100
+ i0.ɵɵtemplate(0, ConversationChatAreaComponent_Conditional_1_Conditional_1_ng_container_0_Template, 1, 0, "ng-container", 29);
90
101
  } if (rf & 2) {
91
102
  const ctx_r0 = i0.ɵɵnextContext(2);
92
- i0.ɵɵproperty("ngTemplateOutlet", ctx)("ngTemplateOutletContext", i0.ɵɵpureFunction5(2, _c5, ctx_r0.agentCharacterConfig, (ctx_r0.agentCharacterConfig == null ? null : ctx_r0.agentCharacterConfig.state) ?? "idle", ctx_r0.agentCharacterConfig == null ? null : ctx_r0.agentCharacterConfig.characterName, ctx_r0.agentCharacterConfig == null ? null : ctx_r0.agentCharacterConfig.avatarUrl, (ctx_r0.agentCharacterConfig == null ? null : ctx_r0.agentCharacterConfig.voiceStateMode) ?? "subtle"));
103
+ i0.ɵɵproperty("ngTemplateOutlet", ctx)("ngTemplateOutletContext", i0.ɵɵpureFunction5(2, _c6, ctx_r0.agentCharacterConfig, (ctx_r0.agentCharacterConfig == null ? null : ctx_r0.agentCharacterConfig.state) ?? "idle", ctx_r0.agentCharacterConfig == null ? null : ctx_r0.agentCharacterConfig.characterName, ctx_r0.agentCharacterConfig == null ? null : ctx_r0.agentCharacterConfig.avatarUrl, (ctx_r0.agentCharacterConfig == null ? null : ctx_r0.agentCharacterConfig.voiceStateMode) ?? "subtle"));
93
104
  } }
94
105
  function ConversationChatAreaComponent_Conditional_1_Conditional_2_Template(rf, ctx) { if (rf & 1) {
95
- i0.ɵɵelement(0, "mj-chat-agent-presence-default", 27);
106
+ i0.ɵɵelement(0, "mj-chat-agent-presence-default", 28);
96
107
  } if (rf & 2) {
97
108
  const ctx_r0 = i0.ɵɵnextContext(2);
98
109
  i0.ɵɵproperty("State", (ctx_r0.agentCharacterConfig == null ? null : ctx_r0.agentCharacterConfig.state) ?? "idle")("AgentName", ctx_r0.agentCharacterConfig == null ? null : ctx_r0.agentCharacterConfig.characterName)("AvatarUrl", ctx_r0.agentCharacterConfig == null ? null : ctx_r0.agentCharacterConfig.avatarUrl)("Mode", (ctx_r0.agentCharacterConfig == null ? null : ctx_r0.agentCharacterConfig.voiceStateMode) ?? "subtle");
99
110
  } }
100
111
  function ConversationChatAreaComponent_Conditional_1_Template(rf, ctx) { if (rf & 1) {
101
- i0.ɵɵelementStart(0, "div", 26);
102
- i0.ɵɵconditionalCreate(1, ConversationChatAreaComponent_Conditional_1_Conditional_1_Template, 1, 8, "ng-container")(2, ConversationChatAreaComponent_Conditional_1_Conditional_2_Template, 1, 4, "mj-chat-agent-presence-default", 27);
112
+ i0.ɵɵelementStart(0, "div", 27);
113
+ i0.ɵɵconditionalCreate(1, ConversationChatAreaComponent_Conditional_1_Conditional_1_Template, 1, 8, "ng-container")(2, ConversationChatAreaComponent_Conditional_1_Conditional_2_Template, 1, 4, "mj-chat-agent-presence-default", 28);
103
114
  i0.ɵɵelementEnd();
104
115
  } if (rf & 2) {
105
116
  let tmp_4_0;
@@ -112,31 +123,48 @@ function ConversationChatAreaComponent_Conditional_2_ng_container_0_Template(rf,
112
123
  i0.ɵɵelementContainer(0);
113
124
  } }
114
125
  function ConversationChatAreaComponent_Conditional_2_Template(rf, ctx) { if (rf & 1) {
115
- i0.ɵɵtemplate(0, ConversationChatAreaComponent_Conditional_2_ng_container_0_Template, 1, 0, "ng-container", 28);
126
+ i0.ɵɵtemplate(0, ConversationChatAreaComponent_Conditional_2_ng_container_0_Template, 1, 0, "ng-container", 29);
116
127
  } if (rf & 2) {
117
128
  const ctx_r0 = i0.ɵɵnextContext();
118
- i0.ɵɵproperty("ngTemplateOutlet", ctx)("ngTemplateOutletContext", i0.ɵɵpureFunction5(2, _c6, ctx_r0.conversation, (ctx_r0.conversation == null ? null : ctx_r0.conversation.Name) ?? null, (ctx_r0.sharedByBadge == null ? null : ctx_r0.sharedByBadge.display) ?? null, ctx_r0.artifactCountDisplay, ctx_r0.showArtifactIndicator));
129
+ i0.ɵɵproperty("ngTemplateOutlet", ctx)("ngTemplateOutletContext", i0.ɵɵpureFunction5(2, _c7, ctx_r0.conversation, (ctx_r0.conversation == null ? null : ctx_r0.conversation.Name) ?? null, (ctx_r0.sharedByBadge == null ? null : ctx_r0.sharedByBadge.display) ?? null, ctx_r0.artifactCountDisplay, ctx_r0.showArtifactIndicator));
119
130
  } }
120
131
  function ConversationChatAreaComponent_Conditional_3_Conditional_2_Template(rf, ctx) { if (rf & 1) {
121
132
  const _r3 = i0.ɵɵgetCurrentView();
122
- i0.ɵɵelementStart(0, "button", 44);
133
+ i0.ɵɵelementStart(0, "button", 46);
123
134
  i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_3_Conditional_2_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.sidebarToggleClicked.emit()); });
124
- i0.ɵɵelement(1, "i", 45);
135
+ i0.ɵɵelement(1, "i", 47);
125
136
  i0.ɵɵelementEnd();
126
137
  } }
127
138
  function ConversationChatAreaComponent_Conditional_3_Conditional_3_ng_container_0_Template(rf, ctx) { if (rf & 1) {
128
139
  i0.ɵɵelementContainer(0);
129
140
  } }
141
+ function ConversationChatAreaComponent_Conditional_3_Conditional_3_Conditional_1_Template(rf, ctx) { if (rf & 1) {
142
+ i0.ɵɵelementStart(0, "span", 50);
143
+ i0.ɵɵelement(1, "span", 51);
144
+ i0.ɵɵelementStart(2, "span");
145
+ i0.ɵɵtext(3, "with ");
146
+ i0.ɵɵelementStart(4, "b");
147
+ i0.ɵɵtext(5);
148
+ i0.ɵɵelementEnd()()();
149
+ } if (rf & 2) {
150
+ const ctx_r0 = i0.ɵɵnextContext(3);
151
+ i0.ɵɵstyleProp("--agent-accent", ctx_r0.CurrentOwnerAccentVar);
152
+ i0.ɵɵadvance(5);
153
+ i0.ɵɵtextInterpolate(ctx_r0.CurrentOwnerAgentName);
154
+ } }
130
155
  function ConversationChatAreaComponent_Conditional_3_Conditional_3_Template(rf, ctx) { if (rf & 1) {
131
- i0.ɵɵtemplate(0, ConversationChatAreaComponent_Conditional_3_Conditional_3_ng_container_0_Template, 1, 0, "ng-container", 46);
156
+ i0.ɵɵtemplate(0, ConversationChatAreaComponent_Conditional_3_Conditional_3_ng_container_0_Template, 1, 0, "ng-container", 48);
157
+ i0.ɵɵconditionalCreate(1, ConversationChatAreaComponent_Conditional_3_Conditional_3_Conditional_1_Template, 6, 3, "span", 49);
132
158
  } if (rf & 2) {
133
- i0.ɵɵnextContext(2);
159
+ const ctx_r0 = i0.ɵɵnextContext(2);
134
160
  const titleBar_r4 = i0.ɵɵreference(5);
135
161
  i0.ɵɵproperty("ngTemplateOutlet", titleBar_r4);
162
+ i0.ɵɵadvance();
163
+ i0.ɵɵconditional(ctx_r0.CurrentOwnerAgent ? 1 : -1);
136
164
  } }
137
165
  function ConversationChatAreaComponent_Conditional_3_Conditional_4_Template(rf, ctx) { if (rf & 1) {
138
- i0.ɵɵelementStart(0, "span", 32);
139
- i0.ɵɵelement(1, "i", 47);
166
+ i0.ɵɵelementStart(0, "span", 33);
167
+ i0.ɵɵelement(1, "i", 52);
140
168
  i0.ɵɵelementStart(2, "span");
141
169
  i0.ɵɵtext(3);
142
170
  i0.ɵɵelementEnd()();
@@ -148,9 +176,9 @@ function ConversationChatAreaComponent_Conditional_3_Conditional_4_Template(rf,
148
176
  } }
149
177
  function ConversationChatAreaComponent_Conditional_3_Conditional_5_Template(rf, ctx) { if (rf & 1) {
150
178
  const _r5 = i0.ɵɵgetCurrentView();
151
- i0.ɵɵelementStart(0, "button", 48);
179
+ i0.ɵɵelementStart(0, "button", 53);
152
180
  i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_3_Conditional_5_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r5); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.openProjectSelector()); });
153
- i0.ɵɵelement(1, "i", 49);
181
+ i0.ɵɵelement(1, "i", 54);
154
182
  i0.ɵɵelementStart(2, "span");
155
183
  i0.ɵɵtext(3);
156
184
  i0.ɵɵelementEnd()();
@@ -162,22 +190,22 @@ function ConversationChatAreaComponent_Conditional_3_Conditional_5_Template(rf,
162
190
  } }
163
191
  function ConversationChatAreaComponent_Conditional_3_Conditional_6_Template(rf, ctx) { if (rf & 1) {
164
192
  const _r6 = i0.ɵɵgetCurrentView();
165
- i0.ɵɵelementStart(0, "button", 50);
193
+ i0.ɵɵelementStart(0, "button", 55);
166
194
  i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_3_Conditional_6_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r6); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.viewTestRun(ctx_r0.conversation.TestRunID)); });
167
- i0.ɵɵelement(1, "i", 51);
195
+ i0.ɵɵelement(1, "i", 56);
168
196
  i0.ɵɵelementStart(2, "span");
169
197
  i0.ɵɵtext(3, "Test");
170
198
  i0.ɵɵelementEnd()();
171
199
  } }
172
200
  function ConversationChatAreaComponent_Conditional_3_Conditional_8_Template(rf, ctx) { if (rf & 1) {
173
201
  const _r7 = i0.ɵɵgetCurrentView();
174
- i0.ɵɵelementStart(0, "button", 52, 2);
202
+ i0.ɵɵelementStart(0, "button", 57, 2);
175
203
  i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_3_Conditional_8_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r7); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.ToggleForksPopover()); });
176
- i0.ɵɵelement(2, "i", 53);
177
- i0.ɵɵelementStart(3, "span", 54);
204
+ i0.ɵɵelement(2, "i", 58);
205
+ i0.ɵɵelementStart(3, "span", 59);
178
206
  i0.ɵɵtext(4, "Forks");
179
207
  i0.ɵɵelementEnd();
180
- i0.ɵɵelementStart(5, "span", 55);
208
+ i0.ɵɵelementStart(5, "span", 60);
181
209
  i0.ɵɵtext(6);
182
210
  i0.ɵɵelementEnd()();
183
211
  } if (rf & 2) {
@@ -189,10 +217,10 @@ function ConversationChatAreaComponent_Conditional_3_Conditional_8_Template(rf,
189
217
  } }
190
218
  function ConversationChatAreaComponent_Conditional_3_Conditional_9_Template(rf, ctx) { if (rf & 1) {
191
219
  const _r8 = i0.ɵɵgetCurrentView();
192
- i0.ɵɵelementStart(0, "button", 56);
220
+ i0.ɵɵelementStart(0, "button", 61);
193
221
  i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_3_Conditional_9_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r8); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.TogglePinsPanel()); });
194
- i0.ɵɵelement(1, "i", 57);
195
- i0.ɵɵelementStart(2, "span", 58);
222
+ i0.ɵɵelement(1, "i", 62);
223
+ i0.ɵɵelementStart(2, "span", 63);
196
224
  i0.ɵɵtext(3);
197
225
  i0.ɵɵelementEnd()();
198
226
  } if (rf & 2) {
@@ -203,10 +231,10 @@ function ConversationChatAreaComponent_Conditional_3_Conditional_9_Template(rf,
203
231
  } }
204
232
  function ConversationChatAreaComponent_Conditional_3_Conditional_10_Template(rf, ctx) { if (rf & 1) {
205
233
  const _r9 = i0.ɵɵgetCurrentView();
206
- i0.ɵɵelementStart(0, "button", 59);
234
+ i0.ɵɵelementStart(0, "button", 64);
207
235
  i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_3_Conditional_10_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r9); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.viewArtifacts()); });
208
- i0.ɵɵelement(1, "i", 60);
209
- i0.ɵɵelementStart(2, "span", 61);
236
+ i0.ɵɵelement(1, "i", 65);
237
+ i0.ɵɵelementStart(2, "span", 66);
210
238
  i0.ɵɵtext(3);
211
239
  i0.ɵɵelementEnd()();
212
240
  } if (rf & 2) {
@@ -216,10 +244,23 @@ function ConversationChatAreaComponent_Conditional_3_Conditional_10_Template(rf,
216
244
  } }
217
245
  function ConversationChatAreaComponent_Conditional_3_Conditional_11_Template(rf, ctx) { if (rf & 1) {
218
246
  const _r10 = i0.ɵɵgetCurrentView();
219
- i0.ɵɵelementStart(0, "button", 62);
220
- i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_3_Conditional_11_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r10); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.toggleMembersModal()); });
221
- i0.ɵɵelement(1, "i", 63);
222
- i0.ɵɵelementStart(2, "span", 64);
247
+ i0.ɵɵelementStart(0, "button", 67);
248
+ i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_3_Conditional_11_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r10); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.ToggleRemoteBrowserPanel()); });
249
+ i0.ɵɵelement(1, "i", 68);
250
+ i0.ɵɵelementStart(2, "span", 59);
251
+ i0.ɵɵtext(3, "Browser");
252
+ i0.ɵɵelementEnd()();
253
+ } if (rf & 2) {
254
+ const ctx_r0 = i0.ɵɵnextContext(2);
255
+ i0.ɵɵclassProp("active", ctx_r0.ShowRemoteBrowserPanel || ctx_r0.IsRemoteBrowserLive);
256
+ i0.ɵɵproperty("title", ctx_r0.ShowRemoteBrowserPanel ? "Hide Browser" : ctx_r0.IsRemoteBrowserLive ? "Show Browser (running)" : "Open Browser");
257
+ } }
258
+ function ConversationChatAreaComponent_Conditional_3_Conditional_12_Template(rf, ctx) { if (rf & 1) {
259
+ const _r11 = i0.ɵɵgetCurrentView();
260
+ i0.ɵɵelementStart(0, "button", 69);
261
+ i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_3_Conditional_12_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r11); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.toggleMembersModal()); });
262
+ i0.ɵɵelement(1, "i", 70);
263
+ i0.ɵɵelementStart(2, "span", 71);
223
264
  i0.ɵɵtext(3);
224
265
  i0.ɵɵelementEnd()();
225
266
  } if (rf & 2) {
@@ -227,27 +268,27 @@ function ConversationChatAreaComponent_Conditional_3_Conditional_11_Template(rf,
227
268
  i0.ɵɵadvance(3);
228
269
  i0.ɵɵtextInterpolate(ctx_r0.memberCount);
229
270
  } }
230
- function ConversationChatAreaComponent_Conditional_3_Conditional_12_Template(rf, ctx) { if (rf & 1) {
231
- const _r11 = i0.ɵɵgetCurrentView();
232
- i0.ɵɵelementStart(0, "mj-conversation-mode-picker", 65);
233
- i0.ɵɵlistener("PresetChanged", function ConversationChatAreaComponent_Conditional_3_Conditional_12_Template_mj_conversation_mode_picker_PresetChanged_0_listener($event) { i0.ɵɵrestoreView(_r11); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.OnAgentModePresetChanged($event)); });
271
+ function ConversationChatAreaComponent_Conditional_3_Conditional_13_Template(rf, ctx) { if (rf & 1) {
272
+ const _r12 = i0.ɵɵgetCurrentView();
273
+ i0.ɵɵelementStart(0, "mj-conversation-mode-picker", 72);
274
+ i0.ɵɵlistener("PresetChanged", function ConversationChatAreaComponent_Conditional_3_Conditional_13_Template_mj_conversation_mode_picker_PresetChanged_0_listener($event) { i0.ɵɵrestoreView(_r12); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.OnAgentModePresetChanged($event)); });
234
275
  i0.ɵɵelementEnd();
235
276
  } if (rf & 2) {
236
277
  const ctx_r0 = i0.ɵɵnextContext(2);
237
278
  i0.ɵɵproperty("AgentID", ctx_r0.ModePickerTargetAgentId)("Disabled", ctx_r0.isProcessing);
238
279
  } }
239
- function ConversationChatAreaComponent_Conditional_3_Conditional_13_Template(rf, ctx) { if (rf & 1) {
240
- i0.ɵɵelement(0, "mj-conversation-agent-picker", 41);
280
+ function ConversationChatAreaComponent_Conditional_3_Conditional_14_Template(rf, ctx) { if (rf & 1) {
281
+ i0.ɵɵelement(0, "mj-conversation-agent-picker", 43);
241
282
  } if (rf & 2) {
242
283
  const ctx_r0 = i0.ɵɵnextContext(2);
243
284
  i0.ɵɵproperty("Conversation", ctx_r0.conversation)("CurrentUser", ctx_r0.currentUser)("AllowedAgentIDs", ctx_r0.AllowedAgentIDs)("Disabled", ctx_r0.EffectiveReadOnly);
244
285
  } }
245
- function ConversationChatAreaComponent_Conditional_3_Conditional_14_Template(rf, ctx) { if (rf & 1) {
246
- const _r12 = i0.ɵɵgetCurrentView();
247
- i0.ɵɵelementStart(0, "button", 66);
248
- i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_3_Conditional_14_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r12); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.exportConversation()); });
286
+ function ConversationChatAreaComponent_Conditional_3_Conditional_15_Template(rf, ctx) { if (rf & 1) {
287
+ const _r13 = i0.ɵɵgetCurrentView();
288
+ i0.ɵɵelementStart(0, "button", 73);
289
+ i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_3_Conditional_15_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r13); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.exportConversation()); });
249
290
  i0.ɵɵelement(1, "i");
250
- i0.ɵɵelementStart(2, "span", 54);
291
+ i0.ɵɵelementStart(2, "span", 59);
251
292
  i0.ɵɵtext(3);
252
293
  i0.ɵɵelementEnd()();
253
294
  } if (rf & 2) {
@@ -258,12 +299,12 @@ function ConversationChatAreaComponent_Conditional_3_Conditional_14_Template(rf,
258
299
  i0.ɵɵadvance(2);
259
300
  i0.ɵɵtextInterpolate(ctx_r0.exportButtonLabel);
260
301
  } }
261
- function ConversationChatAreaComponent_Conditional_3_Conditional_15_Template(rf, ctx) { if (rf & 1) {
262
- const _r13 = i0.ɵɵgetCurrentView();
263
- i0.ɵɵelementStart(0, "button", 66);
264
- i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_3_Conditional_15_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r13); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.shareConversation()); });
265
- i0.ɵɵelement(1, "i", 47);
266
- i0.ɵɵelementStart(2, "span", 54);
302
+ function ConversationChatAreaComponent_Conditional_3_Conditional_16_Template(rf, ctx) { if (rf & 1) {
303
+ const _r14 = i0.ɵɵgetCurrentView();
304
+ i0.ɵɵelementStart(0, "button", 73);
305
+ i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_3_Conditional_16_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r14); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.shareConversation()); });
306
+ i0.ɵɵelement(1, "i", 52);
307
+ i0.ɵɵelementStart(2, "span", 59);
267
308
  i0.ɵɵtext(3, "Share");
268
309
  i0.ɵɵelementEnd()();
269
310
  } if (rf & 2) {
@@ -271,39 +312,40 @@ function ConversationChatAreaComponent_Conditional_3_Conditional_15_Template(rf,
271
312
  i0.ɵɵclassProp("shared", ctx_r0.isShared);
272
313
  i0.ɵɵproperty("title", ctx_r0.isShared ? "Manage sharing" : "Share conversation");
273
314
  } }
274
- function ConversationChatAreaComponent_Conditional_3_Conditional_16_ng_container_0_Template(rf, ctx) { if (rf & 1) {
315
+ function ConversationChatAreaComponent_Conditional_3_Conditional_17_ng_container_0_Template(rf, ctx) { if (rf & 1) {
275
316
  i0.ɵɵelementContainer(0);
276
317
  } }
277
- function ConversationChatAreaComponent_Conditional_3_Conditional_16_Template(rf, ctx) { if (rf & 1) {
278
- i0.ɵɵtemplate(0, ConversationChatAreaComponent_Conditional_3_Conditional_16_ng_container_0_Template, 1, 0, "ng-container", 28);
318
+ function ConversationChatAreaComponent_Conditional_3_Conditional_17_Template(rf, ctx) { if (rf & 1) {
319
+ i0.ɵɵtemplate(0, ConversationChatAreaComponent_Conditional_3_Conditional_17_ng_container_0_Template, 1, 0, "ng-container", 29);
279
320
  } if (rf & 2) {
280
321
  const ctx_r0 = i0.ɵɵnextContext(2);
281
- i0.ɵɵproperty("ngTemplateOutlet", ctx)("ngTemplateOutletContext", i0.ɵɵpureFunction3(2, _c7, ctx_r0.conversation, ctx_r0.conversationId, ctx_r0.isProcessing));
322
+ i0.ɵɵproperty("ngTemplateOutlet", ctx)("ngTemplateOutletContext", i0.ɵɵpureFunction3(2, _c8, ctx_r0.conversation, ctx_r0.conversationId, ctx_r0.isProcessing));
282
323
  } }
283
324
  function ConversationChatAreaComponent_Conditional_3_Template(rf, ctx) { if (rf & 1) {
284
325
  const _r2 = i0.ɵɵgetCurrentView();
285
- i0.ɵɵelementStart(0, "div", 29);
326
+ i0.ɵɵelementStart(0, "div", 30);
286
327
  i0.ɵɵlistener("keydown.escape", function ConversationChatAreaComponent_Conditional_3_Template_div_keydown_escape_0_listener($event) { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.OnViewEscape($event)); });
287
- i0.ɵɵelementStart(1, "div", 30);
288
- i0.ɵɵconditionalCreate(2, ConversationChatAreaComponent_Conditional_3_Conditional_2_Template, 2, 0, "button", 31);
289
- i0.ɵɵconditionalCreate(3, ConversationChatAreaComponent_Conditional_3_Conditional_3_Template, 1, 1, "ng-container");
290
- i0.ɵɵconditionalCreate(4, ConversationChatAreaComponent_Conditional_3_Conditional_4_Template, 4, 2, "span", 32);
291
- i0.ɵɵconditionalCreate(5, ConversationChatAreaComponent_Conditional_3_Conditional_5_Template, 4, 2, "button", 33);
292
- i0.ɵɵconditionalCreate(6, ConversationChatAreaComponent_Conditional_3_Conditional_6_Template, 4, 0, "button", 34);
328
+ i0.ɵɵelementStart(1, "div", 31);
329
+ i0.ɵɵconditionalCreate(2, ConversationChatAreaComponent_Conditional_3_Conditional_2_Template, 2, 0, "button", 32);
330
+ i0.ɵɵconditionalCreate(3, ConversationChatAreaComponent_Conditional_3_Conditional_3_Template, 2, 2);
331
+ i0.ɵɵconditionalCreate(4, ConversationChatAreaComponent_Conditional_3_Conditional_4_Template, 4, 2, "span", 33);
332
+ i0.ɵɵconditionalCreate(5, ConversationChatAreaComponent_Conditional_3_Conditional_5_Template, 4, 2, "button", 34);
333
+ i0.ɵɵconditionalCreate(6, ConversationChatAreaComponent_Conditional_3_Conditional_6_Template, 4, 0, "button", 35);
293
334
  i0.ɵɵelementEnd();
294
- i0.ɵɵelementStart(7, "div", 35);
295
- i0.ɵɵconditionalCreate(8, ConversationChatAreaComponent_Conditional_3_Conditional_8_Template, 7, 5, "button", 36);
296
- i0.ɵɵconditionalCreate(9, ConversationChatAreaComponent_Conditional_3_Conditional_9_Template, 4, 3, "button", 37);
297
- i0.ɵɵconditionalCreate(10, ConversationChatAreaComponent_Conditional_3_Conditional_10_Template, 4, 1, "button", 38);
298
- i0.ɵɵconditionalCreate(11, ConversationChatAreaComponent_Conditional_3_Conditional_11_Template, 4, 1, "button", 39);
299
- i0.ɵɵconditionalCreate(12, ConversationChatAreaComponent_Conditional_3_Conditional_12_Template, 1, 2, "mj-conversation-mode-picker", 40);
300
- i0.ɵɵconditionalCreate(13, ConversationChatAreaComponent_Conditional_3_Conditional_13_Template, 1, 4, "mj-conversation-agent-picker", 41);
301
- i0.ɵɵconditionalCreate(14, ConversationChatAreaComponent_Conditional_3_Conditional_14_Template, 4, 4, "button", 42);
302
- i0.ɵɵconditionalCreate(15, ConversationChatAreaComponent_Conditional_3_Conditional_15_Template, 4, 3, "button", 43);
303
- i0.ɵɵconditionalCreate(16, ConversationChatAreaComponent_Conditional_3_Conditional_16_Template, 1, 6, "ng-container");
335
+ i0.ɵɵelementStart(7, "div", 36);
336
+ i0.ɵɵconditionalCreate(8, ConversationChatAreaComponent_Conditional_3_Conditional_8_Template, 7, 5, "button", 37);
337
+ i0.ɵɵconditionalCreate(9, ConversationChatAreaComponent_Conditional_3_Conditional_9_Template, 4, 3, "button", 38);
338
+ i0.ɵɵconditionalCreate(10, ConversationChatAreaComponent_Conditional_3_Conditional_10_Template, 4, 1, "button", 39);
339
+ i0.ɵɵconditionalCreate(11, ConversationChatAreaComponent_Conditional_3_Conditional_11_Template, 4, 3, "button", 40);
340
+ i0.ɵɵconditionalCreate(12, ConversationChatAreaComponent_Conditional_3_Conditional_12_Template, 4, 1, "button", 41);
341
+ i0.ɵɵconditionalCreate(13, ConversationChatAreaComponent_Conditional_3_Conditional_13_Template, 1, 2, "mj-conversation-mode-picker", 42);
342
+ i0.ɵɵconditionalCreate(14, ConversationChatAreaComponent_Conditional_3_Conditional_14_Template, 1, 4, "mj-conversation-agent-picker", 43);
343
+ i0.ɵɵconditionalCreate(15, ConversationChatAreaComponent_Conditional_3_Conditional_15_Template, 4, 4, "button", 44);
344
+ i0.ɵɵconditionalCreate(16, ConversationChatAreaComponent_Conditional_3_Conditional_16_Template, 4, 3, "button", 45);
345
+ i0.ɵɵconditionalCreate(17, ConversationChatAreaComponent_Conditional_3_Conditional_17_Template, 1, 6, "ng-container");
304
346
  i0.ɵɵelementEnd()();
305
347
  } if (rf & 2) {
306
- let tmp_17_0;
348
+ let tmp_18_0;
307
349
  const ctx_r0 = i0.ɵɵnextContext();
308
350
  i0.ɵɵadvance();
309
351
  i0.ɵɵclassProp("with-sidebar-toggle", ctx_r0.showSidebarToggle);
@@ -324,85 +366,87 @@ function ConversationChatAreaComponent_Conditional_3_Template(rf, ctx) { if (rf
324
366
  i0.ɵɵadvance();
325
367
  i0.ɵɵconditional(ctx_r0.showArtifactIndicator && ctx_r0.artifactCountDisplay > 0 ? 10 : -1);
326
368
  i0.ɵɵadvance();
327
- i0.ɵɵconditional(ctx_r0.memberCount > 1 ? 11 : -1);
369
+ i0.ɵɵconditional(ctx_r0.AllowRemoteBrowser && ctx_r0.conversation ? 11 : -1);
370
+ i0.ɵɵadvance();
371
+ i0.ɵɵconditional(ctx_r0.memberCount > 1 ? 12 : -1);
328
372
  i0.ɵɵadvance();
329
- i0.ɵɵconditional(!ctx_r0.overlayMode && ctx_r0.showAgentModePicker && ctx_r0.ModePickerTargetAgentId && !ctx_r0.EffectiveReadOnly ? 12 : -1);
373
+ i0.ɵɵconditional(!ctx_r0.overlayMode && ctx_r0.showAgentModePicker && ctx_r0.ModePickerTargetAgentId && !ctx_r0.EffectiveReadOnly ? 13 : -1);
330
374
  i0.ɵɵadvance();
331
- i0.ɵɵconditional(ctx_r0.showAgentPicker && ctx_r0.conversation ? 13 : -1);
375
+ i0.ɵɵconditional(ctx_r0.showAgentPicker && ctx_r0.conversation ? 14 : -1);
332
376
  i0.ɵɵadvance();
333
- i0.ɵɵconditional(ctx_r0.showExportButton ? 14 : -1);
377
+ i0.ɵɵconditional(ctx_r0.showExportButton ? 15 : -1);
334
378
  i0.ɵɵadvance();
335
- i0.ɵɵconditional(ctx_r0.showShareButton && ctx_r0.canShareConversation ? 15 : -1);
379
+ i0.ɵɵconditional(ctx_r0.showShareButton && ctx_r0.canShareConversation ? 16 : -1);
336
380
  i0.ɵɵadvance();
337
- i0.ɵɵconditional((tmp_17_0 = ctx_r0.slotTemplate("headerActions")) ? 16 : -1, tmp_17_0);
381
+ i0.ɵɵconditional((tmp_18_0 = ctx_r0.slotTemplate("headerActions")) ? 17 : -1, tmp_18_0);
338
382
  } }
339
383
  function ConversationChatAreaComponent_ng_template_4_Conditional_1_ng_container_0_Template(rf, ctx) { if (rf & 1) {
340
384
  i0.ɵɵelementContainer(0);
341
385
  } }
342
386
  function ConversationChatAreaComponent_ng_template_4_Conditional_1_Template(rf, ctx) { if (rf & 1) {
343
- i0.ɵɵtemplate(0, ConversationChatAreaComponent_ng_template_4_Conditional_1_ng_container_0_Template, 1, 0, "ng-container", 46);
387
+ i0.ɵɵtemplate(0, ConversationChatAreaComponent_ng_template_4_Conditional_1_ng_container_0_Template, 1, 0, "ng-container", 48);
344
388
  } if (rf & 2) {
345
389
  i0.ɵɵnextContext(2);
346
- const titleName_r14 = i0.ɵɵreference(7);
347
- i0.ɵɵproperty("ngTemplateOutlet", titleName_r14);
390
+ const titleName_r15 = i0.ɵɵreference(7);
391
+ i0.ɵɵproperty("ngTemplateOutlet", titleName_r15);
348
392
  } }
349
393
  function ConversationChatAreaComponent_ng_template_4_Conditional_2_For_3_Conditional_0_Template(rf, ctx) { if (rf & 1) {
350
- const _r16 = i0.ɵɵgetCurrentView();
351
- i0.ɵɵelementStart(0, "li", 77)(1, "button", 78);
352
- i0.ɵɵlistener("click", function ConversationChatAreaComponent_ng_template_4_Conditional_2_For_3_Conditional_0_Template_button_click_1_listener() { i0.ɵɵrestoreView(_r16); const ctx_r0 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r0.ShowWholePath()); });
394
+ const _r17 = i0.ɵɵgetCurrentView();
395
+ i0.ɵɵelementStart(0, "li", 84)(1, "button", 85);
396
+ i0.ɵɵlistener("click", function ConversationChatAreaComponent_ng_template_4_Conditional_2_For_3_Conditional_0_Template_button_click_1_listener() { i0.ɵɵrestoreView(_r17); const ctx_r0 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r0.ShowWholePath()); });
353
397
  i0.ɵɵtext(2, "\u2026");
354
398
  i0.ɵɵelementEnd();
355
- i0.ɵɵelement(3, "i", 76);
399
+ i0.ɵɵelement(3, "i", 83);
356
400
  i0.ɵɵelementEnd();
357
401
  } if (rf & 2) {
358
402
  const ctx_r0 = i0.ɵɵnextContext(4);
359
403
  i0.ɵɵclassProp("collapses-wide", ctx_r0.HeaderPath.CollapsesWide);
360
404
  } }
361
405
  function ConversationChatAreaComponent_ng_template_4_Conditional_2_For_3_Template(rf, ctx) { if (rf & 1) {
362
- const _r15 = i0.ɵɵgetCurrentView();
363
- i0.ɵɵconditionalCreate(0, ConversationChatAreaComponent_ng_template_4_Conditional_2_For_3_Conditional_0_Template, 4, 2, "li", 72);
364
- i0.ɵɵelementStart(1, "li", 73)(2, "button", 74);
365
- i0.ɵɵlistener("click", function ConversationChatAreaComponent_ng_template_4_Conditional_2_For_3_Template_button_click_2_listener() { const parent_r17 = i0.ɵɵrestoreView(_r15).$implicit; const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.OpenCrumb(parent_r17.Crumb)); });
366
- i0.ɵɵelementStart(3, "span", 75);
406
+ const _r16 = i0.ɵɵgetCurrentView();
407
+ i0.ɵɵconditionalCreate(0, ConversationChatAreaComponent_ng_template_4_Conditional_2_For_3_Conditional_0_Template, 4, 2, "li", 79);
408
+ i0.ɵɵelementStart(1, "li", 80)(2, "button", 81);
409
+ i0.ɵɵlistener("click", function ConversationChatAreaComponent_ng_template_4_Conditional_2_For_3_Template_button_click_2_listener() { const parent_r18 = i0.ɵɵrestoreView(_r16).$implicit; const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.OpenCrumb(parent_r18.Crumb)); });
410
+ i0.ɵɵelementStart(3, "span", 82);
367
411
  i0.ɵɵtext(4);
368
412
  i0.ɵɵelementEnd()();
369
- i0.ɵɵelement(5, "i", 76);
413
+ i0.ɵɵelement(5, "i", 83);
370
414
  i0.ɵɵelementEnd();
371
415
  } if (rf & 2) {
372
- const parent_r17 = ctx.$implicit;
373
- const $index_r18 = ctx.$index;
374
- i0.ɵɵconditional($index_r18 === 1 ? 0 : -1);
416
+ const parent_r18 = ctx.$implicit;
417
+ const $index_r19 = ctx.$index;
418
+ i0.ɵɵconditional($index_r19 === 1 ? 0 : -1);
375
419
  i0.ɵɵadvance();
376
- i0.ɵɵclassProp("path-middle", parent_r17.IsMiddle)("collapsed-wide", parent_r17.CollapsedWide);
420
+ i0.ɵɵclassProp("path-middle", parent_r18.IsMiddle)("collapsed-wide", parent_r18.CollapsedWide);
377
421
  i0.ɵɵadvance();
378
- i0.ɵɵproperty("title", "Back to " + parent_r17.Crumb.Label);
422
+ i0.ɵɵproperty("title", "Back to " + parent_r18.Crumb.Label);
379
423
  i0.ɵɵadvance(2);
380
- i0.ɵɵtextInterpolate(parent_r17.Crumb.Label);
424
+ i0.ɵɵtextInterpolate(parent_r18.Crumb.Label);
381
425
  } }
382
426
  function ConversationChatAreaComponent_ng_template_4_Conditional_2_ng_container_6_Template(rf, ctx) { if (rf & 1) {
383
427
  i0.ɵɵelementContainer(0);
384
428
  } }
385
429
  function ConversationChatAreaComponent_ng_template_4_Conditional_2_Template(rf, ctx) { if (rf & 1) {
386
- i0.ɵɵelementStart(0, "nav", 68)(1, "ol", 69);
430
+ i0.ɵɵelementStart(0, "nav", 75)(1, "ol", 76);
387
431
  i0.ɵɵrepeaterCreate(2, ConversationChatAreaComponent_ng_template_4_Conditional_2_For_3_Template, 6, 7, null, null, i0.ɵɵrepeaterTrackByIndex);
388
- i0.ɵɵelementStart(4, "li", 70);
389
- i0.ɵɵelement(5, "i", 71);
390
- i0.ɵɵtemplate(6, ConversationChatAreaComponent_ng_template_4_Conditional_2_ng_container_6_Template, 1, 0, "ng-container", 46);
432
+ i0.ɵɵelementStart(4, "li", 77);
433
+ i0.ɵɵelement(5, "i", 78);
434
+ i0.ɵɵtemplate(6, ConversationChatAreaComponent_ng_template_4_Conditional_2_ng_container_6_Template, 1, 0, "ng-container", 48);
391
435
  i0.ɵɵelementEnd()()();
392
436
  } if (rf & 2) {
393
437
  const ctx_r0 = i0.ɵɵnextContext(2);
394
- const titleName_r14 = i0.ɵɵreference(7);
438
+ const titleName_r15 = i0.ɵɵreference(7);
395
439
  i0.ɵɵadvance(2);
396
440
  i0.ɵɵrepeater(ctx_r0.HeaderPath.Parents);
397
441
  i0.ɵɵadvance(3);
398
442
  i0.ɵɵclassMap("chat-title-kind " + ctx_r0.OpenViewIcon);
399
443
  i0.ɵɵattribute("data-kind", ctx_r0.OpenViewKind);
400
444
  i0.ɵɵadvance();
401
- i0.ɵɵproperty("ngTemplateOutlet", titleName_r14);
445
+ i0.ɵɵproperty("ngTemplateOutlet", titleName_r15);
402
446
  } }
403
447
  function ConversationChatAreaComponent_ng_template_4_Template(rf, ctx) { if (rf & 1) {
404
- i0.ɵɵelementStart(0, "div", 67);
405
- i0.ɵɵconditionalCreate(1, ConversationChatAreaComponent_ng_template_4_Conditional_1_Template, 1, 1, "ng-container")(2, ConversationChatAreaComponent_ng_template_4_Conditional_2_Template, 7, 4, "nav", 68);
448
+ i0.ɵɵelementStart(0, "div", 74);
449
+ i0.ɵɵconditionalCreate(1, ConversationChatAreaComponent_ng_template_4_Conditional_1_Template, 1, 1, "ng-container")(2, ConversationChatAreaComponent_ng_template_4_Conditional_2_Template, 7, 4, "nav", 75);
406
450
  i0.ɵɵelementEnd();
407
451
  } if (rf & 2) {
408
452
  const ctx_r0 = i0.ɵɵnextContext();
@@ -410,10 +454,10 @@ function ConversationChatAreaComponent_ng_template_4_Template(rf, ctx) { if (rf
410
454
  i0.ɵɵconditional(ctx_r0.OpenView.Kind === "Main" ? 1 : 2);
411
455
  } }
412
456
  function ConversationChatAreaComponent_ng_template_6_Conditional_0_Template(rf, ctx) { if (rf & 1) {
413
- const _r19 = i0.ɵɵgetCurrentView();
414
- i0.ɵɵelementStart(0, "input", 80, 3);
415
- i0.ɵɵtwoWayListener("ngModelChange", function ConversationChatAreaComponent_ng_template_6_Conditional_0_Template_input_ngModelChange_0_listener($event) { i0.ɵɵrestoreView(_r19); const ctx_r0 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r0.TitleRenameText, $event) || (ctx_r0.TitleRenameText = $event); return i0.ɵɵresetView($event); });
416
- i0.ɵɵlistener("keydown.enter", function ConversationChatAreaComponent_ng_template_6_Conditional_0_Template_input_keydown_enter_0_listener($event) { i0.ɵɵrestoreView(_r19); const ctx_r0 = i0.ɵɵnextContext(2); $event.preventDefault(); return i0.ɵɵresetView(ctx_r0.SaveTitleRename(true)); })("keydown.escape", function ConversationChatAreaComponent_ng_template_6_Conditional_0_Template_input_keydown_escape_0_listener($event) { i0.ɵɵrestoreView(_r19); const ctx_r0 = i0.ɵɵnextContext(2); $event.preventDefault(); $event.stopPropagation(); return i0.ɵɵresetView(ctx_r0.CancelTitleRename()); })("blur", function ConversationChatAreaComponent_ng_template_6_Conditional_0_Template_input_blur_0_listener() { i0.ɵɵrestoreView(_r19); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.SaveTitleRename()); });
457
+ const _r20 = i0.ɵɵgetCurrentView();
458
+ i0.ɵɵelementStart(0, "input", 87, 3);
459
+ i0.ɵɵtwoWayListener("ngModelChange", function ConversationChatAreaComponent_ng_template_6_Conditional_0_Template_input_ngModelChange_0_listener($event) { i0.ɵɵrestoreView(_r20); const ctx_r0 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r0.TitleRenameText, $event) || (ctx_r0.TitleRenameText = $event); return i0.ɵɵresetView($event); });
460
+ i0.ɵɵlistener("keydown.enter", function ConversationChatAreaComponent_ng_template_6_Conditional_0_Template_input_keydown_enter_0_listener($event) { i0.ɵɵrestoreView(_r20); const ctx_r0 = i0.ɵɵnextContext(2); $event.preventDefault(); return i0.ɵɵresetView(ctx_r0.SaveTitleRename(true)); })("keydown.escape", function ConversationChatAreaComponent_ng_template_6_Conditional_0_Template_input_keydown_escape_0_listener($event) { i0.ɵɵrestoreView(_r20); const ctx_r0 = i0.ɵɵnextContext(2); $event.preventDefault(); $event.stopPropagation(); return i0.ɵɵresetView(ctx_r0.CancelTitleRename()); })("blur", function ConversationChatAreaComponent_ng_template_6_Conditional_0_Template_input_blur_0_listener() { i0.ɵɵrestoreView(_r20); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.SaveTitleRename()); });
417
461
  i0.ɵɵelementEnd();
418
462
  } if (rf & 2) {
419
463
  const ctx_r0 = i0.ɵɵnextContext(2);
@@ -421,10 +465,10 @@ function ConversationChatAreaComponent_ng_template_6_Conditional_0_Template(rf,
421
465
  i0.ɵɵattribute("aria-label", ctx_r0.TitleRenameLabel);
422
466
  } }
423
467
  function ConversationChatAreaComponent_ng_template_6_Conditional_1_Conditional_2_Template(rf, ctx) { if (rf & 1) {
424
- const _r20 = i0.ɵɵgetCurrentView();
425
- i0.ɵɵelementStart(0, "button", 83, 4);
426
- i0.ɵɵlistener("click", function ConversationChatAreaComponent_ng_template_6_Conditional_1_Conditional_2_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r20); const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.StartTitleRename()); });
427
- i0.ɵɵelement(2, "i", 84);
468
+ const _r21 = i0.ɵɵgetCurrentView();
469
+ i0.ɵɵelementStart(0, "button", 90, 4);
470
+ i0.ɵɵlistener("click", function ConversationChatAreaComponent_ng_template_6_Conditional_1_Conditional_2_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r21); const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.StartTitleRename()); });
471
+ i0.ɵɵelement(2, "i", 91);
428
472
  i0.ɵɵelementEnd();
429
473
  } if (rf & 2) {
430
474
  const ctx_r0 = i0.ɵɵnextContext(3);
@@ -432,10 +476,10 @@ function ConversationChatAreaComponent_ng_template_6_Conditional_1_Conditional_2
432
476
  i0.ɵɵattribute("aria-label", ctx_r0.TitleRenameLabel);
433
477
  } }
434
478
  function ConversationChatAreaComponent_ng_template_6_Conditional_1_Template(rf, ctx) { if (rf & 1) {
435
- i0.ɵɵelementStart(0, "h2", 81);
479
+ i0.ɵɵelementStart(0, "h2", 88);
436
480
  i0.ɵɵtext(1);
437
481
  i0.ɵɵelementEnd();
438
- i0.ɵɵconditionalCreate(2, ConversationChatAreaComponent_ng_template_6_Conditional_1_Conditional_2_Template, 3, 2, "button", 82);
482
+ i0.ɵɵconditionalCreate(2, ConversationChatAreaComponent_ng_template_6_Conditional_1_Conditional_2_Template, 3, 2, "button", 89);
439
483
  } if (rf & 2) {
440
484
  const ctx_r0 = i0.ɵɵnextContext(2);
441
485
  i0.ɵɵproperty("title", ctx_r0.HeaderTitle);
@@ -445,7 +489,7 @@ function ConversationChatAreaComponent_ng_template_6_Conditional_1_Template(rf,
445
489
  i0.ɵɵconditional(ctx_r0.CanRenameTitle ? 2 : -1);
446
490
  } }
447
491
  function ConversationChatAreaComponent_ng_template_6_Template(rf, ctx) { if (rf & 1) {
448
- i0.ɵɵconditionalCreate(0, ConversationChatAreaComponent_ng_template_6_Conditional_0_Template, 2, 2, "input", 79)(1, ConversationChatAreaComponent_ng_template_6_Conditional_1_Template, 3, 3);
492
+ i0.ɵɵconditionalCreate(0, ConversationChatAreaComponent_ng_template_6_Conditional_0_Template, 2, 2, "input", 86)(1, ConversationChatAreaComponent_ng_template_6_Conditional_1_Template, 3, 3);
449
493
  } if (rf & 2) {
450
494
  const ctx_r0 = i0.ɵɵnextContext();
451
495
  i0.ɵɵconditional(ctx_r0.IsRenamingTitle ? 0 : 1);
@@ -454,28 +498,28 @@ function ConversationChatAreaComponent_Conditional_9_ng_container_1_Template(rf,
454
498
  i0.ɵɵelementContainer(0);
455
499
  } }
456
500
  function ConversationChatAreaComponent_Conditional_9_Template(rf, ctx) { if (rf & 1) {
457
- i0.ɵɵelementStart(0, "div", 13);
458
- i0.ɵɵtemplate(1, ConversationChatAreaComponent_Conditional_9_ng_container_1_Template, 1, 0, "ng-container", 28);
501
+ i0.ɵɵelementStart(0, "div", 14);
502
+ i0.ɵɵtemplate(1, ConversationChatAreaComponent_Conditional_9_ng_container_1_Template, 1, 0, "ng-container", 29);
459
503
  i0.ɵɵelementEnd();
460
504
  } if (rf & 2) {
461
505
  const ctx_r0 = i0.ɵɵnextContext();
462
506
  i0.ɵɵadvance();
463
- i0.ɵɵproperty("ngTemplateOutlet", ctx_r0.slotTemplate("demonstrationSurface"))("ngTemplateOutletContext", i0.ɵɵpureFunction3(2, _c8, ctx_r0.demonstrationSurfaceContent, ctx_r0.demonstrationSurfaceContent, ctx_r0.showDemonstrationSurface));
507
+ i0.ɵɵproperty("ngTemplateOutlet", ctx_r0.slotTemplate("demonstrationSurface"))("ngTemplateOutletContext", i0.ɵɵpureFunction3(2, _c9, ctx_r0.demonstrationSurfaceContent, ctx_r0.demonstrationSurfaceContent, ctx_r0.showDemonstrationSurface));
464
508
  } }
465
509
  function ConversationChatAreaComponent_Conditional_11_Conditional_0_Template(rf, ctx) { if (rf & 1) {
466
- i0.ɵɵelementStart(0, "div", 85);
467
- i0.ɵɵelement(1, "mj-loading", 86);
510
+ i0.ɵɵelementStart(0, "div", 92);
511
+ i0.ɵɵelement(1, "mj-loading", 93);
468
512
  i0.ɵɵelementEnd();
469
513
  } }
470
514
  function ConversationChatAreaComponent_Conditional_11_Template(rf, ctx) { if (rf & 1) {
471
- i0.ɵɵconditionalCreate(0, ConversationChatAreaComponent_Conditional_11_Conditional_0_Template, 2, 0, "div", 85);
515
+ i0.ɵɵconditionalCreate(0, ConversationChatAreaComponent_Conditional_11_Conditional_0_Template, 2, 0, "div", 92);
472
516
  } if (rf & 2) {
473
517
  const ctx_r0 = i0.ɵɵnextContext();
474
518
  i0.ɵɵconditional(ctx_r0.showLoadingState ? 0 : -1);
475
519
  } }
476
520
  function ConversationChatAreaComponent_Conditional_12_Conditional_0_Template(rf, ctx) { if (rf & 1) {
477
- i0.ɵɵelementStart(0, "div", 87);
478
- i0.ɵɵelement(1, "i", 89);
521
+ i0.ɵɵelementStart(0, "div", 94);
522
+ i0.ɵɵelement(1, "i", 96);
479
523
  i0.ɵɵelementStart(2, "span");
480
524
  i0.ɵɵtext(3);
481
525
  i0.ɵɵelementEnd()();
@@ -488,30 +532,30 @@ function ConversationChatAreaComponent_Conditional_12_Conditional_1_ng_container
488
532
  i0.ɵɵelementContainer(0);
489
533
  } }
490
534
  function ConversationChatAreaComponent_Conditional_12_Conditional_1_Template(rf, ctx) { if (rf & 1) {
491
- i0.ɵɵtemplate(0, ConversationChatAreaComponent_Conditional_12_Conditional_1_ng_container_0_Template, 1, 0, "ng-container", 28);
535
+ i0.ɵɵtemplate(0, ConversationChatAreaComponent_Conditional_12_Conditional_1_ng_container_0_Template, 1, 0, "ng-container", 29);
492
536
  } if (rf & 2) {
493
537
  const ctx_r0 = i0.ɵɵnextContext(2);
494
- i0.ɵɵproperty("ngTemplateOutlet", ctx)("ngTemplateOutletContext", i0.ɵɵpureFunction4(3, _c10, ctx_r0.emptyStateConfig, (ctx_r0.emptyStateConfig == null ? null : ctx_r0.emptyStateConfig.greeting) ?? ctx_r0.emptyStateGreeting, ctx_r0.emptyStateConfig == null ? null : ctx_r0.emptyStateConfig.subtext, (ctx_r0.emptyStateConfig == null ? null : ctx_r0.emptyStateConfig.suggestedPrompts) ?? i0.ɵɵpureFunction0(2, _c9)));
538
+ i0.ɵɵproperty("ngTemplateOutlet", ctx)("ngTemplateOutletContext", i0.ɵɵpureFunction4(3, _c11, ctx_r0.emptyStateConfig, (ctx_r0.emptyStateConfig == null ? null : ctx_r0.emptyStateConfig.greeting) ?? ctx_r0.emptyStateGreeting, ctx_r0.emptyStateConfig == null ? null : ctx_r0.emptyStateConfig.subtext, (ctx_r0.emptyStateConfig == null ? null : ctx_r0.emptyStateConfig.suggestedPrompts) ?? i0.ɵɵpureFunction0(2, _c10)));
495
539
  } }
496
540
  function ConversationChatAreaComponent_Conditional_12_Conditional_2_Template(rf, ctx) { if (rf & 1) {
497
- const _r21 = i0.ɵɵgetCurrentView();
498
- i0.ɵɵelementStart(0, "mj-conversation-empty-state", 90);
499
- i0.ɵɵlistener("initialDraftApplied", function ConversationChatAreaComponent_Conditional_12_Conditional_2_Template_mj_conversation_empty_state_initialDraftApplied_0_listener() { i0.ɵɵrestoreView(_r21); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.OnComposerDraftApplied()); })("DraftStateChanged", function ConversationChatAreaComponent_Conditional_12_Conditional_2_Template_mj_conversation_empty_state_DraftStateChanged_0_listener($event) { i0.ɵɵrestoreView(_r21); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.OnDraftStateChanged(null, $event)); })("ComposerBlurred", function ConversationChatAreaComponent_Conditional_12_Conditional_2_Template_mj_conversation_empty_state_ComposerBlurred_0_listener() { i0.ɵɵrestoreView(_r21); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.OnComposerBlurred()); })("sidebarToggleClicked", function ConversationChatAreaComponent_Conditional_12_Conditional_2_Template_mj_conversation_empty_state_sidebarToggleClicked_0_listener() { i0.ɵɵrestoreView(_r21); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.sidebarToggleClicked.emit()); })("messageSent", function ConversationChatAreaComponent_Conditional_12_Conditional_2_Template_mj_conversation_empty_state_messageSent_0_listener($event) { i0.ɵɵrestoreView(_r21); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.onEmptyStateMessageSent($event)); });
541
+ const _r22 = i0.ɵɵgetCurrentView();
542
+ i0.ɵɵelementStart(0, "mj-conversation-empty-state", 97);
543
+ i0.ɵɵlistener("initialDraftApplied", function ConversationChatAreaComponent_Conditional_12_Conditional_2_Template_mj_conversation_empty_state_initialDraftApplied_0_listener() { i0.ɵɵrestoreView(_r22); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.OnComposerDraftApplied()); })("DraftStateChanged", function ConversationChatAreaComponent_Conditional_12_Conditional_2_Template_mj_conversation_empty_state_DraftStateChanged_0_listener($event) { i0.ɵɵrestoreView(_r22); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.OnDraftStateChanged(null, $event)); })("ComposerBlurred", function ConversationChatAreaComponent_Conditional_12_Conditional_2_Template_mj_conversation_empty_state_ComposerBlurred_0_listener() { i0.ɵɵrestoreView(_r22); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.OnComposerBlurred()); })("sidebarToggleClicked", function ConversationChatAreaComponent_Conditional_12_Conditional_2_Template_mj_conversation_empty_state_sidebarToggleClicked_0_listener() { i0.ɵɵrestoreView(_r22); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.sidebarToggleClicked.emit()); })("messageSent", function ConversationChatAreaComponent_Conditional_12_Conditional_2_Template_mj_conversation_empty_state_messageSent_0_listener($event) { i0.ɵɵrestoreView(_r22); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.onEmptyStateMessageSent($event)); });
500
544
  i0.ɵɵelementEnd();
501
545
  } if (rf & 2) {
502
546
  const ctx_r0 = i0.ɵɵnextContext(2);
503
547
  i0.ɵɵproperty("currentUser", ctx_r0.currentUser)("initialDraft", ctx_r0.GetInitialDraftFor(null))("disabled", ctx_r0.isProcessing)("showSidebarToggle", ctx_r0.showSidebarToggle)("overlayMode", ctx_r0.overlayMode)("greeting", (ctx_r0.emptyStateConfig == null ? null : ctx_r0.emptyStateConfig.greeting) ?? ctx_r0.emptyStateGreeting)("showSuggestedPrompts", ctx_r0.showSuggestedPrompts)("enableAttachments", ctx_r0.enableAttachments && ctx_r0.allowAttachments)("enableMentions", ctx_r0.allowMentions)("enableAgentMentions", ctx_r0.allowAgentMentions)("enableEntityMentions", ctx_r0.allowEntityMentions)("enableSkillCommands", ctx_r0.allowSkillCommands)("AllowedAgentIDs", ctx_r0.AllowedAgentIDs)("MentionPeople", ctx_r0.MentionPeople)("ComposerExtraTemplate", ctx_r0.slotTemplate("composerExtra"))("maxAttachments", ctx_r0.maxAttachments)("maxAttachmentSizeBytes", ctx_r0.maxAttachmentSizeBytes)("acceptedFileTypes", ctx_r0.acceptedFileTypes);
504
548
  } }
505
549
  function ConversationChatAreaComponent_Conditional_12_Template(rf, ctx) { if (rf & 1) {
506
- i0.ɵɵconditionalCreate(0, ConversationChatAreaComponent_Conditional_12_Conditional_0_Template, 4, 1, "div", 87)(1, ConversationChatAreaComponent_Conditional_12_Conditional_1_Template, 1, 8, "ng-container")(2, ConversationChatAreaComponent_Conditional_12_Conditional_2_Template, 1, 18, "mj-conversation-empty-state", 88);
550
+ i0.ɵɵconditionalCreate(0, ConversationChatAreaComponent_Conditional_12_Conditional_0_Template, 4, 1, "div", 94)(1, ConversationChatAreaComponent_Conditional_12_Conditional_1_Template, 1, 8, "ng-container")(2, ConversationChatAreaComponent_Conditional_12_Conditional_2_Template, 1, 18, "mj-conversation-empty-state", 95);
507
551
  } if (rf & 2) {
508
552
  let tmp_3_0;
509
553
  const ctx_r0 = i0.ɵɵnextContext();
510
554
  i0.ɵɵconditional(ctx_r0.ReadOnly ? 0 : (tmp_3_0 = ctx_r0.slotTemplate("emptyState")) ? 1 : 2, tmp_3_0);
511
555
  } }
512
556
  function ConversationChatAreaComponent_Conditional_13_Conditional_3_Template(rf, ctx) { if (rf & 1) {
513
- i0.ɵɵelementStart(0, "div", 87);
514
- i0.ɵɵelement(1, "i", 89);
557
+ i0.ɵɵelementStart(0, "div", 94);
558
+ i0.ɵɵelement(1, "i", 96);
515
559
  i0.ɵɵelementStart(2, "span");
516
560
  i0.ɵɵtext(3);
517
561
  i0.ɵɵelementEnd()();
@@ -524,19 +568,19 @@ function ConversationChatAreaComponent_Conditional_13_Conditional_4_Conditional_
524
568
  i0.ɵɵelementContainer(0);
525
569
  } }
526
570
  function ConversationChatAreaComponent_Conditional_13_Conditional_4_Conditional_0_Template(rf, ctx) { if (rf & 1) {
527
- i0.ɵɵelementStart(0, "div", 93);
528
- i0.ɵɵtemplate(1, ConversationChatAreaComponent_Conditional_13_Conditional_4_Conditional_0_ng_container_1_Template, 1, 0, "ng-container", 28);
571
+ i0.ɵɵelementStart(0, "div", 100);
572
+ i0.ɵɵtemplate(1, ConversationChatAreaComponent_Conditional_13_Conditional_4_Conditional_0_ng_container_1_Template, 1, 0, "ng-container", 29);
529
573
  i0.ɵɵelementEnd();
530
574
  } if (rf & 2) {
531
575
  const ctx_r0 = i0.ɵɵnextContext(3);
532
576
  i0.ɵɵadvance();
533
- i0.ɵɵproperty("ngTemplateOutlet", ctx)("ngTemplateOutletContext", i0.ɵɵpureFunction3(2, _c11, ctx_r0.conversation, ctx_r0.conversationId, ctx_r0.isProcessing));
577
+ i0.ɵɵproperty("ngTemplateOutlet", ctx)("ngTemplateOutletContext", i0.ɵɵpureFunction3(2, _c12, ctx_r0.conversation, ctx_r0.conversationId, ctx_r0.isProcessing));
534
578
  } }
535
579
  function ConversationChatAreaComponent_Conditional_13_Conditional_4_Template(rf, ctx) { if (rf & 1) {
536
- const _r22 = i0.ɵɵgetCurrentView();
537
- i0.ɵɵconditionalCreate(0, ConversationChatAreaComponent_Conditional_13_Conditional_4_Conditional_0_Template, 2, 6, "div", 93);
538
- i0.ɵɵelementStart(1, "div", 94)(2, "mj-message-input", 95, 5);
539
- i0.ɵɵlistener("initialDraftApplied", function ConversationChatAreaComponent_Conditional_13_Conditional_4_Template_mj_message_input_initialDraftApplied_2_listener() { i0.ɵɵrestoreView(_r22); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.OnComposerDraftApplied()); })("DraftStateChanged", function ConversationChatAreaComponent_Conditional_13_Conditional_4_Template_mj_message_input_DraftStateChanged_2_listener($event) { i0.ɵɵrestoreView(_r22); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.OnDraftStateChanged(null, $event)); })("ComposerBlurred", function ConversationChatAreaComponent_Conditional_13_Conditional_4_Template_mj_message_input_ComposerBlurred_2_listener() { i0.ɵɵrestoreView(_r22); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.OnComposerBlurred()); })("emptyStateSubmit", function ConversationChatAreaComponent_Conditional_13_Conditional_4_Template_mj_message_input_emptyStateSubmit_2_listener($event) { i0.ɵɵrestoreView(_r22); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.onEmptyStateMessageSent($event)); });
580
+ const _r23 = i0.ɵɵgetCurrentView();
581
+ i0.ɵɵconditionalCreate(0, ConversationChatAreaComponent_Conditional_13_Conditional_4_Conditional_0_Template, 2, 6, "div", 100);
582
+ i0.ɵɵelementStart(1, "div", 101)(2, "mj-message-input", 102, 5);
583
+ i0.ɵɵlistener("initialDraftApplied", function ConversationChatAreaComponent_Conditional_13_Conditional_4_Template_mj_message_input_initialDraftApplied_2_listener() { i0.ɵɵrestoreView(_r23); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.OnComposerDraftApplied()); })("DraftStateChanged", function ConversationChatAreaComponent_Conditional_13_Conditional_4_Template_mj_message_input_DraftStateChanged_2_listener($event) { i0.ɵɵrestoreView(_r23); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.OnDraftStateChanged(null, $event)); })("ComposerBlurred", function ConversationChatAreaComponent_Conditional_13_Conditional_4_Template_mj_message_input_ComposerBlurred_2_listener() { i0.ɵɵrestoreView(_r23); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.OnComposerBlurred()); })("emptyStateSubmit", function ConversationChatAreaComponent_Conditional_13_Conditional_4_Template_mj_message_input_emptyStateSubmit_2_listener($event) { i0.ɵɵrestoreView(_r23); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.onEmptyStateMessageSent($event)); });
540
584
  i0.ɵɵelementEnd()();
541
585
  } if (rf & 2) {
542
586
  let tmp_5_0;
@@ -546,10 +590,10 @@ function ConversationChatAreaComponent_Conditional_13_Conditional_4_Template(rf,
546
590
  i0.ɵɵproperty("emptyStateMode", true)("initialDraft", ctx_r0.GetInitialDraftFor(null))("currentUser", ctx_r0.currentUser)("disabled", ctx_r0.isProcessing)("ReadOnly", ctx_r0.EffectiveReadOnly)("appContext", ctx_r0.appContext)("applicationId", ctx_r0.applicationId)("defaultAgentId", ctx_r0.defaultAgentId)("enableAttachments", ctx_r0.enableAttachments && ctx_r0.allowAttachments)("enableMentions", ctx_r0.allowMentions)("enableAgentMentions", ctx_r0.allowAgentMentions)("enableEntityMentions", ctx_r0.allowEntityMentions)("enableSkillCommands", ctx_r0.allowSkillCommands)("enablePlanMode", ctx_r0.allowPlanMode)("enableRealtime", ctx_r0.allowRealtime)("AllowedAgentIDs", ctx_r0.AllowedAgentIDs)("MentionPeople", ctx_r0.MentionPeople)("maxAttachments", ctx_r0.maxAttachments)("maxAttachmentSizeBytes", ctx_r0.maxAttachmentSizeBytes)("acceptedFileTypes", ctx_r0.acceptedFileTypes);
547
591
  } }
548
592
  function ConversationChatAreaComponent_Conditional_13_Template(rf, ctx) { if (rf & 1) {
549
- i0.ɵɵelementStart(0, "div", 15);
550
- i0.ɵɵelement(1, "div", 91);
551
- i0.ɵɵelementStart(2, "div", 92);
552
- i0.ɵɵconditionalCreate(3, ConversationChatAreaComponent_Conditional_13_Conditional_3_Template, 4, 1, "div", 87)(4, ConversationChatAreaComponent_Conditional_13_Conditional_4_Template, 4, 21);
593
+ i0.ɵɵelementStart(0, "div", 16);
594
+ i0.ɵɵelement(1, "div", 98);
595
+ i0.ɵɵelementStart(2, "div", 99);
596
+ i0.ɵɵconditionalCreate(3, ConversationChatAreaComponent_Conditional_13_Conditional_3_Template, 4, 1, "div", 94)(4, ConversationChatAreaComponent_Conditional_13_Conditional_4_Template, 4, 21);
553
597
  i0.ɵɵelementEnd()();
554
598
  } if (rf & 2) {
555
599
  const ctx_r0 = i0.ɵɵnextContext();
@@ -560,10 +604,10 @@ function ConversationChatAreaComponent_Conditional_14_Conditional_1_ng_container
560
604
  i0.ɵɵelementContainer(0);
561
605
  } }
562
606
  function ConversationChatAreaComponent_Conditional_14_Conditional_1_Template(rf, ctx) { if (rf & 1) {
563
- const _r24 = i0.ɵɵgetCurrentView();
564
- i0.ɵɵelementStart(0, "div", 102);
565
- i0.ɵɵlistener("keydown.escape", function ConversationChatAreaComponent_Conditional_14_Conditional_1_Template_div_keydown_escape_0_listener($event) { i0.ɵɵrestoreView(_r24); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.OnViewEscape($event)); });
566
- i0.ɵɵtemplate(1, ConversationChatAreaComponent_Conditional_14_Conditional_1_ng_container_1_Template, 1, 0, "ng-container", 46);
607
+ const _r25 = i0.ɵɵgetCurrentView();
608
+ i0.ɵɵelementStart(0, "div", 109);
609
+ i0.ɵɵlistener("keydown.escape", function ConversationChatAreaComponent_Conditional_14_Conditional_1_Template_div_keydown_escape_0_listener($event) { i0.ɵɵrestoreView(_r25); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.OnViewEscape($event)); });
610
+ i0.ɵɵtemplate(1, ConversationChatAreaComponent_Conditional_14_Conditional_1_ng_container_1_Template, 1, 0, "ng-container", 48);
567
611
  i0.ɵɵelementEnd();
568
612
  } if (rf & 2) {
569
613
  i0.ɵɵnextContext(2);
@@ -572,8 +616,8 @@ function ConversationChatAreaComponent_Conditional_14_Conditional_1_Template(rf,
572
616
  i0.ɵɵproperty("ngTemplateOutlet", titleBar_r4);
573
617
  } }
574
618
  function ConversationChatAreaComponent_Conditional_14_Conditional_2_Template(rf, ctx) { if (rf & 1) {
575
- i0.ɵɵelementStart(0, "div", 97);
576
- i0.ɵɵelement(1, "mj-loading", 103);
619
+ i0.ɵɵelementStart(0, "div", 104);
620
+ i0.ɵɵelement(1, "mj-loading", 110);
577
621
  i0.ɵɵelementEnd();
578
622
  } if (rf & 2) {
579
623
  const ctx_r0 = i0.ɵɵnextContext(2);
@@ -581,20 +625,20 @@ function ConversationChatAreaComponent_Conditional_14_Conditional_2_Template(rf,
581
625
  i0.ɵɵproperty("text", ctx_r0.uploadingMessage);
582
626
  } }
583
627
  function ConversationChatAreaComponent_Conditional_14_Conditional_6_Template(rf, ctx) { if (rf & 1) {
584
- const _r25 = i0.ɵɵgetCurrentView();
585
- i0.ɵɵelementStart(0, "span", 104);
586
- i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_14_Conditional_6_Template_span_click_0_listener() { i0.ɵɵrestoreView(_r25); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.scrollToBottomAnimate()); });
587
- i0.ɵɵelement(1, "i", 105);
628
+ const _r26 = i0.ɵɵgetCurrentView();
629
+ i0.ɵɵelementStart(0, "span", 111);
630
+ i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_14_Conditional_6_Template_span_click_0_listener() { i0.ɵɵrestoreView(_r26); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.scrollToBottomAnimate()); });
631
+ i0.ɵɵelement(1, "i", 112);
588
632
  i0.ɵɵelementEnd();
589
633
  } }
590
634
  function ConversationChatAreaComponent_Conditional_14_Conditional_8_Template(rf, ctx) { if (rf & 1) {
591
- i0.ɵɵelementStart(0, "div", 101);
592
- i0.ɵɵelement(1, "mj-loading", 106);
635
+ i0.ɵɵelementStart(0, "div", 108);
636
+ i0.ɵɵelement(1, "mj-loading", 113);
593
637
  i0.ɵɵelementEnd();
594
638
  } }
595
639
  function ConversationChatAreaComponent_Conditional_14_Conditional_9_Template(rf, ctx) { if (rf & 1) {
596
- i0.ɵɵelementStart(0, "div", 87);
597
- i0.ɵɵelement(1, "i", 89);
640
+ i0.ɵɵelementStart(0, "div", 94);
641
+ i0.ɵɵelement(1, "i", 96);
598
642
  i0.ɵɵelementStart(2, "span");
599
643
  i0.ɵɵtext(3);
600
644
  i0.ɵɵelementEnd()();
@@ -604,8 +648,8 @@ function ConversationChatAreaComponent_Conditional_14_Conditional_9_Template(rf,
604
648
  i0.ɵɵtextInterpolate(ctx_r0.ReadOnlyMessage || "You have view-only access to this conversation.");
605
649
  } }
606
650
  function ConversationChatAreaComponent_Conditional_14_Conditional_10_Conditional_0_Template(rf, ctx) { if (rf & 1) {
607
- i0.ɵɵelementStart(0, "div", 87);
608
- i0.ɵɵelement(1, "i", 89);
651
+ i0.ɵɵelementStart(0, "div", 94);
652
+ i0.ɵɵelement(1, "i", 96);
609
653
  i0.ɵɵelementStart(2, "span");
610
654
  i0.ɵɵtext(3, "You have view-only access to this conversation.");
611
655
  i0.ɵɵelementEnd()();
@@ -614,26 +658,26 @@ function ConversationChatAreaComponent_Conditional_14_Conditional_10_Conditional
614
658
  i0.ɵɵelementContainer(0);
615
659
  } }
616
660
  function ConversationChatAreaComponent_Conditional_14_Conditional_10_Conditional_1_Template(rf, ctx) { if (rf & 1) {
617
- i0.ɵɵelementStart(0, "div", 93);
618
- i0.ɵɵtemplate(1, ConversationChatAreaComponent_Conditional_14_Conditional_10_Conditional_1_ng_container_1_Template, 1, 0, "ng-container", 28);
661
+ i0.ɵɵelementStart(0, "div", 100);
662
+ i0.ɵɵtemplate(1, ConversationChatAreaComponent_Conditional_14_Conditional_10_Conditional_1_ng_container_1_Template, 1, 0, "ng-container", 29);
619
663
  i0.ɵɵelementEnd();
620
664
  } if (rf & 2) {
621
665
  const ctx_r0 = i0.ɵɵnextContext(3);
622
666
  i0.ɵɵadvance();
623
- i0.ɵɵproperty("ngTemplateOutlet", ctx)("ngTemplateOutletContext", i0.ɵɵpureFunction3(2, _c11, ctx_r0.conversation, ctx_r0.conversationId, ctx_r0.isProcessing));
667
+ i0.ɵɵproperty("ngTemplateOutlet", ctx)("ngTemplateOutletContext", i0.ɵɵpureFunction3(2, _c12, ctx_r0.conversation, ctx_r0.conversationId, ctx_r0.isProcessing));
624
668
  } }
625
669
  function ConversationChatAreaComponent_Conditional_14_Conditional_10_For_4_Template(rf, ctx) { if (rf & 1) {
626
- const _r26 = i0.ɵɵgetCurrentView();
627
- i0.ɵɵelementStart(0, "mj-message-input", 109, 7);
628
- i0.ɵɵlistener("DraftStateChanged", function ConversationChatAreaComponent_Conditional_14_Conditional_10_For_4_Template_mj_message_input_DraftStateChanged_0_listener($event) { const inputRef_r27 = i0.ɵɵrestoreView(_r26).$implicit; const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.OnDraftStateChanged(inputRef_r27.conversationId, $event)); })("ComposerBlurred", function ConversationChatAreaComponent_Conditional_14_Conditional_10_For_4_Template_mj_message_input_ComposerBlurred_0_listener() { i0.ɵɵrestoreView(_r26); const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.OnComposerBlurred()); })("StopClicked", function ConversationChatAreaComponent_Conditional_14_Conditional_10_For_4_Template_mj_message_input_StopClicked_0_listener() { i0.ɵɵrestoreView(_r26); const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.OnComposerStopClicked()); })("initialMessageAutoSendStarted", function ConversationChatAreaComponent_Conditional_14_Conditional_10_For_4_Template_mj_message_input_initialMessageAutoSendStarted_0_listener($event) { i0.ɵɵrestoreView(_r26); const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.onInitialMessageAutoSendStarted($event)); })("initialMessageAutoSendFailed", function ConversationChatAreaComponent_Conditional_14_Conditional_10_For_4_Template_mj_message_input_initialMessageAutoSendFailed_0_listener($event) { i0.ɵɵrestoreView(_r26); const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.onInitialMessageAutoSendFailed($event)); })("messageSent", function ConversationChatAreaComponent_Conditional_14_Conditional_10_For_4_Template_mj_message_input_messageSent_0_listener($event) { i0.ɵɵrestoreView(_r26); const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.onMessageSent($event)); })("MessageStreamed", function ConversationChatAreaComponent_Conditional_14_Conditional_10_For_4_Template_mj_message_input_MessageStreamed_0_listener($event) { i0.ɵɵrestoreView(_r26); const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.OnMessageStreamed($event)); })("agentResponse", function ConversationChatAreaComponent_Conditional_14_Conditional_10_For_4_Template_mj_message_input_agentResponse_0_listener($event) { i0.ɵɵrestoreView(_r26); const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.onAgentResponse($event)); })("agentRunDetected", function ConversationChatAreaComponent_Conditional_14_Conditional_10_For_4_Template_mj_message_input_agentRunDetected_0_listener($event) { i0.ɵɵrestoreView(_r26); const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.onAgentRunDetected($event)); })("agentRunUpdate", function ConversationChatAreaComponent_Conditional_14_Conditional_10_For_4_Template_mj_message_input_agentRunUpdate_0_listener($event) { i0.ɵɵrestoreView(_r26); const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.onAgentRunUpdate($event)); })("messageComplete", function ConversationChatAreaComponent_Conditional_14_Conditional_10_For_4_Template_mj_message_input_messageComplete_0_listener($event) { i0.ɵɵrestoreView(_r26); const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.onMessageComplete($event)); })("artifactCreated", function ConversationChatAreaComponent_Conditional_14_Conditional_10_For_4_Template_mj_message_input_artifactCreated_0_listener($event) { i0.ɵɵrestoreView(_r26); const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.onArtifactCreated($event)); })("conversationRenamed", function ConversationChatAreaComponent_Conditional_14_Conditional_10_For_4_Template_mj_message_input_conversationRenamed_0_listener($event) { i0.ɵɵrestoreView(_r26); const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.onConversationRenamed($event)); })("intentCheckStarted", function ConversationChatAreaComponent_Conditional_14_Conditional_10_For_4_Template_mj_message_input_intentCheckStarted_0_listener($event) { i0.ɵɵrestoreView(_r26); const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.onIntentCheckStarted($event)); })("intentCheckCompleted", function ConversationChatAreaComponent_Conditional_14_Conditional_10_For_4_Template_mj_message_input_intentCheckCompleted_0_listener($event) { i0.ɵɵrestoreView(_r26); const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.onIntentCheckCompleted($event)); })("beforeAgentTurn", function ConversationChatAreaComponent_Conditional_14_Conditional_10_For_4_Template_mj_message_input_beforeAgentTurn_0_listener($event) { i0.ɵɵrestoreView(_r26); const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.beforeAgentTurn.emit($event)); })("afterAgentTurn", function ConversationChatAreaComponent_Conditional_14_Conditional_10_For_4_Template_mj_message_input_afterAgentTurn_0_listener($event) { i0.ɵɵrestoreView(_r26); const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.afterAgentTurn.emit($event)); })("uploadStateChanged", function ConversationChatAreaComponent_Conditional_14_Conditional_10_For_4_Template_mj_message_input_uploadStateChanged_0_listener($event) { i0.ɵɵrestoreView(_r26); const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.onUploadStateChanged($event)); });
670
+ const _r27 = i0.ɵɵgetCurrentView();
671
+ i0.ɵɵelementStart(0, "mj-message-input", 116, 7);
672
+ i0.ɵɵlistener("DraftStateChanged", function ConversationChatAreaComponent_Conditional_14_Conditional_10_For_4_Template_mj_message_input_DraftStateChanged_0_listener($event) { const inputRef_r28 = i0.ɵɵrestoreView(_r27).$implicit; const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.OnDraftStateChanged(inputRef_r28.conversationId, $event)); })("ComposerBlurred", function ConversationChatAreaComponent_Conditional_14_Conditional_10_For_4_Template_mj_message_input_ComposerBlurred_0_listener() { i0.ɵɵrestoreView(_r27); const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.OnComposerBlurred()); })("StopClicked", function ConversationChatAreaComponent_Conditional_14_Conditional_10_For_4_Template_mj_message_input_StopClicked_0_listener() { i0.ɵɵrestoreView(_r27); const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.OnComposerStopClicked()); })("initialMessageAutoSendStarted", function ConversationChatAreaComponent_Conditional_14_Conditional_10_For_4_Template_mj_message_input_initialMessageAutoSendStarted_0_listener($event) { i0.ɵɵrestoreView(_r27); const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.onInitialMessageAutoSendStarted($event)); })("initialMessageAutoSendFailed", function ConversationChatAreaComponent_Conditional_14_Conditional_10_For_4_Template_mj_message_input_initialMessageAutoSendFailed_0_listener($event) { i0.ɵɵrestoreView(_r27); const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.onInitialMessageAutoSendFailed($event)); })("messageSent", function ConversationChatAreaComponent_Conditional_14_Conditional_10_For_4_Template_mj_message_input_messageSent_0_listener($event) { i0.ɵɵrestoreView(_r27); const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.onMessageSent($event)); })("MessageStreamed", function ConversationChatAreaComponent_Conditional_14_Conditional_10_For_4_Template_mj_message_input_MessageStreamed_0_listener($event) { i0.ɵɵrestoreView(_r27); const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.OnMessageStreamed($event)); })("agentResponse", function ConversationChatAreaComponent_Conditional_14_Conditional_10_For_4_Template_mj_message_input_agentResponse_0_listener($event) { i0.ɵɵrestoreView(_r27); const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.onAgentResponse($event)); })("agentRunDetected", function ConversationChatAreaComponent_Conditional_14_Conditional_10_For_4_Template_mj_message_input_agentRunDetected_0_listener($event) { i0.ɵɵrestoreView(_r27); const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.onAgentRunDetected($event)); })("agentRunUpdate", function ConversationChatAreaComponent_Conditional_14_Conditional_10_For_4_Template_mj_message_input_agentRunUpdate_0_listener($event) { i0.ɵɵrestoreView(_r27); const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.onAgentRunUpdate($event)); })("messageComplete", function ConversationChatAreaComponent_Conditional_14_Conditional_10_For_4_Template_mj_message_input_messageComplete_0_listener($event) { i0.ɵɵrestoreView(_r27); const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.onMessageComplete($event)); })("artifactCreated", function ConversationChatAreaComponent_Conditional_14_Conditional_10_For_4_Template_mj_message_input_artifactCreated_0_listener($event) { i0.ɵɵrestoreView(_r27); const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.onArtifactCreated($event)); })("conversationRenamed", function ConversationChatAreaComponent_Conditional_14_Conditional_10_For_4_Template_mj_message_input_conversationRenamed_0_listener($event) { i0.ɵɵrestoreView(_r27); const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.onConversationRenamed($event)); })("intentCheckStarted", function ConversationChatAreaComponent_Conditional_14_Conditional_10_For_4_Template_mj_message_input_intentCheckStarted_0_listener($event) { i0.ɵɵrestoreView(_r27); const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.onIntentCheckStarted($event)); })("intentCheckCompleted", function ConversationChatAreaComponent_Conditional_14_Conditional_10_For_4_Template_mj_message_input_intentCheckCompleted_0_listener($event) { i0.ɵɵrestoreView(_r27); const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.onIntentCheckCompleted($event)); })("beforeAgentTurn", function ConversationChatAreaComponent_Conditional_14_Conditional_10_For_4_Template_mj_message_input_beforeAgentTurn_0_listener($event) { i0.ɵɵrestoreView(_r27); const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.beforeAgentTurn.emit($event)); })("afterAgentTurn", function ConversationChatAreaComponent_Conditional_14_Conditional_10_For_4_Template_mj_message_input_afterAgentTurn_0_listener($event) { i0.ɵɵrestoreView(_r27); const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.afterAgentTurn.emit($event)); })("uploadStateChanged", function ConversationChatAreaComponent_Conditional_14_Conditional_10_For_4_Template_mj_message_input_uploadStateChanged_0_listener($event) { i0.ɵɵrestoreView(_r27); const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.onUploadStateChanged($event)); });
629
673
  i0.ɵɵelementEnd();
630
674
  } if (rf & 2) {
631
- const inputRef_r27 = ctx.$implicit;
675
+ const inputRef_r28 = ctx.$implicit;
632
676
  const ctx_r0 = i0.ɵɵnextContext(3);
633
- i0.ɵɵproperty("hidden", inputRef_r27.conversationId !== ctx_r0.conversationId)("initialDraft", ctx_r0.GetInitialDraftFor(inputRef_r27.conversationId))("conversationId", inputRef_r27.conversationId)("conversationName", inputRef_r27.conversationName)("currentUser", ctx_r0.currentUser)("conversationHistory", inputRef_r27.conversationId === ctx_r0.conversationId ? ctx_r0.messages : i0.ɵɵpureFunction0(44, _c9))("artifactsByDetailId", inputRef_r27.conversationId === ctx_r0.conversationId ? ctx_r0.artifactsByDetailId : ctx_r0.emptyArtifactsMap)("systemArtifactsByDetailId", inputRef_r27.conversationId === ctx_r0.conversationId ? ctx_r0.systemArtifactsByDetailId : ctx_r0.emptyArtifactsMap)("agentRunsByDetailId", inputRef_r27.conversationId === ctx_r0.conversationId ? ctx_r0.agentRunsByDetailId : ctx_r0.emptyAgentRunsMap)("appContext", ctx_r0.appContext)("applicationId", ctx_r0.applicationId)("defaultAgentId", ctx_r0.defaultAgentId)("conversationDefaultAgentId", inputRef_r27.conversationId === ctx_r0.conversationId ? (ctx_r0.conversation == null ? null : ctx_r0.conversation.DefaultAgentID) ?? null : null)("agentConfigurationPresetId", inputRef_r27.conversationId === ctx_r0.conversationId ? ctx_r0.ActiveAgentConfigurationPresetId : null)("AgentReplyMode", ctx_r0.AgentReplyMode)("AllowedAgentIDs", ctx_r0.AllowedAgentIDs)("MentionPeople", ctx_r0.MentionPeople)("AgentHistoryFrom", ctx_r0.AgentHistoryFrom)("TargetBranchID", ctx_r0.TargetBranchIdFor(inputRef_r27.conversationId))("ResolveTargetBranch", inputRef_r27.conversationId === ctx_r0.conversationId ? ctx_r0.ResolveComposerBranch : null)("AgentTurnHandler", ctx_r0.AgentTurnHandler)("AutoNameConversation", ctx_r0.AutoNameConversation)("EnableDecisionRouting", ctx_r0.EnableDecisionRouting)("inProgressMessageIds", inputRef_r27.conversationId === ctx_r0.conversationId ? ctx_r0.inProgressMessageIds : ctx_r0.emptyInProgressIds)("disabled", ctx_r0.isProcessing || ctx_r0.isReadOnlyView)("ReadOnly", ctx_r0.EffectiveReadOnly)("enableAttachments", ctx_r0.enableAttachments && ctx_r0.allowAttachments)("enableMentions", ctx_r0.allowMentions)("enableAgentMentions", ctx_r0.allowAgentMentions)("enableEntityMentions", ctx_r0.allowEntityMentions)("enableSkillCommands", ctx_r0.allowSkillCommands)("enablePlanMode", ctx_r0.allowPlanMode)("enableRealtime", ctx_r0.allowRealtime && ctx_r0.OpenView.Kind !== "DraftFork")("Placeholder", ctx_r0.ComposerPlaceholderFor(inputRef_r27.conversationId))("SendSlotMode", inputRef_r27.conversationId === ctx_r0.conversationId ? ctx_r0.SendSlotMode : "send")("StopCount", inputRef_r27.conversationId === ctx_r0.conversationId ? ctx_r0.StopCount : 0)("StopLabel", ctx_r0.StopLabel)("StatusText", inputRef_r27.conversationId === ctx_r0.conversationId ? ctx_r0.StatusText : null)("StatusElapsed", inputRef_r27.conversationId === ctx_r0.conversationId ? ctx_r0.StatusElapsed : null)("maxAttachments", ctx_r0.maxAttachments)("maxAttachmentSizeBytes", ctx_r0.maxAttachmentSizeBytes)("acceptedFileTypes", ctx_r0.acceptedFileTypes)("initialMessage", ctx_r0.shouldDeliverPendingMessageTo(inputRef_r27.conversationId) ? ctx_r0.pendingMessage : null)("initialAttachments", ctx_r0.shouldDeliverPendingMessageTo(inputRef_r27.conversationId) ? ctx_r0.pendingAttachments : null);
677
+ i0.ɵɵproperty("hidden", inputRef_r28.conversationId !== ctx_r0.conversationId)("initialDraft", ctx_r0.GetInitialDraftFor(inputRef_r28.conversationId))("conversationId", inputRef_r28.conversationId)("conversationName", inputRef_r28.conversationName)("currentUser", ctx_r0.currentUser)("conversationHistory", inputRef_r28.conversationId === ctx_r0.conversationId ? ctx_r0.messages : i0.ɵɵpureFunction0(44, _c10))("artifactsByDetailId", inputRef_r28.conversationId === ctx_r0.conversationId ? ctx_r0.artifactsByDetailId : ctx_r0.emptyArtifactsMap)("systemArtifactsByDetailId", inputRef_r28.conversationId === ctx_r0.conversationId ? ctx_r0.systemArtifactsByDetailId : ctx_r0.emptyArtifactsMap)("agentRunsByDetailId", inputRef_r28.conversationId === ctx_r0.conversationId ? ctx_r0.agentRunsByDetailId : ctx_r0.emptyAgentRunsMap)("appContext", ctx_r0.EffectiveAppContext)("applicationId", ctx_r0.applicationId)("defaultAgentId", ctx_r0.defaultAgentId)("conversationDefaultAgentId", inputRef_r28.conversationId === ctx_r0.conversationId ? (ctx_r0.conversation == null ? null : ctx_r0.conversation.DefaultAgentID) ?? null : null)("agentConfigurationPresetId", inputRef_r28.conversationId === ctx_r0.conversationId ? ctx_r0.ActiveAgentConfigurationPresetId : null)("AgentReplyMode", ctx_r0.AgentReplyMode)("AllowedAgentIDs", ctx_r0.AllowedAgentIDs)("MentionPeople", ctx_r0.MentionPeople)("AgentHistoryFrom", ctx_r0.AgentHistoryFrom)("TargetBranchID", ctx_r0.TargetBranchIdFor(inputRef_r28.conversationId))("ResolveTargetBranch", inputRef_r28.conversationId === ctx_r0.conversationId ? ctx_r0.ResolveComposerBranch : null)("AgentTurnHandler", ctx_r0.AgentTurnHandler)("AutoNameConversation", ctx_r0.AutoNameConversation)("EnableDecisionRouting", ctx_r0.EnableDecisionRouting)("inProgressMessageIds", inputRef_r28.conversationId === ctx_r0.conversationId ? ctx_r0.inProgressMessageIds : ctx_r0.emptyInProgressIds)("disabled", ctx_r0.isProcessing || ctx_r0.isReadOnlyView)("ReadOnly", ctx_r0.EffectiveReadOnly)("enableAttachments", ctx_r0.enableAttachments && ctx_r0.allowAttachments)("enableMentions", ctx_r0.allowMentions)("enableAgentMentions", ctx_r0.allowAgentMentions)("enableEntityMentions", ctx_r0.allowEntityMentions)("enableSkillCommands", ctx_r0.allowSkillCommands)("enablePlanMode", ctx_r0.allowPlanMode)("enableRealtime", ctx_r0.allowRealtime && ctx_r0.OpenView.Kind !== "DraftFork")("Placeholder", ctx_r0.ComposerPlaceholderFor(inputRef_r28.conversationId))("SendSlotMode", inputRef_r28.conversationId === ctx_r0.conversationId ? ctx_r0.SendSlotMode : "send")("StopCount", inputRef_r28.conversationId === ctx_r0.conversationId ? ctx_r0.StopCount : 0)("StopLabel", ctx_r0.StopLabel)("StatusText", inputRef_r28.conversationId === ctx_r0.conversationId ? ctx_r0.StatusText : null)("StatusElapsed", inputRef_r28.conversationId === ctx_r0.conversationId ? ctx_r0.StatusElapsed : null)("maxAttachments", ctx_r0.maxAttachments)("maxAttachmentSizeBytes", ctx_r0.maxAttachmentSizeBytes)("acceptedFileTypes", ctx_r0.acceptedFileTypes)("initialMessage", ctx_r0.shouldDeliverPendingMessageTo(inputRef_r28.conversationId) ? ctx_r0.pendingMessage : null)("initialAttachments", ctx_r0.shouldDeliverPendingMessageTo(inputRef_r28.conversationId) ? ctx_r0.pendingAttachments : null);
634
678
  } }
635
679
  function ConversationChatAreaComponent_Conditional_14_Conditional_10_Conditional_5_Template(rf, ctx) { if (rf & 1) {
636
- i0.ɵɵelementStart(0, "div", 108);
680
+ i0.ɵɵelementStart(0, "div", 115);
637
681
  i0.ɵɵtext(1);
638
682
  i0.ɵɵelementEnd();
639
683
  } if (rf & 2) {
@@ -642,12 +686,12 @@ function ConversationChatAreaComponent_Conditional_14_Conditional_10_Conditional
642
686
  i0.ɵɵtextInterpolate(ctx_r0.ComposerHint);
643
687
  } }
644
688
  function ConversationChatAreaComponent_Conditional_14_Conditional_10_Template(rf, ctx) { if (rf & 1) {
645
- i0.ɵɵconditionalCreate(0, ConversationChatAreaComponent_Conditional_14_Conditional_10_Conditional_0_Template, 4, 0, "div", 87);
646
- i0.ɵɵconditionalCreate(1, ConversationChatAreaComponent_Conditional_14_Conditional_10_Conditional_1_Template, 2, 6, "div", 93);
647
- i0.ɵɵelementStart(2, "div", 94);
648
- i0.ɵɵrepeaterCreate(3, ConversationChatAreaComponent_Conditional_14_Conditional_10_For_4_Template, 2, 45, "mj-message-input", 107, _forTrack0);
689
+ i0.ɵɵconditionalCreate(0, ConversationChatAreaComponent_Conditional_14_Conditional_10_Conditional_0_Template, 4, 0, "div", 94);
690
+ i0.ɵɵconditionalCreate(1, ConversationChatAreaComponent_Conditional_14_Conditional_10_Conditional_1_Template, 2, 6, "div", 100);
691
+ i0.ɵɵelementStart(2, "div", 101);
692
+ i0.ɵɵrepeaterCreate(3, ConversationChatAreaComponent_Conditional_14_Conditional_10_For_4_Template, 2, 45, "mj-message-input", 114, _forTrack0, true);
649
693
  i0.ɵɵelementEnd();
650
- i0.ɵɵconditionalCreate(5, ConversationChatAreaComponent_Conditional_14_Conditional_10_Conditional_5_Template, 2, 1, "div", 108);
694
+ i0.ɵɵconditionalCreate(5, ConversationChatAreaComponent_Conditional_14_Conditional_10_Conditional_5_Template, 2, 1, "div", 115);
651
695
  } if (rf & 2) {
652
696
  let tmp_6_0;
653
697
  const ctx_r0 = i0.ɵɵnextContext(2);
@@ -660,19 +704,19 @@ function ConversationChatAreaComponent_Conditional_14_Conditional_10_Template(rf
660
704
  i0.ɵɵconditional(ctx_r0.ComposerHint ? 5 : -1);
661
705
  } }
662
706
  function ConversationChatAreaComponent_Conditional_14_Template(rf, ctx) { if (rf & 1) {
663
- const _r23 = i0.ɵɵgetCurrentView();
664
- i0.ɵɵelementStart(0, "div", 15);
665
- i0.ɵɵconditionalCreate(1, ConversationChatAreaComponent_Conditional_14_Conditional_1_Template, 2, 1, "div", 96);
666
- i0.ɵɵconditionalCreate(2, ConversationChatAreaComponent_Conditional_14_Conditional_2_Template, 2, 1, "div", 97);
667
- i0.ɵɵelementStart(3, "div", 98, 6);
668
- i0.ɵɵlistener("scroll", function ConversationChatAreaComponent_Conditional_14_Template_div_scroll_3_listener() { i0.ɵɵrestoreView(_r23); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.checkScroll()); })("keydown.escape", function ConversationChatAreaComponent_Conditional_14_Template_div_keydown_escape_3_listener($event) { i0.ɵɵrestoreView(_r23); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.OnViewEscape($event)); });
669
- i0.ɵɵelementStart(5, "mj-conversation-message-list", 99);
670
- i0.ɵɵlistener("OlderRequested", function ConversationChatAreaComponent_Conditional_14_Template_mj_conversation_message_list_OlderRequested_5_listener() { i0.ɵɵrestoreView(_r23); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onOlderMessagesRequested()); })("DateJumpRequested", function ConversationChatAreaComponent_Conditional_14_Template_mj_conversation_message_list_DateJumpRequested_5_listener($event) { i0.ɵɵrestoreView(_r23); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onDateJumpRequested($event)); })("ForkOpenRequested", function ConversationChatAreaComponent_Conditional_14_Template_mj_conversation_message_list_ForkOpenRequested_5_listener($event) { i0.ɵɵrestoreView(_r23); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.OnForkOpenRequested($event)); })("EditResendRequested", function ConversationChatAreaComponent_Conditional_14_Template_mj_conversation_message_list_EditResendRequested_5_listener($event) { i0.ɵɵrestoreView(_r23); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.OnEditResendRequested($event)); })("RegenerateRequested", function ConversationChatAreaComponent_Conditional_14_Template_mj_conversation_message_list_RegenerateRequested_5_listener($event) { i0.ɵɵrestoreView(_r23); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.OnRegenerateRequested($event)); })("ResendInPlaceRequested", function ConversationChatAreaComponent_Conditional_14_Template_mj_conversation_message_list_ResendInPlaceRequested_5_listener($event) { i0.ɵɵrestoreView(_r23); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.OnResendInPlaceRequested($event)); })("ForkRequested", function ConversationChatAreaComponent_Conditional_14_Template_mj_conversation_message_list_ForkRequested_5_listener($event) { i0.ɵɵrestoreView(_r23); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.OnForkRequested($event)); })("realtimeSessionOpenRequested", function ConversationChatAreaComponent_Conditional_14_Template_mj_conversation_message_list_realtimeSessionOpenRequested_5_listener($event) { i0.ɵɵrestoreView(_r23); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.OpenRealtimeSessionReview($event)); })("deleteMessage", function ConversationChatAreaComponent_Conditional_14_Template_mj_conversation_message_list_deleteMessage_5_listener($event) { i0.ɵɵrestoreView(_r23); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onDeleteMessage($event)); })("BeforeStopClicked", function ConversationChatAreaComponent_Conditional_14_Template_mj_conversation_message_list_BeforeStopClicked_5_listener($event) { i0.ɵɵrestoreView(_r23); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.BeforeStopClicked.emit($event)); })("StopMessage", function ConversationChatAreaComponent_Conditional_14_Template_mj_conversation_message_list_StopMessage_5_listener($event) { i0.ɵɵrestoreView(_r23); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.OnStopMessage($event)); })("testFeedbackMessage", function ConversationChatAreaComponent_Conditional_14_Template_mj_conversation_message_list_testFeedbackMessage_5_listener($event) { i0.ɵɵrestoreView(_r23); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onTestFeedbackMessage($event)); })("artifactClicked", function ConversationChatAreaComponent_Conditional_14_Template_mj_conversation_message_list_artifactClicked_5_listener($event) { i0.ɵɵrestoreView(_r23); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onArtifactClicked($event)); })("messageEdited", function ConversationChatAreaComponent_Conditional_14_Template_mj_conversation_message_list_messageEdited_5_listener($event) { i0.ɵɵrestoreView(_r23); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onMessageEdited($event)); })("openEntityRecord", function ConversationChatAreaComponent_Conditional_14_Template_mj_conversation_message_list_openEntityRecord_5_listener($event) { i0.ɵɵrestoreView(_r23); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onOpenEntityRecord($event)); })("suggestedResponseSelected", function ConversationChatAreaComponent_Conditional_14_Template_mj_conversation_message_list_suggestedResponseSelected_5_listener($event) { i0.ɵɵrestoreView(_r23); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onSuggestedResponseSelected($event)); })("attachmentClicked", function ConversationChatAreaComponent_Conditional_14_Template_mj_conversation_message_list_attachmentClicked_5_listener($event) { i0.ɵɵrestoreView(_r23); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onAttachmentClicked($event)); })("diagnosticRequested", function ConversationChatAreaComponent_Conditional_14_Template_mj_conversation_message_list_diagnosticRequested_5_listener($event) { i0.ɵɵrestoreView(_r23); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onDiagnosticRequested($event)); })("LivenessCheckRequested", function ConversationChatAreaComponent_Conditional_14_Template_mj_conversation_message_list_LivenessCheckRequested_5_listener($event) { i0.ɵɵrestoreView(_r23); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.OnLivenessCheckRequested($event)); })("messagePinToggled", function ConversationChatAreaComponent_Conditional_14_Template_mj_conversation_message_list_messagePinToggled_5_listener($event) { i0.ɵɵrestoreView(_r23); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onMessagePinToggled($event)); })("beforeResponseFormSubmitted", function ConversationChatAreaComponent_Conditional_14_Template_mj_conversation_message_list_beforeResponseFormSubmitted_5_listener($event) { i0.ɵɵrestoreView(_r23); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.beforeResponseFormSubmitted.emit($event)); })("afterResponseFormSubmitted", function ConversationChatAreaComponent_Conditional_14_Template_mj_conversation_message_list_afterResponseFormSubmitted_5_listener($event) { i0.ɵɵrestoreView(_r23); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.afterResponseFormSubmitted.emit($event)); })("TaskGraphPanelRequested", function ConversationChatAreaComponent_Conditional_14_Template_mj_conversation_message_list_TaskGraphPanelRequested_5_listener($event) { i0.ɵɵrestoreView(_r23); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.OnTaskGraphPanelRequested($event)); })("ScrollToMessageRequested", function ConversationChatAreaComponent_Conditional_14_Template_mj_conversation_message_list_ScrollToMessageRequested_5_listener($event) { i0.ɵɵrestoreView(_r23); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.OnJumpToMessage($event)); });
707
+ const _r24 = i0.ɵɵgetCurrentView();
708
+ i0.ɵɵelementStart(0, "div", 16);
709
+ i0.ɵɵconditionalCreate(1, ConversationChatAreaComponent_Conditional_14_Conditional_1_Template, 2, 1, "div", 103);
710
+ i0.ɵɵconditionalCreate(2, ConversationChatAreaComponent_Conditional_14_Conditional_2_Template, 2, 1, "div", 104);
711
+ i0.ɵɵelementStart(3, "div", 105, 6);
712
+ i0.ɵɵlistener("scroll", function ConversationChatAreaComponent_Conditional_14_Template_div_scroll_3_listener() { i0.ɵɵrestoreView(_r24); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.checkScroll()); })("keydown.escape", function ConversationChatAreaComponent_Conditional_14_Template_div_keydown_escape_3_listener($event) { i0.ɵɵrestoreView(_r24); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.OnViewEscape($event)); });
713
+ i0.ɵɵelementStart(5, "mj-conversation-message-list", 106);
714
+ i0.ɵɵlistener("OlderRequested", function ConversationChatAreaComponent_Conditional_14_Template_mj_conversation_message_list_OlderRequested_5_listener() { i0.ɵɵrestoreView(_r24); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onOlderMessagesRequested()); })("DateJumpRequested", function ConversationChatAreaComponent_Conditional_14_Template_mj_conversation_message_list_DateJumpRequested_5_listener($event) { i0.ɵɵrestoreView(_r24); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onDateJumpRequested($event)); })("ForkOpenRequested", function ConversationChatAreaComponent_Conditional_14_Template_mj_conversation_message_list_ForkOpenRequested_5_listener($event) { i0.ɵɵrestoreView(_r24); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.OnForkOpenRequested($event)); })("EditResendRequested", function ConversationChatAreaComponent_Conditional_14_Template_mj_conversation_message_list_EditResendRequested_5_listener($event) { i0.ɵɵrestoreView(_r24); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.OnEditResendRequested($event)); })("RegenerateRequested", function ConversationChatAreaComponent_Conditional_14_Template_mj_conversation_message_list_RegenerateRequested_5_listener($event) { i0.ɵɵrestoreView(_r24); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.OnRegenerateRequested($event)); })("ResendInPlaceRequested", function ConversationChatAreaComponent_Conditional_14_Template_mj_conversation_message_list_ResendInPlaceRequested_5_listener($event) { i0.ɵɵrestoreView(_r24); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.OnResendInPlaceRequested($event)); })("ForkRequested", function ConversationChatAreaComponent_Conditional_14_Template_mj_conversation_message_list_ForkRequested_5_listener($event) { i0.ɵɵrestoreView(_r24); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.OnForkRequested($event)); })("realtimeSessionOpenRequested", function ConversationChatAreaComponent_Conditional_14_Template_mj_conversation_message_list_realtimeSessionOpenRequested_5_listener($event) { i0.ɵɵrestoreView(_r24); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.OpenRealtimeSessionReview($event)); })("deleteMessage", function ConversationChatAreaComponent_Conditional_14_Template_mj_conversation_message_list_deleteMessage_5_listener($event) { i0.ɵɵrestoreView(_r24); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onDeleteMessage($event)); })("BeforeStopClicked", function ConversationChatAreaComponent_Conditional_14_Template_mj_conversation_message_list_BeforeStopClicked_5_listener($event) { i0.ɵɵrestoreView(_r24); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.BeforeStopClicked.emit($event)); })("StopMessage", function ConversationChatAreaComponent_Conditional_14_Template_mj_conversation_message_list_StopMessage_5_listener($event) { i0.ɵɵrestoreView(_r24); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.OnStopMessage($event)); })("testFeedbackMessage", function ConversationChatAreaComponent_Conditional_14_Template_mj_conversation_message_list_testFeedbackMessage_5_listener($event) { i0.ɵɵrestoreView(_r24); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onTestFeedbackMessage($event)); })("artifactClicked", function ConversationChatAreaComponent_Conditional_14_Template_mj_conversation_message_list_artifactClicked_5_listener($event) { i0.ɵɵrestoreView(_r24); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onArtifactClicked($event)); })("messageEdited", function ConversationChatAreaComponent_Conditional_14_Template_mj_conversation_message_list_messageEdited_5_listener($event) { i0.ɵɵrestoreView(_r24); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onMessageEdited($event)); })("openEntityRecord", function ConversationChatAreaComponent_Conditional_14_Template_mj_conversation_message_list_openEntityRecord_5_listener($event) { i0.ɵɵrestoreView(_r24); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onOpenEntityRecord($event)); })("suggestedResponseSelected", function ConversationChatAreaComponent_Conditional_14_Template_mj_conversation_message_list_suggestedResponseSelected_5_listener($event) { i0.ɵɵrestoreView(_r24); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onSuggestedResponseSelected($event)); })("attachmentClicked", function ConversationChatAreaComponent_Conditional_14_Template_mj_conversation_message_list_attachmentClicked_5_listener($event) { i0.ɵɵrestoreView(_r24); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onAttachmentClicked($event)); })("diagnosticRequested", function ConversationChatAreaComponent_Conditional_14_Template_mj_conversation_message_list_diagnosticRequested_5_listener($event) { i0.ɵɵrestoreView(_r24); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onDiagnosticRequested($event)); })("LivenessCheckRequested", function ConversationChatAreaComponent_Conditional_14_Template_mj_conversation_message_list_LivenessCheckRequested_5_listener($event) { i0.ɵɵrestoreView(_r24); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.OnLivenessCheckRequested($event)); })("messagePinToggled", function ConversationChatAreaComponent_Conditional_14_Template_mj_conversation_message_list_messagePinToggled_5_listener($event) { i0.ɵɵrestoreView(_r24); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onMessagePinToggled($event)); })("beforeResponseFormSubmitted", function ConversationChatAreaComponent_Conditional_14_Template_mj_conversation_message_list_beforeResponseFormSubmitted_5_listener($event) { i0.ɵɵrestoreView(_r24); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.beforeResponseFormSubmitted.emit($event)); })("afterResponseFormSubmitted", function ConversationChatAreaComponent_Conditional_14_Template_mj_conversation_message_list_afterResponseFormSubmitted_5_listener($event) { i0.ɵɵrestoreView(_r24); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.afterResponseFormSubmitted.emit($event)); })("TaskGraphPanelRequested", function ConversationChatAreaComponent_Conditional_14_Template_mj_conversation_message_list_TaskGraphPanelRequested_5_listener($event) { i0.ɵɵrestoreView(_r24); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.OnTaskGraphPanelRequested($event)); })("ScrollToMessageRequested", function ConversationChatAreaComponent_Conditional_14_Template_mj_conversation_message_list_ScrollToMessageRequested_5_listener($event) { i0.ɵɵrestoreView(_r24); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.OnJumpToMessage($event)); });
671
715
  i0.ɵɵelementEnd();
672
- i0.ɵɵconditionalCreate(6, ConversationChatAreaComponent_Conditional_14_Conditional_6_Template, 2, 0, "span", 100);
716
+ i0.ɵɵconditionalCreate(6, ConversationChatAreaComponent_Conditional_14_Conditional_6_Template, 2, 0, "span", 107);
673
717
  i0.ɵɵelementEnd();
674
- i0.ɵɵelementStart(7, "div", 92);
675
- i0.ɵɵconditionalCreate(8, ConversationChatAreaComponent_Conditional_14_Conditional_8_Template, 2, 0, "div", 101)(9, ConversationChatAreaComponent_Conditional_14_Conditional_9_Template, 4, 1, "div", 87)(10, ConversationChatAreaComponent_Conditional_14_Conditional_10_Template, 6, 3);
718
+ i0.ɵɵelementStart(7, "div", 99);
719
+ i0.ɵɵconditionalCreate(8, ConversationChatAreaComponent_Conditional_14_Conditional_8_Template, 2, 0, "div", 108)(9, ConversationChatAreaComponent_Conditional_14_Conditional_9_Template, 4, 1, "div", 94)(10, ConversationChatAreaComponent_Conditional_14_Conditional_10_Template, 6, 3);
676
720
  i0.ɵɵelementEnd()();
677
721
  } if (rf & 2) {
678
722
  const ctx_r0 = i0.ɵɵnextContext();
@@ -681,23 +725,23 @@ function ConversationChatAreaComponent_Conditional_14_Template(rf, ctx) { if (rf
681
725
  i0.ɵɵadvance();
682
726
  i0.ɵɵconditional(ctx_r0.isUploadingAttachments ? 2 : -1);
683
727
  i0.ɵɵadvance(3);
684
- i0.ɵɵproperty("showEmptyFill", ctx_r0.showEmptyFill)("showDateNavigation", ctx_r0.showDateNavigation)("showAgentRunDetails", ctx_r0.showAgentRunDetails)("showReactions", ctx_r0.showReactions)("showMessageRating", ctx_r0.showMessageRating)("allowPinning", ctx_r0.allowPinning && !ctx_r0.EffectiveReadOnly)("allowMessageEdit", ctx_r0.allowMessageEdit && !ctx_r0.EffectiveReadOnly)("allowMessageDelete", ctx_r0.allowMessageDelete && !ctx_r0.EffectiveReadOnly)("ReadOnly", ctx_r0.EffectiveReadOnly)("AllowStopRun", ctx_r0.AllowStopRun)("InFlightCount", ctx_r0.InFlightCount)("assistantDisplayName", ctx_r0.assistantDisplayName)("assistantAvatarUrl", ctx_r0.assistantAvatarUrl)("messages", ctx_r0.DisplayMessages)("HasMoreAbove", ctx_r0.ListHasMoreAbove)("IsLoadingOlder", ctx_r0.isLoadingOlderMessages)("ScrollRoot", ctx_r0.messageScrollRoot)("conversation", ctx_r0.conversation)("currentUser", ctx_r0.currentUser)("isProcessing", ctx_r0.isProcessing)("artifactMap", ctx_r0.effectiveArtifactsMap)("agentRunMap", ctx_r0.agentRunsByDetailId)("ratingsMap", ctx_r0.ratingsByDetailId)("userAvatarMap", ctx_r0.userAvatarMap)("attachmentsMap", ctx_r0.attachmentsByDetailId)("messageRendererTemplate", ctx_r0.slotTemplate("messageRenderer"))("messageExtraTemplate", ctx_r0.slotTemplate("messageExtra"))("sessionMetaMap", ctx_r0.realtimeSessionMetaMap)("ForkChipMap", ctx_r0.ForkChipMap)("ForkLayout", ctx_r0.ForkLayout)("CanFork", ctx_r0.CanFork)("InPlaceTurn", ctx_r0.InPlaceTurn);
728
+ i0.ɵɵproperty("showEmptyFill", ctx_r0.showEmptyFill)("showDateNavigation", ctx_r0.showDateNavigation)("showAgentRunDetails", ctx_r0.showAgentRunDetails)("showReactions", ctx_r0.showReactions)("showMessageRating", ctx_r0.showMessageRating)("allowPinning", ctx_r0.allowPinning && !ctx_r0.EffectiveReadOnly)("allowMessageEdit", ctx_r0.allowMessageEdit && !ctx_r0.EffectiveReadOnly)("allowMessageDelete", ctx_r0.allowMessageDelete && !ctx_r0.EffectiveReadOnly)("ReadOnly", ctx_r0.EffectiveReadOnly)("AllowStopRun", ctx_r0.AllowStopRun)("InFlightCount", ctx_r0.InFlightCount)("assistantDisplayName", ctx_r0.assistantDisplayName)("assistantAvatarUrl", ctx_r0.assistantAvatarUrl)("messages", ctx_r0.DisplayMessages)("HasMoreAbove", ctx_r0.ListHasMoreAbove)("IsLoadingOlder", ctx_r0.isLoadingOlderMessages)("ScrollRoot", ctx_r0.messageScrollRoot)("conversation", ctx_r0.conversation)("currentUser", ctx_r0.currentUser)("isProcessing", ctx_r0.isProcessing)("artifactMap", ctx_r0.effectiveArtifactsMap)("agentRunMap", ctx_r0.agentRunsByDetailId)("HandoffMap", ctx_r0.HandoffsByDetailId)("ratingsMap", ctx_r0.ratingsByDetailId)("userAvatarMap", ctx_r0.userAvatarMap)("attachmentsMap", ctx_r0.attachmentsByDetailId)("messageRendererTemplate", ctx_r0.slotTemplate("messageRenderer"))("messageExtraTemplate", ctx_r0.slotTemplate("messageExtra"))("sessionMetaMap", ctx_r0.realtimeSessionMetaMap)("ForkChipMap", ctx_r0.ForkChipMap)("ForkLayout", ctx_r0.ForkLayout)("CanFork", ctx_r0.CanFork)("InPlaceTurn", ctx_r0.InPlaceTurn);
685
729
  i0.ɵɵadvance();
686
730
  i0.ɵɵconditional(ctx_r0.showScrollToBottomIcon && ctx_r0.DisplayMessages.length > 0 ? 6 : -1);
687
731
  i0.ɵɵadvance(2);
688
732
  i0.ɵɵconditional(ctx_r0.isLoadingPeripheralData ? 8 : ctx_r0.ReadOnly ? 9 : 10);
689
733
  } }
690
734
  function ConversationChatAreaComponent_Conditional_15_Conditional_0_Template(rf, ctx) { if (rf & 1) {
691
- const _r29 = i0.ɵɵgetCurrentView();
692
- i0.ɵɵelementStart(0, "div", 113);
693
- i0.ɵɵlistener("mousedown", function ConversationChatAreaComponent_Conditional_15_Conditional_0_Template_div_mousedown_0_listener($event) { i0.ɵɵrestoreView(_r29); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.onResizeStart($event)); })("touchstart", function ConversationChatAreaComponent_Conditional_15_Conditional_0_Template_div_touchstart_0_listener($event) { i0.ɵɵrestoreView(_r29); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.onResizeTouchStart($event)); });
735
+ const _r30 = i0.ɵɵgetCurrentView();
736
+ i0.ɵɵelementStart(0, "div", 120);
737
+ i0.ɵɵlistener("mousedown", function ConversationChatAreaComponent_Conditional_15_Conditional_0_Template_div_mousedown_0_listener($event) { i0.ɵɵrestoreView(_r30); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.onResizeStart($event)); })("touchstart", function ConversationChatAreaComponent_Conditional_15_Conditional_0_Template_div_touchstart_0_listener($event) { i0.ɵɵrestoreView(_r30); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.onResizeTouchStart($event)); });
694
738
  i0.ɵɵelementEnd();
695
739
  } }
696
740
  function ConversationChatAreaComponent_Conditional_15_Template(rf, ctx) { if (rf & 1) {
697
- const _r28 = i0.ɵɵgetCurrentView();
698
- i0.ɵɵconditionalCreate(0, ConversationChatAreaComponent_Conditional_15_Conditional_0_Template, 1, 0, "div", 110);
699
- i0.ɵɵelementStart(1, "div", 111)(2, "mj-artifact-viewer-panel", 112);
700
- i0.ɵɵlistener("closed", function ConversationChatAreaComponent_Conditional_15_Template_mj_artifact_viewer_panel_closed_2_listener() { i0.ɵɵrestoreView(_r28); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onCloseArtifactPanel()); })("saveToCollectionRequested", function ConversationChatAreaComponent_Conditional_15_Template_mj_artifact_viewer_panel_saveToCollectionRequested_2_listener($event) { i0.ɵɵrestoreView(_r28); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onSaveToCollectionRequested($event)); })("navigateToLink", function ConversationChatAreaComponent_Conditional_15_Template_mj_artifact_viewer_panel_navigateToLink_2_listener($event) { i0.ɵɵrestoreView(_r28); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onArtifactLinkNavigation($event)); })("shareRequested", function ConversationChatAreaComponent_Conditional_15_Template_mj_artifact_viewer_panel_shareRequested_2_listener($event) { i0.ɵɵrestoreView(_r28); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onArtifactShareRequested($event)); })("maximizeToggled", function ConversationChatAreaComponent_Conditional_15_Template_mj_artifact_viewer_panel_maximizeToggled_2_listener() { i0.ɵɵrestoreView(_r28); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.toggleMaximizeArtifactPane()); })("openEntityRecord", function ConversationChatAreaComponent_Conditional_15_Template_mj_artifact_viewer_panel_openEntityRecord_2_listener($event) { i0.ɵɵrestoreView(_r28); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onOpenEntityRecord($event)); })("navigationRequest", function ConversationChatAreaComponent_Conditional_15_Template_mj_artifact_viewer_panel_navigationRequest_2_listener($event) { i0.ɵɵrestoreView(_r28); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onNavigationRequest($event)); })("analyzeRequested", function ConversationChatAreaComponent_Conditional_15_Template_mj_artifact_viewer_panel_analyzeRequested_2_listener($event) { i0.ɵɵrestoreView(_r28); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.OnAnalyzeArtifact($event)); })("applyFormRequested", function ConversationChatAreaComponent_Conditional_15_Template_mj_artifact_viewer_panel_applyFormRequested_2_listener($event) { i0.ɵɵrestoreView(_r28); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.OnApplyFormRequested($event)); });
741
+ const _r29 = i0.ɵɵgetCurrentView();
742
+ i0.ɵɵconditionalCreate(0, ConversationChatAreaComponent_Conditional_15_Conditional_0_Template, 1, 0, "div", 117);
743
+ i0.ɵɵelementStart(1, "div", 118)(2, "mj-artifact-viewer-panel", 119);
744
+ i0.ɵɵlistener("closed", function ConversationChatAreaComponent_Conditional_15_Template_mj_artifact_viewer_panel_closed_2_listener() { i0.ɵɵrestoreView(_r29); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onCloseArtifactPanel()); })("saveToCollectionRequested", function ConversationChatAreaComponent_Conditional_15_Template_mj_artifact_viewer_panel_saveToCollectionRequested_2_listener($event) { i0.ɵɵrestoreView(_r29); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onSaveToCollectionRequested($event)); })("navigateToLink", function ConversationChatAreaComponent_Conditional_15_Template_mj_artifact_viewer_panel_navigateToLink_2_listener($event) { i0.ɵɵrestoreView(_r29); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onArtifactLinkNavigation($event)); })("shareRequested", function ConversationChatAreaComponent_Conditional_15_Template_mj_artifact_viewer_panel_shareRequested_2_listener($event) { i0.ɵɵrestoreView(_r29); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onArtifactShareRequested($event)); })("maximizeToggled", function ConversationChatAreaComponent_Conditional_15_Template_mj_artifact_viewer_panel_maximizeToggled_2_listener() { i0.ɵɵrestoreView(_r29); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.toggleMaximizeArtifactPane()); })("openEntityRecord", function ConversationChatAreaComponent_Conditional_15_Template_mj_artifact_viewer_panel_openEntityRecord_2_listener($event) { i0.ɵɵrestoreView(_r29); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onOpenEntityRecord($event)); })("navigationRequest", function ConversationChatAreaComponent_Conditional_15_Template_mj_artifact_viewer_panel_navigationRequest_2_listener($event) { i0.ɵɵrestoreView(_r29); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onNavigationRequest($event)); })("analyzeRequested", function ConversationChatAreaComponent_Conditional_15_Template_mj_artifact_viewer_panel_analyzeRequested_2_listener($event) { i0.ɵɵrestoreView(_r29); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.OnAnalyzeArtifact($event)); })("applyFormRequested", function ConversationChatAreaComponent_Conditional_15_Template_mj_artifact_viewer_panel_applyFormRequested_2_listener($event) { i0.ɵɵrestoreView(_r29); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.OnApplyFormRequested($event)); });
701
745
  i0.ɵɵelementEnd()();
702
746
  } if (rf & 2) {
703
747
  const ctx_r0 = i0.ɵɵnextContext();
@@ -709,42 +753,42 @@ function ConversationChatAreaComponent_Conditional_15_Template(rf, ctx) { if (rf
709
753
  i0.ɵɵproperty("artifactId", ctx_r0.selectedArtifactId)("currentUser", ctx_r0.currentUser)("environmentId", ctx_r0.environmentId)("versionNumber", ctx_r0.selectedVersionNumber)("viewContext", "conversation")("Scope", ctx_r0.ArtifactViewerScope)("canShare", ctx_r0.canShareSelectedArtifact)("canEdit", ctx_r0.canEditSelectedArtifact)("isMaximized", ctx_r0.isArtifactPaneMaximized)("refreshTrigger", ctx_r0.artifactViewerRefresh$);
710
754
  } }
711
755
  function ConversationChatAreaComponent_Conditional_16_Conditional_0_Template(rf, ctx) { if (rf & 1) {
712
- const _r31 = i0.ɵɵgetCurrentView();
713
- i0.ɵɵelementStart(0, "div", 113);
714
- i0.ɵɵlistener("mousedown", function ConversationChatAreaComponent_Conditional_16_Conditional_0_Template_div_mousedown_0_listener($event) { i0.ɵɵrestoreView(_r31); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.onResizeStart($event)); })("touchstart", function ConversationChatAreaComponent_Conditional_16_Conditional_0_Template_div_touchstart_0_listener($event) { i0.ɵɵrestoreView(_r31); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.onResizeTouchStart($event)); });
756
+ const _r32 = i0.ɵɵgetCurrentView();
757
+ i0.ɵɵelementStart(0, "div", 120);
758
+ i0.ɵɵlistener("mousedown", function ConversationChatAreaComponent_Conditional_16_Conditional_0_Template_div_mousedown_0_listener($event) { i0.ɵɵrestoreView(_r32); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.onResizeStart($event)); })("touchstart", function ConversationChatAreaComponent_Conditional_16_Conditional_0_Template_div_touchstart_0_listener($event) { i0.ɵɵrestoreView(_r32); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.onResizeTouchStart($event)); });
715
759
  i0.ɵɵelementEnd();
716
760
  } }
717
761
  function ConversationChatAreaComponent_Conditional_16_Template(rf, ctx) { if (rf & 1) {
718
- const _r30 = i0.ɵɵgetCurrentView();
719
- i0.ɵɵconditionalCreate(0, ConversationChatAreaComponent_Conditional_16_Conditional_0_Template, 1, 0, "div", 110);
720
- i0.ɵɵelementStart(1, "div", 114)(2, "div", 115)(3, "div", 116)(4, "span", 117);
721
- i0.ɵɵelement(5, "i", 118);
762
+ const _r31 = i0.ɵɵgetCurrentView();
763
+ i0.ɵɵconditionalCreate(0, ConversationChatAreaComponent_Conditional_16_Conditional_0_Template, 1, 0, "div", 117);
764
+ i0.ɵɵelementStart(1, "div", 121)(2, "div", 122)(3, "div", 123)(4, "span", 124);
765
+ i0.ɵɵelement(5, "i", 125);
722
766
  i0.ɵɵelementEnd();
723
- i0.ɵɵelementStart(6, "div", 119)(7, "span", 120);
767
+ i0.ɵɵelementStart(6, "div", 126)(7, "span", 127);
724
768
  i0.ɵɵtext(8);
725
769
  i0.ɵɵelementEnd();
726
- i0.ɵɵelementStart(9, "span", 121);
770
+ i0.ɵɵelementStart(9, "span", 128);
727
771
  i0.ɵɵtext(10, "Interactive Task Graph & Step Inspector");
728
772
  i0.ɵɵelementEnd()()();
729
- i0.ɵɵelementStart(11, "div", 122)(12, "button", 123);
730
- i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_16_Template_button_click_12_listener() { i0.ɵɵrestoreView(_r30); const taskGraphRunView_r32 = i0.ɵɵreference(22); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.OnSaveTaskGraphAsWorkflow(taskGraphRunView_r32.Spec)); });
731
- i0.ɵɵelement(13, "i", 124);
773
+ i0.ɵɵelementStart(11, "div", 129)(12, "button", 130);
774
+ i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_16_Template_button_click_12_listener() { i0.ɵɵrestoreView(_r31); const taskGraphRunView_r33 = i0.ɵɵreference(22); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.OnSaveTaskGraphAsWorkflow(taskGraphRunView_r33.Spec)); });
775
+ i0.ɵɵelement(13, "i", 131);
732
776
  i0.ɵɵelementStart(14, "span");
733
777
  i0.ɵɵtext(15);
734
778
  i0.ɵɵelementEnd()();
735
- i0.ɵɵelementStart(16, "button", 125);
736
- i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_16_Template_button_click_16_listener() { i0.ɵɵrestoreView(_r30); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.toggleMaximizeArtifactPane()); });
737
- i0.ɵɵelement(17, "i", 124);
779
+ i0.ɵɵelementStart(16, "button", 132);
780
+ i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_16_Template_button_click_16_listener() { i0.ɵɵrestoreView(_r31); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.toggleMaximizeArtifactPane()); });
781
+ i0.ɵɵelement(17, "i", 131);
738
782
  i0.ɵɵelementEnd();
739
- i0.ɵɵelementStart(18, "button", 126);
740
- i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_16_Template_button_click_18_listener() { i0.ɵɵrestoreView(_r30); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.OnCloseTaskGraphPanel()); });
741
- i0.ɵɵelement(19, "i", 127);
783
+ i0.ɵɵelementStart(18, "button", 133);
784
+ i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_16_Template_button_click_18_listener() { i0.ɵɵrestoreView(_r31); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.OnCloseTaskGraphPanel()); });
785
+ i0.ɵɵelement(19, "i", 134);
742
786
  i0.ɵɵelementEnd()()();
743
- i0.ɵɵelementStart(20, "div", 128);
744
- i0.ɵɵelement(21, "mj-task-graph-run-view", 129, 8);
787
+ i0.ɵɵelementStart(20, "div", 135);
788
+ i0.ɵɵelement(21, "mj-task-graph-run-view", 136, 8);
745
789
  i0.ɵɵelementEnd()();
746
790
  } if (rf & 2) {
747
- const taskGraphRunView_r32 = i0.ɵɵreference(22);
791
+ const taskGraphRunView_r33 = i0.ɵɵreference(22);
748
792
  const ctx_r0 = i0.ɵɵnextContext();
749
793
  i0.ɵɵconditional(!ctx_r0.isArtifactPaneMaximized ? 0 : -1);
750
794
  i0.ɵɵadvance();
@@ -753,7 +797,7 @@ function ConversationChatAreaComponent_Conditional_16_Template(rf, ctx) { if (rf
753
797
  i0.ɵɵadvance(7);
754
798
  i0.ɵɵtextInterpolate(ctx_r0.SelectedTaskGraphPanel.workflowTitle);
755
799
  i0.ɵɵadvance(4);
756
- i0.ɵɵproperty("disabled", ctx_r0.IsSavingTaskGraphWorkflow || !(taskGraphRunView_r32.Spec == null ? null : taskGraphRunView_r32.Spec.tasks == null ? null : taskGraphRunView_r32.Spec.tasks.length));
800
+ i0.ɵɵproperty("disabled", ctx_r0.IsSavingTaskGraphWorkflow || !(taskGraphRunView_r33.Spec == null ? null : taskGraphRunView_r33.Spec.tasks == null ? null : taskGraphRunView_r33.Spec.tasks.length));
757
801
  i0.ɵɵadvance();
758
802
  i0.ɵɵclassProp("fa-spinner", ctx_r0.IsSavingTaskGraphWorkflow)("fa-spin", ctx_r0.IsSavingTaskGraphWorkflow)("fa-floppy-disk", !ctx_r0.IsSavingTaskGraphWorkflow);
759
803
  i0.ɵɵadvance(2);
@@ -765,33 +809,89 @@ function ConversationChatAreaComponent_Conditional_16_Template(rf, ctx) { if (rf
765
809
  i0.ɵɵadvance(4);
766
810
  i0.ɵɵproperty("ParentTaskID", ctx_r0.SelectedTaskGraphPanel.parentTaskId)("WorkflowName", ctx_r0.SelectedTaskGraphPanel.workflowTitle)("LiveUpdates", true)("ShowVariables", true)("Height", "100%");
767
811
  } }
768
- function ConversationChatAreaComponent_Conditional_18_Template(rf, ctx) { if (rf & 1) {
769
- const _r33 = i0.ɵɵgetCurrentView();
770
- i0.ɵɵelementStart(0, "mj-pinned-messages-panel", 130);
771
- i0.ɵɵlistener("closed", function ConversationChatAreaComponent_Conditional_18_Template_mj_pinned_messages_panel_closed_0_listener() { i0.ɵɵrestoreView(_r33); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.showPinsPanel = false); })("jumpRequested", function ConversationChatAreaComponent_Conditional_18_Template_mj_pinned_messages_panel_jumpRequested_0_listener($event) { i0.ɵɵrestoreView(_r33); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onJumpToMessage($event)); })("unpinRequested", function ConversationChatAreaComponent_Conditional_18_Template_mj_pinned_messages_panel_unpinRequested_0_listener($event) { i0.ɵɵrestoreView(_r33); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onUnpinFromPanel($event)); });
812
+ function ConversationChatAreaComponent_Conditional_17_Conditional_0_Template(rf, ctx) { if (rf & 1) {
813
+ const _r35 = i0.ɵɵgetCurrentView();
814
+ i0.ɵɵelementStart(0, "div", 120);
815
+ i0.ɵɵlistener("mousedown", function ConversationChatAreaComponent_Conditional_17_Conditional_0_Template_div_mousedown_0_listener($event) { i0.ɵɵrestoreView(_r35); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.onResizeStart($event)); })("touchstart", function ConversationChatAreaComponent_Conditional_17_Conditional_0_Template_div_touchstart_0_listener($event) { i0.ɵɵrestoreView(_r35); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.onResizeTouchStart($event)); });
816
+ i0.ɵɵelementEnd();
817
+ } }
818
+ function ConversationChatAreaComponent_Conditional_17_Template(rf, ctx) { if (rf & 1) {
819
+ const _r34 = i0.ɵɵgetCurrentView();
820
+ i0.ɵɵconditionalCreate(0, ConversationChatAreaComponent_Conditional_17_Conditional_0_Template, 1, 0, "div", 117);
821
+ i0.ɵɵelementStart(1, "div", 137)(2, "div", 122)(3, "div", 123)(4, "span", 124);
822
+ i0.ɵɵelement(5, "i", 68);
823
+ i0.ɵɵelementEnd();
824
+ i0.ɵɵelementStart(6, "div", 126)(7, "span", 127);
825
+ i0.ɵɵtext(8, "Remote Browser");
772
826
  i0.ɵɵelementEnd();
827
+ i0.ɵɵelementStart(9, "span", 128);
828
+ i0.ɵɵtext(10, "Shared live browser workspace");
829
+ i0.ɵɵelementEnd()()();
830
+ i0.ɵɵelementStart(11, "div", 129)(12, "input", 138);
831
+ i0.ɵɵtwoWayListener("ngModelChange", function ConversationChatAreaComponent_Conditional_17_Template_input_ngModelChange_12_listener($event) { i0.ɵɵrestoreView(_r34); const ctx_r0 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r0.RemoteBrowserUrlInput, $event) || (ctx_r0.RemoteBrowserUrlInput = $event); return i0.ɵɵresetView($event); });
832
+ i0.ɵɵlistener("keydown.enter", function ConversationChatAreaComponent_Conditional_17_Template_input_keydown_enter_12_listener($event) { i0.ɵɵrestoreView(_r34); const ctx_r0 = i0.ɵɵnextContext(); $event.preventDefault(); return i0.ɵɵresetView(ctx_r0.NavigateRemoteBrowserFromInput()); });
833
+ i0.ɵɵelementEnd();
834
+ i0.ɵɵelementStart(13, "button", 139);
835
+ i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_17_Template_button_click_13_listener() { i0.ɵɵrestoreView(_r34); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.NavigateRemoteBrowserFromInput()); });
836
+ i0.ɵɵelement(14, "i", 131);
837
+ i0.ɵɵelementStart(15, "span");
838
+ i0.ɵɵtext(16, "Go");
839
+ i0.ɵɵelementEnd()();
840
+ i0.ɵɵelementStart(17, "button", 132);
841
+ i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_17_Template_button_click_17_listener() { i0.ɵɵrestoreView(_r34); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.toggleMaximizeArtifactPane()); });
842
+ i0.ɵɵelement(18, "i", 131);
843
+ i0.ɵɵelementEnd();
844
+ i0.ɵɵelementStart(19, "button", 140);
845
+ i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_17_Template_button_click_19_listener() { i0.ɵɵrestoreView(_r34); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.CloseRemoteBrowserPanel()); });
846
+ i0.ɵɵelement(20, "i", 134);
847
+ i0.ɵɵelementEnd()()();
848
+ i0.ɵɵelementStart(21, "div", 135);
849
+ i0.ɵɵelement(22, "mj-realtime-remote-browser-surface", null, 9);
850
+ i0.ɵɵelementEnd()();
773
851
  } if (rf & 2) {
774
852
  const ctx_r0 = i0.ɵɵnextContext();
775
- i0.ɵɵproperty("pinnedMessages", ctx_r0.pinnedMessages)("isLoading", ctx_r0.isLoadingPins)("AllowUnpin", !ctx_r0.EffectiveReadOnly);
853
+ i0.ɵɵconditional(!ctx_r0.isArtifactPaneMaximized ? 0 : -1);
854
+ i0.ɵɵadvance();
855
+ i0.ɵɵstyleProp("width", ctx_r0.artifactPaneWidth, "%");
856
+ i0.ɵɵclassProp("maximized", ctx_r0.isArtifactPaneMaximized);
857
+ i0.ɵɵadvance(11);
858
+ i0.ɵɵtwoWayProperty("ngModel", ctx_r0.RemoteBrowserUrlInput);
859
+ i0.ɵɵadvance();
860
+ i0.ɵɵproperty("disabled", ctx_r0.IsRemoteBrowserNavigating || !ctx_r0.RemoteBrowserUrlInput.trim());
861
+ i0.ɵɵadvance();
862
+ i0.ɵɵclassProp("fa-spinner", ctx_r0.IsRemoteBrowserNavigating)("fa-spin", ctx_r0.IsRemoteBrowserNavigating)("fa-arrow-right", !ctx_r0.IsRemoteBrowserNavigating);
863
+ i0.ɵɵadvance(3);
864
+ i0.ɵɵproperty("title", ctx_r0.isArtifactPaneMaximized ? "Restore panel size" : "Maximize panel");
865
+ i0.ɵɵadvance();
866
+ i0.ɵɵclassProp("fa-compress", ctx_r0.isArtifactPaneMaximized)("fa-expand", !ctx_r0.isArtifactPaneMaximized);
776
867
  } }
777
868
  function ConversationChatAreaComponent_Conditional_19_Template(rf, ctx) { if (rf & 1) {
778
- const _r34 = i0.ɵɵgetCurrentView();
779
- i0.ɵɵelementStart(0, "mj-conversation-forks-popover", 131);
780
- i0.ɵɵlistener("ForkSelected", function ConversationChatAreaComponent_Conditional_19_Template_mj_conversation_forks_popover_ForkSelected_0_listener($event) { i0.ɵɵrestoreView(_r34); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.OnForkSelectedFromList($event)); })("Closed", function ConversationChatAreaComponent_Conditional_19_Template_mj_conversation_forks_popover_Closed_0_listener() { i0.ɵɵrestoreView(_r34); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.CloseForksPopover()); });
869
+ const _r36 = i0.ɵɵgetCurrentView();
870
+ i0.ɵɵelementStart(0, "mj-pinned-messages-panel", 141);
871
+ i0.ɵɵlistener("closed", function ConversationChatAreaComponent_Conditional_19_Template_mj_pinned_messages_panel_closed_0_listener() { i0.ɵɵrestoreView(_r36); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.showPinsPanel = false); })("jumpRequested", function ConversationChatAreaComponent_Conditional_19_Template_mj_pinned_messages_panel_jumpRequested_0_listener($event) { i0.ɵɵrestoreView(_r36); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onJumpToMessage($event)); })("unpinRequested", function ConversationChatAreaComponent_Conditional_19_Template_mj_pinned_messages_panel_unpinRequested_0_listener($event) { i0.ɵɵrestoreView(_r36); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onUnpinFromPanel($event)); });
872
+ i0.ɵɵelementEnd();
873
+ } if (rf & 2) {
874
+ const ctx_r0 = i0.ɵɵnextContext();
875
+ i0.ɵɵproperty("pinnedMessages", ctx_r0.pinnedMessages)("isLoading", ctx_r0.isLoadingPins)("AllowUnpin", !ctx_r0.EffectiveReadOnly);
876
+ } }
877
+ function ConversationChatAreaComponent_Conditional_20_Template(rf, ctx) { if (rf & 1) {
878
+ const _r37 = i0.ɵɵgetCurrentView();
879
+ i0.ɵɵelementStart(0, "mj-conversation-forks-popover", 142);
880
+ i0.ɵɵlistener("ForkSelected", function ConversationChatAreaComponent_Conditional_20_Template_mj_conversation_forks_popover_ForkSelected_0_listener($event) { i0.ɵɵrestoreView(_r37); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.OnForkSelectedFromList($event)); })("Closed", function ConversationChatAreaComponent_Conditional_20_Template_mj_conversation_forks_popover_Closed_0_listener() { i0.ɵɵrestoreView(_r37); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.CloseForksPopover()); });
781
881
  i0.ɵɵelementEnd();
782
882
  } if (rf & 2) {
783
883
  const ctx_r0 = i0.ɵɵnextContext();
784
884
  i0.ɵɵproperty("PanelID", ctx_r0.ForksPopoverID)("Summaries", ctx_r0.ForkSummaries)("CurrentUserID", ctx_r0.CurrentUser.ID);
785
885
  } }
786
- function ConversationChatAreaComponent_Conditional_20_Conditional_2_Template(rf, ctx) { if (rf & 1) {
787
- const _r36 = i0.ɵɵgetCurrentView();
788
- i0.ɵɵelementStart(0, "button", 134);
789
- i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_20_Conditional_2_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r36); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.RealtimeSession.SetMinimized(false)); });
790
- i0.ɵɵelement(1, "span", 135)(2, "i", 136);
791
- i0.ɵɵelementStart(3, "span", 137)(4, "span", 138);
886
+ function ConversationChatAreaComponent_Conditional_21_Conditional_2_Template(rf, ctx) { if (rf & 1) {
887
+ const _r39 = i0.ɵɵgetCurrentView();
888
+ i0.ɵɵelementStart(0, "button", 145);
889
+ i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_21_Conditional_2_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r39); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.RealtimeSession.SetMinimized(false)); });
890
+ i0.ɵɵelement(1, "span", 146)(2, "i", 147);
891
+ i0.ɵɵelementStart(3, "span", 148)(4, "span", 149);
792
892
  i0.ɵɵtext(5);
793
893
  i0.ɵɵelementEnd();
794
- i0.ɵɵelementStart(6, "span", 139);
894
+ i0.ɵɵelementStart(6, "span", 150);
795
895
  i0.ɵɵtext(7, "Tap to return");
796
896
  i0.ɵɵelementEnd()()();
797
897
  } if (rf & 2) {
@@ -799,13 +899,13 @@ function ConversationChatAreaComponent_Conditional_20_Conditional_2_Template(rf,
799
899
  i0.ɵɵadvance(5);
800
900
  i0.ɵɵtextInterpolate1("On call \u00B7 ", ctx_r0.RealtimeSession.CurrentAgentName);
801
901
  } }
802
- function ConversationChatAreaComponent_Conditional_20_Template(rf, ctx) { if (rf & 1) {
803
- const _r35 = i0.ɵɵgetCurrentView();
804
- i0.ɵɵelementStart(0, "mj-realtime-session-overlay", 132);
902
+ function ConversationChatAreaComponent_Conditional_21_Template(rf, ctx) { if (rf & 1) {
903
+ const _r38 = i0.ɵɵgetCurrentView();
904
+ i0.ɵɵelementStart(0, "mj-realtime-session-overlay", 143);
805
905
  i0.ɵɵpipe(1, "async");
806
- i0.ɵɵlistener("NavigateRequest", function ConversationChatAreaComponent_Conditional_20_Template_mj_realtime_session_overlay_NavigateRequest_0_listener($event) { i0.ɵɵrestoreView(_r35); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onRealtimeNavigateRequest($event)); })("StartLiveRequested", function ConversationChatAreaComponent_Conditional_20_Template_mj_realtime_session_overlay_StartLiveRequested_0_listener($event) { i0.ɵɵrestoreView(_r35); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onReviewStartLive($event)); })("ReviewClosed", function ConversationChatAreaComponent_Conditional_20_Template_mj_realtime_session_overlay_ReviewClosed_0_listener() { i0.ɵɵrestoreView(_r35); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onReviewClosed()); });
906
+ i0.ɵɵlistener("NavigateRequest", function ConversationChatAreaComponent_Conditional_21_Template_mj_realtime_session_overlay_NavigateRequest_0_listener($event) { i0.ɵɵrestoreView(_r38); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onRealtimeNavigateRequest($event)); })("StartLiveRequested", function ConversationChatAreaComponent_Conditional_21_Template_mj_realtime_session_overlay_StartLiveRequested_0_listener($event) { i0.ɵɵrestoreView(_r38); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onReviewStartLive($event)); })("ReviewClosed", function ConversationChatAreaComponent_Conditional_21_Template_mj_realtime_session_overlay_ReviewClosed_0_listener() { i0.ɵɵrestoreView(_r38); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onReviewClosed()); });
807
907
  i0.ɵɵelementEnd();
808
- i0.ɵɵconditionalCreate(2, ConversationChatAreaComponent_Conditional_20_Conditional_2_Template, 8, 1, "button", 133);
908
+ i0.ɵɵconditionalCreate(2, ConversationChatAreaComponent_Conditional_21_Conditional_2_Template, 8, 1, "button", 144);
809
909
  i0.ɵɵpipe(3, "async");
810
910
  } if (rf & 2) {
811
911
  const ctx_r0 = i0.ɵɵnextContext();
@@ -813,32 +913,32 @@ function ConversationChatAreaComponent_Conditional_20_Template(rf, ctx) { if (rf
813
913
  i0.ɵɵadvance(2);
814
914
  i0.ɵɵconditional(i0.ɵɵpipeBind1(3, 13, ctx_r0.RealtimeSession.Minimized$) ? 2 : -1);
815
915
  } }
816
- function ConversationChatAreaComponent_Conditional_25_Template(rf, ctx) { if (rf & 1) {
817
- const _r37 = i0.ɵɵgetCurrentView();
818
- i0.ɵɵelementStart(0, "div", 140);
819
- i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_25_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r37); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.showProjectSelector = false); });
820
- i0.ɵɵelementStart(1, "div", 141);
821
- i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_25_Template_div_click_1_listener($event) { return $event.stopPropagation(); });
822
- i0.ɵɵelementStart(2, "div", 142)(3, "h3");
916
+ function ConversationChatAreaComponent_Conditional_26_Template(rf, ctx) { if (rf & 1) {
917
+ const _r40 = i0.ɵɵgetCurrentView();
918
+ i0.ɵɵelementStart(0, "div", 151);
919
+ i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_26_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r40); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.showProjectSelector = false); });
920
+ i0.ɵɵelementStart(1, "div", 152);
921
+ i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_26_Template_div_click_1_listener($event) { return $event.stopPropagation(); });
922
+ i0.ɵɵelementStart(2, "div", 153)(3, "h3");
823
923
  i0.ɵɵtext(4, "Assign Project");
824
924
  i0.ɵɵelementEnd();
825
- i0.ɵɵelementStart(5, "button", 143);
826
- i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_25_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r37); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.showProjectSelector = false); });
827
- i0.ɵɵelement(6, "i", 144);
925
+ i0.ɵɵelementStart(5, "button", 154);
926
+ i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_26_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r40); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.showProjectSelector = false); });
927
+ i0.ɵɵelement(6, "i", 155);
828
928
  i0.ɵɵelementEnd()();
829
- i0.ɵɵelementStart(7, "div", 145)(8, "mj-project-selector", 146);
830
- i0.ɵɵlistener("projectSelected", function ConversationChatAreaComponent_Conditional_25_Template_mj_project_selector_projectSelected_8_listener($event) { i0.ɵɵrestoreView(_r37); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onProjectSelected($event)); });
929
+ i0.ɵɵelementStart(7, "div", 156)(8, "mj-project-selector", 157);
930
+ i0.ɵɵlistener("projectSelected", function ConversationChatAreaComponent_Conditional_26_Template_mj_project_selector_projectSelected_8_listener($event) { i0.ɵɵrestoreView(_r40); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onProjectSelected($event)); });
831
931
  i0.ɵɵelementEnd()()()();
832
932
  } if (rf & 2) {
833
933
  const ctx_r0 = i0.ɵɵnextContext();
834
934
  i0.ɵɵadvance(8);
835
935
  i0.ɵɵproperty("environmentId", ctx_r0.environmentId)("currentUser", ctx_r0.currentUser)("selectedProjectId", ctx_r0.conversation.ProjectID);
836
936
  } }
837
- function ConversationChatAreaComponent_Conditional_26_Conditional_6_Template(rf, ctx) { if (rf & 1) {
838
- const _r39 = i0.ɵɵgetCurrentView();
839
- i0.ɵɵelementStart(0, "button", 153);
840
- i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_26_Conditional_6_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r39); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.toggleSystemArtifacts()); });
841
- i0.ɵɵelement(1, "i", 154);
937
+ function ConversationChatAreaComponent_Conditional_27_Conditional_6_Template(rf, ctx) { if (rf & 1) {
938
+ const _r42 = i0.ɵɵgetCurrentView();
939
+ i0.ɵɵelementStart(0, "button", 164);
940
+ i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_27_Conditional_6_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r42); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.toggleSystemArtifacts()); });
941
+ i0.ɵɵelement(1, "i", 165);
842
942
  i0.ɵɵelementStart(2, "span");
843
943
  i0.ɵɵtext(3);
844
944
  i0.ɵɵelementEnd()();
@@ -848,106 +948,106 @@ function ConversationChatAreaComponent_Conditional_26_Conditional_6_Template(rf,
848
948
  i0.ɵɵadvance(3);
849
949
  i0.ɵɵtextInterpolate1("", ctx_r0.showSystemArtifacts ? "Hide" : "Show", " System");
850
950
  } }
851
- function ConversationChatAreaComponent_Conditional_26_Conditional_10_Template(rf, ctx) { if (rf & 1) {
852
- i0.ɵɵelement(0, "mj-empty-state", 151);
951
+ function ConversationChatAreaComponent_Conditional_27_Conditional_10_Template(rf, ctx) { if (rf & 1) {
952
+ i0.ɵɵelement(0, "mj-empty-state", 162);
853
953
  } }
854
- function ConversationChatAreaComponent_Conditional_26_For_12_Conditional_8_Template(rf, ctx) { if (rf & 1) {
954
+ function ConversationChatAreaComponent_Conditional_27_For_12_Conditional_8_Template(rf, ctx) { if (rf & 1) {
855
955
  i0.ɵɵtext(0);
856
956
  } if (rf & 2) {
857
- const artifact_r41 = i0.ɵɵnextContext().$implicit;
858
- i0.ɵɵtextInterpolate1(" ", artifact_r41.versionCount, " versions ");
957
+ const artifact_r44 = i0.ɵɵnextContext().$implicit;
958
+ i0.ɵɵtextInterpolate1(" ", artifact_r44.versionCount, " versions ");
859
959
  } }
860
- function ConversationChatAreaComponent_Conditional_26_For_12_Conditional_9_Template(rf, ctx) { if (rf & 1) {
960
+ function ConversationChatAreaComponent_Conditional_27_For_12_Conditional_9_Template(rf, ctx) { if (rf & 1) {
861
961
  i0.ɵɵtext(0, " 1 version ");
862
962
  } }
863
- function ConversationChatAreaComponent_Conditional_26_For_12_Conditional_10_Template(rf, ctx) { if (rf & 1) {
864
- const _r42 = i0.ɵɵgetCurrentView();
865
- i0.ɵɵelementStart(0, "button", 166);
866
- i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_26_For_12_Conditional_10_Template_button_click_0_listener($event) { i0.ɵɵrestoreView(_r42); const artifact_r41 = i0.ɵɵnextContext().$implicit; const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.toggleArtifactExpansion(artifact_r41.artifactId, $event)); });
867
- i0.ɵɵelement(1, "i", 167);
963
+ function ConversationChatAreaComponent_Conditional_27_For_12_Conditional_10_Template(rf, ctx) { if (rf & 1) {
964
+ const _r45 = i0.ɵɵgetCurrentView();
965
+ i0.ɵɵelementStart(0, "button", 177);
966
+ i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_27_For_12_Conditional_10_Template_button_click_0_listener($event) { i0.ɵɵrestoreView(_r45); const artifact_r44 = i0.ɵɵnextContext().$implicit; const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.toggleArtifactExpansion(artifact_r44.artifactId, $event)); });
967
+ i0.ɵɵelement(1, "i", 178);
868
968
  i0.ɵɵelementEnd();
869
969
  } if (rf & 2) {
870
- const artifact_r41 = i0.ɵɵnextContext().$implicit;
970
+ const artifact_r44 = i0.ɵɵnextContext().$implicit;
871
971
  const ctx_r0 = i0.ɵɵnextContext(2);
872
972
  i0.ɵɵadvance();
873
- i0.ɵɵclassProp("fa-chevron-down", ctx_r0.expandedArtifactId !== artifact_r41.artifactId)("fa-chevron-up", ctx_r0.expandedArtifactId === artifact_r41.artifactId);
973
+ i0.ɵɵclassProp("fa-chevron-down", ctx_r0.expandedArtifactId !== artifact_r44.artifactId)("fa-chevron-up", ctx_r0.expandedArtifactId === artifact_r44.artifactId);
874
974
  } }
875
- function ConversationChatAreaComponent_Conditional_26_For_12_Conditional_13_For_2_Template(rf, ctx) { if (rf & 1) {
876
- const _r43 = i0.ɵɵgetCurrentView();
877
- i0.ɵɵelementStart(0, "div", 169);
878
- i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_26_For_12_Conditional_13_For_2_Template_div_click_0_listener($event) { const version_r44 = i0.ɵɵrestoreView(_r43).$implicit; const artifact_r41 = i0.ɵɵnextContext(2).$implicit; const ctx_r0 = i0.ɵɵnextContext(2); ctx_r0.openArtifactFromModal(artifact_r41.artifactId, version_r44.versionNumber); return i0.ɵɵresetView($event.stopPropagation()); });
879
- i0.ɵɵelementStart(1, "span", 170);
975
+ function ConversationChatAreaComponent_Conditional_27_For_12_Conditional_13_For_2_Template(rf, ctx) { if (rf & 1) {
976
+ const _r46 = i0.ɵɵgetCurrentView();
977
+ i0.ɵɵelementStart(0, "div", 180);
978
+ i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_27_For_12_Conditional_13_For_2_Template_div_click_0_listener($event) { const version_r47 = i0.ɵɵrestoreView(_r46).$implicit; const artifact_r44 = i0.ɵɵnextContext(2).$implicit; const ctx_r0 = i0.ɵɵnextContext(2); ctx_r0.openArtifactFromModal(artifact_r44.artifactId, version_r47.versionNumber); return i0.ɵɵresetView($event.stopPropagation()); });
979
+ i0.ɵɵelementStart(1, "span", 181);
880
980
  i0.ɵɵtext(2);
881
981
  i0.ɵɵelementEnd();
882
- i0.ɵɵelementStart(3, "span", 171);
982
+ i0.ɵɵelementStart(3, "span", 182);
883
983
  i0.ɵɵtext(4, "Open this version");
884
984
  i0.ɵɵelementEnd();
885
- i0.ɵɵelement(5, "i", 172);
985
+ i0.ɵɵelement(5, "i", 183);
886
986
  i0.ɵɵelementEnd();
887
987
  } if (rf & 2) {
888
- const version_r44 = ctx.$implicit;
988
+ const version_r47 = ctx.$implicit;
889
989
  i0.ɵɵadvance(2);
890
- i0.ɵɵtextInterpolate1("v", version_r44.versionNumber);
990
+ i0.ɵɵtextInterpolate1("v", version_r47.versionNumber);
891
991
  } }
892
- function ConversationChatAreaComponent_Conditional_26_For_12_Conditional_13_Template(rf, ctx) { if (rf & 1) {
893
- i0.ɵɵelementStart(0, "div", 165);
894
- i0.ɵɵrepeaterCreate(1, ConversationChatAreaComponent_Conditional_26_For_12_Conditional_13_For_2_Template, 6, 1, "div", 168, _forTrack2);
992
+ function ConversationChatAreaComponent_Conditional_27_For_12_Conditional_13_Template(rf, ctx) { if (rf & 1) {
993
+ i0.ɵɵelementStart(0, "div", 176);
994
+ i0.ɵɵrepeaterCreate(1, ConversationChatAreaComponent_Conditional_27_For_12_Conditional_13_For_2_Template, 6, 1, "div", 179, _forTrack2);
895
995
  i0.ɵɵelementEnd();
896
996
  } if (rf & 2) {
897
- const artifact_r41 = i0.ɵɵnextContext().$implicit;
997
+ const artifact_r44 = i0.ɵɵnextContext().$implicit;
898
998
  i0.ɵɵadvance();
899
- i0.ɵɵrepeater(artifact_r41.versions);
999
+ i0.ɵɵrepeater(artifact_r44.versions);
900
1000
  } }
901
- function ConversationChatAreaComponent_Conditional_26_For_12_Template(rf, ctx) { if (rf & 1) {
902
- const _r40 = i0.ɵɵgetCurrentView();
903
- i0.ɵɵelementStart(0, "div", 155)(1, "div", 156);
904
- i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_26_For_12_Template_div_click_1_listener() { const artifact_r41 = i0.ɵɵrestoreView(_r40).$implicit; const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.openArtifactFromModal(artifact_r41.artifactId)); });
905
- i0.ɵɵelementStart(2, "div", 157);
906
- i0.ɵɵelement(3, "i", 158);
1001
+ function ConversationChatAreaComponent_Conditional_27_For_12_Template(rf, ctx) { if (rf & 1) {
1002
+ const _r43 = i0.ɵɵgetCurrentView();
1003
+ i0.ɵɵelementStart(0, "div", 166)(1, "div", 167);
1004
+ i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_27_For_12_Template_div_click_1_listener() { const artifact_r44 = i0.ɵɵrestoreView(_r43).$implicit; const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.openArtifactFromModal(artifact_r44.artifactId)); });
1005
+ i0.ɵɵelementStart(2, "div", 168);
1006
+ i0.ɵɵelement(3, "i", 169);
907
1007
  i0.ɵɵelementEnd();
908
- i0.ɵɵelementStart(4, "div", 159)(5, "div", 160);
1008
+ i0.ɵɵelementStart(4, "div", 170)(5, "div", 171);
909
1009
  i0.ɵɵtext(6);
910
1010
  i0.ɵɵelementEnd();
911
- i0.ɵɵelementStart(7, "div", 161);
912
- i0.ɵɵconditionalCreate(8, ConversationChatAreaComponent_Conditional_26_For_12_Conditional_8_Template, 1, 1)(9, ConversationChatAreaComponent_Conditional_26_For_12_Conditional_9_Template, 1, 0);
1011
+ i0.ɵɵelementStart(7, "div", 172);
1012
+ i0.ɵɵconditionalCreate(8, ConversationChatAreaComponent_Conditional_27_For_12_Conditional_8_Template, 1, 1)(9, ConversationChatAreaComponent_Conditional_27_For_12_Conditional_9_Template, 1, 0);
913
1013
  i0.ɵɵelementEnd()();
914
- i0.ɵɵconditionalCreate(10, ConversationChatAreaComponent_Conditional_26_For_12_Conditional_10_Template, 2, 4, "button", 162);
915
- i0.ɵɵelementStart(11, "div", 163);
916
- i0.ɵɵelement(12, "i", 164);
1014
+ i0.ɵɵconditionalCreate(10, ConversationChatAreaComponent_Conditional_27_For_12_Conditional_10_Template, 2, 4, "button", 173);
1015
+ i0.ɵɵelementStart(11, "div", 174);
1016
+ i0.ɵɵelement(12, "i", 175);
917
1017
  i0.ɵɵelementEnd()();
918
- i0.ɵɵconditionalCreate(13, ConversationChatAreaComponent_Conditional_26_For_12_Conditional_13_Template, 3, 0, "div", 165);
1018
+ i0.ɵɵconditionalCreate(13, ConversationChatAreaComponent_Conditional_27_For_12_Conditional_13_Template, 3, 0, "div", 176);
919
1019
  i0.ɵɵelementEnd();
920
1020
  } if (rf & 2) {
921
- const artifact_r41 = ctx.$implicit;
1021
+ const artifact_r44 = ctx.$implicit;
922
1022
  const ctx_r0 = i0.ɵɵnextContext(2);
923
- i0.ɵɵclassProp("expanded", ctx_r0.expandedArtifactId === artifact_r41.artifactId)("system-artifact", artifact_r41.visibility === "System Only");
1023
+ i0.ɵɵclassProp("expanded", ctx_r0.expandedArtifactId === artifact_r44.artifactId)("system-artifact", artifact_r44.visibility === "System Only");
924
1024
  i0.ɵɵadvance(6);
925
- i0.ɵɵtextInterpolate(artifact_r41.name);
1025
+ i0.ɵɵtextInterpolate(artifact_r44.name);
926
1026
  i0.ɵɵadvance(2);
927
- i0.ɵɵconditional(artifact_r41.versionCount > 1 ? 8 : 9);
1027
+ i0.ɵɵconditional(artifact_r44.versionCount > 1 ? 8 : 9);
928
1028
  i0.ɵɵadvance(2);
929
- i0.ɵɵconditional(artifact_r41.versionCount > 1 ? 10 : -1);
1029
+ i0.ɵɵconditional(artifact_r44.versionCount > 1 ? 10 : -1);
930
1030
  i0.ɵɵadvance(3);
931
- i0.ɵɵconditional(ctx_r0.expandedArtifactId === artifact_r41.artifactId && artifact_r41.versionCount > 1 ? 13 : -1);
1031
+ i0.ɵɵconditional(ctx_r0.expandedArtifactId === artifact_r44.artifactId && artifact_r44.versionCount > 1 ? 13 : -1);
932
1032
  } }
933
- function ConversationChatAreaComponent_Conditional_26_Template(rf, ctx) { if (rf & 1) {
934
- const _r38 = i0.ɵɵgetCurrentView();
935
- i0.ɵɵelementStart(0, "div", 140);
936
- i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_26_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r38); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.showArtifactsModal = false); });
937
- i0.ɵɵelementStart(1, "div", 147);
938
- i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_26_Template_div_click_1_listener($event) { return $event.stopPropagation(); });
939
- i0.ɵɵelementStart(2, "div", 142)(3, "h3");
1033
+ function ConversationChatAreaComponent_Conditional_27_Template(rf, ctx) { if (rf & 1) {
1034
+ const _r41 = i0.ɵɵgetCurrentView();
1035
+ i0.ɵɵelementStart(0, "div", 151);
1036
+ i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_27_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r41); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.showArtifactsModal = false); });
1037
+ i0.ɵɵelementStart(1, "div", 158);
1038
+ i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_27_Template_div_click_1_listener($event) { return $event.stopPropagation(); });
1039
+ i0.ɵɵelementStart(2, "div", 153)(3, "h3");
940
1040
  i0.ɵɵtext(4, "Conversation Artifacts");
941
1041
  i0.ɵɵelementEnd();
942
- i0.ɵɵelementStart(5, "div", 148);
943
- i0.ɵɵconditionalCreate(6, ConversationChatAreaComponent_Conditional_26_Conditional_6_Template, 4, 3, "button", 149);
944
- i0.ɵɵelementStart(7, "button", 143);
945
- i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_26_Template_button_click_7_listener() { i0.ɵɵrestoreView(_r38); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.showArtifactsModal = false); });
946
- i0.ɵɵelement(8, "i", 144);
1042
+ i0.ɵɵelementStart(5, "div", 159);
1043
+ i0.ɵɵconditionalCreate(6, ConversationChatAreaComponent_Conditional_27_Conditional_6_Template, 4, 3, "button", 160);
1044
+ i0.ɵɵelementStart(7, "button", 154);
1045
+ i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_27_Template_button_click_7_listener() { i0.ɵɵrestoreView(_r41); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.showArtifactsModal = false); });
1046
+ i0.ɵɵelement(8, "i", 155);
947
1047
  i0.ɵɵelementEnd()()();
948
- i0.ɵɵelementStart(9, "div", 150);
949
- i0.ɵɵconditionalCreate(10, ConversationChatAreaComponent_Conditional_26_Conditional_10_Template, 1, 0, "mj-empty-state", 151);
950
- i0.ɵɵrepeaterCreate(11, ConversationChatAreaComponent_Conditional_26_For_12_Template, 14, 8, "div", 152, _forTrack1);
1048
+ i0.ɵɵelementStart(9, "div", 161);
1049
+ i0.ɵɵconditionalCreate(10, ConversationChatAreaComponent_Conditional_27_Conditional_10_Template, 1, 0, "mj-empty-state", 162);
1050
+ i0.ɵɵrepeaterCreate(11, ConversationChatAreaComponent_Conditional_27_For_12_Template, 14, 8, "div", 163, _forTrack1);
951
1051
  i0.ɵɵelementEnd()()();
952
1052
  } if (rf & 2) {
953
1053
  const ctx_r0 = i0.ɵɵnextContext();
@@ -958,28 +1058,28 @@ function ConversationChatAreaComponent_Conditional_26_Template(rf, ctx) { if (rf
958
1058
  i0.ɵɵadvance();
959
1059
  i0.ɵɵrepeater(ctx_r0.getArtifactsArray());
960
1060
  } }
961
- function ConversationChatAreaComponent_Conditional_27_Template(rf, ctx) { if (rf & 1) {
962
- const _r45 = i0.ɵɵgetCurrentView();
963
- i0.ɵɵelementStart(0, "mj-artifact-collection-picker-modal", 173);
964
- i0.ɵɵlistener("completed", function ConversationChatAreaComponent_Conditional_27_Template_mj_artifact_collection_picker_modal_completed_0_listener($event) { i0.ɵɵrestoreView(_r45); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onCollectionPickerCompleted($event)); })("cancelled", function ConversationChatAreaComponent_Conditional_27_Template_mj_artifact_collection_picker_modal_cancelled_0_listener() { i0.ɵɵrestoreView(_r45); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onCollectionPickerCancelled()); });
1061
+ function ConversationChatAreaComponent_Conditional_28_Template(rf, ctx) { if (rf & 1) {
1062
+ const _r48 = i0.ɵɵgetCurrentView();
1063
+ i0.ɵɵelementStart(0, "mj-artifact-collection-picker-modal", 184);
1064
+ i0.ɵɵlistener("completed", function ConversationChatAreaComponent_Conditional_28_Template_mj_artifact_collection_picker_modal_completed_0_listener($event) { i0.ɵɵrestoreView(_r48); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onCollectionPickerCompleted($event)); })("cancelled", function ConversationChatAreaComponent_Conditional_28_Template_mj_artifact_collection_picker_modal_cancelled_0_listener() { i0.ɵɵrestoreView(_r48); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onCollectionPickerCancelled()); });
965
1065
  i0.ɵɵelementEnd();
966
1066
  } if (rf & 2) {
967
1067
  const ctx_r0 = i0.ɵɵnextContext();
968
1068
  i0.ɵɵproperty("isOpen", ctx_r0.showCollectionPicker)("environmentId", ctx_r0.environmentId)("currentUser", ctx_r0.currentUser)("excludeCollectionIds", ctx_r0.collectionPickerExcludedIds)("artifactVersionId", ctx_r0.collectionPickerVersionId)("artifactName", ctx_r0.collectionPickerArtifactName)("artifactVersionNumber", ctx_r0.collectionPickerVersionNumber);
969
1069
  } }
970
- function ConversationChatAreaComponent_Conditional_28_Template(rf, ctx) { if (rf & 1) {
971
- const _r46 = i0.ɵɵgetCurrentView();
972
- i0.ɵɵelementStart(0, "mj-test-feedback-dialog", 174);
973
- i0.ɵɵlistener("closed", function ConversationChatAreaComponent_Conditional_28_Template_mj_test_feedback_dialog_closed_0_listener($event) { i0.ɵɵrestoreView(_r46); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onTestFeedbackDialogClosed($event)); });
1070
+ function ConversationChatAreaComponent_Conditional_29_Template(rf, ctx) { if (rf & 1) {
1071
+ const _r49 = i0.ɵɵgetCurrentView();
1072
+ i0.ɵɵelementStart(0, "mj-test-feedback-dialog", 185);
1073
+ i0.ɵɵlistener("closed", function ConversationChatAreaComponent_Conditional_29_Template_mj_test_feedback_dialog_closed_0_listener($event) { i0.ɵɵrestoreView(_r49); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onTestFeedbackDialogClosed($event)); });
974
1074
  i0.ɵɵelementEnd();
975
1075
  } if (rf & 2) {
976
1076
  const ctx_r0 = i0.ɵɵnextContext();
977
1077
  i0.ɵɵproperty("data", ctx_r0.testFeedbackDialogData)("visible", ctx_r0.showTestFeedbackDialog);
978
1078
  } }
979
- function ConversationChatAreaComponent_Conditional_29_Template(rf, ctx) { if (rf & 1) {
980
- const _r47 = i0.ɵɵgetCurrentView();
981
- i0.ɵɵelementStart(0, "mj-image-viewer", 175);
982
- i0.ɵɵlistener("closed", function ConversationChatAreaComponent_Conditional_29_Template_mj_image_viewer_closed_0_listener() { i0.ɵɵrestoreView(_r47); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onImageViewerClosed()); });
1079
+ function ConversationChatAreaComponent_Conditional_30_Template(rf, ctx) { if (rf & 1) {
1080
+ const _r50 = i0.ɵɵgetCurrentView();
1081
+ i0.ɵɵelementStart(0, "mj-image-viewer", 186);
1082
+ i0.ɵɵlistener("closed", function ConversationChatAreaComponent_Conditional_30_Template_mj_image_viewer_closed_0_listener() { i0.ɵɵrestoreView(_r50); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onImageViewerClosed()); });
983
1083
  i0.ɵɵelementEnd();
984
1084
  } if (rf & 2) {
985
1085
  const ctx_r0 = i0.ɵɵnextContext();
@@ -987,6 +1087,7 @@ function ConversationChatAreaComponent_Conditional_29_Template(rf, ctx) { if (rf
987
1087
  } }
988
1088
  /** `MJ: Resource Types.ID` for Conversations. */
989
1089
  const CONVERSATIONS_RESOURCE_TYPE_ID = '81D4BC3D-9FEB-EF11-B01A-286B35C04427';
1090
+ const EMPTY_THREAD_REPLY_ROOTS = new UUIDMap();
990
1091
  /** Run statuses that mean the run is over, for the run-list fallback. `Paused` is still working. */
991
1092
  const RUN_LIST_TERMINAL_STATUSES = ['Completed', 'AwaitingFeedback', 'Failed', 'Cancelled'];
992
1093
  /** Default width (percentage) for the artifact viewer pane */
@@ -1084,7 +1185,16 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
1084
1185
  set conversationId(value) {
1085
1186
  this.ConversationId = value;
1086
1187
  }
1087
- Conversation = null;
1188
+ _conversation = null;
1189
+ set Conversation(value) {
1190
+ this._conversation = value;
1191
+ if (value?.ID && value.Name) {
1192
+ this.syncCachedMessageInputName(value.ID, value.Name);
1193
+ }
1194
+ }
1195
+ get Conversation() {
1196
+ return this._conversation;
1197
+ }
1088
1198
  /** @deprecated Use {@link Conversation}. */
1089
1199
  set conversation(value) {
1090
1200
  this.Conversation = value;
@@ -1211,6 +1321,12 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
1211
1321
  * that authorization to a role to stop the server creating forks as well.
1212
1322
  */
1213
1323
  AllowForking = true;
1324
+ /**
1325
+ * Host-level opt-in for the conversation's Remote Browser: the header's Browser button, its drawer,
1326
+ * and the `browser_*` tools that let this conversation's agents drive it. Defaults false; a host
1327
+ * that wants an agent-driven browser beside the chat sets true.
1328
+ */
1329
+ AllowRemoteBrowser = false;
1214
1330
  /**
1215
1331
  * Host-level cap for stopping and continuing agent runs: the composer's Stop and Stop all, the
1216
1332
  * Stop pill on an in-progress reply, the Continue button on a stopped reply, and the "Continue,
@@ -1805,11 +1921,100 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
1805
1921
  return this.ShowAgentModePicker && !!this.ModePickerTargetAgentId;
1806
1922
  }
1807
1923
  get ModePickerTargetAgentId() {
1808
- return this.Conversation?.DefaultAgentID
1924
+ return this.CurrentOwnerAgent?.ID
1925
+ ?? this.Conversation?.DefaultAgentID
1809
1926
  ?? this.DefaultAgentId
1810
1927
  ?? this.conversationManagerAgent?.ID
1811
1928
  ?? null;
1812
1929
  }
1930
+ _cachedOwnerAgentKey;
1931
+ _cachedOwnerAgent = null;
1932
+ /**
1933
+ * Current conversation owner agent for the header `.with-chip` and composer
1934
+ * placeholder: continuity (last non-Sage reply not preceded by a newer
1935
+ * `@Sage` user message) -> pinned/default agent -> conversation manager.
1936
+ * Memoized by message count and active routing inputs so template evaluation
1937
+ * does not scan `messages` on every change-detection cycle.
1938
+ */
1939
+ get CurrentOwnerAgent() {
1940
+ const managerId = this.conversationManagerAgent?.ID ?? null;
1941
+ const rows = this.DisplayMessages?.length ? this.DisplayMessages : this.messages ?? [];
1942
+ const lastRow = rows.length > 0 ? rows[rows.length - 1] : null;
1943
+ const defaultId = this.Conversation?.DefaultAgentID ?? this.DefaultAgentId ?? null;
1944
+ const floorMs = this.AgentHistoryFrom ? new Date(this.AgentHistoryFrom).getTime() : '';
1945
+ const allowedKey = this.AllowedAgentIDs ? this.AllowedAgentIDs.join(',') : '';
1946
+ const cacheKey = `${rows.length}|${lastRow?.ID ?? ''}|${lastRow?.AgentID ?? ''}|${defaultId ?? ''}|${managerId ?? ''}|${floorMs}|${allowedKey}`;
1947
+ if (this._cachedOwnerAgentKey === cacheKey) {
1948
+ return this._cachedOwnerAgent ?? null;
1949
+ }
1950
+ const continuity = FindContinuityAgentMessage(rows, managerId, {
1951
+ conversationManagerName: this.conversationManagerAgent?.Name ?? 'Sage',
1952
+ isWithinFloor: msg => !this.AgentHistoryFrom || msg.__mj_CreatedAt >= this.AgentHistoryFrom,
1953
+ });
1954
+ let targetId = null;
1955
+ if (continuity?.AgentID && this.isOwnerAgentAllowed(continuity.AgentID)) {
1956
+ targetId = continuity.AgentID;
1957
+ }
1958
+ else {
1959
+ const fallbackId = defaultId ?? managerId;
1960
+ if (fallbackId && this.isOwnerAgentAllowed(fallbackId)) {
1961
+ targetId = fallbackId;
1962
+ }
1963
+ }
1964
+ if (!targetId) {
1965
+ this._cachedOwnerAgentKey = cacheKey;
1966
+ this._cachedOwnerAgent = null;
1967
+ return null;
1968
+ }
1969
+ const meta = this.resolveHandoffAgentMeta(targetId);
1970
+ const isManager = managerId ? UUIDsEqual(targetId, managerId) : false;
1971
+ const owner = {
1972
+ ID: targetId,
1973
+ Name: meta?.Name || (isManager ? (this.conversationManagerAgent?.Name || 'Sage') : 'Agent'),
1974
+ IsConversationManager: isManager,
1975
+ };
1976
+ this._cachedOwnerAgentKey = cacheKey;
1977
+ this._cachedOwnerAgent = owner;
1978
+ return owner;
1979
+ }
1980
+ get CurrentOwnerAgentName() {
1981
+ return this.CurrentOwnerAgent?.Name || this.conversationManagerAgent?.Name || 'Sage';
1982
+ }
1983
+ get CurrentOwnerAccentVar() {
1984
+ return AgentAccentVar(this.CurrentOwnerAgent?.ID);
1985
+ }
1986
+ isOwnerAgentAllowed(agentId) {
1987
+ if (!agentId) {
1988
+ return false;
1989
+ }
1990
+ if (this.AllowedAgentIDs == null) {
1991
+ return true;
1992
+ }
1993
+ return this.AllowedAgentIDs.some(allowed => UUIDsEqual(allowed, agentId));
1994
+ }
1995
+ resolveHandoffAgentMeta(agentId) {
1996
+ if (this.conversationManagerAgent && UUIDsEqual(this.conversationManagerAgent.ID, agentId)) {
1997
+ return {
1998
+ Name: this.conversationManagerAgent.Name,
1999
+ LogoURL: this.conversationManagerAgent.LogoURL,
2000
+ IconClass: this.conversationManagerAgent.IconClass,
2001
+ };
2002
+ }
2003
+ const agents = AIEngineBase.Instance?.Agents;
2004
+ const found = agents?.find(a => UUIDsEqual(a.ID, agentId));
2005
+ if (found) {
2006
+ return {
2007
+ Name: found.Name,
2008
+ LogoURL: found.LogoURL,
2009
+ IconClass: found.IconClass,
2010
+ };
2011
+ }
2012
+ const msg = this.messages?.find(m => UUIDsEqual(m.AgentID, agentId) && m.Agent);
2013
+ if (msg) {
2014
+ return { Name: msg.Agent };
2015
+ }
2016
+ return null;
2017
+ }
1813
2018
  /**
1814
2019
  * Mode picker emitted a new selection. Store it; the next message's
1815
2020
  * route picks it up via `<mj-message-input>`'s
@@ -2268,7 +2473,7 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
2268
2473
  */
2269
2474
  initialDraftSnapshots = new Map();
2270
2475
  GetInitialDraftFor(conversationId) {
2271
- const key = conversationId ? conversationId.trim().toLowerCase() : 'new';
2476
+ const key = conversationId ? NormalizeUUID(conversationId) : 'new';
2272
2477
  if (!this.initialDraftSnapshots.has(key)) {
2273
2478
  let snapshot;
2274
2479
  if (this._composerAgentMention) {
@@ -2303,14 +2508,17 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
2303
2508
  }
2304
2509
  // New/unsaved conversations render the empty-state composer; established ones
2305
2510
  // use the active cached input. Both resolve the agent to a pill.
2306
- const target = this.emptyStateComponent ? 'empty-state' : this.messageInputComponents?.first ? 'active-input' : null;
2511
+ const activeInput = this.getActiveMessageInputComponent() ??
2512
+ this.messageInputComponents?.last ??
2513
+ this.messageInputComponents?.first;
2514
+ const target = this.emptyStateComponent ? 'empty-state' : activeInput ? 'active-input' : null;
2307
2515
  if (attempt === 0 || attempt % 10 === 0 || target) {
2308
2516
  console.log(`[Omnibar→Chat] chat-area apply('${agentName}') attempt ${attempt}: target=${target ?? 'none-mounted'}`);
2309
2517
  }
2310
2518
  const insert = this.emptyStateComponent
2311
2519
  ? this.emptyStateComponent.InsertAgentMention(agentName, true)
2312
- : this.messageInputComponents?.first
2313
- ? this.messageInputComponents.first.InsertAgentMention(agentName, true)
2520
+ : activeInput
2521
+ ? activeInput.InsertAgentMention(agentName, true)
2314
2522
  : null;
2315
2523
  if (insert) {
2316
2524
  void insert.then((applied) => {
@@ -2421,6 +2629,13 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
2421
2629
  reconcileInFlight = null;
2422
2630
  /** Reason for one more reconcile pass, requested while a pass was running. */
2423
2631
  reconcileRerunReason = null;
2632
+ /**
2633
+ * Set when a TRANSPORT reconnect asks for a pass; consumed by the next pass that starts. Held as a
2634
+ * flag rather than read off the pass's reason because {@link ReconcileNow} folds requests that
2635
+ * arrive mid-pass into one follow-up carrying only the LAST reason — a reconnect followed by a
2636
+ * tab-visible would otherwise lose the window refresh the reconnect needs.
2637
+ */
2638
+ reconcileWindowRefreshPending = false;
2424
2639
  IsProcessing = false;
2425
2640
  /** @deprecated Use {@link IsProcessing}. */
2426
2641
  get isProcessing() {
@@ -2551,6 +2766,44 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
2551
2766
  }
2552
2767
  ShowArtifactPanel = false;
2553
2768
  SelectedTaskGraphPanel = null;
2769
+ ShowRemoteBrowserPanel = false;
2770
+ RemoteBrowserUrlInput = '';
2771
+ IsRemoteBrowserNavigating = false;
2772
+ /** Whether this conversation's browser is running, shown or not (the header button stays lit while it is). */
2773
+ get IsRemoteBrowserLive() {
2774
+ return this.remoteBrowser?.ConversationId != null;
2775
+ }
2776
+ /** The conversation's browser, built on first open so a chat area that never opens one pays nothing. */
2777
+ remoteBrowser = null;
2778
+ ensureRemoteBrowser() {
2779
+ if (!this.remoteBrowser) {
2780
+ const browser = new ConversationRemoteBrowserController({
2781
+ OnAutoOpenSurface: () => this.OpenRemoteBrowserPanel(),
2782
+ // Fires on open, close and a real URL change, never per screencast frame.
2783
+ OnStateChange: () => {
2784
+ this.RemoteBrowserUrlInput = browser.CurrentUrl ?? '';
2785
+ this.cdr.detectChanges();
2786
+ },
2787
+ OnSessionRefused: (message) => {
2788
+ this.ShowRemoteBrowserPanel = false;
2789
+ MJNotificationService.Instance.CreateSimpleNotification(message, 'error', 6000);
2790
+ this.cdr.detectChanges();
2791
+ },
2792
+ });
2793
+ const provider = this.ProviderToUse;
2794
+ browser.Initialize(this.agentClientService, provider instanceof GraphQLDataProvider ? provider : null);
2795
+ this.remoteBrowser = browser;
2796
+ }
2797
+ return this.remoteBrowser;
2798
+ }
2799
+ set ConversationRemoteBrowserSurface(surface) {
2800
+ if (surface) {
2801
+ this.remoteBrowser?.BindSurface(surface);
2802
+ }
2803
+ else {
2804
+ this.remoteBrowser?.UnbindSurface();
2805
+ }
2806
+ }
2554
2807
  /** @deprecated Use {@link ShowArtifactPanel}. */
2555
2808
  get showArtifactPanel() {
2556
2809
  return this.ShowArtifactPanel;
@@ -2767,6 +3020,12 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
2767
3020
  set agentRunsByDetailId(value) {
2768
3021
  this.AgentRunsByDetailId = value;
2769
3022
  }
3023
+ /**
3024
+ * Handoff metadata by source conversation detail ID, built from the source
3025
+ * run's `Handoff` step (`MJ: AI Agent Run Steps`) and subsequent target reply.
3026
+ */
3027
+ HandoffsByDetailId = new Map();
3028
+ handoffStepsByRunId = new Map();
2770
3029
  /**
2771
3030
  * Ratings by conversation detail ID (parsed from RatingsJSON)
2772
3031
  */
@@ -2803,6 +3062,8 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
2803
3062
  this.syncSendSlot();
2804
3063
  }
2805
3064
  _inProgressMessageIds = [];
3065
+ /** Tracks the ID each in-progress reply entity was last registered under so adopting the server's row ID drops the local placeholder UUID. */
3066
+ inProgressIdByEntity;
2806
3067
  // ── The composer's send slot as the stop control ──────────────────────────────────────
2807
3068
  // While replies are in flight the composer's send slot is the stop control (one run: "Stop
2808
3069
  // {agent}"; several: "Stop all N", and each reply shows its own pill as well). The slot's mode,
@@ -3631,6 +3892,11 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
3631
3892
  namedThisSession = false;
3632
3893
  this.onRealtimeSessionStarted();
3633
3894
  });
3895
+ // A call that ends over a failure (a failed start, a dropped connection, a time limit) is ended by the
3896
+ // runtime itself, which closes the call surface with it: say why, or the call just vanishes.
3897
+ this.RealtimeSession.SessionEnded$
3898
+ .pipe(takeUntil(this.destroy$))
3899
+ .subscribe((ended) => this.notifyIfCallFailed(ended.reason));
3634
3900
  let voiceWasActive = false;
3635
3901
  this.RealtimeSession.Active$
3636
3902
  .pipe(takeUntil(this.destroy$))
@@ -3780,7 +4046,7 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
3780
4046
  this.resetComponentState(conversationId);
3781
4047
  await this.decideAndApplyArtifactPanel(artifactBaseline, conversationId);
3782
4048
  this.messages = [...this.messages];
3783
- this.followTranscript('new');
4049
+ this.followTranscript('new', newlyLoaded);
3784
4050
  this.cdr.detectChanges();
3785
4051
  }
3786
4052
  else {
@@ -3951,11 +4217,19 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
3951
4217
  for (const id of [...(this._stopFallbackTimers?.keys() ?? [])]) {
3952
4218
  this.clearStopFallbackTimer(id);
3953
4219
  }
4220
+ // Leaving the chat surface altogether ends any live voice call (including
4221
+ // minimized calls or calls minted from the empty state).
4222
+ if (this.RealtimeSession?.IsActive) {
4223
+ void this.RealtimeSession.EndRealtimeSession();
4224
+ }
3954
4225
  // Remove resize listeners
3955
- window.removeEventListener('mousemove', this.boundOnResizeMove);
3956
- window.removeEventListener('mouseup', this.boundOnResizeEnd);
3957
- window.removeEventListener('touchmove', this.boundOnResizeTouchMove);
3958
- window.removeEventListener('touchend', this.boundOnResizeTouchEnd);
4226
+ if (typeof window !== 'undefined') {
4227
+ window.removeEventListener('mousemove', this.boundOnResizeMove);
4228
+ window.removeEventListener('mouseup', this.boundOnResizeEnd);
4229
+ window.removeEventListener('touchmove', this.boundOnResizeTouchMove);
4230
+ window.removeEventListener('touchend', this.boundOnResizeTouchEnd);
4231
+ }
4232
+ this.remoteBrowser?.Dispose();
3959
4233
  }
3960
4234
  isActiveConversation(conversationId) {
3961
4235
  return UUIDsEqual(conversationId, this.ConversationId);
@@ -3972,6 +4246,13 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
3972
4246
  this.clearTurnTracking();
3973
4247
  this.ShowArtifactPanel = false;
3974
4248
  this.SelectedTaskGraphPanel = null;
4249
+ // A conversation's browser ends with it: the next conversation starts without one. Reloading the SAME
4250
+ // conversation (the overlay-to-workspace handoff) keeps it.
4251
+ const browserConversation = this.remoteBrowser?.ConversationId;
4252
+ if (!browserConversation || !UUIDsEqual(browserConversation, this._conversationId)) {
4253
+ this.ShowRemoteBrowserPanel = false;
4254
+ void this.remoteBrowser?.Close();
4255
+ }
3975
4256
  this.SelectedArtifactId = null;
3976
4257
  this.SelectedVersionNumber = undefined;
3977
4258
  this.CanShareSelectedArtifact = false;
@@ -4012,6 +4293,8 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
4012
4293
  this.ForkSummaries = [];
4013
4294
  this.ShowForksPopover = false;
4014
4295
  this.IsRenamingTitle = false;
4296
+ this.HandoffsByDetailId = new Map();
4297
+ this.handoffStepsByRunId?.clear();
4015
4298
  if (this.forkSummaryRefreshTimer) {
4016
4299
  clearTimeout(this.forkSummaryRefreshTimer);
4017
4300
  this.forkSummaryRefreshTimer = null;
@@ -4045,12 +4328,7 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
4045
4328
  if ((this.ArtifactsByDetailId?.size ?? 0) === 0 && this.artifactMapConversationId === null) {
4046
4329
  this.artifactMapConversationId = conversationId;
4047
4330
  }
4048
- if (!this.messageInputMetadataCache.has(conversationId)) {
4049
- this.messageInputMetadataCache.set(conversationId, {
4050
- conversationId: conversationId,
4051
- conversationName: this.Conversation?.Name || null
4052
- });
4053
- }
4331
+ this.touchMessageInputCache(conversationId);
4054
4332
  // Only show loading spinner if the engine doesn't have cached data for this conversation.
4055
4333
  // This prevents the "no messages" flash when switching between conversations.
4056
4334
  const hasCachedMessages = this.engine.HasCachedDetails(conversationId);
@@ -4112,13 +4390,129 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
4112
4390
  this.conversationLoadEnded$?.next();
4113
4391
  }
4114
4392
  }
4393
+ _cachedInputsArray = [];
4394
+ _cachedInputsKey = '';
4395
+ /** Max hidden composers kept mounted for draft/state preservation; older idle ones are unmounted. */
4396
+ static MAX_CACHED_MESSAGE_INPUTS = 10;
4397
+ /** Stable case-normalized track key for `@for` so case-only UUID changes reuse the mounted composer. */
4398
+ NormalizeCachedInputId(conversationId) {
4399
+ return NormalizeUUID(conversationId);
4400
+ }
4401
+ findMessageInputCacheEntry(conversationId) {
4402
+ const exact = this.messageInputMetadataCache.get(conversationId);
4403
+ if (exact) {
4404
+ return { key: conversationId, meta: exact };
4405
+ }
4406
+ for (const [key, meta] of this.messageInputMetadataCache.entries()) {
4407
+ if (UUIDsEqual(key, conversationId)) {
4408
+ return { key, meta };
4409
+ }
4410
+ }
4411
+ return undefined;
4412
+ }
4413
+ resolveConversationNameForCache(conversationId) {
4414
+ const activeConv = this.Conversation;
4415
+ if (activeConv?.Name && (!activeConv.ID || UUIDsEqual(activeConv.ID, conversationId))) {
4416
+ return activeConv.Name;
4417
+ }
4418
+ return this.engine?.GetConversation?.(conversationId)?.Name || null;
4419
+ }
4420
+ syncCachedMessageInputName(conversationId, name) {
4421
+ if (!this.messageInputMetadataCache || !conversationId || !name) {
4422
+ return;
4423
+ }
4424
+ const found = this.findMessageInputCacheEntry(conversationId);
4425
+ if (found && found.meta.conversationName !== name) {
4426
+ this.messageInputMetadataCache.set(found.key, {
4427
+ ...found.meta,
4428
+ conversationName: name,
4429
+ });
4430
+ }
4431
+ }
4432
+ findMessageInputComponent(conversationId) {
4433
+ if (!this.messageInputComponents || !conversationId) {
4434
+ return undefined;
4435
+ }
4436
+ return this.messageInputComponents.find(component => UUIDsEqual(component.ConversationId ?? component.conversationId, conversationId));
4437
+ }
4438
+ /**
4439
+ * True when a cached hidden composer for `candidateId` is idle and safe to unmount.
4440
+ * Never evicts the newly-activated conversation, a conversation awaiting auto-send of
4441
+ * `PendingMessage`, a conversation hosting a live voice session, a conversation with
4442
+ * running tasks in `ActiveTasksService`, or a mounted composer with in-flight streaming
4443
+ * callbacks / DB watches / unsent file attachments (`HasActiveWork`).
4444
+ */
4445
+ canEvictCachedMessageInput(candidateId, activeConversationId) {
4446
+ if (UUIDsEqual(candidateId, activeConversationId) || UUIDsEqual(candidateId, this.ConversationId)) {
4447
+ return false;
4448
+ }
4449
+ if (this._pendingMessage && this.ShouldDeliverPendingMessageTo(candidateId)) {
4450
+ return false;
4451
+ }
4452
+ if (this.RealtimeSession?.IsActiveFor?.(candidateId)) {
4453
+ return false;
4454
+ }
4455
+ if (this.activeTasks?.HasActiveTasksForConversation?.(candidateId)) {
4456
+ return false;
4457
+ }
4458
+ const mounted = this.findMessageInputComponent(candidateId);
4459
+ if (mounted?.HasActiveWork) {
4460
+ return false;
4461
+ }
4462
+ return true;
4463
+ }
4464
+ /**
4465
+ * Registers `conversationId` as the most-recently-used composer and unmounts the
4466
+ * least-recently-used idle ones beyond the cap. Each cache entry keeps a live
4467
+ * `mj-message-input` component, so without a bound memory grows with every
4468
+ * conversation visited. Composers actively running an agent turn, holding unsent
4469
+ * file attachments, or hosting a live voice call are skipped until idle. Drafts
4470
+ * live in the draft store, so an evicted composer's frozen restore snapshot is
4471
+ * dropped to let a remount re-read the latest draft.
4472
+ */
4473
+ touchMessageInputCache(conversationId) {
4474
+ const existing = this.findMessageInputCacheEntry(conversationId);
4475
+ if (existing) {
4476
+ this.messageInputMetadataCache.delete(existing.key); // re-insert to refresh recency & align casing
4477
+ }
4478
+ const conversationName = existing?.meta.conversationName ?? this.resolveConversationNameForCache(conversationId);
4479
+ this.messageInputMetadataCache.set(conversationId, {
4480
+ conversationId,
4481
+ conversationName,
4482
+ });
4483
+ if (this.messageInputMetadataCache.size <= ConversationChatAreaComponent.MAX_CACHED_MESSAGE_INPUTS) {
4484
+ return;
4485
+ }
4486
+ for (const [candidateKey, entry] of [...this.messageInputMetadataCache.entries()]) {
4487
+ if (this.messageInputMetadataCache.size <= ConversationChatAreaComponent.MAX_CACHED_MESSAGE_INPUTS) {
4488
+ break;
4489
+ }
4490
+ if (!this.canEvictCachedMessageInput(entry.conversationId, conversationId)) {
4491
+ continue;
4492
+ }
4493
+ this.messageInputMetadataCache.delete(candidateKey);
4494
+ this.initialDraftSnapshots?.delete(NormalizeUUID(entry.conversationId));
4495
+ }
4496
+ }
4115
4497
  /**
4116
- * Returns array of cached message-input metadata for rendering
4498
+ * Returns array of cached message-input metadata for rendering.
4117
4499
  * This allows multiple message-input components to exist simultaneously (hidden)
4118
- * preserving their state when switching conversations
4500
+ * preserving their state when switching conversations.
4501
+ * Memoized on cache contents so template `@for` loops receive a stable array reference across CD ticks.
4119
4502
  */
4120
4503
  GetCachedInputs() {
4121
- return Array.from(this.messageInputMetadataCache.values());
4504
+ if (this.messageInputMetadataCache.size === 0) {
4505
+ return this._cachedInputsArray.length === 0 ? this._cachedInputsArray : (this._cachedInputsArray = []);
4506
+ }
4507
+ let key = '';
4508
+ for (const [id, meta] of this.messageInputMetadataCache.entries()) {
4509
+ key += `${id}:${meta.conversationName ?? ''}|`;
4510
+ }
4511
+ if (key !== this._cachedInputsKey) {
4512
+ this._cachedInputsKey = key;
4513
+ this._cachedInputsArray = Array.from(this.messageInputMetadataCache.values());
4514
+ }
4515
+ return this._cachedInputsArray;
4122
4516
  }
4123
4517
  /** @deprecated Use {@link GetCachedInputs}. */
4124
4518
  getCachedInputs() {
@@ -4141,10 +4535,10 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
4141
4535
  * we need to find the one that matches the current conversationId.
4142
4536
  */
4143
4537
  getActiveMessageInputComponent() {
4144
- if (!this.messageInputComponents || !this.ConversationId) {
4538
+ if (!this.ConversationId) {
4145
4539
  return undefined;
4146
4540
  }
4147
- return this.messageInputComponents.find(component => component.conversationId === this.ConversationId);
4541
+ return this.findMessageInputComponent(this.ConversationId);
4148
4542
  }
4149
4543
  async loadMessages(conversationId, loadToken) {
4150
4544
  try {
@@ -4298,7 +4692,7 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
4298
4692
  if (!this.isActiveConversationLoad(conversationId, loadToken)) {
4299
4693
  return;
4300
4694
  }
4301
- this.windowStore.SetPinnedCount(result.Success ? result.TotalRowCount : 0);
4695
+ this.windowStore.SetPinnedCount(result.Success ? result.TotalRowCount ?? 0 : 0);
4302
4696
  }
4303
4697
  /**
4304
4698
  * Hydrates the pins panel's rows — first panel open only.
@@ -4419,6 +4813,18 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
4419
4813
  if (sessionMeta.size > 0) {
4420
4814
  this.RealtimeSessionMetaMap = new Map([...this.RealtimeSessionMetaMap, ...sessionMeta]);
4421
4815
  }
4816
+ const newRunIds = newIds
4817
+ .map(id => this.AgentRunsByDetailId.get(id)?.ID)
4818
+ .filter((id) => !!id);
4819
+ if (newRunIds.length > 0) {
4820
+ await this.loadHandoffStepsForRunIds(newRunIds, conversationId);
4821
+ if (!this.isActiveConversation(conversationId)) {
4822
+ return;
4823
+ }
4824
+ }
4825
+ else {
4826
+ this.rebuildHandoffsMap();
4827
+ }
4422
4828
  // A page of OLDER artifacts just entered the map. Any artifact-panel baseline taken before
4423
4829
  // this point can no longer be diffed against the map for creations — these arrived from
4424
4830
  // history, not from a run. See snapshotArtifactPanelBaseline.
@@ -4460,6 +4866,7 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
4460
4866
  this.ArtifactsByDetailId.clear();
4461
4867
  this.SystemArtifactsByDetailId.clear();
4462
4868
  this.RatingsByDetailId.clear();
4869
+ this.handoffStepsByRunId.clear();
4463
4870
  // Copy agent runs from engine (cast to extended type for UI compatibility)
4464
4871
  for (const [detailId, agentRun] of cacheEntry.AgentRunsByDetailId) {
4465
4872
  this.AgentRunsByDetailId.set(detailId, agentRun);
@@ -4491,6 +4898,13 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
4491
4898
  if (!this.isCurrentConversationContext(conversationId, loadToken)) {
4492
4899
  return;
4493
4900
  }
4901
+ const runIds = Array.from(this.AgentRunsByDetailId.values())
4902
+ .map(r => r?.ID)
4903
+ .filter((id) => !!id);
4904
+ await this.loadHandoffStepsForRunIds(runIds, conversationId, loadToken);
4905
+ if (!this.isCurrentConversationContext(conversationId, loadToken)) {
4906
+ return;
4907
+ }
4494
4908
  // Create new Map references to trigger Angular change detection
4495
4909
  this.AgentRunsByDetailId = new Map(this.AgentRunsByDetailId);
4496
4910
  this.ArtifactsByDetailId = new Map(this.ArtifactsByDetailId);
@@ -4513,6 +4927,42 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
4513
4927
  this.artifactMapConversationId = null;
4514
4928
  }
4515
4929
  }
4930
+ async loadHandoffStepsForRunIds(runIds, conversationId, loadToken) {
4931
+ if (runIds.length > 0) {
4932
+ const steps = await LoadHandoffStepsForRuns(this.ProviderToUse, runIds);
4933
+ if (conversationId != null &&
4934
+ !this.isCurrentConversationContext(conversationId, loadToken)) {
4935
+ return;
4936
+ }
4937
+ for (const step of steps) {
4938
+ if (step && step.ID && step.AgentRunID && (!step.StepType || step.StepType === 'Handoff')) {
4939
+ this.handoffStepsByRunId.set(step.ID, step);
4940
+ }
4941
+ }
4942
+ }
4943
+ this.rebuildHandoffsMap();
4944
+ }
4945
+ rebuildHandoffsMap() {
4946
+ const stepsMap = this.handoffStepsByRunId;
4947
+ if (!stepsMap || stepsMap.size === 0 || !this.AgentRunsByDetailId || this.AgentRunsByDetailId.size === 0) {
4948
+ if (!this.HandoffsByDetailId || this.HandoffsByDetailId.size > 0) {
4949
+ this.HandoffsByDetailId = new Map();
4950
+ }
4951
+ return;
4952
+ }
4953
+ const engineAgents = AIEngineBase.Instance?.Agents ?? [];
4954
+ const agents = this.conversationManagerAgent &&
4955
+ !engineAgents.some(a => UUIDsEqual(a.ID, this.conversationManagerAgent?.ID))
4956
+ ? [this.conversationManagerAgent, ...engineAgents]
4957
+ : engineAgents;
4958
+ this.HandoffsByDetailId = BuildHandoffsByDetailId({
4959
+ Messages: this.messages ?? [],
4960
+ AgentRunsByDetailId: this.AgentRunsByDetailId,
4961
+ HandoffSteps: Array.from(stepsMap.values()),
4962
+ Agents: agents,
4963
+ Presets: AIEngineBase.Instance?.AgentConfigurations ?? [],
4964
+ });
4965
+ }
4516
4966
  /**
4517
4967
  * Loads the `MJ: AI Agent Sessions` rows referenced by the conversation's
4518
4968
  * session-stamped details (one batched lookup, narrow fields, only when stamped rows
@@ -4607,12 +5057,25 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
4607
5057
  this.replaceDisplayedRow(message);
4608
5058
  this.windowStore.ApplyLocalDetail(message);
4609
5059
  }
5060
+ const rootId = this.collapsedThreadRootId(message);
5061
+ if (rootId !== null) {
5062
+ if (index < 0) {
5063
+ // A hidden reply's first frame: the full path adds the row once; later frames patch it in place above.
5064
+ this.ngZone.run(() => void this.OnMessageSent(message));
5065
+ return;
5066
+ }
5067
+ const root = (this.messages ?? []).find(m => UUIDsEqual(m.ID, rootId));
5068
+ if (root) {
5069
+ this.messageListComponent?.RefreshRenderedMessage(root);
5070
+ }
5071
+ return;
5072
+ }
4610
5073
  if (!this.messageListComponent?.RefreshRenderedMessage(message)) {
4611
5074
  // The first delta can beat the bubble's own render; the full path handles that one update.
4612
5075
  this.ngZone.run(() => void this.OnMessageSent(message));
4613
5076
  return;
4614
5077
  }
4615
- this.followTranscript('stream');
5078
+ this.followTranscript('stream', message);
4616
5079
  }
4617
5080
  /** Drops a landing still queued or retrying, so it cannot resolve after a newer one. */
4618
5081
  cancelPendingLanding() {
@@ -4655,18 +5118,11 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
4655
5118
  this.windowStore.ApplyLocalDetail(message);
4656
5119
  // Check if message already exists in the array (by ID) to prevent duplicates
4657
5120
  // Messages can be emitted multiple times as they're updated (e.g., status changes)
4658
- const existingIndex = this.messages.findIndex(m => UUIDsEqual(m.ID, message.ID));
4659
- if (existingIndex >= 0) {
4660
- // Update existing message in place (replace with updated version)
4661
- this.messages = [
4662
- ...this.messages.slice(0, existingIndex),
4663
- message,
4664
- ...this.messages.slice(existingIndex + 1)
4665
- ];
4666
- }
4667
- else {
4668
- // Add new message to the list
4669
- this.messages = [...this.messages, message];
5121
+ // An agent reply's placeholder takes the server row's ID when the run is acknowledged; a refresh may already have
5122
+ // brought that row in, so other copies of the ID are dropped.
5123
+ const upsert = UpsertMessageById(this.messages, message);
5124
+ this.messages = upsert.Messages;
5125
+ if (!upsert.Existed) {
4670
5126
  // Ensure current user is in the avatar map for new messages
4671
5127
  this.ensureCurrentUserInAvatarMap();
4672
5128
  // Invalidate cache when new message is added.
@@ -4687,8 +5143,17 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
4687
5143
  // row does not stay In-Progress until the conversation is opened again. Register the row
4688
5144
  // for the live callback either way — an update of an existing In-Progress row included.
4689
5145
  if (message.Status === 'In-Progress' && message.ID) {
4690
- if (!this.InProgressMessageIds.some((id) => UUIDsEqual(id, message.ID))) {
4691
- this.InProgressMessageIds = [...this.InProgressMessageIds, message.ID];
5146
+ const entityMap = (this.inProgressIdByEntity ??= new WeakMap());
5147
+ const previousId = entityMap.get(message);
5148
+ entityMap.set(message, message.ID);
5149
+ const withoutPrevious = previousId && !UUIDsEqual(previousId, message.ID)
5150
+ ? this.InProgressMessageIds.filter((id) => !UUIDsEqual(id, previousId))
5151
+ : this.InProgressMessageIds;
5152
+ if (!withoutPrevious.some((id) => UUIDsEqual(id, message.ID))) {
5153
+ this.InProgressMessageIds = [...withoutPrevious, message.ID];
5154
+ }
5155
+ else if (withoutPrevious !== this.InProgressMessageIds) {
5156
+ this.InProgressMessageIds = withoutPrevious;
4692
5157
  }
4693
5158
  const recentCompletion = this.streamingService.GetRecentCompletion(message.ID);
4694
5159
  if (recentCompletion) {
@@ -4698,9 +5163,16 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
4698
5163
  }
4699
5164
  }
4700
5165
  }
5166
+ else if (this.isSettled(message)) {
5167
+ // The final frame of a reply can arrive as a plain send; it leaves the in-flight list here.
5168
+ this.dropSettledFromInFlight();
5169
+ }
4701
5170
  // Where the viewport goes: a fresh send follows — an in-place update of a message that
4702
- // is already on screen must not re-run the send path's scroll.
4703
- this.followTranscript(existingIndex >= 0 ? 'update' : 'new', message);
5171
+ // is already on screen must not re-run the send path's scroll or rebuild the handoffs map.
5172
+ if (!upsert.Existed) {
5173
+ this.rebuildHandoffsMap();
5174
+ }
5175
+ this.followTranscript(upsert.Existed ? 'update' : 'new', message);
4704
5176
  // Force change detection — zone.js 0.15 no longer patches graphql-ws WebSocket callbacks,
4705
5177
  // so progress updates that arrive via PubSub run outside Angular's zone. Without this,
4706
5178
  // the UI does not update when the messages array is modified from a streaming callback.
@@ -4825,10 +5297,17 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
4825
5297
  ConversationEngine.Instance.SetAgentRunForDetail(event.conversationId, event.conversationDetailId, newEntity);
4826
5298
  }
4827
5299
  }
5300
+ await this.loadHandoffStepsForRunIds([existingAgentRun.ID], event.conversationId);
5301
+ if (!this.isActiveConversation(event.conversationId)) {
5302
+ return;
5303
+ }
4828
5304
  // Trigger re-render to show updated status
4829
5305
  this.messages = [...this.messages];
4830
5306
  this.cdr.detectChanges();
4831
5307
  }
5308
+ else {
5309
+ this.rebuildHandoffsMap();
5310
+ }
4832
5311
  // Reload attachments for this message to pick up newly created media attachments
4833
5312
  // (e.g., images generated by agent via Generate Image action)
4834
5313
  // This must be done after agent completion because attachments are created by AgentRunner
@@ -4864,6 +5343,9 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
4864
5343
  ConversationEngine.Instance.SetAgentRunForDetail(event.conversationId, event.conversationDetailId, event.agentRun);
4865
5344
  }
4866
5345
  }
5346
+ if (!existingRun || !UUIDsEqual(existingRun.ID, event.agentRun.ID)) {
5347
+ this.rebuildHandoffsMap();
5348
+ }
4867
5349
  }
4868
5350
  else {
4869
5351
  // no agent run, should have agentRunId
@@ -4919,7 +5401,7 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
4919
5401
  // Track existing message IDs before reload to identify new messages
4920
5402
  const existingMessageIds = new Set(this.messages.map(m => m.ID));
4921
5403
  // Merge the refreshed window with existing client-side messages.
4922
- // Preserves messages added client-side (e.g., by handleSubAgentInvocation)
5404
+ // Preserves messages added client-side (e.g., server-followed handoff rows)
4923
5405
  // that haven't been picked up by entity events yet due to timing.
4924
5406
  const merged = new Map();
4925
5407
  for (const msg of engineDetails) {
@@ -4931,20 +5413,24 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
4931
5413
  merged.set(msg.ID, msg);
4932
5414
  }
4933
5415
  }
4934
- this.messages = Array.from(merged.values())
4935
- .sort((a, b) => (a.__mj_CreatedAt?.getTime() || 0) - (b.__mj_CreatedAt?.getTime() || 0));
5416
+ this.messages = Array.from(merged.values()).sort(CompareMessagesByCreatedAt);
4936
5417
  // Find newly discovered messages (delegated agents)
4937
5418
  const newMessages = engineDetails.filter(m => !existingMessageIds.has(m.ID));
4938
5419
  // Check engine cache for agent runs on new messages
5420
+ const discoveredRunIds = [];
4939
5421
  for (const message of newMessages) {
4940
5422
  if (message.AgentID && message.ID) {
4941
5423
  const agentRun = this.engine.GetAgentRunForDetail(conversationId, message.ID);
4942
5424
  if (agentRun) {
4943
5425
  this.AgentRunsByDetailId.set(message.ID, agentRun);
5426
+ if (agentRun.ID) {
5427
+ discoveredRunIds.push(agentRun.ID);
5428
+ }
4944
5429
  LogStatusEx({ message: `✅ Found cached agent run for new delegated message ${message.ID}`, verboseOnly: true });
4945
5430
  }
4946
5431
  }
4947
5432
  }
5433
+ await this.loadHandoffStepsForRunIds(discoveredRunIds, conversationId);
4948
5434
  LogStatusEx({ message: `✅ Refreshed ${engineDetails.length} messages from engine cache (${newMessages.length} new)`, verboseOnly: true });
4949
5435
  }
4950
5436
  catch (error) {
@@ -5584,22 +6070,36 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
5584
6070
  const view = this.WindowView;
5585
6071
  const branches = UUIDsEqual(this.branchRowsConversationId, this.ConversationId) ? (this.branches ?? NO_BRANCHES) : NO_BRANCHES;
5586
6072
  const canFork = this.CanFork;
6073
+ const collapseThreads = Boolean(this.CollapseThreadReplies);
5587
6074
  const cache = this.inPlaceTurnCache;
5588
- if (cache && cache.Messages === messages && cache.View === view && cache.Branches === branches && cache.CanFork === canFork) {
6075
+ if (cache &&
6076
+ cache.Messages === messages &&
6077
+ cache.View === view &&
6078
+ cache.Branches === branches &&
6079
+ cache.CanFork === canFork &&
6080
+ cache.CollapseThreads === collapseThreads) {
5589
6081
  return cache.Turn;
5590
6082
  }
5591
6083
  const turn = canFork ? null : this.unblockedLatestTurn(messages, view, branches);
5592
- this.inPlaceTurnCache = { Messages: messages, View: view, Branches: branches, CanFork: canFork, Turn: turn };
6084
+ this.inPlaceTurnCache = {
6085
+ Messages: messages,
6086
+ View: view,
6087
+ Branches: branches,
6088
+ CanFork: canFork,
6089
+ CollapseThreads: collapseThreads,
6090
+ Turn: turn,
6091
+ };
5593
6092
  return turn;
5594
6093
  }
5595
6094
  /** The latest turn of the rows, or null when there is none or a fork depends on its answer rows. */
5596
6095
  unblockedLatestTurn(messages, view, branches) {
5597
- const turn = FindLatestTurn(messages, view);
5598
- const user = turn ? messages.find(m => UUIDsEqual(m.ID, turn.UserDetailID)) : undefined;
6096
+ const mainFlow = this.CollapseThreadReplies ? this.displayState().MainFlow : messages;
6097
+ const turn = FindLatestTurn(mainFlow, view);
6098
+ const user = turn ? mainFlow.find(m => UUIDsEqual(m.ID, turn.UserDetailID)) : undefined;
5599
6099
  if (!turn || !user) {
5600
6100
  return null;
5601
6101
  }
5602
- return ForkDependsOnRows(user.BranchID ?? null, TurnRowsAfter(messages, user), branches) ? null : turn;
6102
+ return ForkDependsOnRows(user.BranchID ?? null, this.turnRowsAfter(messages, user), branches) ? null : turn;
5603
6103
  }
5604
6104
  /** "Save and resend": the message item saved the new text of the latest user message; reruns its turn in place. */
5605
6105
  async OnResendInPlaceRequested(userMessage) {
@@ -5623,7 +6123,7 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
5623
6123
  if (!input) {
5624
6124
  return;
5625
6125
  }
5626
- const answerRows = TurnRowsAfter(this.messages ?? [], userMessage);
6126
+ const answerRows = this.turnRowsAfter(this.messages ?? [], userMessage);
5627
6127
  if (answerRows.some(r => r.Status === 'In-Progress')) {
5628
6128
  MJNotificationService.Instance.CreateSimpleNotification('Wait for the current reply to finish', 'error', 3000);
5629
6129
  return;
@@ -5667,6 +6167,23 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
5667
6167
  this.inPlaceRerunInFlight = false;
5668
6168
  }
5669
6169
  }
6170
+ /**
6171
+ * The rows of `userMessage`'s turn that an in-place rerun replaces: when thread replies are
6172
+ * collapsed, the main-flow rows after `userMessage` plus any thread replies rooted on those rows.
6173
+ */
6174
+ turnRowsAfter(messages, userMessage) {
6175
+ if (!this.CollapseThreadReplies) {
6176
+ return TurnRowsAfter(messages, userMessage);
6177
+ }
6178
+ const roots = GetThreadReplyRoots(messages);
6179
+ const mainFlow = messages.filter(m => !roots.Has(m.ID));
6180
+ const mainAfter = TurnRowsAfter(mainFlow, userMessage);
6181
+ const afterRoots = new UUIDSet(mainAfter.map(m => m.ID));
6182
+ return TurnRowsAfter(messages, userMessage).filter(m => {
6183
+ const rootId = roots.Get(m.ID);
6184
+ return afterRoots.Has(m.ID) || (rootId !== undefined && afterRoots.Has(rootId));
6185
+ });
6186
+ }
5670
6187
  /**
5671
6188
  * Marks each row replaced, one save at a time (parallel saves race on the server's transaction
5672
6189
  * counter): `ReplacedAt` set and `HiddenToUser` true; the rows are kept for audit. Takes the saved rows
@@ -5756,7 +6273,7 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
5756
6273
  }
5757
6274
  /** The nearest earlier User row in the loaded window; null when the window holds none. */
5758
6275
  findUserMessageBefore(aiMessage) {
5759
- const sorted = [...this.messages].sort((a, b) => a.Sequence - b.Sequence);
6276
+ const sorted = [...this.displayState().MainFlow].sort((a, b) => a.Sequence - b.Sequence);
5760
6277
  const index = sorted.findIndex(m => UUIDsEqual(m.ID, aiMessage.ID));
5761
6278
  for (let i = index - 1; i >= 0; i--) {
5762
6279
  if (sorted[i].Role === 'User') {
@@ -5869,6 +6386,17 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
5869
6386
  get WindowView() {
5870
6387
  return this.windowView ?? MAIN_OPEN_VIEW;
5871
6388
  }
6389
+ /**
6390
+ * When true, thread replies in the loaded window are omitted from top-level `DisplayMessages` so
6391
+ * they can be rendered inside a collapsed thread under their root message (see
6392
+ * {@link GetThreadReplyRoots}).
6393
+ */
6394
+ CollapseThreadReplies = false;
6395
+ /**
6396
+ * Emits when a jump targets a collapsed thread reply, after scrolling to its top-level root
6397
+ * message, so the host can open the thread and reveal the reply.
6398
+ */
6399
+ ThreadReplyRevealRequested = new EventEmitter();
5872
6400
  /**
5873
6401
  * The rows the message list shows for the window view; the same array until the rows or the view
5874
6402
  * change. Main shows every loaded row; a fork shows every inherited row, then its own rows; a draft
@@ -5881,16 +6409,45 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
5881
6409
  displayState() {
5882
6410
  const messages = this.messages ?? [];
5883
6411
  const view = this.WindowView;
6412
+ const collapseThreads = Boolean(this.CollapseThreadReplies);
5884
6413
  const cache = this.displayCache;
5885
- if (cache && cache.Messages === messages && cache.View === view) {
6414
+ if (cache && cache.Messages === messages && cache.View === view && cache.CollapseThreads === collapseThreads) {
5886
6415
  return cache;
5887
6416
  }
5888
- const split = SplitForkRows(messages, view);
5889
- const rows = view.Kind === 'Main' ? messages : [...split.Inherited, ...split.Own];
5890
- const next = { Messages: messages, View: view, Split: split, Rows: rows };
6417
+ const threadReplyRoots = collapseThreads ? GetThreadReplyRoots(messages) : EMPTY_THREAD_REPLY_ROOTS;
6418
+ const mainFlow = collapseThreads ? messages.filter((m) => !threadReplyRoots.Has(m.ID)) : messages;
6419
+ const split = SplitForkRows(mainFlow, view);
6420
+ const rows = view.Kind === 'Main' ? mainFlow : [...split.Inherited, ...split.Own];
6421
+ const next = {
6422
+ Messages: messages,
6423
+ View: view,
6424
+ CollapseThreads: collapseThreads,
6425
+ ThreadReplyRoots: threadReplyRoots,
6426
+ MainFlow: mainFlow,
6427
+ Split: split,
6428
+ Rows: rows,
6429
+ };
5891
6430
  this.displayCache = next;
5892
6431
  return next;
5893
6432
  }
6433
+ /**
6434
+ * Top-level root ID for `message` when {@link CollapseThreadReplies} is on and `message` is a
6435
+ * thread reply; null when thread collapsing is off or `message` belongs in the main flow.
6436
+ */
6437
+ collapsedThreadRootId(message) {
6438
+ if (!this.CollapseThreadReplies) {
6439
+ return null;
6440
+ }
6441
+ const fromLoaded = this.displayState().ThreadReplyRoots.Get(message.ID);
6442
+ if (fromLoaded) {
6443
+ return fromLoaded;
6444
+ }
6445
+ const loaded = this.messages ?? [];
6446
+ if (loaded.some((m) => UUIDsEqual(m.ID, message.ID))) {
6447
+ return null;
6448
+ }
6449
+ return GetThreadReplyRoots([...loaded, message]).Get(message.ID) ?? null;
6450
+ }
5894
6451
  /**
5895
6452
  * Puts `message` in place of the row with its id in the displayed rows and their split, keeping those
5896
6453
  * arrays. They are copies of `messages`, so an entity replaced in place there is replaced here too.
@@ -5900,6 +6457,7 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
5900
6457
  if (!cache || cache.Messages !== this.messages) {
5901
6458
  return;
5902
6459
  }
6460
+ this.replaceRowIn(cache.MainFlow, message);
5903
6461
  this.replaceRowIn(cache.Rows, message);
5904
6462
  this.replaceRowIn(cache.Split.Inherited, message);
5905
6463
  this.replaceRowIn(cache.Split.Own, message);
@@ -5960,6 +6518,13 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
5960
6518
  if (stoppedAgent !== undefined) {
5961
6519
  return `Continue, or tell ${stoppedAgent ?? 'the agent'} what to do differently`;
5962
6520
  }
6521
+ const owner = this.CurrentOwnerAgent;
6522
+ if (owner && !owner.IsConversationManager) {
6523
+ if (owner.Name.trim().toLowerCase() === 'video studio') {
6524
+ return `Ask ${owner.Name} for changes, like "make the opening faster"`;
6525
+ }
6526
+ return `Ask ${owner.Name} for changes or a follow-up...`;
6527
+ }
5963
6528
  }
5964
6529
  return MAIN_COMPOSER_PLACEHOLDER;
5965
6530
  }
@@ -6076,7 +6641,8 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
6076
6641
  if (anchor) {
6077
6642
  return anchor;
6078
6643
  }
6079
- const inherited = view === this.WindowView ? this.displayState().Split.Inherited : SplitForkRows(messages, view).Inherited;
6644
+ const state = this.displayState();
6645
+ const inherited = view === this.WindowView ? state.Split.Inherited : SplitForkRows(state.MainFlow, view).Inherited;
6080
6646
  return inherited.length > 0 ? inherited[inherited.length - 1] : null;
6081
6647
  }
6082
6648
  /** A short date and time for fork text, in the person's locale. */
@@ -6262,6 +6828,10 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
6262
6828
  if (!isCurrent()) {
6263
6829
  return;
6264
6830
  }
6831
+ await this.loadHandoffStepsForRunIds([agentRun.ID], expectedConversationId, loadToken);
6832
+ if (!isCurrent()) {
6833
+ return;
6834
+ }
6265
6835
  }
6266
6836
  }
6267
6837
  // Reload artifacts for this completed message
@@ -6300,6 +6870,7 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
6300
6870
  // The completed message was mutated in place — refresh the window's copy too.
6301
6871
  this.windowStore.ApplyLocalDetail(message);
6302
6872
  // Force re-render with updated agent run and artifacts
6873
+ this.rebuildHandoffsMap();
6303
6874
  this.messages = [...this.messages];
6304
6875
  this.cdr.detectChanges();
6305
6876
  LogStatusEx({ message: `✅ Completion handled for message ${message.ID}`, verboseOnly: true });
@@ -6314,6 +6885,8 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
6314
6885
  if (!finished && completionId) {
6315
6886
  this.handledCompletionIds?.delete(completionId);
6316
6887
  }
6888
+ // The row was loaded above whatever happened after; if it settled, it is no longer in flight.
6889
+ this.dropSettledFromInFlight();
6317
6890
  }
6318
6891
  }
6319
6892
  async OnAgentResponse(event) {
@@ -6406,6 +6979,10 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
6406
6979
  ConversationEngine.Instance.SetAgentRunForDetail(conversationId, conversationDetailId, existingRun);
6407
6980
  }
6408
6981
  }
6982
+ await this.loadHandoffStepsForRunIds([agentRunId], conversationId);
6983
+ if (!this.isActiveConversation(conversationId)) {
6984
+ return agentRun;
6985
+ }
6409
6986
  // Refresh the target message in place when already rendered; fall back to
6410
6987
  // shallow array copy only when the message is not yet mounted in the list.
6411
6988
  const targetMessage = this.messages.find(m => UUIDsEqual(m.ID, conversationDetailId));
@@ -6680,17 +7257,30 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
6680
7257
  get hasSystemArtifacts() {
6681
7258
  return this.HasSystemArtifacts;
6682
7259
  }
7260
+ _artifactsArrayCache = [];
7261
+ _artifactsArrayKey = '';
6683
7262
  /**
6684
- * Get unique artifacts grouped by artifact ID (not by conversation detail)
6685
- * Returns the latest version info for each unique artifact with all versions
6686
- * Works with LazyArtifactInfo - uses display data without loading full entities
6687
- * Respects showSystemArtifacts toggle
7263
+ * Get unique artifacts grouped by artifact ID (not by conversation detail).
7264
+ * Returns the latest version info for each unique artifact with all versions.
7265
+ * Works with LazyArtifactInfo - uses display data without loading full entities.
7266
+ * Respects showSystemArtifacts toggle and memoizes the result across CD passes.
6688
7267
  */
6689
7268
  GetArtifactsArray() {
7269
+ const effectiveMap = this.EffectiveArtifactsMap;
7270
+ let sig = `${this.ShowSystemArtifacts ? 1 : 0}|${effectiveMap.size}|`;
7271
+ for (const artifactList of effectiveMap.values()) {
7272
+ for (const info of artifactList) {
7273
+ sig += `${info.artifactVersionId}:${info.artifactName ?? ''};`;
7274
+ }
7275
+ }
7276
+ if (sig === this._artifactsArrayKey) {
7277
+ return this._artifactsArrayCache;
7278
+ }
7279
+ this._artifactsArrayKey = sig;
6690
7280
  const artifactMap = new Map();
6691
7281
  // Group by artifactId, collecting all version details
6692
7282
  // Use effectiveArtifactsMap to respect showSystemArtifacts toggle
6693
- for (const artifactList of this.EffectiveArtifactsMap.values()) {
7283
+ for (const artifactList of effectiveMap.values()) {
6694
7284
  for (const info of artifactList) {
6695
7285
  const artifactId = info.artifactId;
6696
7286
  const versionId = info.artifactVersionId;
@@ -6717,7 +7307,7 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
6717
7307
  }
6718
7308
  }
6719
7309
  // Convert to array with version count, sorted by version number descending
6720
- return Array.from(artifactMap.values()).map(item => ({
7310
+ this._artifactsArrayCache = Array.from(artifactMap.values()).map(item => ({
6721
7311
  artifactId: item.artifactId,
6722
7312
  versionId: item.versionId,
6723
7313
  name: item.name,
@@ -6725,6 +7315,7 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
6725
7315
  versionCount: item.versions.length,
6726
7316
  versions: item.versions.sort((a, b) => b.versionNumber - a.versionNumber)
6727
7317
  }));
7318
+ return this._artifactsArrayCache;
6728
7319
  }
6729
7320
  /** @deprecated Use {@link GetArtifactsArray}. */
6730
7321
  getArtifactsArray() {
@@ -6969,14 +7560,13 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
6969
7560
  // region the list unmounts into spacers — so this button silently did nothing for any pin
6970
7561
  // that wasn't already on screen. The list resolves through the timeline key, which a
6971
7562
  // spacer shares with the item it stands in for.
6972
- if (this.messageListComponent?.ScrollToMessage(messageId)) {
6973
- this.beaconMessage(messageId);
7563
+ if (this.scrollToMessageOrThreadRoot(messageId)) {
6974
7564
  return;
6975
7565
  }
6976
7566
  // Not in the loaded window. Pins are fetched by their own query precisely so the panel can
6977
7567
  // list pins older than the transcript, so this is the EXPECTED case for an old pin, not an
6978
7568
  // error — page back until it is loaded, the same way a date jump does.
6979
- const reached = await this.loadUntilMessageIsWindowed(messageId);
7569
+ const reached = (await this.loadUntilMessageIsWindowed(messageId)) && (await this.loadUntilThreadRootIsWindowed(messageId));
6980
7570
  if (!reached) {
6981
7571
  MJNotificationService.Instance.CreateSimpleNotification('Could not reach that message — it is further back than this jump loads.', 'info', 3000);
6982
7572
  return;
@@ -6984,10 +7574,7 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
6984
7574
  // The paging loop deliberately skipped the per-page peripheral rebuild — pay it once,
6985
7575
  // here, before asking the list for element positions.
6986
7576
  await this.refreshAfterPaging(this.ConversationId);
6987
- if (this.messageListComponent?.ScrollToMessage(messageId)) {
6988
- this.beaconMessage(messageId);
6989
- }
6990
- else {
7577
+ if (!this.scrollToMessageOrThreadRoot(messageId)) {
6991
7578
  MJNotificationService.Instance.CreateSimpleNotification('Could not find that message in this conversation', 'info', 3000);
6992
7579
  }
6993
7580
  }
@@ -7019,6 +7606,10 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
7019
7606
  return false;
7020
7607
  }
7021
7608
  await this.loadUntilSequenceIsWindowed(sequence);
7609
+ const hit = this.windowStore.GetSnapshot().Details.find(m => m.Sequence === sequence && UUIDsEqual(m.BranchID ?? null, branchId));
7610
+ if (hit) {
7611
+ await this.loadUntilThreadRootIsWindowed(hit.ID);
7612
+ }
7022
7613
  if (!this.isActiveConversation(conversationId)) {
7023
7614
  return false;
7024
7615
  }
@@ -7029,13 +7620,43 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
7029
7620
  this.scrollToBottom = false;
7030
7621
  this.bottomFollowSuppressedUntil = Date.now() + 1500;
7031
7622
  }
7032
- if (!row || !this.messageListComponent?.ScrollToMessage(row.ID)) {
7623
+ if (!row || !this.scrollToMessageOrThreadRoot(row.ID, 'search-hit-highlight', 2000)) {
7033
7624
  MJNotificationService.Instance.CreateSimpleNotification('Could not find that message in this conversation', 'info', 3000);
7034
7625
  return false;
7035
7626
  }
7036
- this.beaconMessage(row.ID, 'search-hit-highlight', 2000);
7037
7627
  return true;
7038
7628
  }
7629
+ /**
7630
+ * Scrolls to `messageId`, or when {@link CollapseThreadReplies} hides `messageId` under a thread
7631
+ * root, scrolls to that root and emits {@link ThreadReplyRevealRequested} so the host can open
7632
+ * the thread. False when the row (or its root) is not loaded, so the caller can page back for it.
7633
+ */
7634
+ scrollToMessageOrThreadRoot(messageId, cssClass = 'pin-beacon', durationMs = 1500) {
7635
+ const rootId = this.CollapseThreadReplies
7636
+ ? this.displayState().ThreadReplyRoots.Get(messageId)
7637
+ : undefined;
7638
+ if (rootId) {
7639
+ if (!this.messageListComponent?.ScrollToMessage(rootId)) {
7640
+ return false;
7641
+ }
7642
+ this.beaconMessage(rootId, cssClass, durationMs);
7643
+ this.emitThreadReplyReveal(messageId, rootId);
7644
+ return true;
7645
+ }
7646
+ if (this.messageListComponent?.ScrollToMessage(messageId)) {
7647
+ this.beaconMessage(messageId, cssClass, durationMs);
7648
+ return true;
7649
+ }
7650
+ return false;
7651
+ }
7652
+ emitThreadReplyReveal(replyId, rootId) {
7653
+ const loadedReply = (this.messages ?? []).find(m => UUIDsEqual(m.ID, replyId));
7654
+ const loadedRoot = (this.messages ?? []).find(m => UUIDsEqual(m.ID, rootId));
7655
+ this.ThreadReplyRevealRequested.emit({
7656
+ ReplyID: loadedReply?.ID ?? replyId,
7657
+ RootID: loadedRoot?.ID ?? rootId,
7658
+ });
7659
+ }
7039
7660
  /**
7040
7661
  * Waits until the load of `conversationId` has ended. False when another conversation
7041
7662
  * becomes active first or the component is destroyed.
@@ -7051,12 +7672,39 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
7051
7672
  }
7052
7673
  /** Pages older history until the pinned message `messageId` falls inside the loaded window. */
7053
7674
  async loadUntilMessageIsWindowed(messageId) {
7054
- const target = this.PinnedMessages.find(p => UUIDsEqual(p.ID, messageId));
7675
+ const target = this.PinnedMessages?.find(p => UUIDsEqual(p.ID, messageId));
7055
7676
  if (!target) {
7056
7677
  return false; // not a loaded pin — nothing tells us how far back to page
7057
7678
  }
7058
7679
  return this.loadUntilSequenceIsWindowed(target.Sequence);
7059
7680
  }
7681
+ /**
7682
+ * With {@link CollapseThreadReplies} on, pages older history until the top-level root of the loaded
7683
+ * thread reply `messageId` is loaded too, since the jump lands on the root. True when nothing more is
7684
+ * needed (collapsing off, `messageId` not a loaded thread reply, or its root loaded).
7685
+ */
7686
+ async loadUntilThreadRootIsWindowed(messageId) {
7687
+ if (!this.CollapseThreadReplies) {
7688
+ return true;
7689
+ }
7690
+ const conversationId = this.ConversationId;
7691
+ for (let page = 0; page < DATE_JUMP_MAX_PAGES; page++) {
7692
+ const snapshot = this.windowStore.GetSnapshot();
7693
+ // Recomputed per page: a loaded parent that is itself a reply moves the root further up.
7694
+ const rootId = GetThreadReplyRoots(snapshot.Details).Get(messageId);
7695
+ if (!rootId || new UUIDSet(snapshot.Details.map(m => m.ID)).Has(rootId)) {
7696
+ return true;
7697
+ }
7698
+ if (!snapshot.Cursor.HasMoreAbove) {
7699
+ return false;
7700
+ }
7701
+ await this.windowStore.LoadOlder(this.CurrentUser);
7702
+ if (!this.isActiveConversation(conversationId)) {
7703
+ return false;
7704
+ }
7705
+ }
7706
+ return false;
7707
+ }
7060
7708
  /**
7061
7709
  * Pages older history until the loaded window reaches back to `sequence`.
7062
7710
  *
@@ -7111,7 +7759,9 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
7111
7759
  message.IsPinned = false;
7112
7760
  this.cdr.detectChanges();
7113
7761
  try {
7114
- await message.Save();
7762
+ if (!(await SavePinState(this.ProviderToUse, message.ID, false))) {
7763
+ throw new Error(`the pin on message ${message.ID} could not be saved`);
7764
+ }
7115
7765
  this.OnMessagePinToggled(message);
7116
7766
  }
7117
7767
  catch (err) {
@@ -7180,10 +7830,9 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
7180
7830
  }
7181
7831
  // Find this message and all messages after it sorted by Sequence
7182
7832
  const sortedMessages = [...this.messages].sort((a, b) => a.Sequence - b.Sequence);
7183
- const targetIndex = sortedMessages.findIndex(m => UUIDsEqual(m.ID, message.ID));
7184
- if (targetIndex === -1)
7833
+ const toHide = this.rowsToDeleteFrom(sortedMessages, message.ID);
7834
+ if (toHide.length === 0)
7185
7835
  return;
7186
- const toHide = sortedMessages.slice(targetIndex);
7187
7836
  const count = toHide.length;
7188
7837
  const confirmed = await this.confirmDialog.confirm({
7189
7838
  title: 'Delete Messages',
@@ -7216,15 +7865,52 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
7216
7865
  console.error(`Failed to delete ConversationDetail ${e.ID}: ${last?.Message ?? 'unknown error'}`, last?.Error ?? '');
7217
7866
  }
7218
7867
  }
7219
- const hideIds = new Set(toHide.map(m => m.ID));
7868
+ const hideIds = new UUIDSet(toHide.map(m => m.ID));
7220
7869
  // Drop them from the window too, or the next RefreshLatest merge reinstates them.
7221
- for (const id of hideIds) {
7222
- this.windowStore.RemoveDetail(id);
7870
+ for (const m of toHide) {
7871
+ this.windowStore.RemoveDetail(m.ID);
7223
7872
  }
7224
- this.messages = this.messages.filter(m => !hideIds.has(m.ID));
7873
+ this.messages = this.messages.filter(m => !hideIds.Has(m.ID));
7225
7874
  this.resetComponentState(this.ConversationId);
7226
7875
  this.cdr.detectChanges();
7227
7876
  }
7877
+ /**
7878
+ * The rows removed by "delete this and everything after": when thread replies are collapsed,
7879
+ * the target, every main-flow row after it, and any thread replies whose root is among those rows.
7880
+ * When the target is itself a thread reply, only the target and the replies under it.
7881
+ */
7882
+ rowsToDeleteFrom(sortedMessages, targetId) {
7883
+ const targetIndex = sortedMessages.findIndex(m => UUIDsEqual(m.ID, targetId));
7884
+ if (targetIndex === -1) {
7885
+ return [];
7886
+ }
7887
+ if (!this.CollapseThreadReplies) {
7888
+ return sortedMessages.slice(targetIndex);
7889
+ }
7890
+ const roots = GetThreadReplyRoots(sortedMessages);
7891
+ if (roots.Has(targetId)) {
7892
+ // Sorted by Sequence, so a reply always follows its parent: one pass collects the subtree.
7893
+ const subtree = new UUIDSet([sortedMessages[targetIndex].ID]);
7894
+ for (let i = targetIndex + 1; i < sortedMessages.length; i++) {
7895
+ const parentId = sortedMessages[i].ParentID;
7896
+ if (parentId && subtree.Has(parentId)) {
7897
+ subtree.Add(sortedMessages[i].ID);
7898
+ }
7899
+ }
7900
+ return sortedMessages.filter(m => subtree.Has(m.ID));
7901
+ }
7902
+ const removedRoots = new UUIDSet();
7903
+ for (let i = targetIndex; i < sortedMessages.length; i++) {
7904
+ const id = sortedMessages[i].ID;
7905
+ if (!roots.Has(id) || i === targetIndex) {
7906
+ removedRoots.Add(id);
7907
+ }
7908
+ }
7909
+ return sortedMessages.filter(m => {
7910
+ const rootId = roots.Get(m.ID);
7911
+ return removedRoots.Has(m.ID) || (rootId !== undefined && removedRoots.Has(rootId));
7912
+ });
7913
+ }
7228
7914
  /** @deprecated Use {@link OnDeleteMessage}. */
7229
7915
  async onDeleteMessage(message) {
7230
7916
  return this.OnDeleteMessage(message);
@@ -7331,6 +8017,7 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
7331
8017
  this.SelectedVersionNumber = undefined;
7332
8018
  }
7333
8019
  this.SelectedTaskGraphPanel = null;
8020
+ this.ShowRemoteBrowserPanel = false;
7334
8021
  this.ShowArtifactPanel = true;
7335
8022
  // Load permissions for the selected artifact
7336
8023
  await this.loadArtifactPermissions(data.artifactId, conversationId, data.artifactId);
@@ -7355,6 +8042,7 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
7355
8042
  return;
7356
8043
  }
7357
8044
  this.ShowArtifactPanel = false;
8045
+ this.ShowRemoteBrowserPanel = false;
7358
8046
  this.SelectedArtifactId = null;
7359
8047
  this.SelectedTaskGraphPanel = {
7360
8048
  parentTaskId: data.parentTaskId,
@@ -7368,6 +8056,73 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
7368
8056
  this.resetArtifactPaneSizing();
7369
8057
  this.cdr.detectChanges();
7370
8058
  }
8059
+ ToggleRemoteBrowserPanel() {
8060
+ if (this.ShowRemoteBrowserPanel) {
8061
+ this.CloseRemoteBrowserPanel();
8062
+ }
8063
+ else {
8064
+ this.OpenRemoteBrowserPanel();
8065
+ }
8066
+ }
8067
+ OpenRemoteBrowserPanel() {
8068
+ if (this.ShowRemoteBrowserPanel || !this.AllowRemoteBrowser || !this.ConversationId) {
8069
+ return;
8070
+ }
8071
+ // Open before the drawer renders: binding its surface starts the screencast for this conversation.
8072
+ this.ensureRemoteBrowser().Open(this.ConversationId);
8073
+ this.ShowArtifactPanel = false;
8074
+ this.SelectedTaskGraphPanel = null;
8075
+ this.SelectedArtifactId = null;
8076
+ this.ShowRemoteBrowserPanel = true;
8077
+ this.cdr.detectChanges();
8078
+ }
8079
+ /** Closing the drawer ends the browser (hiding it behind an artifact does not). */
8080
+ CloseRemoteBrowserPanel() {
8081
+ if (!this.ShowRemoteBrowserPanel) {
8082
+ return;
8083
+ }
8084
+ this.ShowRemoteBrowserPanel = false;
8085
+ this.resetArtifactPaneSizing();
8086
+ void this.remoteBrowser?.Close();
8087
+ this.cdr.detectChanges();
8088
+ }
8089
+ async NavigateRemoteBrowserFromInput() {
8090
+ const rawUrl = this.RemoteBrowserUrlInput?.trim();
8091
+ if (!rawUrl || this.IsRemoteBrowserNavigating) {
8092
+ return;
8093
+ }
8094
+ this.IsRemoteBrowserNavigating = true;
8095
+ this.cdr.detectChanges();
8096
+ try {
8097
+ const result = await this.remoteBrowser?.Navigate(rawUrl);
8098
+ // A refused session already said why (OnSessionRefused) and closed the browser.
8099
+ if (result && !result.Success && this.IsRemoteBrowserLive) {
8100
+ MJNotificationService.Instance.CreateSimpleNotification(result.ErrorMessage ?? 'The page could not be opened.', 'error', 5000);
8101
+ }
8102
+ }
8103
+ finally {
8104
+ this.IsRemoteBrowserNavigating = false;
8105
+ this.cdr.detectChanges();
8106
+ }
8107
+ }
8108
+ /**
8109
+ * `AppContext` plus the conversation's open browser (its URL, and the `browser_*` tools while this
8110
+ * chat area owns them). Cached: it is bound to an input, so a fresh object per check would re-fire it.
8111
+ */
8112
+ get EffectiveAppContext() {
8113
+ const controller = this.remoteBrowser;
8114
+ if (!controller) {
8115
+ return this.AppContext;
8116
+ }
8117
+ const owns = controller.ConversationId !== null && controller.OwnsTools;
8118
+ let memo = this.effectiveAppContextMemo;
8119
+ if (!memo || memo.Base !== this.AppContext || memo.Version !== controller.StateVersion || memo.Owns !== owns) {
8120
+ memo = { Base: this.AppContext, Version: controller.StateVersion, Owns: owns, Value: controller.WithBrowserContext(this.AppContext) };
8121
+ this.effectiveAppContextMemo = memo;
8122
+ }
8123
+ return memo.Value;
8124
+ }
8125
+ effectiveAppContextMemo = null;
7371
8126
  /**
7372
8127
  * Persists the currently displayed Task Graph in the chat side-panel as a reusable
7373
8128
  * Draft Flow Agent workflow via {@link WorkflowSaveOperation} and opens the new
@@ -7648,6 +8403,9 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
7648
8403
  }
7649
8404
  OnConversationRenamed(event) {
7650
8405
  LogStatusEx({ message: '🎉 Conversation renamed', verboseOnly: true, additionalArgs: [event] });
8406
+ if (event?.conversationId && event.name) {
8407
+ this.syncCachedMessageInputName(event.conversationId, event.name);
8408
+ }
7651
8409
  // Pass the event up to workspace component for animation
7652
8410
  this.ConversationRenamed.emit(event);
7653
8411
  }
@@ -7918,6 +8676,17 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
7918
8676
  void this.engine.EnsureConversationLoaded(created, this.CurrentUser);
7919
8677
  this.RealtimeConversationReady.emit({ conversationId: created, select: false });
7920
8678
  }
8679
+ /**
8680
+ * Says why a call ended only when it ended over a failure. A `'deadline'` end (the runtime's time-limit auto-end) is
8681
+ * a normal end: the call surface closes on its own and the visitor needs no error toast.
8682
+ */
8683
+ notifyIfCallFailed(reason) {
8684
+ if (reason !== 'error') {
8685
+ return;
8686
+ }
8687
+ const notice = DescribeCallFailureNotice(this.RealtimeSession.LastStartError, this.RealtimeSession.LastSessionError);
8688
+ MJNotificationService.Instance.CreateSimpleNotification(notice, 'error', 6000);
8689
+ }
7921
8690
  /**
7922
8691
  * Post-call hook. Two responsibilities:
7923
8692
  * 1. Reload the ACTIVE conversation's timeline so the session that just ended — whose
@@ -8688,6 +9457,9 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
8688
9457
  * in flight.
8689
9458
  */
8690
9459
  followTranscript(change, message) {
9460
+ if (message && this.collapsedThreadRootId(message) !== null) {
9461
+ return;
9462
+ }
8691
9463
  if (change === 'load') {
8692
9464
  this.scrollToBottom = true;
8693
9465
  return;
@@ -8731,6 +9503,27 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
8731
9503
  isSettled(message) {
8732
9504
  return message.Status === 'Complete' || message.Status === 'Error';
8733
9505
  }
9506
+ /**
9507
+ * Drops every in-flight ID whose loaded row has settled. A settled reply is never in flight:
9508
+ * the list drives the composer's Stop slot and its ticker, and every reconcile path scans the
9509
+ * rows for `In-Progress`, so an ID left behind after its row settled would never be looked at
9510
+ * again (the overlay's Stop button ticked for hours after Regenerate-as-fork this way). An ID
9511
+ * with no loaded row is kept; the row may simply not be on screen yet.
9512
+ */
9513
+ dropSettledFromInFlight() {
9514
+ const ids = this.InProgressMessageIds;
9515
+ if (ids.length === 0) {
9516
+ return;
9517
+ }
9518
+ const byID = IndexByUUID(this.messages ?? []);
9519
+ const stillInFlight = ids.filter((id) => {
9520
+ const row = byID.Get(id);
9521
+ return !row || !this.isSettled(row);
9522
+ });
9523
+ if (stillInFlight.length !== ids.length) {
9524
+ this.InProgressMessageIds = stillInFlight;
9525
+ }
9526
+ }
8734
9527
  /**
8735
9528
  * Where the viewport goes on a streamed delta, in the same frame as the DOM change so growth and
8736
9529
  * scroll paint together. Without ReadReplyFromTop, or for a turn this component never saw open
@@ -8900,6 +9693,7 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
8900
9693
  // (prioritizing ParentRunID == null and ContinuationDepth == 0 over continuation
8901
9694
  // synthesis runs, and newest __mj_CreatedAt among ties so retried messages use their latest run).
8902
9695
  const chosenByDetailId = new Map();
9696
+ const refreshedRunIds = [];
8903
9697
  for (const run of result.Results || []) {
8904
9698
  const detailId = run.ConversationDetailID;
8905
9699
  if (!detailId) {
@@ -8912,9 +9706,13 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
8912
9706
  }
8913
9707
  for (const [detailId, run] of chosenByDetailId.entries()) {
8914
9708
  this.AgentRunsByDetailId.set(detailId, run);
9709
+ if (run.ID) {
9710
+ refreshedRunIds.push(run.ID);
9711
+ }
8915
9712
  }
8916
9713
  // New map reference so OnPush children re-read it.
8917
9714
  this.AgentRunsByDetailId = new Map(this.AgentRunsByDetailId);
9715
+ await this.loadHandoffStepsForRunIds(refreshedRunIds, conversationId, loadToken);
8918
9716
  }
8919
9717
  /**
8920
9718
  * Reconcile in-progress messages against durable server state, on demand.
@@ -8929,6 +9727,9 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
8929
9727
  * @param reason What prompted it — carried only for logging.
8930
9728
  */
8931
9729
  async ReconcileNow(reason) {
9730
+ if (ConversationChatAreaComponent.TRANSPORT_RECONNECT_REASONS.includes(reason)) {
9731
+ this.reconcileWindowRefreshPending = true;
9732
+ }
8932
9733
  if (this.reconcileInFlight) {
8933
9734
  this.reconcileRerunReason = reason;
8934
9735
  return this.reconcileInFlight;
@@ -8950,6 +9751,49 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
8950
9751
  this.reconcileInFlight = null;
8951
9752
  }
8952
9753
  }
9754
+ /**
9755
+ * Supervisor reasons that mean the transport itself was down, so anything published meanwhile
9756
+ * was dropped. Only these pay for {@link refreshNewestWindow}; the other triggers
9757
+ * (tab-visible, browser-online, message-liveness, completion-for-unloaded-message) keep the
9758
+ * narrow run-row refresh alone.
9759
+ */
9760
+ static TRANSPORT_RECONNECT_REASONS = ['socket-reconnected', 'stream-reconnected'];
9761
+ /**
9762
+ * After a transport reconnect, re-read the newest window page before reconciling, when any AI
9763
+ * message is still unsettled.
9764
+ *
9765
+ * Two things {@link refreshAgentRunsForInProgress} alone does not cover:
9766
+ *
9767
+ * - **Error-status messages.** {@link correctStaleErrorMessages} can repair a message the client
9768
+ * marked Error while the server went on to complete the run — but only against a fresh run
9769
+ * row, and the narrow refresh reads runs for In-Progress messages only. Rebuilding the
9770
+ * peripherals from the refreshed window gives it current runs for every message in view.
9771
+ * - **Rows written while the socket was down.** Their events were dropped, so only a re-read
9772
+ * brings them into the window.
9773
+ *
9774
+ * Newest page only, the same choice the poll-completion path makes: a full-history refresh
9775
+ * would replace the loaded window with every row. Only called when
9776
+ * {@link hasUnsettledAgentReplies} is true, so a quiet conversation costs one array scan.
9777
+ *
9778
+ * @returns false when the conversation changed underneath, so the caller abandons the pass.
9779
+ */
9780
+ async refreshNewestWindow(conversationId, loadToken) {
9781
+ await this.windowStore.RefreshLatest(this.currentUser);
9782
+ if (!this.isActiveConversationLoad(conversationId, loadToken)) {
9783
+ return false;
9784
+ }
9785
+ const refreshed = this.windowStore.GetSnapshot();
9786
+ this.messages = refreshed.Details;
9787
+ // loadPeripheralData short-circuits when it has already run for this conversation; clearing
9788
+ // the marker is what lets it rebuild the run map from the fresh window.
9789
+ this.lastLoadedConversationId = null;
9790
+ await this.loadPeripheralData(conversationId, refreshed, loadToken);
9791
+ return this.isActiveConversationLoad(conversationId, loadToken);
9792
+ }
9793
+ /** Whether any agent reply is still In-Progress, or is Error and may have completed server-side. */
9794
+ hasUnsettledAgentReplies() {
9795
+ return (this.messages ?? []).some(m => m.Role === 'AI' && (m.Status === 'In-Progress' || m.Status === 'Error'));
9796
+ }
8953
9797
  /** One reconcile pass over the in-progress messages of the active conversation. */
8954
9798
  async reconcileOnce(reason) {
8955
9799
  const conversationId = this.conversationId;
@@ -8962,6 +9806,16 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
8962
9806
  const loadToken = this.conversationLoadToken;
8963
9807
  LogStatusEx({ message: `🔁 Reconciling in-progress runs (${reason})`, verboseOnly: true });
8964
9808
  try {
9809
+ if (this.reconcileWindowRefreshPending) {
9810
+ this.reconcileWindowRefreshPending = false;
9811
+ // Decided synchronously so a pass with nothing unsettled adds no await to next's path.
9812
+ if (this.hasUnsettledAgentReplies()) {
9813
+ const stillActive = await this.refreshNewestWindow(conversationId, loadToken);
9814
+ if (!stillActive) {
9815
+ return;
9816
+ }
9817
+ }
9818
+ }
8965
9819
  await this.refreshAgentRunsForInProgress(conversationId, loadToken);
8966
9820
  if (!this.isActiveConversationLoad(conversationId, loadToken)) {
8967
9821
  return;
@@ -9062,6 +9916,8 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
9062
9916
  * Reconnect to in-progress agent runs whose completion events were missed.
9063
9917
  */
9064
9918
  async reconnectInProgressRuns(conversationId, loadToken) {
9919
+ // An ID whose row settled while its completion was missed would never be found by the scan below.
9920
+ this.dropSettledFromInFlight();
9065
9921
  const inProgressMessages = this.messages.filter(m => m.Status === 'In-Progress' && m.Role === 'AI');
9066
9922
  if (inProgressMessages.length === 0) {
9067
9923
  return;
@@ -9165,7 +10021,7 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
9165
10021
  scrollToMessage(messageId) {
9166
10022
  // Wait for DOM to update, then scroll
9167
10023
  setTimeout(() => {
9168
- if (this.messageListComponent?.ScrollToMessage(messageId)) {
10024
+ if (this.scrollToMessageOrThreadRoot(messageId)) {
9169
10025
  return;
9170
10026
  }
9171
10027
  const messageElement = document.querySelector(`[data-message-id="${messageId}"]`);
@@ -9241,52 +10097,54 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
9241
10097
  let _t;
9242
10098
  i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.chatSlotChildren = _t);
9243
10099
  } }, viewQuery: function ConversationChatAreaComponent_Query(rf, ctx) { if (rf & 1) {
9244
- i0.ɵɵviewQuery(_c0, 5)(ArtifactViewerPanelComponent, 5)(ConversationEmptyStateComponent, 5)(MessageListComponent, 5)(_c1, 5)(_c2, 5, ElementRef)(_c3, 5, ElementRef)(_c4, 5);
10100
+ i0.ɵɵviewQuery(_c0, 5)(ArtifactViewerPanelComponent, 5)(ConversationEmptyStateComponent, 5)(_c1, 5)(MessageListComponent, 5)(_c2, 5)(_c3, 5, ElementRef)(_c4, 5, ElementRef)(_c5, 5);
9245
10101
  } if (rf & 2) {
9246
10102
  let _t;
9247
10103
  i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.scrollContainerRef = _t.first);
9248
10104
  i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.artifactViewerComponent = _t.first);
9249
10105
  i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.emptyStateComponent = _t.first);
10106
+ i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.ConversationRemoteBrowserSurface = _t.first);
9250
10107
  i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.messageListComponent = _t.first);
9251
10108
  i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.titleNameInput = _t.first);
9252
10109
  i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.titleRenameButton = _t.first);
9253
10110
  i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.forksButton = _t.first);
9254
10111
  i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.messageInputComponents = _t);
9255
- } }, inputs: { EnvironmentId: "EnvironmentId", environmentId: "environmentId", CurrentUser: "CurrentUser", currentUser: "currentUser", ConversationId: "ConversationId", conversationId: "conversationId", Conversation: "Conversation", conversation: "conversation", SuppressNewConversationEmptyState: "SuppressNewConversationEmptyState", suppressNewConversationEmptyState: "suppressNewConversationEmptyState", AllowMentions: "AllowMentions", allowMentions: "allowMentions", AllowAgentMentions: "AllowAgentMentions", allowAgentMentions: "allowAgentMentions", AllowEntityMentions: "AllowEntityMentions", allowEntityMentions: "allowEntityMentions", AllowSkillCommands: "AllowSkillCommands", allowSkillCommands: "allowSkillCommands", AllowAttachments: "AllowAttachments", allowAttachments: "allowAttachments", AllowPlanMode: "AllowPlanMode", allowPlanMode: "allowPlanMode", AllowRealtime: "AllowRealtime", allowRealtime: "allowRealtime", AllowForking: "AllowForking", AllowStopRun: "AllowStopRun", ShowEmptyFill: "ShowEmptyFill", showEmptyFill: "showEmptyFill", ShowLoadingState: "ShowLoadingState", showLoadingState: "showLoadingState", ReadReplyFromTop: "ReadReplyFromTop", readReplyFromTop: "readReplyFromTop", ShowAgentRunDetails: "ShowAgentRunDetails", showAgentRunDetails: "showAgentRunDetails", ShowReactions: "ShowReactions", showReactions: "showReactions", ShowMessageRating: "ShowMessageRating", showMessageRating: "showMessageRating", AllowPinning: "AllowPinning", allowPinning: "allowPinning", AllowMessageEdit: "AllowMessageEdit", allowMessageEdit: "allowMessageEdit", AllowMessageDelete: "AllowMessageDelete", allowMessageDelete: "allowMessageDelete", ReadOnly: "ReadOnly", ReadOnlyMessage: "ReadOnlyMessage", ShowSuggestedPrompts: "ShowSuggestedPrompts", showSuggestedPrompts: "showSuggestedPrompts", ShowDateNavigation: "ShowDateNavigation", showDateNavigation: "showDateNavigation", AssistantDisplayName: "AssistantDisplayName", assistantDisplayName: "assistantDisplayName", AssistantAvatarUrl: "AssistantAvatarUrl", assistantAvatarUrl: "assistantAvatarUrl", IsNewConversation: "IsNewConversation", isNewConversation: "isNewConversation", PendingMessage: "PendingMessage", pendingMessage: "pendingMessage", PendingMessageConversationId: "PendingMessageConversationId", pendingMessageConversationId: "pendingMessageConversationId", PendingAttachments: "PendingAttachments", pendingAttachments: "pendingAttachments", PendingArtifactId: "PendingArtifactId", pendingArtifactId: "pendingArtifactId", PendingArtifactVersionNumber: "PendingArtifactVersionNumber", pendingArtifactVersionNumber: "pendingArtifactVersionNumber", PendingArtifactConversationId: "PendingArtifactConversationId", pendingArtifactConversationId: "pendingArtifactConversationId", OverlayMode: "OverlayMode", overlayMode: "overlayMode", ShowExportButton: "ShowExportButton", showExportButton: "showExportButton", ExportButtonLabel: "ExportButtonLabel", exportButtonLabel: "exportButtonLabel", ExportButtonIcon: "ExportButtonIcon", exportButtonIcon: "exportButtonIcon", ExportBranding: "ExportBranding", exportBranding: "exportBranding", ShowShareButton: "ShowShareButton", showShareButton: "showShareButton", ShowArtifactIndicator: "ShowArtifactIndicator", showArtifactIndicator: "showArtifactIndicator", AppContext: "AppContext", appContext: "appContext", DefaultAgentId: "DefaultAgentId", defaultAgentId: "defaultAgentId", AgentReplyMode: "AgentReplyMode", AllowedAgentIDs: "AllowedAgentIDs", MentionPeople: "MentionPeople", AgentHistoryFrom: "AgentHistoryFrom", AgentTurnHandler: "AgentTurnHandler", AutoNameConversation: "AutoNameConversation", EnableDecisionRouting: "EnableDecisionRouting", ApplicationScope: "ApplicationScope", applicationScope: "applicationScope", ApplicationId: "ApplicationId", applicationId: "applicationId", LinkedEntityId: "LinkedEntityId", linkedEntityId: "linkedEntityId", LinkedRecordId: "LinkedRecordId", linkedRecordId: "linkedRecordId", ShowAgentPicker: "ShowAgentPicker", showAgentPicker: "showAgentPicker", ShowAgentModePicker: "ShowAgentModePicker", showAgentModePicker: "showAgentModePicker", EmptyStateGreeting: "EmptyStateGreeting", emptyStateGreeting: "emptyStateGreeting", ShowSidebarToggle: "ShowSidebarToggle", showSidebarToggle: "showSidebarToggle", ShowAgentCharacter: "ShowAgentCharacter", showAgentCharacter: "showAgentCharacter", AgentCharacterConfig: "AgentCharacterConfig", agentCharacterConfig: "agentCharacterConfig", EmptyStateConfig: "EmptyStateConfig", emptyStateConfig: "emptyStateConfig", ShowDemonstrationSurface: "ShowDemonstrationSurface", showDemonstrationSurface: "showDemonstrationSurface", DemonstrationSurfaceContent: "DemonstrationSurfaceContent", demonstrationSurfaceContent: "demonstrationSurfaceContent", ComposerDraft: "ComposerDraft", composerDraft: "composerDraft", ComposerAgentMention: "ComposerAgentMention", composerAgentMention: "composerAgentMention" }, outputs: { BeforeAgentTurn: "BeforeAgentTurn", beforeAgentTurn: "beforeAgentTurn", AfterAgentTurn: "AfterAgentTurn", afterAgentTurn: "afterAgentTurn", BeforeToolInvoked: "BeforeToolInvoked", beforeToolInvoked: "beforeToolInvoked", AfterToolInvoked: "AfterToolInvoked", afterToolInvoked: "afterToolInvoked", BeforeResponseFormSubmitted: "BeforeResponseFormSubmitted", beforeResponseFormSubmitted: "beforeResponseFormSubmitted", AfterResponseFormSubmitted: "AfterResponseFormSubmitted", afterResponseFormSubmitted: "afterResponseFormSubmitted", BeforeStopClicked: "BeforeStopClicked", AfterStopClicked: "AfterStopClicked", SessionStarted: "SessionStarted", sessionStarted: "sessionStarted", SessionChannelStateChanged: "SessionChannelStateChanged", sessionChannelStateChanged: "sessionChannelStateChanged", SessionEnded: "SessionEnded", sessionEnded: "sessionEnded", ConversationRenamed: "ConversationRenamed", conversationRenamed: "conversationRenamed", OpenEntityRecord: "OpenEntityRecord", openEntityRecord: "openEntityRecord", RealtimeConversationReady: "RealtimeConversationReady", realtimeConversationReady: "realtimeConversationReady", navigationRequest: "navigationRequest", TaskClicked: "TaskClicked", taskClicked: "taskClicked", ArtifactLinkClicked: "ArtifactLinkClicked", artifactLinkClicked: "artifactLinkClicked", SidebarToggleClicked: "SidebarToggleClicked", sidebarToggleClicked: "sidebarToggleClicked", ConversationCreated: "ConversationCreated", conversationCreated: "conversationCreated", PendingArtifactConsumed: "PendingArtifactConsumed", pendingArtifactConsumed: "pendingArtifactConsumed", PendingMessageConsumed: "PendingMessageConsumed", pendingMessageConsumed: "pendingMessageConsumed", PendingMessageRequested: "PendingMessageRequested", pendingMessageRequested: "pendingMessageRequested", ComposerDraftConsumed: "ComposerDraftConsumed", composerDraftConsumed: "composerDraftConsumed", ComposerAgentMentionConsumed: "ComposerAgentMentionConsumed", composerAgentMentionConsumed: "composerAgentMentionConsumed" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 30, vars: 36, consts: [["titleBar", ""], ["titleName", ""], ["forksButton", ""], ["titleNameInput", ""], ["titleRenameButton", ""], ["emptyStateInput", ""], ["scrollContainer", ""], ["messageInput", ""], ["taskGraphRunView", ""], [1, "chat-area"], [1, "chat-agent-presence", 3, "chat-agent-presence--prominent"], [1, "chat-header"], [1, "chat-content-area"], [1, "chat-demonstration-stage"], [1, "chat-messages-pane"], [1, "chat-messages-wrapper"], [3, "saved", "cancelled", "isOpen", "artifact", "currentUser"], [3, "pinnedMessages", "isLoading", "AllowUnpin"], [3, "PanelID", "Summaries", "CurrentUserID"], [3, "cancelled", "exported", "branding", "isVisible", "conversation", "Scope", "currentUser"], [3, "Result", "Visible", "Context", "Adapter"], [3, "cancelled", "membersChanged", "isVisible", "conversation", "currentUser"], [1, "modal-overlay"], [3, "isOpen", "environmentId", "currentUser", "excludeCollectionIds", "artifactVersionId", "artifactName", "artifactVersionNumber"], [3, "data", "visible"], [3, "imageUrl", "alt", "fileName", "visible"], [1, "chat-agent-presence"], [3, "State", "AgentName", "AvatarUrl", "Mode"], [4, "ngTemplateOutlet", "ngTemplateOutletContext"], [1, "chat-header", 3, "keydown.escape"], [1, "chat-info"], ["title", "Show conversations", 1, "sidebar-toggle-btn"], [1, "shared-by-badge", 3, "title"], [1, "project-tag"], ["title", "View Test Run", 1, "test-indicator"], [1, "chat-actions", "chat-actions-buttons"], ["mjButton", "", "Variant", "flat", "Size", "sm", "aria-haspopup", "dialog", "title", "Forks in this conversation", 1, "forks-button", 3, "active"], ["title", "View pinned messages", 1, "pin-chip", 3, "active"], ["title", "View artifacts", 1, "artifact-indicator"], ["title", "View members", 1, "chat-members"], [3, "AgentID", "Disabled"], [3, "Conversation", "CurrentUser", "AllowedAgentIDs", "Disabled"], ["mjButton", "", "variant", "flat", "size", "sm", 3, "title"], ["mjButton", "", "variant", "flat", "size", "sm", 3, "shared", "title"], ["title", "Show conversations", 1, "sidebar-toggle-btn", 3, "click"], [1, "fas", "fa-table-columns"], [4, "ngTemplateOutlet"], [1, "fas", "fa-share-nodes"], [1, "project-tag", 3, "click"], [1, "fas", "fa-folder"], ["title", "View Test Run", 1, "test-indicator", 3, "click"], [1, "fas", "fa-flask"], ["mjButton", "", "Variant", "flat", "Size", "sm", "aria-haspopup", "dialog", "title", "Forks in this conversation", 1, "forks-button", 3, "click"], [1, "fa-solid", "fa-code-branch"], [1, "btn-label"], [1, "forks-count"], ["title", "View pinned messages", 1, "pin-chip", 3, "click"], [1, "fas", "fa-thumbtack"], [1, "pin-chip-count"], ["title", "View artifacts", 1, "artifact-indicator", 3, "click"], [1, "fas", "fa-cube"], [1, "artifact-badge"], ["title", "View members", 1, "chat-members", 3, "click"], [1, "fas", "fa-users"], [1, "members-badge"], [3, "PresetChanged", "AgentID", "Disabled"], ["mjButton", "", "variant", "flat", "size", "sm", 3, "click", "title"], [1, "chat-title-bar"], ["aria-label", "Breadcrumb", 1, "chat-title-path"], [1, "chat-title-crumbs"], ["aria-current", "page", 1, "chat-title-current"], ["aria-hidden", "true"], [1, "chat-title-crumb", "chat-title-ellipsis", 3, "collapses-wide"], [1, "chat-title-crumb"], ["mjButton", "", "Variant", "flat", "Size", "sm", "type", "button", 3, "click", "title"], [1, "chat-title-crumb-label"], ["aria-hidden", "true", 1, "fa-solid", "fa-chevron-right", "chat-title-sep"], [1, "chat-title-crumb", "chat-title-ellipsis"], ["mjButton", "", "Variant", "flat", "Size", "sm", "type", "button", "aria-label", "Show the whole path", "title", "Show the whole path", 3, "click"], ["type", "text", "maxlength", "255", 1, "chat-title-input", 3, "ngModel"], ["type", "text", "maxlength", "255", 1, "chat-title-input", 3, "ngModelChange", "keydown.enter", "keydown.escape", "blur", "ngModel"], [1, "chat-title", 3, "title"], ["mjButton", "", "Variant", "icon", "Size", "sm", "type", "button", 1, "chat-title-rename", 3, "title"], ["mjButton", "", "Variant", "icon", "Size", "sm", "type", "button", 1, "chat-title-rename", 3, "click", "title"], ["aria-hidden", "true", 1, "fa-solid", "fa-pen"], [1, "conversation-loading-state"], ["text", "Loading conversation...", "size", "large"], ["role", "status", 1, "read-only-banner"], [3, "currentUser", "initialDraft", "disabled", "showSidebarToggle", "overlayMode", "greeting", "showSuggestedPrompts", "enableAttachments", "enableMentions", "enableAgentMentions", "enableEntityMentions", "enableSkillCommands", "AllowedAgentIDs", "MentionPeople", "ComposerExtraTemplate", "maxAttachments", "maxAttachmentSizeBytes", "acceptedFileTypes"], [1, "fas", "fa-eye"], [3, "initialDraftApplied", "DraftStateChanged", "ComposerBlurred", "sidebarToggleClicked", "messageSent", "currentUser", "initialDraft", "disabled", "showSidebarToggle", "overlayMode", "greeting", "showSuggestedPrompts", "enableAttachments", "enableMentions", "enableAgentMentions", "enableEntityMentions", "enableSkillCommands", "AllowedAgentIDs", "MentionPeople", "ComposerExtraTemplate", "maxAttachments", "maxAttachmentSizeBytes", "acceptedFileTypes"], [1, "chat-messages-container"], [1, "chat-input-container"], [1, "chat-composer-extra"], [1, "message-input-container-wrapper"], [3, "initialDraftApplied", "DraftStateChanged", "ComposerBlurred", "emptyStateSubmit", "emptyStateMode", "initialDraft", "currentUser", "disabled", "ReadOnly", "appContext", "applicationId", "defaultAgentId", "enableAttachments", "enableMentions", "enableAgentMentions", "enableEntityMentions", "enableSkillCommands", "enablePlanMode", "enableRealtime", "AllowedAgentIDs", "MentionPeople", "maxAttachments", "maxAttachmentSizeBytes", "acceptedFileTypes"], ["role", "region", "aria-label", "Fork", 1, "fork-view-bar"], [1, "upload-indicator-overlay"], [1, "chat-messages-container", 3, "scroll", "keydown.escape"], [3, "OlderRequested", "DateJumpRequested", "ForkOpenRequested", "EditResendRequested", "RegenerateRequested", "ResendInPlaceRequested", "ForkRequested", "realtimeSessionOpenRequested", "deleteMessage", "BeforeStopClicked", "StopMessage", "testFeedbackMessage", "artifactClicked", "messageEdited", "openEntityRecord", "suggestedResponseSelected", "attachmentClicked", "diagnosticRequested", "LivenessCheckRequested", "messagePinToggled", "beforeResponseFormSubmitted", "afterResponseFormSubmitted", "TaskGraphPanelRequested", "ScrollToMessageRequested", "showEmptyFill", "showDateNavigation", "showAgentRunDetails", "showReactions", "showMessageRating", "allowPinning", "allowMessageEdit", "allowMessageDelete", "ReadOnly", "AllowStopRun", "InFlightCount", "assistantDisplayName", "assistantAvatarUrl", "messages", "HasMoreAbove", "IsLoadingOlder", "ScrollRoot", "conversation", "currentUser", "isProcessing", "artifactMap", "agentRunMap", "ratingsMap", "userAvatarMap", "attachmentsMap", "messageRendererTemplate", "messageExtraTemplate", "sessionMetaMap", "ForkChipMap", "ForkLayout", "CanFork", "InPlaceTurn"], [1, "scroll-to-bottom-icon", 2, "left", "50%"], [1, "loading-peripheral-placeholder"], ["role", "region", "aria-label", "Fork", 1, "fork-view-bar", 3, "keydown.escape"], ["size", "medium", 3, "text"], [1, "scroll-to-bottom-icon", 2, "left", "50%", 3, "click"], [1, "fas", "fa-arrow-down"], ["text", "Loading conversation data...", "size", "medium"], [3, "hidden", "initialDraft", "conversationId", "conversationName", "currentUser", "conversationHistory", "artifactsByDetailId", "systemArtifactsByDetailId", "agentRunsByDetailId", "appContext", "applicationId", "defaultAgentId", "conversationDefaultAgentId", "agentConfigurationPresetId", "AgentReplyMode", "AllowedAgentIDs", "MentionPeople", "AgentHistoryFrom", "TargetBranchID", "ResolveTargetBranch", "AgentTurnHandler", "AutoNameConversation", "EnableDecisionRouting", "inProgressMessageIds", "disabled", "ReadOnly", "enableAttachments", "enableMentions", "enableAgentMentions", "enableEntityMentions", "enableSkillCommands", "enablePlanMode", "enableRealtime", "Placeholder", "SendSlotMode", "StopCount", "StopLabel", "StatusText", "StatusElapsed", "maxAttachments", "maxAttachmentSizeBytes", "acceptedFileTypes", "initialMessage", "initialAttachments"], [1, "fork-composer-hint"], [3, "DraftStateChanged", "ComposerBlurred", "StopClicked", "initialMessageAutoSendStarted", "initialMessageAutoSendFailed", "messageSent", "MessageStreamed", "agentResponse", "agentRunDetected", "agentRunUpdate", "messageComplete", "artifactCreated", "conversationRenamed", "intentCheckStarted", "intentCheckCompleted", "beforeAgentTurn", "afterAgentTurn", "uploadStateChanged", "hidden", "initialDraft", "conversationId", "conversationName", "currentUser", "conversationHistory", "artifactsByDetailId", "systemArtifactsByDetailId", "agentRunsByDetailId", "appContext", "applicationId", "defaultAgentId", "conversationDefaultAgentId", "agentConfigurationPresetId", "AgentReplyMode", "AllowedAgentIDs", "MentionPeople", "AgentHistoryFrom", "TargetBranchID", "ResolveTargetBranch", "AgentTurnHandler", "AutoNameConversation", "EnableDecisionRouting", "inProgressMessageIds", "disabled", "ReadOnly", "enableAttachments", "enableMentions", "enableAgentMentions", "enableEntityMentions", "enableSkillCommands", "enablePlanMode", "enableRealtime", "Placeholder", "SendSlotMode", "StopCount", "StopLabel", "StatusText", "StatusElapsed", "maxAttachments", "maxAttachmentSizeBytes", "acceptedFileTypes", "initialMessage", "initialAttachments"], [1, "resize-handle"], [1, "chat-artifact-pane"], [3, "closed", "saveToCollectionRequested", "navigateToLink", "shareRequested", "maximizeToggled", "openEntityRecord", "navigationRequest", "analyzeRequested", "applyFormRequested", "artifactId", "currentUser", "environmentId", "versionNumber", "viewContext", "Scope", "canShare", "canEdit", "isMaximized", "refreshTrigger"], [1, "resize-handle", 3, "mousedown", "touchstart"], [1, "chat-artifact-pane", "chat-task-graph-pane"], [1, "task-graph-pane-header"], [1, "task-graph-pane-title-group"], [1, "task-graph-pane-icon"], [1, "fa-solid", "fa-diagram-project"], [1, "task-graph-pane-titles"], [1, "task-graph-pane-title"], [1, "task-graph-pane-subtitle"], [1, "task-graph-pane-actions"], ["type", "button", "title", "Save this task graph as a reusable Draft Flow Agent workflow", 1, "task-graph-pane-save-btn", 3, "click", "disabled"], [1, "fa-solid"], ["type", "button", 1, "task-graph-pane-btn", 3, "click", "title"], ["type", "button", "title", "Close Task Graph panel", 1, "task-graph-pane-btn", 3, "click"], [1, "fa-solid", "fa-xmark"], [1, "task-graph-pane-body"], [3, "ParentTaskID", "WorkflowName", "LiveUpdates", "ShowVariables", "Height"], [3, "closed", "jumpRequested", "unpinRequested", "pinnedMessages", "isLoading", "AllowUnpin"], [3, "ForkSelected", "Closed", "PanelID", "Summaries", "CurrentUserID"], [3, "NavigateRequest", "StartLiveRequested", "ReviewClosed", "AgentName", "Hidden", "CurrentUser", "EnvironmentID", "ReviewData", "AllowStartLive", "Chrome", "Compact", "ShowDevLinks", "ShowDensityPicker"], ["type", "button", "title", "Return to the live call", "aria-label", "Return to the live call", 1, "voice-call-pill"], ["type", "button", "title", "Return to the live call", "aria-label", "Return to the live call", 1, "voice-call-pill", 3, "click"], ["aria-hidden", "true", 1, "voice-call-pill__pulse"], ["aria-hidden", "true", 1, "fa-solid", "fa-phone-volume"], [1, "voice-call-pill__text"], [1, "voice-call-pill__name"], [1, "voice-call-pill__hint"], [1, "modal-overlay", 3, "click"], [1, "modal-content", "project-selector-modal", 3, "click"], [1, "modal-header"], [1, "modal-close-btn", 3, "click"], [1, "fas", "fa-times"], [1, "modal-body"], [3, "projectSelected", "environmentId", "currentUser", "selectedProjectId"], [1, "modal-content", "artifacts-modal", 3, "click"], [1, "modal-header-actions"], ["title", "Toggle system artifacts visibility", 1, "toggle-system-btn", 3, "active"], [1, "modal-body", "artifacts-grid"], ["Icon", "fa-solid fa-cube", "Title", "No artifacts in this conversation yet", 1, "artifacts-empty-fill"], [1, "artifact-modal-card", 3, "expanded", "system-artifact"], ["title", "Toggle system artifacts visibility", 1, "toggle-system-btn", 3, "click"], [1, "fas", "fa-cog"], [1, "artifact-modal-card"], [1, "artifact-card-header", 3, "click"], [1, "artifact-modal-icon"], [1, "fas", "fa-file-code"], [1, "artifact-modal-info"], [1, "artifact-modal-title"], [1, "artifact-modal-meta"], [1, "expand-btn"], [1, "artifact-modal-action"], [1, "fas", "fa-external-link-alt"], [1, "artifact-versions-list"], [1, "expand-btn", 3, "click"], [1, "fas"], [1, "artifact-version-item"], [1, "artifact-version-item", 3, "click"], [1, "version-badge"], [1, "version-open-text"], [1, "fas", "fa-arrow-right"], [3, "completed", "cancelled", "isOpen", "environmentId", "currentUser", "excludeCollectionIds", "artifactVersionId", "artifactName", "artifactVersionNumber"], [3, "closed", "data", "visible"], [3, "closed", "imageUrl", "alt", "fileName", "visible"]], template: function ConversationChatAreaComponent_Template(rf, ctx) { if (rf & 1) {
9256
- i0.ɵɵelementStart(0, "div", 9);
9257
- i0.ɵɵconditionalCreate(1, ConversationChatAreaComponent_Conditional_1_Template, 3, 3, "div", 10);
9258
- i0.ɵɵconditionalCreate(2, ConversationChatAreaComponent_Conditional_2_Template, 1, 8, "ng-container")(3, ConversationChatAreaComponent_Conditional_3_Template, 17, 16, "div", 11);
10112
+ } }, inputs: { EnvironmentId: "EnvironmentId", environmentId: "environmentId", CurrentUser: "CurrentUser", currentUser: "currentUser", ConversationId: "ConversationId", conversationId: "conversationId", Conversation: "Conversation", conversation: "conversation", SuppressNewConversationEmptyState: "SuppressNewConversationEmptyState", suppressNewConversationEmptyState: "suppressNewConversationEmptyState", AllowMentions: "AllowMentions", allowMentions: "allowMentions", AllowAgentMentions: "AllowAgentMentions", allowAgentMentions: "allowAgentMentions", AllowEntityMentions: "AllowEntityMentions", allowEntityMentions: "allowEntityMentions", AllowSkillCommands: "AllowSkillCommands", allowSkillCommands: "allowSkillCommands", AllowAttachments: "AllowAttachments", allowAttachments: "allowAttachments", AllowPlanMode: "AllowPlanMode", allowPlanMode: "allowPlanMode", AllowRealtime: "AllowRealtime", allowRealtime: "allowRealtime", AllowForking: "AllowForking", AllowRemoteBrowser: "AllowRemoteBrowser", AllowStopRun: "AllowStopRun", ShowEmptyFill: "ShowEmptyFill", showEmptyFill: "showEmptyFill", ShowLoadingState: "ShowLoadingState", showLoadingState: "showLoadingState", ReadReplyFromTop: "ReadReplyFromTop", readReplyFromTop: "readReplyFromTop", ShowAgentRunDetails: "ShowAgentRunDetails", showAgentRunDetails: "showAgentRunDetails", ShowReactions: "ShowReactions", showReactions: "showReactions", ShowMessageRating: "ShowMessageRating", showMessageRating: "showMessageRating", AllowPinning: "AllowPinning", allowPinning: "allowPinning", AllowMessageEdit: "AllowMessageEdit", allowMessageEdit: "allowMessageEdit", AllowMessageDelete: "AllowMessageDelete", allowMessageDelete: "allowMessageDelete", ReadOnly: "ReadOnly", ReadOnlyMessage: "ReadOnlyMessage", ShowSuggestedPrompts: "ShowSuggestedPrompts", showSuggestedPrompts: "showSuggestedPrompts", ShowDateNavigation: "ShowDateNavigation", showDateNavigation: "showDateNavigation", AssistantDisplayName: "AssistantDisplayName", assistantDisplayName: "assistantDisplayName", AssistantAvatarUrl: "AssistantAvatarUrl", assistantAvatarUrl: "assistantAvatarUrl", IsNewConversation: "IsNewConversation", isNewConversation: "isNewConversation", PendingMessage: "PendingMessage", pendingMessage: "pendingMessage", PendingMessageConversationId: "PendingMessageConversationId", pendingMessageConversationId: "pendingMessageConversationId", PendingAttachments: "PendingAttachments", pendingAttachments: "pendingAttachments", PendingArtifactId: "PendingArtifactId", pendingArtifactId: "pendingArtifactId", PendingArtifactVersionNumber: "PendingArtifactVersionNumber", pendingArtifactVersionNumber: "pendingArtifactVersionNumber", PendingArtifactConversationId: "PendingArtifactConversationId", pendingArtifactConversationId: "pendingArtifactConversationId", OverlayMode: "OverlayMode", overlayMode: "overlayMode", ShowExportButton: "ShowExportButton", showExportButton: "showExportButton", ExportButtonLabel: "ExportButtonLabel", exportButtonLabel: "exportButtonLabel", ExportButtonIcon: "ExportButtonIcon", exportButtonIcon: "exportButtonIcon", ExportBranding: "ExportBranding", exportBranding: "exportBranding", ShowShareButton: "ShowShareButton", showShareButton: "showShareButton", ShowArtifactIndicator: "ShowArtifactIndicator", showArtifactIndicator: "showArtifactIndicator", AppContext: "AppContext", appContext: "appContext", DefaultAgentId: "DefaultAgentId", defaultAgentId: "defaultAgentId", AgentReplyMode: "AgentReplyMode", AllowedAgentIDs: "AllowedAgentIDs", MentionPeople: "MentionPeople", AgentHistoryFrom: "AgentHistoryFrom", AgentTurnHandler: "AgentTurnHandler", AutoNameConversation: "AutoNameConversation", EnableDecisionRouting: "EnableDecisionRouting", ApplicationScope: "ApplicationScope", applicationScope: "applicationScope", ApplicationId: "ApplicationId", applicationId: "applicationId", LinkedEntityId: "LinkedEntityId", linkedEntityId: "linkedEntityId", LinkedRecordId: "LinkedRecordId", linkedRecordId: "linkedRecordId", ShowAgentPicker: "ShowAgentPicker", showAgentPicker: "showAgentPicker", ShowAgentModePicker: "ShowAgentModePicker", showAgentModePicker: "showAgentModePicker", EmptyStateGreeting: "EmptyStateGreeting", emptyStateGreeting: "emptyStateGreeting", ShowSidebarToggle: "ShowSidebarToggle", showSidebarToggle: "showSidebarToggle", ShowAgentCharacter: "ShowAgentCharacter", showAgentCharacter: "showAgentCharacter", AgentCharacterConfig: "AgentCharacterConfig", agentCharacterConfig: "agentCharacterConfig", EmptyStateConfig: "EmptyStateConfig", emptyStateConfig: "emptyStateConfig", ShowDemonstrationSurface: "ShowDemonstrationSurface", showDemonstrationSurface: "showDemonstrationSurface", DemonstrationSurfaceContent: "DemonstrationSurfaceContent", demonstrationSurfaceContent: "demonstrationSurfaceContent", ComposerDraft: "ComposerDraft", composerDraft: "composerDraft", ComposerAgentMention: "ComposerAgentMention", composerAgentMention: "composerAgentMention", CollapseThreadReplies: "CollapseThreadReplies" }, outputs: { BeforeAgentTurn: "BeforeAgentTurn", beforeAgentTurn: "beforeAgentTurn", AfterAgentTurn: "AfterAgentTurn", afterAgentTurn: "afterAgentTurn", BeforeToolInvoked: "BeforeToolInvoked", beforeToolInvoked: "beforeToolInvoked", AfterToolInvoked: "AfterToolInvoked", afterToolInvoked: "afterToolInvoked", BeforeResponseFormSubmitted: "BeforeResponseFormSubmitted", beforeResponseFormSubmitted: "beforeResponseFormSubmitted", AfterResponseFormSubmitted: "AfterResponseFormSubmitted", afterResponseFormSubmitted: "afterResponseFormSubmitted", BeforeStopClicked: "BeforeStopClicked", AfterStopClicked: "AfterStopClicked", SessionStarted: "SessionStarted", sessionStarted: "sessionStarted", SessionChannelStateChanged: "SessionChannelStateChanged", sessionChannelStateChanged: "sessionChannelStateChanged", SessionEnded: "SessionEnded", sessionEnded: "sessionEnded", ConversationRenamed: "ConversationRenamed", conversationRenamed: "conversationRenamed", OpenEntityRecord: "OpenEntityRecord", openEntityRecord: "openEntityRecord", RealtimeConversationReady: "RealtimeConversationReady", realtimeConversationReady: "realtimeConversationReady", navigationRequest: "navigationRequest", TaskClicked: "TaskClicked", taskClicked: "taskClicked", ArtifactLinkClicked: "ArtifactLinkClicked", artifactLinkClicked: "artifactLinkClicked", SidebarToggleClicked: "SidebarToggleClicked", sidebarToggleClicked: "sidebarToggleClicked", ConversationCreated: "ConversationCreated", conversationCreated: "conversationCreated", PendingArtifactConsumed: "PendingArtifactConsumed", pendingArtifactConsumed: "pendingArtifactConsumed", PendingMessageConsumed: "PendingMessageConsumed", pendingMessageConsumed: "pendingMessageConsumed", PendingMessageRequested: "PendingMessageRequested", pendingMessageRequested: "pendingMessageRequested", ComposerDraftConsumed: "ComposerDraftConsumed", composerDraftConsumed: "composerDraftConsumed", ComposerAgentMentionConsumed: "ComposerAgentMentionConsumed", composerAgentMentionConsumed: "composerAgentMentionConsumed", ThreadReplyRevealRequested: "ThreadReplyRevealRequested" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 31, vars: 37, consts: [["titleBar", ""], ["titleName", ""], ["forksButton", ""], ["titleNameInput", ""], ["titleRenameButton", ""], ["emptyStateInput", ""], ["scrollContainer", ""], ["messageInput", ""], ["taskGraphRunView", ""], ["conversationRemoteBrowserSurface", ""], [1, "chat-area"], [1, "chat-agent-presence", 3, "chat-agent-presence--prominent"], [1, "chat-header"], [1, "chat-content-area"], [1, "chat-demonstration-stage"], [1, "chat-messages-pane"], [1, "chat-messages-wrapper"], [3, "saved", "cancelled", "isOpen", "artifact", "currentUser"], [3, "pinnedMessages", "isLoading", "AllowUnpin"], [3, "PanelID", "Summaries", "CurrentUserID"], [3, "cancelled", "exported", "branding", "isVisible", "conversation", "Scope", "currentUser"], [3, "Result", "Visible", "Context", "Adapter"], [3, "cancelled", "membersChanged", "isVisible", "conversation", "currentUser"], [1, "modal-overlay"], [3, "isOpen", "environmentId", "currentUser", "excludeCollectionIds", "artifactVersionId", "artifactName", "artifactVersionNumber"], [3, "data", "visible"], [3, "imageUrl", "alt", "fileName", "visible"], [1, "chat-agent-presence"], [3, "State", "AgentName", "AvatarUrl", "Mode"], [4, "ngTemplateOutlet", "ngTemplateOutletContext"], [1, "chat-header", 3, "keydown.escape"], [1, "chat-info"], ["title", "Show conversations", 1, "sidebar-toggle-btn"], [1, "shared-by-badge", 3, "title"], [1, "project-tag"], ["title", "View Test Run", 1, "test-indicator"], [1, "chat-actions", "chat-actions-buttons"], ["mjButton", "", "Variant", "flat", "Size", "sm", "aria-haspopup", "dialog", "title", "Forks in this conversation", 1, "forks-button", 3, "active"], ["title", "View pinned messages", 1, "pin-chip", 3, "active"], ["title", "View artifacts", 1, "artifact-indicator"], ["mjButton", "", "variant", "flat", "size", "sm", 1, "remote-browser-toggle-btn", 3, "active", "title"], ["title", "View members", 1, "chat-members"], [3, "AgentID", "Disabled"], [3, "Conversation", "CurrentUser", "AllowedAgentIDs", "Disabled"], ["mjButton", "", "variant", "flat", "size", "sm", 3, "title"], ["mjButton", "", "variant", "flat", "size", "sm", 3, "shared", "title"], ["title", "Show conversations", 1, "sidebar-toggle-btn", 3, "click"], [1, "fas", "fa-table-columns"], [4, "ngTemplateOutlet"], [1, "with-chip", 3, "--agent-accent"], [1, "with-chip"], ["aria-hidden", "true", 1, "dot"], [1, "fas", "fa-share-nodes"], [1, "project-tag", 3, "click"], [1, "fas", "fa-folder"], ["title", "View Test Run", 1, "test-indicator", 3, "click"], [1, "fas", "fa-flask"], ["mjButton", "", "Variant", "flat", "Size", "sm", "aria-haspopup", "dialog", "title", "Forks in this conversation", 1, "forks-button", 3, "click"], [1, "fa-solid", "fa-code-branch"], [1, "btn-label"], [1, "forks-count"], ["title", "View pinned messages", 1, "pin-chip", 3, "click"], [1, "fas", "fa-thumbtack"], [1, "pin-chip-count"], ["title", "View artifacts", 1, "artifact-indicator", 3, "click"], [1, "fas", "fa-cube"], [1, "artifact-badge"], ["mjButton", "", "variant", "flat", "size", "sm", 1, "remote-browser-toggle-btn", 3, "click", "title"], [1, "fa-solid", "fa-globe"], ["title", "View members", 1, "chat-members", 3, "click"], [1, "fas", "fa-users"], [1, "members-badge"], [3, "PresetChanged", "AgentID", "Disabled"], ["mjButton", "", "variant", "flat", "size", "sm", 3, "click", "title"], [1, "chat-title-bar"], ["aria-label", "Breadcrumb", 1, "chat-title-path"], [1, "chat-title-crumbs"], ["aria-current", "page", 1, "chat-title-current"], ["aria-hidden", "true"], [1, "chat-title-crumb", "chat-title-ellipsis", 3, "collapses-wide"], [1, "chat-title-crumb"], ["mjButton", "", "Variant", "flat", "Size", "sm", "type", "button", 3, "click", "title"], [1, "chat-title-crumb-label"], ["aria-hidden", "true", 1, "fa-solid", "fa-chevron-right", "chat-title-sep"], [1, "chat-title-crumb", "chat-title-ellipsis"], ["mjButton", "", "Variant", "flat", "Size", "sm", "type", "button", "aria-label", "Show the whole path", "title", "Show the whole path", 3, "click"], ["type", "text", "maxlength", "255", 1, "chat-title-input", 3, "ngModel"], ["type", "text", "maxlength", "255", 1, "chat-title-input", 3, "ngModelChange", "keydown.enter", "keydown.escape", "blur", "ngModel"], [1, "chat-title", 3, "title"], ["mjButton", "", "Variant", "icon", "Size", "sm", "type", "button", 1, "chat-title-rename", 3, "title"], ["mjButton", "", "Variant", "icon", "Size", "sm", "type", "button", 1, "chat-title-rename", 3, "click", "title"], ["aria-hidden", "true", 1, "fa-solid", "fa-pen"], [1, "conversation-loading-state"], ["text", "Loading conversation...", "size", "large"], ["role", "status", 1, "read-only-banner"], [3, "currentUser", "initialDraft", "disabled", "showSidebarToggle", "overlayMode", "greeting", "showSuggestedPrompts", "enableAttachments", "enableMentions", "enableAgentMentions", "enableEntityMentions", "enableSkillCommands", "AllowedAgentIDs", "MentionPeople", "ComposerExtraTemplate", "maxAttachments", "maxAttachmentSizeBytes", "acceptedFileTypes"], [1, "fas", "fa-eye"], [3, "initialDraftApplied", "DraftStateChanged", "ComposerBlurred", "sidebarToggleClicked", "messageSent", "currentUser", "initialDraft", "disabled", "showSidebarToggle", "overlayMode", "greeting", "showSuggestedPrompts", "enableAttachments", "enableMentions", "enableAgentMentions", "enableEntityMentions", "enableSkillCommands", "AllowedAgentIDs", "MentionPeople", "ComposerExtraTemplate", "maxAttachments", "maxAttachmentSizeBytes", "acceptedFileTypes"], [1, "chat-messages-container"], [1, "chat-input-container"], [1, "chat-composer-extra"], [1, "message-input-container-wrapper"], [3, "initialDraftApplied", "DraftStateChanged", "ComposerBlurred", "emptyStateSubmit", "emptyStateMode", "initialDraft", "currentUser", "disabled", "ReadOnly", "appContext", "applicationId", "defaultAgentId", "enableAttachments", "enableMentions", "enableAgentMentions", "enableEntityMentions", "enableSkillCommands", "enablePlanMode", "enableRealtime", "AllowedAgentIDs", "MentionPeople", "maxAttachments", "maxAttachmentSizeBytes", "acceptedFileTypes"], ["role", "region", "aria-label", "Fork", 1, "fork-view-bar"], [1, "upload-indicator-overlay"], [1, "chat-messages-container", 3, "scroll", "keydown.escape"], [3, "OlderRequested", "DateJumpRequested", "ForkOpenRequested", "EditResendRequested", "RegenerateRequested", "ResendInPlaceRequested", "ForkRequested", "realtimeSessionOpenRequested", "deleteMessage", "BeforeStopClicked", "StopMessage", "testFeedbackMessage", "artifactClicked", "messageEdited", "openEntityRecord", "suggestedResponseSelected", "attachmentClicked", "diagnosticRequested", "LivenessCheckRequested", "messagePinToggled", "beforeResponseFormSubmitted", "afterResponseFormSubmitted", "TaskGraphPanelRequested", "ScrollToMessageRequested", "showEmptyFill", "showDateNavigation", "showAgentRunDetails", "showReactions", "showMessageRating", "allowPinning", "allowMessageEdit", "allowMessageDelete", "ReadOnly", "AllowStopRun", "InFlightCount", "assistantDisplayName", "assistantAvatarUrl", "messages", "HasMoreAbove", "IsLoadingOlder", "ScrollRoot", "conversation", "currentUser", "isProcessing", "artifactMap", "agentRunMap", "HandoffMap", "ratingsMap", "userAvatarMap", "attachmentsMap", "messageRendererTemplate", "messageExtraTemplate", "sessionMetaMap", "ForkChipMap", "ForkLayout", "CanFork", "InPlaceTurn"], [1, "scroll-to-bottom-icon", 2, "left", "50%"], [1, "loading-peripheral-placeholder"], ["role", "region", "aria-label", "Fork", 1, "fork-view-bar", 3, "keydown.escape"], ["size", "medium", 3, "text"], [1, "scroll-to-bottom-icon", 2, "left", "50%", 3, "click"], [1, "fas", "fa-arrow-down"], ["text", "Loading conversation data...", "size", "medium"], [3, "hidden", "initialDraft", "conversationId", "conversationName", "currentUser", "conversationHistory", "artifactsByDetailId", "systemArtifactsByDetailId", "agentRunsByDetailId", "appContext", "applicationId", "defaultAgentId", "conversationDefaultAgentId", "agentConfigurationPresetId", "AgentReplyMode", "AllowedAgentIDs", "MentionPeople", "AgentHistoryFrom", "TargetBranchID", "ResolveTargetBranch", "AgentTurnHandler", "AutoNameConversation", "EnableDecisionRouting", "inProgressMessageIds", "disabled", "ReadOnly", "enableAttachments", "enableMentions", "enableAgentMentions", "enableEntityMentions", "enableSkillCommands", "enablePlanMode", "enableRealtime", "Placeholder", "SendSlotMode", "StopCount", "StopLabel", "StatusText", "StatusElapsed", "maxAttachments", "maxAttachmentSizeBytes", "acceptedFileTypes", "initialMessage", "initialAttachments"], [1, "fork-composer-hint"], [3, "DraftStateChanged", "ComposerBlurred", "StopClicked", "initialMessageAutoSendStarted", "initialMessageAutoSendFailed", "messageSent", "MessageStreamed", "agentResponse", "agentRunDetected", "agentRunUpdate", "messageComplete", "artifactCreated", "conversationRenamed", "intentCheckStarted", "intentCheckCompleted", "beforeAgentTurn", "afterAgentTurn", "uploadStateChanged", "hidden", "initialDraft", "conversationId", "conversationName", "currentUser", "conversationHistory", "artifactsByDetailId", "systemArtifactsByDetailId", "agentRunsByDetailId", "appContext", "applicationId", "defaultAgentId", "conversationDefaultAgentId", "agentConfigurationPresetId", "AgentReplyMode", "AllowedAgentIDs", "MentionPeople", "AgentHistoryFrom", "TargetBranchID", "ResolveTargetBranch", "AgentTurnHandler", "AutoNameConversation", "EnableDecisionRouting", "inProgressMessageIds", "disabled", "ReadOnly", "enableAttachments", "enableMentions", "enableAgentMentions", "enableEntityMentions", "enableSkillCommands", "enablePlanMode", "enableRealtime", "Placeholder", "SendSlotMode", "StopCount", "StopLabel", "StatusText", "StatusElapsed", "maxAttachments", "maxAttachmentSizeBytes", "acceptedFileTypes", "initialMessage", "initialAttachments"], [1, "resize-handle"], [1, "chat-artifact-pane"], [3, "closed", "saveToCollectionRequested", "navigateToLink", "shareRequested", "maximizeToggled", "openEntityRecord", "navigationRequest", "analyzeRequested", "applyFormRequested", "artifactId", "currentUser", "environmentId", "versionNumber", "viewContext", "Scope", "canShare", "canEdit", "isMaximized", "refreshTrigger"], [1, "resize-handle", 3, "mousedown", "touchstart"], [1, "chat-artifact-pane", "chat-task-graph-pane"], [1, "task-graph-pane-header"], [1, "task-graph-pane-title-group"], [1, "task-graph-pane-icon"], [1, "fa-solid", "fa-diagram-project"], [1, "task-graph-pane-titles"], [1, "task-graph-pane-title"], [1, "task-graph-pane-subtitle"], [1, "task-graph-pane-actions"], ["type", "button", "title", "Save this task graph as a reusable Draft Flow Agent workflow", 1, "task-graph-pane-save-btn", 3, "click", "disabled"], [1, "fa-solid"], ["type", "button", 1, "task-graph-pane-btn", 3, "click", "title"], ["type", "button", "title", "Close Task Graph panel", 1, "task-graph-pane-btn", 3, "click"], [1, "fa-solid", "fa-xmark"], [1, "task-graph-pane-body"], [3, "ParentTaskID", "WorkflowName", "LiveUpdates", "ShowVariables", "Height"], [1, "chat-artifact-pane", "chat-task-graph-pane", "chat-remote-browser-pane"], ["type", "text", "placeholder", "Enter URL or domain\u2026", 1, "remote-browser-url-input", 3, "ngModelChange", "keydown.enter", "ngModel"], ["type", "button", "title", "Navigate to URL", 1, "task-graph-pane-save-btn", 3, "click", "disabled"], ["type", "button", "title", "Close Browser panel", 1, "task-graph-pane-btn", 3, "click"], [3, "closed", "jumpRequested", "unpinRequested", "pinnedMessages", "isLoading", "AllowUnpin"], [3, "ForkSelected", "Closed", "PanelID", "Summaries", "CurrentUserID"], [3, "NavigateRequest", "StartLiveRequested", "ReviewClosed", "AgentName", "Hidden", "CurrentUser", "EnvironmentID", "ReviewData", "AllowStartLive", "Chrome", "Compact", "ShowDevLinks", "ShowDensityPicker"], ["type", "button", "title", "Return to the live call", "aria-label", "Return to the live call", 1, "voice-call-pill"], ["type", "button", "title", "Return to the live call", "aria-label", "Return to the live call", 1, "voice-call-pill", 3, "click"], ["aria-hidden", "true", 1, "voice-call-pill__pulse"], ["aria-hidden", "true", 1, "fa-solid", "fa-phone-volume"], [1, "voice-call-pill__text"], [1, "voice-call-pill__name"], [1, "voice-call-pill__hint"], [1, "modal-overlay", 3, "click"], [1, "modal-content", "project-selector-modal", 3, "click"], [1, "modal-header"], [1, "modal-close-btn", 3, "click"], [1, "fas", "fa-times"], [1, "modal-body"], [3, "projectSelected", "environmentId", "currentUser", "selectedProjectId"], [1, "modal-content", "artifacts-modal", 3, "click"], [1, "modal-header-actions"], ["title", "Toggle system artifacts visibility", 1, "toggle-system-btn", 3, "active"], [1, "modal-body", "artifacts-grid"], ["Icon", "fa-solid fa-cube", "Title", "No artifacts in this conversation yet", 1, "artifacts-empty-fill"], [1, "artifact-modal-card", 3, "expanded", "system-artifact"], ["title", "Toggle system artifacts visibility", 1, "toggle-system-btn", 3, "click"], [1, "fas", "fa-cog"], [1, "artifact-modal-card"], [1, "artifact-card-header", 3, "click"], [1, "artifact-modal-icon"], [1, "fas", "fa-file-code"], [1, "artifact-modal-info"], [1, "artifact-modal-title"], [1, "artifact-modal-meta"], [1, "expand-btn"], [1, "artifact-modal-action"], [1, "fas", "fa-external-link-alt"], [1, "artifact-versions-list"], [1, "expand-btn", 3, "click"], [1, "fas"], [1, "artifact-version-item"], [1, "artifact-version-item", 3, "click"], [1, "version-badge"], [1, "version-open-text"], [1, "fas", "fa-arrow-right"], [3, "completed", "cancelled", "isOpen", "environmentId", "currentUser", "excludeCollectionIds", "artifactVersionId", "artifactName", "artifactVersionNumber"], [3, "closed", "data", "visible"], [3, "closed", "imageUrl", "alt", "fileName", "visible"]], template: function ConversationChatAreaComponent_Template(rf, ctx) { if (rf & 1) {
10113
+ i0.ɵɵelementStart(0, "div", 10);
10114
+ i0.ɵɵconditionalCreate(1, ConversationChatAreaComponent_Conditional_1_Template, 3, 3, "div", 11);
10115
+ i0.ɵɵconditionalCreate(2, ConversationChatAreaComponent_Conditional_2_Template, 1, 8, "ng-container")(3, ConversationChatAreaComponent_Conditional_3_Template, 18, 17, "div", 12);
9259
10116
  i0.ɵɵtemplate(4, ConversationChatAreaComponent_ng_template_4_Template, 3, 1, "ng-template", null, 0, i0.ɵɵtemplateRefExtractor)(6, ConversationChatAreaComponent_ng_template_6_Template, 2, 1, "ng-template", null, 1, i0.ɵɵtemplateRefExtractor);
9260
- i0.ɵɵelementStart(8, "div", 12);
9261
- i0.ɵɵconditionalCreate(9, ConversationChatAreaComponent_Conditional_9_Template, 2, 6, "div", 13);
9262
- i0.ɵɵelementStart(10, "div", 14);
9263
- i0.ɵɵconditionalCreate(11, ConversationChatAreaComponent_Conditional_11_Template, 1, 1)(12, ConversationChatAreaComponent_Conditional_12_Template, 3, 1)(13, ConversationChatAreaComponent_Conditional_13_Template, 5, 1, "div", 15)(14, ConversationChatAreaComponent_Conditional_14_Template, 11, 36, "div", 15);
10117
+ i0.ɵɵelementStart(8, "div", 13);
10118
+ i0.ɵɵconditionalCreate(9, ConversationChatAreaComponent_Conditional_9_Template, 2, 6, "div", 14);
10119
+ i0.ɵɵelementStart(10, "div", 15);
10120
+ i0.ɵɵconditionalCreate(11, ConversationChatAreaComponent_Conditional_11_Template, 1, 1)(12, ConversationChatAreaComponent_Conditional_12_Template, 3, 1)(13, ConversationChatAreaComponent_Conditional_13_Template, 5, 1, "div", 16)(14, ConversationChatAreaComponent_Conditional_14_Template, 11, 37, "div", 16);
9264
10121
  i0.ɵɵelementEnd();
9265
10122
  i0.ɵɵconditionalCreate(15, ConversationChatAreaComponent_Conditional_15_Template, 3, 15);
9266
10123
  i0.ɵɵconditionalCreate(16, ConversationChatAreaComponent_Conditional_16_Template, 23, 24);
9267
- i0.ɵɵelementStart(17, "mj-artifact-share-modal", 16);
9268
- i0.ɵɵlistener("saved", function ConversationChatAreaComponent_Template_mj_artifact_share_modal_saved_17_listener() { return ctx.onArtifactShared(); })("cancelled", function ConversationChatAreaComponent_Template_mj_artifact_share_modal_cancelled_17_listener() { return ctx.onArtifactShareModalClose(); });
10124
+ i0.ɵɵconditionalCreate(17, ConversationChatAreaComponent_Conditional_17_Template, 24, 18);
10125
+ i0.ɵɵelementStart(18, "mj-artifact-share-modal", 17);
10126
+ i0.ɵɵlistener("saved", function ConversationChatAreaComponent_Template_mj_artifact_share_modal_saved_18_listener() { return ctx.onArtifactShared(); })("cancelled", function ConversationChatAreaComponent_Template_mj_artifact_share_modal_cancelled_18_listener() { return ctx.onArtifactShareModalClose(); });
9269
10127
  i0.ɵɵelementEnd();
9270
- i0.ɵɵconditionalCreate(18, ConversationChatAreaComponent_Conditional_18_Template, 1, 3, "mj-pinned-messages-panel", 17);
9271
- i0.ɵɵconditionalCreate(19, ConversationChatAreaComponent_Conditional_19_Template, 1, 3, "mj-conversation-forks-popover", 18);
10128
+ i0.ɵɵconditionalCreate(19, ConversationChatAreaComponent_Conditional_19_Template, 1, 3, "mj-pinned-messages-panel", 18);
10129
+ i0.ɵɵconditionalCreate(20, ConversationChatAreaComponent_Conditional_20_Template, 1, 3, "mj-conversation-forks-popover", 19);
9272
10130
  i0.ɵɵelementEnd();
9273
- i0.ɵɵconditionalCreate(20, ConversationChatAreaComponent_Conditional_20_Template, 4, 15);
9274
- i0.ɵɵpipe(21, "async");
10131
+ i0.ɵɵconditionalCreate(21, ConversationChatAreaComponent_Conditional_21_Template, 4, 15);
10132
+ i0.ɵɵpipe(22, "async");
9275
10133
  i0.ɵɵelementEnd();
9276
- i0.ɵɵelementStart(22, "mj-export-modal", 19);
9277
- i0.ɵɵlistener("cancelled", function ConversationChatAreaComponent_Template_mj_export_modal_cancelled_22_listener() { return ctx.onExportModalCancelled(); })("exported", function ConversationChatAreaComponent_Template_mj_export_modal_exported_22_listener() { return ctx.onExportModalComplete(); });
10134
+ i0.ɵɵelementStart(23, "mj-export-modal", 20);
10135
+ i0.ɵɵlistener("cancelled", function ConversationChatAreaComponent_Template_mj_export_modal_cancelled_23_listener() { return ctx.onExportModalCancelled(); })("exported", function ConversationChatAreaComponent_Template_mj_export_modal_exported_23_listener() { return ctx.onExportModalComplete(); });
9278
10136
  i0.ɵɵelementEnd();
9279
- i0.ɵɵelementStart(23, "mj-resource-share-dialog", 20);
9280
- i0.ɵɵlistener("Result", function ConversationChatAreaComponent_Template_mj_resource_share_dialog_Result_23_listener($event) { return ctx.onShareDialogResult($event); });
10137
+ i0.ɵɵelementStart(24, "mj-resource-share-dialog", 21);
10138
+ i0.ɵɵlistener("Result", function ConversationChatAreaComponent_Template_mj_resource_share_dialog_Result_24_listener($event) { return ctx.onShareDialogResult($event); });
9281
10139
  i0.ɵɵelementEnd();
9282
- i0.ɵɵelementStart(24, "mj-members-modal", 21);
9283
- i0.ɵɵlistener("cancelled", function ConversationChatAreaComponent_Template_mj_members_modal_cancelled_24_listener() { return ctx.showMembersModal = false; })("membersChanged", function ConversationChatAreaComponent_Template_mj_members_modal_membersChanged_24_listener() { return ctx.showMembersModal = false; });
10140
+ i0.ɵɵelementStart(25, "mj-members-modal", 22);
10141
+ i0.ɵɵlistener("cancelled", function ConversationChatAreaComponent_Template_mj_members_modal_cancelled_25_listener() { return ctx.showMembersModal = false; })("membersChanged", function ConversationChatAreaComponent_Template_mj_members_modal_membersChanged_25_listener() { return ctx.showMembersModal = false; });
9284
10142
  i0.ɵɵelementEnd();
9285
- i0.ɵɵconditionalCreate(25, ConversationChatAreaComponent_Conditional_25_Template, 9, 3, "div", 22);
9286
- i0.ɵɵconditionalCreate(26, ConversationChatAreaComponent_Conditional_26_Template, 13, 2, "div", 22);
9287
- i0.ɵɵconditionalCreate(27, ConversationChatAreaComponent_Conditional_27_Template, 1, 7, "mj-artifact-collection-picker-modal", 23);
9288
- i0.ɵɵconditionalCreate(28, ConversationChatAreaComponent_Conditional_28_Template, 1, 2, "mj-test-feedback-dialog", 24);
9289
- i0.ɵɵconditionalCreate(29, ConversationChatAreaComponent_Conditional_29_Template, 1, 4, "mj-image-viewer", 25);
10143
+ i0.ɵɵconditionalCreate(26, ConversationChatAreaComponent_Conditional_26_Template, 9, 3, "div", 23);
10144
+ i0.ɵɵconditionalCreate(27, ConversationChatAreaComponent_Conditional_27_Template, 13, 2, "div", 23);
10145
+ i0.ɵɵconditionalCreate(28, ConversationChatAreaComponent_Conditional_28_Template, 1, 7, "mj-artifact-collection-picker-modal", 24);
10146
+ i0.ɵɵconditionalCreate(29, ConversationChatAreaComponent_Conditional_29_Template, 1, 2, "mj-test-feedback-dialog", 25);
10147
+ i0.ɵɵconditionalCreate(30, ConversationChatAreaComponent_Conditional_30_Template, 1, 4, "mj-image-viewer", 26);
9290
10148
  } if (rf & 2) {
9291
10149
  let tmp_3_0;
9292
10150
  i0.ɵɵadvance();
@@ -9298,7 +10156,7 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
9298
10156
  i0.ɵɵadvance();
9299
10157
  i0.ɵɵconditional(ctx.isDemonstrationActive ? 9 : -1);
9300
10158
  i0.ɵɵadvance();
9301
- i0.ɵɵclassProp("full-width", !ctx.showArtifactPanel && !ctx.SelectedTaskGraphPanel)("hidden", ctx.isArtifactPaneMaximized);
10159
+ i0.ɵɵclassProp("full-width", !ctx.showArtifactPanel && !ctx.SelectedTaskGraphPanel && !ctx.ShowRemoteBrowserPanel)("hidden", ctx.isArtifactPaneMaximized);
9302
10160
  i0.ɵɵadvance();
9303
10161
  i0.ɵɵconditional(ctx.isLoadingConversation ? 11 : (ctx.isNewConversation || !ctx.conversationId) && !ctx.suppressNewConversationEmptyState ? 12 : (ctx.isNewConversation || !ctx.conversationId) && ctx.suppressNewConversationEmptyState ? 13 : 14);
9304
10162
  i0.ɵɵadvance(4);
@@ -9306,13 +10164,15 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
9306
10164
  i0.ɵɵadvance();
9307
10165
  i0.ɵɵconditional(ctx.SelectedTaskGraphPanel ? 16 : -1);
9308
10166
  i0.ɵɵadvance();
10167
+ i0.ɵɵconditional(ctx.ShowRemoteBrowserPanel ? 17 : -1);
10168
+ i0.ɵɵadvance();
9309
10169
  i0.ɵɵproperty("isOpen", ctx.isArtifactShareModalOpen)("artifact", ctx.artifactToShare)("currentUser", ctx.currentUser);
9310
10170
  i0.ɵɵadvance();
9311
- i0.ɵɵconditional(ctx.allowPinning && ctx.showPinsPanel ? 18 : -1);
10171
+ i0.ɵɵconditional(ctx.allowPinning && ctx.showPinsPanel ? 19 : -1);
9312
10172
  i0.ɵɵadvance();
9313
- i0.ɵɵconditional(ctx.ShowForksPopover ? 19 : -1);
10173
+ i0.ɵɵconditional(ctx.ShowForksPopover ? 20 : -1);
9314
10174
  i0.ɵɵadvance();
9315
- i0.ɵɵconditional(i0.ɵɵpipeBind1(21, 34, ctx.RealtimeSession.Active$) || ctx.RealtimeReview ? 20 : -1);
10175
+ i0.ɵɵconditional(i0.ɵɵpipeBind1(22, 35, ctx.RealtimeSession.Active$) || ctx.RealtimeReview ? 21 : -1);
9316
10176
  i0.ɵɵadvance(2);
9317
10177
  i0.ɵɵproperty("branding", ctx.exportBranding)("isVisible", ctx.showExportModal)("conversation", ctx.conversation || undefined)("Scope", ctx.ExportScope)("currentUser", ctx.currentUser);
9318
10178
  i0.ɵɵadvance();
@@ -9320,20 +10180,20 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
9320
10180
  i0.ɵɵadvance();
9321
10181
  i0.ɵɵproperty("isVisible", ctx.showMembersModal)("conversation", ctx.conversation || undefined)("currentUser", ctx.currentUser);
9322
10182
  i0.ɵɵadvance();
9323
- i0.ɵɵconditional(ctx.showProjectSelector && ctx.conversation ? 25 : -1);
10183
+ i0.ɵɵconditional(ctx.showProjectSelector && ctx.conversation ? 26 : -1);
9324
10184
  i0.ɵɵadvance();
9325
- i0.ɵɵconditional(ctx.showArtifactsModal ? 26 : -1);
10185
+ i0.ɵɵconditional(ctx.showArtifactsModal ? 27 : -1);
9326
10186
  i0.ɵɵadvance();
9327
- i0.ɵɵconditional(ctx.showCollectionPicker ? 27 : -1);
10187
+ i0.ɵɵconditional(ctx.showCollectionPicker ? 28 : -1);
9328
10188
  i0.ɵɵadvance();
9329
- i0.ɵɵconditional(ctx.testFeedbackDialogData ? 28 : -1);
10189
+ i0.ɵɵconditional(ctx.testFeedbackDialogData ? 29 : -1);
9330
10190
  i0.ɵɵadvance();
9331
- i0.ɵɵconditional(ctx.showImageViewer ? 29 : -1);
9332
- } }, dependencies: [i13.NgTemplateOutlet, i14.DefaultValueAccessor, i14.NgControlStatus, i14.MaxLengthValidator, i14.NgModel, i15.TaskGraphRunViewComponent, i16.MJButtonDirective, i16.MJEmptyStateComponent, i10.ArtifactViewerPanelComponent, i17.TestFeedbackDialogComponent, i18.LoadingComponent, i19.GenericShareDialogComponent, i20.ArtifactCollectionPickerModalComponent, i21.ArtifactShareModalComponent, i22.MJChatAgentPresenceDefaultComponent, i23.RealtimeSessionOverlayComponent, i24.MessageListComponent, i25.MessageInputComponent, i26.ConversationEmptyStateComponent, i27.ConversationAgentPickerComponent, i28.ConversationModePickerComponent, i29.ProjectSelectorComponent, i30.MembersModalComponent, i31.ExportModalComponent, i32.ImageViewerComponent, i33.PinnedMessagesPanelComponent, i34.ForksPopoverComponent, i13.AsyncPipe], styles: ["[_nghost-%COMP%] {\n display: flex;\n width: 100%;\n height: 100%;\n}\n\n.chat-area[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n overflow: hidden;\n \n position: relative;\n}\n\n.chat-header[_ngcontent-%COMP%] {\n flex-shrink: 0;\n padding: 12px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n display: flex;\n justify-content: space-between;\n align-items: center;\n gap: 16px;\n background: var(--mj-bg-surface-card);\n z-index: 10;\n box-shadow: var(--mj-shadow-sm);\n}\n\n\n\n\n\n\n.chat-agent-presence[_ngcontent-%COMP%] {\n flex-shrink: 0;\n padding: 8px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-card);\n display: flex;\n align-items: center;\n z-index: 11;\n}\n\n.chat-agent-presence--prominent[_ngcontent-%COMP%] {\n padding: 16px 20px;\n justify-content: center;\n}\n\n.chat-info[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n flex: 1;\n min-width: 0;\n}\n\n\n.sidebar-toggle-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n background: transparent;\n border: none;\n border-radius: 6px;\n cursor: pointer;\n transition: all 0.15s ease;\n flex-shrink: 0;\n}\n\n.sidebar-toggle-btn[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-text-primary) 8%, transparent);\n}\n\n.sidebar-toggle-btn[_ngcontent-%COMP%]:active {\n background: color-mix(in srgb, var(--mj-text-primary) 12%, transparent);\n}\n\n.sidebar-toggle-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary);\n font-size: 18px;\n transition: color 0.15s ease;\n}\n\n.sidebar-toggle-btn[_ngcontent-%COMP%]:hover i[_ngcontent-%COMP%] {\n color: var(--mj-text-primary);\n}\n\n\n.chat-title-bar[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: var(--mj-space-1);\n flex: 0 1 auto;\n min-width: 0;\n}\n\n.chat-title[_ngcontent-%COMP%] {\n flex: 0 1 auto;\n min-width: 0;\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.chat-title-path[_ngcontent-%COMP%] {\n min-width: 0;\n}\n\n.chat-title-crumbs[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: var(--mj-space-1);\n min-width: 0;\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n\n.chat-title-crumb[_ngcontent-%COMP%] {\n display: flex;\n flex: 0 100 auto;\n align-items: center;\n gap: var(--mj-space-1);\n min-width: 80px;\n}\n\n.chat-title-crumb.chat-title-ellipsis[_ngcontent-%COMP%] {\n flex: 0 0 auto;\n min-width: 0;\n}\n\n.chat-title-crumb[_ngcontent-%COMP%] > button[_ngcontent-%COMP%] {\n min-width: 0;\n color: var(--mj-text-muted);\n font-size: var(--mj-text-sm);\n font-weight: 500;\n}\n\n.chat-title-crumb-label[_ngcontent-%COMP%] {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n\n.chat-title-crumb.collapsed-wide[_ngcontent-%COMP%], \n.chat-title-ellipsis[_ngcontent-%COMP%]:not(.collapses-wide) {\n display: none;\n}\n\n.chat-title-sep[_ngcontent-%COMP%] {\n flex-shrink: 0;\n font-size: 12px;\n color: var(--mj-border-strong);\n}\n\n.chat-title-current[_ngcontent-%COMP%] {\n display: flex;\n flex: 0 1 auto;\n align-items: center;\n gap: var(--mj-space-1);\n min-width: 120px;\n}\n\n.chat-title-kind[_ngcontent-%COMP%] {\n flex-shrink: 0;\n margin: 0 var(--mj-space-1);\n color: var(--mj-status-info);\n}\n\n.chat-title-kind[data-kind='Edit'][_ngcontent-%COMP%] {\n color: var(--mj-status-warning);\n}\n\n.chat-title-kind[data-kind='Regenerate'][_ngcontent-%COMP%] {\n color: var(--mj-brand-tertiary);\n}\n\n.chat-title-bar[_ngcontent-%COMP%] .chat-title-rename[_ngcontent-%COMP%] {\n flex-shrink: 0;\n color: var(--mj-text-muted);\n opacity: 0.6;\n transition: opacity 0.15s ease, color 0.15s ease;\n}\n\n.chat-title-bar[_ngcontent-%COMP%]:hover .chat-title-rename[_ngcontent-%COMP%], \n.chat-title-bar[_ngcontent-%COMP%] .chat-title-rename[_ngcontent-%COMP%]:focus-visible {\n color: var(--mj-text-primary);\n opacity: 1;\n}\n\n.chat-title-input[_ngcontent-%COMP%] {\n flex: 0 1 360px;\n min-width: 120px;\n padding: var(--mj-space-1) var(--mj-space-2);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font: inherit;\n font-size: 16px;\n font-weight: 600;\n}\n\n.chat-title-input[_ngcontent-%COMP%]:focus-visible {\n outline: none;\n border-color: var(--mj-brand-primary);\n box-shadow: var(--mj-focus-ring);\n}\n\n.shared-by-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 3px 10px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n color: var(--mj-brand-primary);\n border-radius: 999px;\n font-size: 12px;\n font-weight: 500;\n flex-shrink: 0;\n max-width: 240px;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.shared-by-badge[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 10px;\n}\n\n.shared-by-badge[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.project-tag[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n border-radius: 16px;\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-text-muted);\n cursor: pointer;\n transition: all 0.2s;\n height: 28px;\n margin-left: 12px;\n}\n\n.project-tag[_ngcontent-%COMP%]:hover {\n background: var(--mj-border-default);\n border-color: var(--mj-text-muted);\n}\n\n.project-tag[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 10px;\n}\n\n.test-indicator[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n background: color-mix(in srgb, var(--mj-status-warning) 10%, var(--mj-bg-surface));\n border: 1px solid var(--mj-status-warning);\n border-radius: 16px;\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-status-warning);\n cursor: pointer;\n transition: all 0.2s;\n height: 28px;\n margin-left: 8px;\n}\n\n.test-indicator[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-status-warning) 20%, var(--mj-bg-surface));\n border-color: var(--mj-status-warning);\n}\n\n.test-indicator[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 10px;\n}\n\n\n.pin-chip[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 5px;\n padding: 5px 10px;\n background: color-mix(in srgb, var(--mj-status-warning) 12%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-status-warning) 45%, transparent);\n border-radius: 20px;\n color: var(--mj-status-warning-text, var(--mj-status-warning));\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s;\n}\n\n.pin-chip[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 11px;\n}\n\n.pin-chip[_ngcontent-%COMP%]:hover, \n.pin-chip.active[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 20%, var(--mj-bg-surface));\n border-color: var(--mj-status-warning);\n}\n\n.pin-chip-count[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 700;\n}\n\n.chat-members[_ngcontent-%COMP%], \n.artifact-indicator[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n position: relative;\n padding: 6px 8px;\n background: transparent;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n font-size: 14px;\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: all 150ms ease;\n}\n\n.chat-members[_ngcontent-%COMP%]:hover, \n.artifact-indicator[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n}\n\n\n.artifact-badge[_ngcontent-%COMP%], \n.members-badge[_ngcontent-%COMP%] {\n position: absolute;\n top: -6px;\n right: -6px;\n min-width: 16px;\n height: 16px;\n padding: 0 4px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n font-size: 10px;\n font-weight: 600;\n border-radius: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n line-height: 1;\n}\n\n.members-badge[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n}\n\n.ambient-agent-indicator[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n font-size: 13px;\n color: var(--mj-text-secondary);\n animation: _ngcontent-%COMP%_pulse 2s ease-in-out infinite;\n}\n\n.ambient-agent-indicator[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n@keyframes _ngcontent-%COMP%_pulse {\n 0%, 100% {\n opacity: 1;\n }\n 50% {\n opacity: 0.7;\n }\n}\n.chat-actions[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.action-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 12px;\n background: transparent;\n border: 1px solid var(--mj-border-default);\n cursor: pointer;\n border-radius: 6px;\n font-size: 13px;\n color: var(--mj-text-secondary);\n transition: all 150ms ease;\n}\n\n.action-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n}\n\n.share-btn.shared[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-color: var(--mj-brand-primary-hover);\n color: var(--mj-brand-primary-hover);\n}\n\n.share-btn.shared[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary-hover);\n}\n\n.chat-content-area[_ngcontent-%COMP%] {\n flex: 1;\n min-height: 0;\n overflow: hidden;\n display: flex;\n flex-direction: row;\n position: relative;\n}\n\n.chat-messages-pane[_ngcontent-%COMP%] {\n height: 100%;\n display: flex;\n flex-direction: column;\n min-width: min(300px, 100%); \n overflow: hidden;\n transition: width 0.3s ease;\n}\n\n.chat-messages-pane.full-width[_ngcontent-%COMP%] {\n width: 100%;\n}\n\n.chat-messages-pane[_ngcontent-%COMP%]:not(.full-width) {\n flex: 1;\n}\n\n.chat-messages-pane.hidden[_ngcontent-%COMP%] {\n display: none;\n}\n\n.resize-handle[_ngcontent-%COMP%] {\n width: 4px;\n background: transparent;\n cursor: col-resize;\n flex-shrink: 0;\n position: relative;\n transition: background-color 0.2s;\n}\n\n.resize-handle[_ngcontent-%COMP%]:hover {\n background: var(--mj-brand-primary);\n}\n\n.resize-handle[_ngcontent-%COMP%]::before {\n content: \"\";\n position: absolute;\n left: -4px;\n right: -4px;\n top: 0;\n bottom: 0;\n}\n\n.chat-artifact-pane[_ngcontent-%COMP%] {\n height: 100%;\n display: flex;\n flex-direction: column;\n background: var(--mj-bg-surface-sunken);\n overflow: hidden;\n flex-shrink: 0;\n}\n\n.chat-artifact-pane.maximized[_ngcontent-%COMP%] {\n width: 100% !important;\n}\n\n.chat-artifact-pane[_ngcontent-%COMP%] > mj-artifact-viewer-panel[_ngcontent-%COMP%] {\n display: flex;\n flex: 1;\n min-height: 0;\n overflow: hidden;\n}\n\n.chat-task-graph-pane[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border-left: 1px solid var(--mj-border-default);\n}\n\n.task-graph-pane-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n padding: 12px 16px;\n background: var(--mj-bg-surface-card);\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n\n.task-graph-pane-title-group[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n min-width: 0;\n}\n\n.task-graph-pane-icon[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n border-radius: 8px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, transparent);\n color: var(--mj-brand-primary);\n font-size: 14px;\n flex-shrink: 0;\n}\n\n.task-graph-pane-titles[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 1px;\n min-width: 0;\n}\n\n.task-graph-pane-title[_ngcontent-%COMP%] {\n font-size: 13.5px;\n font-weight: 600;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.task-graph-pane-subtitle[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-muted);\n}\n\n.task-graph-pane-actions[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n flex-shrink: 0;\n}\n\n.task-graph-pane-save-btn[_ngcontent-%COMP%] {\n height: 30px;\n padding: 0 10px;\n border-radius: 6px;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n font-weight: 500;\n border: 1px solid var(--mj-brand-primary);\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse, #ffffff);\n cursor: pointer;\n transition: opacity 0.15s ease, filter 0.15s ease;\n}\n\n.task-graph-pane-save-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n filter: brightness(1.06);\n}\n\n.task-graph-pane-save-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.55;\n cursor: not-allowed;\n}\n\n.task-graph-pane-btn[_ngcontent-%COMP%] {\n width: 30px;\n height: 30px;\n border-radius: 6px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border: 1px solid var(--mj-border-subtle);\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease;\n}\n\n.task-graph-pane-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n border-color: var(--mj-border-default);\n}\n\n.task-graph-pane-body[_ngcontent-%COMP%] {\n flex: 1;\n width: 100%;\n min-height: 0;\n min-width: 0;\n padding: 12px 16px 16px;\n box-sizing: border-box;\n overflow: hidden;\n display: flex;\n flex-direction: column;\n}\n\n.task-graph-pane-body[_ngcontent-%COMP%] > mj-task-graph-run-view[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n flex: 1;\n width: 100%;\n min-height: 0;\n min-width: 0;\n overflow: hidden;\n}\n\n.chat-messages-wrapper[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n min-height: 0;\n overflow: hidden;\n position: relative; \n}\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n.chat-demonstration-stage[_ngcontent-%COMP%] {\n height: 100%;\n display: flex;\n flex-direction: column;\n overflow: auto;\n background: var(--mj-bg-surface);\n border-right: 1px solid var(--mj-border-default);\n flex: 1;\n min-width: 0;\n}\n\n.chat-content-area.demonstration-mode[_ngcontent-%COMP%] .chat-messages-pane[_ngcontent-%COMP%], \n.chat-content-area.demonstration-mode[_ngcontent-%COMP%] .chat-messages-pane.full-width[_ngcontent-%COMP%] {\n flex: 0 0 320px;\n width: 320px;\n min-width: 0;\n}\n\n@media (max-width: 768px) {\n .chat-content-area.demonstration-mode[_ngcontent-%COMP%] {\n flex-direction: column;\n }\n\n .chat-content-area.demonstration-mode[_ngcontent-%COMP%] .chat-demonstration-stage[_ngcontent-%COMP%] {\n flex: 1 1 60%;\n border-right: none;\n border-bottom: 1px solid var(--mj-border-default);\n height: auto;\n }\n\n .chat-content-area.demonstration-mode[_ngcontent-%COMP%] .chat-messages-pane[_ngcontent-%COMP%], \n .chat-content-area.demonstration-mode[_ngcontent-%COMP%] .chat-messages-pane.full-width[_ngcontent-%COMP%] {\n flex: 1 1 40%;\n width: 100%;\n height: auto;\n }\n}\n\n\n.upload-indicator-overlay[_ngcontent-%COMP%] {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 1rem 1.5rem;\n background: color-mix(in srgb, var(--mj-bg-surface-card) 95%, transparent);\n border-radius: 12px;\n box-shadow: var(--mj-shadow-md);\n z-index: 100;\n pointer-events: none;\n}\n\n.chat-messages-container[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n background: var(--mj-bg-surface-card);\n min-height: 0;\n position: relative;\n}\n\n.scroll-to-bottom-icon[_ngcontent-%COMP%] {\n position: sticky;\n bottom: 21px;\n left: 50%;\n transform: translateX(-50%);\n width: 40px;\n height: 40px;\n margin-top: -40px;\n margin-left: auto;\n margin-right: auto;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n box-shadow: var(--mj-shadow-md);\n transition: all 0.2s ease;\n z-index: 100;\n pointer-events: auto;\n}\n\n.scroll-to-bottom-icon[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-brand-primary);\n transform: translateX(-50%) translateY(-2px);\n box-shadow: color-mix(in srgb, var(--mj-brand-primary) 20%, transparent) 0 4px 12px;\n}\n\n.scroll-to-bottom-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary);\n font-size: 16px;\n transition: color 0.2s;\n}\n\n.scroll-to-bottom-icon[_ngcontent-%COMP%]:hover i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.chat-input-container[_ngcontent-%COMP%] {\n flex-shrink: 0;\n background: var(--mj-bg-surface-card);\n padding: 0 1.25rem 1.25rem 1.25rem;\n overflow: visible;\n}\n\n\n.chat-composer-extra[_ngcontent-%COMP%] {\n margin-bottom: 0.5rem;\n}\n\n.read-only-banner[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n margin: 0 1.25rem 0.5rem 1.25rem;\n padding: 8px 12px;\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, transparent);\n color: var(--mj-text-secondary);\n border-radius: 6px;\n font-size: 12px;\n}\n\n.read-only-banner[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n font-size: 12px;\n}\n\n.loading-peripheral-placeholder[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: 140px;\n padding: 24px;\n background: color-mix(in srgb, var(--mj-bg-surface-card) 50%, transparent);\n backdrop-filter: blur(2px);\n border-radius: 12px;\n margin: 12px;\n animation: _ngcontent-%COMP%_fadeIn 0.2s ease-in-out;\n}\n\n.modal-overlay[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: var(--mj-bg-overlay);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n}\n\n.modal-content[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-card);\n border-radius: 8px;\n box-shadow: var(--mj-shadow-md);\n max-width: 90vw;\n max-height: 90vh;\n display: flex;\n flex-direction: column;\n}\n\n.project-selector-modal[_ngcontent-%COMP%] {\n width: 600px;\n height: 500px;\n}\n\n.modal-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.modal-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 18px;\n font-weight: 600;\n}\n\n.modal-header-actions[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.toggle-system-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n cursor: pointer;\n color: var(--mj-text-secondary);\n padding: 6px 12px;\n border-radius: 6px;\n font-size: 13px;\n font-weight: 500;\n transition: all 0.2s;\n}\n\n.toggle-system-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-border-default);\n border-color: var(--mj-border-default);\n color: var(--mj-text-primary);\n}\n\n.toggle-system-btn.active[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.toggle-system-btn.active[_ngcontent-%COMP%]:hover {\n background: var(--mj-brand-primary-hover);\n border-color: var(--mj-brand-primary-hover);\n}\n\n.toggle-system-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n}\n\n.modal-close-btn[_ngcontent-%COMP%] {\n background: none;\n border: none;\n cursor: pointer;\n color: var(--mj-text-secondary);\n padding: 4px 8px;\n border-radius: 4px;\n transition: all 0.2s;\n}\n\n.modal-close-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n}\n\n.modal-body[_ngcontent-%COMP%] {\n flex: 1;\n overflow: auto;\n padding: 20px;\n}\n\n.artifacts-modal[_ngcontent-%COMP%] {\n width: 700px;\n max-height: 600px;\n}\n\n.artifacts-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));\n gap: 16px;\n}\n\n\n.artifacts-empty-fill[_ngcontent-%COMP%] {\n grid-column: 1/-1;\n}\n\n.artifact-modal-card[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n background: var(--mj-bg-surface-card);\n border: 1.5px solid var(--mj-border-default);\n border-radius: 12px;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n overflow: hidden;\n}\n\n.artifact-modal-card.expanded[_ngcontent-%COMP%] {\n border-color: var(--mj-brand-primary);\n}\n\n.artifact-modal-card.system-artifact[_ngcontent-%COMP%] {\n opacity: 0.85;\n border-color: var(--mj-border-default);\n border-style: dashed;\n position: relative;\n}\n\n.artifact-modal-card.system-artifact[_ngcontent-%COMP%]::before {\n content: \"SYSTEM\";\n position: absolute;\n top: 8px;\n right: 8px;\n font-size: 9px;\n font-weight: 600;\n color: var(--mj-text-muted);\n background: var(--mj-bg-surface-sunken);\n padding: 2px 6px;\n border-radius: 3px;\n letter-spacing: 0.5px;\n z-index: 10;\n}\n\n.artifact-modal-card.system-artifact[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-text-muted);\n box-shadow: var(--mj-shadow-md);\n}\n\n.artifact-card-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 16px;\n cursor: pointer;\n}\n\n.artifact-card-header[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.artifact-modal-card[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-brand-primary);\n box-shadow: var(--mj-shadow-md);\n transform: translateY(-2px);\n}\n\n.artifact-modal-icon[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-radius: 10px;\n color: var(--mj-brand-primary);\n flex-shrink: 0;\n}\n\n.artifact-modal-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 18px;\n}\n\n.artifact-modal-info[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.artifact-modal-title[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin-bottom: 4px;\n}\n\n.artifact-modal-meta[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-secondary);\n}\n\n.artifact-modal-action[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n transition: color 0.2s;\n}\n\n.artifact-modal-card[_ngcontent-%COMP%]:hover .artifact-modal-action[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.expand-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n border: none;\n background: transparent;\n color: var(--mj-text-secondary);\n cursor: pointer;\n border-radius: 6px;\n transition: all 0.2s;\n}\n.expand-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-brand-primary);\n}\n\n.artifact-versions-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n padding: 0 1rem 1rem 1rem;\n background: var(--mj-bg-surface-sunken);\n}\n\n.artifact-version-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 16px 12px 68px;\n cursor: pointer;\n transition: background 0.15s;\n}\n.artifact-version-item[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n}\n.artifact-version-item[_ngcontent-%COMP%] .version-badge[_ngcontent-%COMP%] {\n display: inline-block;\n padding: 4px 8px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n font-size: 12px;\n font-weight: 600;\n font-family: monospace;\n border-radius: 4px;\n}\n.artifact-version-item[_ngcontent-%COMP%] .version-open-text[_ngcontent-%COMP%] {\n flex: 1;\n font-size: 13px;\n color: var(--mj-text-secondary);\n}\n.artifact-version-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n font-size: 12px;\n}\n.artifact-version-item[_ngcontent-%COMP%]:hover .version-badge[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n.artifact-version-item[_ngcontent-%COMP%]:hover .version-open-text[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n.artifact-version-item[_ngcontent-%COMP%]:hover i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.loading-peripheral-content[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 16px 24px;\n background: var(--mj-bg-surface-card);\n border: 2px solid var(--mj-border-default);\n border-radius: 12px;\n box-shadow: var(--mj-shadow-md);\n color: var(--mj-text-secondary);\n font-size: 14px;\n font-weight: 500;\n}\n.loading-peripheral-content[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 20px;\n color: var(--mj-brand-primary);\n}\n\n@keyframes _ngcontent-%COMP%_fadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n.conversation-loading-state[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n height: 100%;\n width: 100%;\n}\n\n.loading-content[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n padding-top: 20px;\n gap: 16px;\n color: var(--mj-text-secondary);\n font-size: 15px;\n}\n.loading-content[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 32px;\n color: var(--mj-brand-primary);\n}\n.loading-content[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n font-weight: 500;\n}\n\n\n@media (max-width: 768px) {\n .chat-header[_ngcontent-%COMP%] {\n padding: 8px 12px;\n gap: 6px;\n flex-direction: row;\n flex-wrap: wrap;\n align-items: center;\n position: relative;\n }\n .chat-info[_ngcontent-%COMP%] {\n flex-direction: row;\n align-items: center;\n gap: 8px;\n flex: 1;\n min-width: 0;\n order: 1;\n }\n .chat-title-bar[_ngcontent-%COMP%] {\n flex: 1;\n }\n .chat-title[_ngcontent-%COMP%] {\n font-size: 15px;\n font-weight: 700;\n }\n \n .chat-title-crumb.path-middle[_ngcontent-%COMP%] {\n display: none;\n }\n .chat-title-ellipsis[_ngcontent-%COMP%]:not(.collapses-wide) {\n display: flex;\n }\n .project-tag[_ngcontent-%COMP%] {\n margin-left: 0;\n font-size: 10px;\n padding: 3px 8px;\n height: 24px;\n display: none; \n }\n .test-indicator[_ngcontent-%COMP%] {\n margin-left: 0;\n font-size: 10px;\n padding: 3px 8px;\n height: 24px;\n }\n \n .chat-actions-buttons[_ngcontent-%COMP%] {\n order: 2;\n flex-shrink: 0;\n }\n .chat-actions-buttons[_ngcontent-%COMP%] .action-btn[_ngcontent-%COMP%] {\n padding: 6px 8px;\n min-width: auto;\n }\n .chat-actions-buttons[_ngcontent-%COMP%] .action-btn[_ngcontent-%COMP%] .btn-label[_ngcontent-%COMP%] {\n display: none;\n }\n .chat-actions[_ngcontent-%COMP%] {\n flex-wrap: nowrap;\n }\n .chat-members[_ngcontent-%COMP%], \n .artifact-indicator[_ngcontent-%COMP%] {\n padding: 5px 7px;\n font-size: 13px;\n }\n .action-btn[_ngcontent-%COMP%] {\n padding: 6px 8px;\n font-size: 12px;\n }\n .ambient-agent-indicator[_ngcontent-%COMP%] {\n font-size: 12px;\n padding: 4px 8px;\n }\n .project-selector-modal[_ngcontent-%COMP%] {\n width: min(95vw, 600px);\n height: auto;\n }\n .artifacts-modal[_ngcontent-%COMP%] {\n width: min(95vw, 700px);\n }\n .artifacts-grid[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n }\n .chat-input-container[_ngcontent-%COMP%] {\n padding: 0 0.75rem 0.75rem 0.75rem;\n }\n .scroll-to-bottom-icon[_ngcontent-%COMP%] {\n bottom: 16px;\n width: 36px;\n height: 36px;\n }\n \n .chat-content-area[_ngcontent-%COMP%] {\n position: relative;\n }\n .chat-artifact-pane[_ngcontent-%COMP%] {\n position: fixed;\n left: 0;\n right: 0;\n top: 56px; \n bottom: 0;\n width: 100% !important;\n z-index: 100;\n background: var(--mj-bg-surface-card);\n }\n .resize-handle[_ngcontent-%COMP%] {\n display: none;\n }\n}\n\n@media (max-width: 480px) {\n .chat-header[_ngcontent-%COMP%] {\n padding: 6px 8px;\n gap: 4px;\n }\n .chat-title[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 700;\n }\n .project-tag[_ngcontent-%COMP%] {\n font-size: 9px;\n padding: 2px 6px;\n height: 20px;\n display: none;\n }\n .test-indicator[_ngcontent-%COMP%] {\n font-size: 9px;\n padding: 2px 6px;\n height: 20px;\n }\n .chat-members[_ngcontent-%COMP%], \n .artifact-indicator[_ngcontent-%COMP%] {\n padding: 4px 8px;\n font-size: 11px;\n }\n .action-btn[_ngcontent-%COMP%] {\n padding: 5px 7px;\n font-size: 11px;\n }\n .ambient-agent-indicator[_ngcontent-%COMP%] {\n font-size: 11px;\n padding: 3px 6px;\n }\n .project-selector-modal[_ngcontent-%COMP%], \n .artifacts-modal[_ngcontent-%COMP%] {\n width: 100vw;\n height: 100vh;\n border-radius: 0;\n }\n .chat-input-container[_ngcontent-%COMP%] {\n padding: 0 0.5rem 0.5rem 0.5rem;\n }\n .scroll-to-bottom-icon[_ngcontent-%COMP%] {\n bottom: 12px;\n width: 32px;\n height: 32px;\n }\n .scroll-to-bottom-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n }\n}\n\n\n.artifact-picker-overlay[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background: var(--mj-bg-overlay);\n z-index: 999;\n}\n\n.artifact-picker-panel[_ngcontent-%COMP%] {\n position: fixed;\n right: 0;\n top: 0;\n width: 360px;\n height: 100%;\n background: var(--mj-bg-surface);\n border-left: 1px solid var(--mj-border-default);\n z-index: 1000;\n display: flex;\n flex-direction: column;\n box-shadow: -4px 0 12px rgba(0, 0, 0, 0.1);\n animation: _ngcontent-%COMP%_slideInRight 0.2s ease-out;\n}\n\n@keyframes _ngcontent-%COMP%_slideInRight {\n from { transform: translateX(100%); }\n to { transform: translateX(0); }\n}\n\n.artifact-picker-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.artifact-picker-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.artifact-picker-close[_ngcontent-%COMP%] {\n background: none;\n border: none;\n cursor: pointer;\n padding: 4px 8px;\n color: var(--mj-text-muted);\n border-radius: 4px;\n}\n\n.artifact-picker-close[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n\n.artifact-picker-body[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n padding: 12px;\n}\n\n.artifact-picker-empty[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 40px 20px;\n text-align: center;\n color: var(--mj-text-muted);\n gap: 8px;\n}\n\n.artifact-picker-hint[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-disabled);\n}\n\n.artifact-picker-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.artifact-picker-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 10px 12px;\n border: 1px solid var(--mj-border-subtle);\n border-radius: 6px;\n background: var(--mj-bg-surface-card);\n cursor: pointer;\n text-align: left;\n width: 100%;\n transition: background 0.15s, border-color 0.15s;\n}\n\n.artifact-picker-item[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n border-color: var(--mj-brand-primary);\n}\n\n.artifact-picker-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 20px;\n width: 24px;\n text-align: center;\n flex-shrink: 0;\n}\n\n.artifact-picker-item[_ngcontent-%COMP%] i.fa-file-pdf[_ngcontent-%COMP%] { color: var(--mj-status-error); }\n.artifact-picker-item[_ngcontent-%COMP%] i.fa-file-excel[_ngcontent-%COMP%] { color: var(--mj-status-success); }\n.artifact-picker-item[_ngcontent-%COMP%] i.fa-file-word[_ngcontent-%COMP%] { color: var(--mj-brand-primary); }\n.artifact-picker-item[_ngcontent-%COMP%] i.fa-file[_ngcontent-%COMP%] { color: var(--mj-text-muted); }\n\n.artifact-picker-item-info[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n min-width: 0;\n}\n\n.artifact-picker-item-name[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.artifact-picker-item-meta[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-muted);\n}\n\n\n\n\n\n.voice-call-pill[_ngcontent-%COMP%] {\n position: absolute;\n right: 18px;\n bottom: 18px;\n z-index: 49; \n display: flex;\n align-items: center;\n gap: 10px;\n padding: 9px 16px 9px 13px;\n border-radius: var(--mj-radius-full, 9999px);\n border: 1px solid var(--mj-border-strong);\n background: var(--mj-bg-surface-elevated, var(--mj-bg-surface));\n color: var(--mj-text-primary);\n font-family: inherit;\n cursor: pointer;\n box-shadow: 0 8px 24px color-mix(in srgb, var(--mj-brand-primary) 18%, transparent);\n transition: border-color 150ms ease, box-shadow 150ms ease, transform 150ms ease;\n}\n.voice-call-pill[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 10px 28px color-mix(in srgb, var(--mj-brand-primary) 28%, transparent);\n transform: translateY(-1px);\n}\n.voice-call-pill[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n color: var(--mj-brand-primary);\n}\n.voice-call-pill__pulse[_ngcontent-%COMP%] {\n width: 9px;\n height: 9px;\n border-radius: 50%;\n background: var(--mj-status-success);\n flex-shrink: 0;\n animation: _ngcontent-%COMP%_voice-pill-pulse 1.6s ease-in-out infinite;\n}\n.voice-call-pill__text[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n line-height: 1.25;\n}\n.voice-call-pill__name[_ngcontent-%COMP%] {\n font-size: 12.5px;\n font-weight: 700;\n}\n.voice-call-pill__hint[_ngcontent-%COMP%] {\n font-size: 10.5px;\n color: var(--mj-text-muted);\n}\n@keyframes _ngcontent-%COMP%_voice-pill-pulse {\n 0%, 100% {\n box-shadow: 0 0 0 0 color-mix(in srgb, var(--mj-status-success) 45%, transparent);\n }\n 50% {\n box-shadow: 0 0 0 5px color-mix(in srgb, var(--mj-status-success) 0%, transparent);\n }\n}\n\n\n.fork-view-bar[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n padding: var(--mj-space-2) var(--mj-space-4);\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n}\n.fork-composer-hint[_ngcontent-%COMP%] {\n padding: var(--mj-space-1) var(--mj-space-4) 0;\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n}\n.chat-actions-buttons[_ngcontent-%COMP%] > .forks-button[_ngcontent-%COMP%] .forks-count[_ngcontent-%COMP%] {\n margin-left: var(--mj-space-1);\n padding: 0 var(--mj-space-2);\n border-radius: var(--mj-radius-full);\n background: var(--mj-brand-primary);\n color: var(--mj-brand-on-primary);\n font-size: var(--mj-text-xs);\n font-weight: 600;\n}\n.chat-actions-buttons[_ngcontent-%COMP%] > .forks-button.active[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}"] });
10191
+ i0.ɵɵconditional(ctx.showImageViewer ? 30 : -1);
10192
+ } }, dependencies: [i13.NgTemplateOutlet, i14.DefaultValueAccessor, i14.NgControlStatus, i14.MaxLengthValidator, i14.NgModel, i15.TaskGraphRunViewComponent, i16.MJButtonDirective, i16.MJEmptyStateComponent, i10.ArtifactViewerPanelComponent, i17.TestFeedbackDialogComponent, i18.LoadingComponent, i19.GenericShareDialogComponent, i20.ArtifactCollectionPickerModalComponent, i21.ArtifactShareModalComponent, i22.MJChatAgentPresenceDefaultComponent, i23.RealtimeSessionOverlayComponent, i24.RemoteBrowserSurfaceComponent, i25.MessageListComponent, i26.MessageInputComponent, i27.ConversationEmptyStateComponent, i28.ConversationAgentPickerComponent, i29.ConversationModePickerComponent, i30.ProjectSelectorComponent, i31.MembersModalComponent, i32.ExportModalComponent, i33.ImageViewerComponent, i34.PinnedMessagesPanelComponent, i35.ForksPopoverComponent, i13.AsyncPipe], styles: ["[_nghost-%COMP%] {\n display: flex;\n width: 100%;\n height: 100%;\n}\n\n.chat-area[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n overflow: hidden;\n \n position: relative;\n}\n\n.chat-header[_ngcontent-%COMP%] {\n flex-shrink: 0;\n padding: 12px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n display: flex;\n justify-content: space-between;\n align-items: center;\n gap: 16px;\n background: var(--mj-bg-surface-card);\n z-index: 10;\n box-shadow: var(--mj-shadow-sm);\n}\n\n\n\n\n\n\n.chat-agent-presence[_ngcontent-%COMP%] {\n flex-shrink: 0;\n padding: 8px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-card);\n display: flex;\n align-items: center;\n z-index: 11;\n}\n\n.chat-agent-presence--prominent[_ngcontent-%COMP%] {\n padding: 16px 20px;\n justify-content: center;\n}\n\n.chat-info[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n flex: 1;\n min-width: 0;\n}\n\n\n.sidebar-toggle-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n background: transparent;\n border: none;\n border-radius: 6px;\n cursor: pointer;\n transition: all 0.15s ease;\n flex-shrink: 0;\n}\n\n.sidebar-toggle-btn[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-text-primary) 8%, transparent);\n}\n\n.sidebar-toggle-btn[_ngcontent-%COMP%]:active {\n background: color-mix(in srgb, var(--mj-text-primary) 12%, transparent);\n}\n\n.sidebar-toggle-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary);\n font-size: 18px;\n transition: color 0.15s ease;\n}\n\n.sidebar-toggle-btn[_ngcontent-%COMP%]:hover i[_ngcontent-%COMP%] {\n color: var(--mj-text-primary);\n}\n\n\n.chat-title-bar[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: var(--mj-space-1);\n flex: 0 1 auto;\n min-width: 0;\n}\n\n.chat-title[_ngcontent-%COMP%] {\n flex: 0 1 auto;\n min-width: 0;\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.chat-title-path[_ngcontent-%COMP%] {\n min-width: 0;\n}\n\n.chat-title-crumbs[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: var(--mj-space-1);\n min-width: 0;\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n\n.chat-title-crumb[_ngcontent-%COMP%] {\n display: flex;\n flex: 0 100 auto;\n align-items: center;\n gap: var(--mj-space-1);\n min-width: 80px;\n}\n\n.chat-title-crumb.chat-title-ellipsis[_ngcontent-%COMP%] {\n flex: 0 0 auto;\n min-width: 0;\n}\n\n.chat-title-crumb[_ngcontent-%COMP%] > button[_ngcontent-%COMP%] {\n min-width: 0;\n color: var(--mj-text-muted);\n font-size: var(--mj-text-sm);\n font-weight: 500;\n}\n\n.chat-title-crumb-label[_ngcontent-%COMP%] {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n\n.chat-title-crumb.collapsed-wide[_ngcontent-%COMP%], \n.chat-title-ellipsis[_ngcontent-%COMP%]:not(.collapses-wide) {\n display: none;\n}\n\n.chat-title-sep[_ngcontent-%COMP%] {\n flex-shrink: 0;\n font-size: 12px;\n color: var(--mj-border-strong);\n}\n\n.chat-title-current[_ngcontent-%COMP%] {\n display: flex;\n flex: 0 1 auto;\n align-items: center;\n gap: var(--mj-space-1);\n min-width: 120px;\n}\n\n.chat-title-kind[_ngcontent-%COMP%] {\n flex-shrink: 0;\n margin: 0 var(--mj-space-1);\n color: var(--mj-status-info);\n}\n\n.chat-title-kind[data-kind='Edit'][_ngcontent-%COMP%] {\n color: var(--mj-status-warning);\n}\n\n.chat-title-kind[data-kind='Regenerate'][_ngcontent-%COMP%] {\n color: var(--mj-brand-tertiary);\n}\n\n.chat-title-bar[_ngcontent-%COMP%] .chat-title-rename[_ngcontent-%COMP%] {\n flex-shrink: 0;\n color: var(--mj-text-muted);\n opacity: 0.6;\n transition: opacity 0.15s ease, color 0.15s ease;\n}\n\n.chat-title-bar[_ngcontent-%COMP%]:hover .chat-title-rename[_ngcontent-%COMP%], \n.chat-title-bar[_ngcontent-%COMP%] .chat-title-rename[_ngcontent-%COMP%]:focus-visible {\n color: var(--mj-text-primary);\n opacity: 1;\n}\n\n.chat-title-input[_ngcontent-%COMP%] {\n flex: 0 1 360px;\n min-width: 120px;\n padding: var(--mj-space-1) var(--mj-space-2);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font: inherit;\n font-size: 16px;\n font-weight: 600;\n}\n\n.chat-title-input[_ngcontent-%COMP%]:focus-visible {\n outline: none;\n border-color: var(--mj-brand-primary);\n box-shadow: var(--mj-focus-ring);\n}\n\n.with-chip[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: var(--mj-space-1-5);\n padding: 2px var(--mj-space-2);\n border-radius: var(--mj-radius-full);\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-subtle);\n color: var(--mj-text-secondary);\n font-size: var(--mj-text-xs);\n line-height: var(--mj-leading-tight);\n flex-shrink: 0;\n}\n\n.with-chip[_ngcontent-%COMP%] .dot[_ngcontent-%COMP%] {\n width: 6px;\n height: 6px;\n border-radius: var(--mj-radius-full);\n background: var(--agent-accent, var(--mj-brand-primary));\n transition: background-color 240ms cubic-bezier(0.22, 1, 0.36, 1);\n flex-shrink: 0;\n}\n\n.with-chip[_ngcontent-%COMP%] b[_ngcontent-%COMP%] {\n color: var(--mj-text-primary);\n font-weight: var(--mj-font-semibold);\n}\n\n@media (prefers-reduced-motion: reduce) {\n .with-chip[_ngcontent-%COMP%] .dot[_ngcontent-%COMP%] {\n transition: none;\n }\n}\n\n.shared-by-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 3px 10px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n color: var(--mj-brand-primary);\n border-radius: 999px;\n font-size: 12px;\n font-weight: 500;\n flex-shrink: 0;\n max-width: 240px;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.shared-by-badge[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 10px;\n}\n\n.shared-by-badge[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.project-tag[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n border-radius: 16px;\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-text-muted);\n cursor: pointer;\n transition: all 0.2s;\n height: 28px;\n margin-left: 12px;\n}\n\n.project-tag[_ngcontent-%COMP%]:hover {\n background: var(--mj-border-default);\n border-color: var(--mj-text-muted);\n}\n\n.project-tag[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 10px;\n}\n\n.test-indicator[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n background: color-mix(in srgb, var(--mj-status-warning) 10%, var(--mj-bg-surface));\n border: 1px solid var(--mj-status-warning);\n border-radius: 16px;\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-status-warning);\n cursor: pointer;\n transition: all 0.2s;\n height: 28px;\n margin-left: 8px;\n}\n\n.test-indicator[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-status-warning) 20%, var(--mj-bg-surface));\n border-color: var(--mj-status-warning);\n}\n\n.test-indicator[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 10px;\n}\n\n\n.pin-chip[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 5px;\n padding: 5px 10px;\n background: color-mix(in srgb, var(--mj-status-warning) 12%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-status-warning) 45%, transparent);\n border-radius: 20px;\n color: var(--mj-status-warning-text, var(--mj-status-warning));\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s;\n}\n\n.pin-chip[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 11px;\n}\n\n.pin-chip[_ngcontent-%COMP%]:hover, \n.pin-chip.active[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 20%, var(--mj-bg-surface));\n border-color: var(--mj-status-warning);\n}\n\n.pin-chip-count[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 700;\n}\n\n.chat-members[_ngcontent-%COMP%], \n.artifact-indicator[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n position: relative;\n padding: 6px 8px;\n background: transparent;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n font-size: 14px;\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: all 150ms ease;\n}\n\n.chat-members[_ngcontent-%COMP%]:hover, \n.artifact-indicator[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n}\n\n\n.artifact-badge[_ngcontent-%COMP%], \n.members-badge[_ngcontent-%COMP%] {\n position: absolute;\n top: -6px;\n right: -6px;\n min-width: 16px;\n height: 16px;\n padding: 0 4px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n font-size: 10px;\n font-weight: 600;\n border-radius: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n line-height: 1;\n}\n\n.members-badge[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n}\n\n.ambient-agent-indicator[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n font-size: 13px;\n color: var(--mj-text-secondary);\n animation: _ngcontent-%COMP%_pulse 2s ease-in-out infinite;\n}\n\n.ambient-agent-indicator[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n@keyframes _ngcontent-%COMP%_pulse {\n 0%, 100% {\n opacity: 1;\n }\n 50% {\n opacity: 0.7;\n }\n}\n.chat-actions[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.action-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 12px;\n background: transparent;\n border: 1px solid var(--mj-border-default);\n cursor: pointer;\n border-radius: 6px;\n font-size: 13px;\n color: var(--mj-text-secondary);\n transition: all 150ms ease;\n}\n\n.action-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n}\n\n.share-btn.shared[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-color: var(--mj-brand-primary-hover);\n color: var(--mj-brand-primary-hover);\n}\n\n.share-btn.shared[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary-hover);\n}\n\n.chat-content-area[_ngcontent-%COMP%] {\n flex: 1;\n min-height: 0;\n overflow: hidden;\n display: flex;\n flex-direction: row;\n position: relative;\n}\n\n.chat-messages-pane[_ngcontent-%COMP%] {\n height: 100%;\n display: flex;\n flex-direction: column;\n min-width: min(300px, 100%); \n overflow: hidden;\n transition: width 0.3s ease;\n}\n\n.chat-messages-pane.full-width[_ngcontent-%COMP%] {\n width: 100%;\n}\n\n.chat-messages-pane[_ngcontent-%COMP%]:not(.full-width) {\n flex: 1;\n}\n\n.chat-messages-pane.hidden[_ngcontent-%COMP%] {\n display: none;\n}\n\n.resize-handle[_ngcontent-%COMP%] {\n width: 4px;\n background: transparent;\n cursor: col-resize;\n flex-shrink: 0;\n position: relative;\n transition: background-color 0.2s;\n}\n\n.resize-handle[_ngcontent-%COMP%]:hover {\n background: var(--mj-brand-primary);\n}\n\n.resize-handle[_ngcontent-%COMP%]::before {\n content: \"\";\n position: absolute;\n left: -4px;\n right: -4px;\n top: 0;\n bottom: 0;\n}\n\n.chat-artifact-pane[_ngcontent-%COMP%] {\n height: 100%;\n display: flex;\n flex-direction: column;\n background: var(--mj-bg-surface-sunken);\n overflow: hidden;\n flex-shrink: 0;\n}\n\n.chat-artifact-pane.maximized[_ngcontent-%COMP%] {\n width: 100% !important;\n}\n\n.chat-artifact-pane[_ngcontent-%COMP%] > mj-artifact-viewer-panel[_ngcontent-%COMP%] {\n display: flex;\n flex: 1;\n min-height: 0;\n overflow: hidden;\n}\n\n.chat-task-graph-pane[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border-left: 1px solid var(--mj-border-default);\n}\n\n.task-graph-pane-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n padding: 12px 16px;\n background: var(--mj-bg-surface-card);\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n\n.task-graph-pane-title-group[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n min-width: 0;\n}\n\n.task-graph-pane-icon[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n border-radius: 8px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, transparent);\n color: var(--mj-brand-primary);\n font-size: 14px;\n flex-shrink: 0;\n}\n\n.task-graph-pane-titles[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 1px;\n min-width: 0;\n}\n\n.task-graph-pane-title[_ngcontent-%COMP%] {\n font-size: 13.5px;\n font-weight: 600;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.task-graph-pane-subtitle[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-muted);\n}\n\n.task-graph-pane-actions[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n flex-shrink: 0;\n}\n\n.task-graph-pane-save-btn[_ngcontent-%COMP%] {\n height: 30px;\n padding: 0 10px;\n border-radius: 6px;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n font-weight: 500;\n border: 1px solid var(--mj-brand-primary);\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse, #ffffff);\n cursor: pointer;\n transition: opacity 0.15s ease, filter 0.15s ease;\n}\n\n.task-graph-pane-save-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n filter: brightness(1.06);\n}\n\n.task-graph-pane-save-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.55;\n cursor: not-allowed;\n}\n\n.task-graph-pane-btn[_ngcontent-%COMP%] {\n width: 30px;\n height: 30px;\n border-radius: 6px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border: 1px solid var(--mj-border-subtle);\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease;\n}\n\n.task-graph-pane-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n border-color: var(--mj-border-default);\n}\n\n.task-graph-pane-body[_ngcontent-%COMP%] {\n flex: 1;\n width: 100%;\n min-height: 0;\n min-width: 0;\n padding: 12px 16px 16px;\n box-sizing: border-box;\n overflow: hidden;\n display: flex;\n flex-direction: column;\n}\n\n.task-graph-pane-body[_ngcontent-%COMP%] > mj-task-graph-run-view[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n flex: 1;\n width: 100%;\n min-height: 0;\n min-width: 0;\n overflow: hidden;\n}\n\n.chat-messages-wrapper[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n min-height: 0;\n overflow: hidden;\n position: relative; \n}\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n.chat-demonstration-stage[_ngcontent-%COMP%] {\n height: 100%;\n display: flex;\n flex-direction: column;\n overflow: auto;\n background: var(--mj-bg-surface);\n border-right: 1px solid var(--mj-border-default);\n flex: 1;\n min-width: 0;\n}\n\n.chat-content-area.demonstration-mode[_ngcontent-%COMP%] .chat-messages-pane[_ngcontent-%COMP%], \n.chat-content-area.demonstration-mode[_ngcontent-%COMP%] .chat-messages-pane.full-width[_ngcontent-%COMP%] {\n flex: 0 0 320px;\n width: 320px;\n min-width: 0;\n}\n\n@media (max-width: 768px) {\n .chat-content-area.demonstration-mode[_ngcontent-%COMP%] {\n flex-direction: column;\n }\n\n .chat-content-area.demonstration-mode[_ngcontent-%COMP%] .chat-demonstration-stage[_ngcontent-%COMP%] {\n flex: 1 1 60%;\n border-right: none;\n border-bottom: 1px solid var(--mj-border-default);\n height: auto;\n }\n\n .chat-content-area.demonstration-mode[_ngcontent-%COMP%] .chat-messages-pane[_ngcontent-%COMP%], \n .chat-content-area.demonstration-mode[_ngcontent-%COMP%] .chat-messages-pane.full-width[_ngcontent-%COMP%] {\n flex: 1 1 40%;\n width: 100%;\n height: auto;\n }\n}\n\n\n.upload-indicator-overlay[_ngcontent-%COMP%] {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 1rem 1.5rem;\n background: color-mix(in srgb, var(--mj-bg-surface-card) 95%, transparent);\n border-radius: 12px;\n box-shadow: var(--mj-shadow-md);\n z-index: 100;\n pointer-events: none;\n}\n\n.chat-messages-container[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n background: var(--mj-bg-surface-card);\n min-height: 0;\n position: relative;\n}\n\n.scroll-to-bottom-icon[_ngcontent-%COMP%] {\n position: sticky;\n bottom: 21px;\n left: 50%;\n transform: translateX(-50%);\n width: 40px;\n height: 40px;\n margin-top: -40px;\n margin-left: auto;\n margin-right: auto;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n box-shadow: var(--mj-shadow-md);\n transition: all 0.2s ease;\n z-index: 100;\n pointer-events: auto;\n}\n\n.scroll-to-bottom-icon[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-brand-primary);\n transform: translateX(-50%) translateY(-2px);\n box-shadow: color-mix(in srgb, var(--mj-brand-primary) 20%, transparent) 0 4px 12px;\n}\n\n.scroll-to-bottom-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary);\n font-size: 16px;\n transition: color 0.2s;\n}\n\n.scroll-to-bottom-icon[_ngcontent-%COMP%]:hover i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.chat-input-container[_ngcontent-%COMP%] {\n flex-shrink: 0;\n background: var(--mj-bg-surface-card);\n padding: 0 1.25rem 1.25rem 1.25rem;\n overflow: visible;\n}\n\n\n.chat-composer-extra[_ngcontent-%COMP%] {\n margin-bottom: 0.5rem;\n}\n\n.read-only-banner[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n margin: 0 1.25rem 0.5rem 1.25rem;\n padding: 8px 12px;\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, transparent);\n color: var(--mj-text-secondary);\n border-radius: 6px;\n font-size: 12px;\n}\n\n.read-only-banner[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n font-size: 12px;\n}\n\n.loading-peripheral-placeholder[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: 140px;\n padding: 24px;\n background: color-mix(in srgb, var(--mj-bg-surface-card) 50%, transparent);\n backdrop-filter: blur(2px);\n border-radius: 12px;\n margin: 12px;\n animation: _ngcontent-%COMP%_fadeIn 0.2s ease-in-out;\n}\n\n.modal-overlay[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: var(--mj-bg-overlay);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n}\n\n.modal-content[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-card);\n border-radius: 8px;\n box-shadow: var(--mj-shadow-md);\n max-width: 90vw;\n max-height: 90vh;\n display: flex;\n flex-direction: column;\n}\n\n.project-selector-modal[_ngcontent-%COMP%] {\n width: 600px;\n height: 500px;\n}\n\n.modal-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.modal-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 18px;\n font-weight: 600;\n}\n\n.modal-header-actions[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.toggle-system-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n cursor: pointer;\n color: var(--mj-text-secondary);\n padding: 6px 12px;\n border-radius: 6px;\n font-size: 13px;\n font-weight: 500;\n transition: all 0.2s;\n}\n\n.toggle-system-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-border-default);\n border-color: var(--mj-border-default);\n color: var(--mj-text-primary);\n}\n\n.toggle-system-btn.active[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.toggle-system-btn.active[_ngcontent-%COMP%]:hover {\n background: var(--mj-brand-primary-hover);\n border-color: var(--mj-brand-primary-hover);\n}\n\n.toggle-system-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n}\n\n.modal-close-btn[_ngcontent-%COMP%] {\n background: none;\n border: none;\n cursor: pointer;\n color: var(--mj-text-secondary);\n padding: 4px 8px;\n border-radius: 4px;\n transition: all 0.2s;\n}\n\n.modal-close-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n}\n\n.modal-body[_ngcontent-%COMP%] {\n flex: 1;\n overflow: auto;\n padding: 20px;\n}\n\n.artifacts-modal[_ngcontent-%COMP%] {\n width: 700px;\n max-height: 600px;\n}\n\n.artifacts-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));\n gap: 16px;\n}\n\n\n.artifacts-empty-fill[_ngcontent-%COMP%] {\n grid-column: 1/-1;\n}\n\n.artifact-modal-card[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n background: var(--mj-bg-surface-card);\n border: 1.5px solid var(--mj-border-default);\n border-radius: 12px;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n overflow: hidden;\n}\n\n.artifact-modal-card.expanded[_ngcontent-%COMP%] {\n border-color: var(--mj-brand-primary);\n}\n\n.artifact-modal-card.system-artifact[_ngcontent-%COMP%] {\n opacity: 0.85;\n border-color: var(--mj-border-default);\n border-style: dashed;\n position: relative;\n}\n\n.artifact-modal-card.system-artifact[_ngcontent-%COMP%]::before {\n content: \"SYSTEM\";\n position: absolute;\n top: 8px;\n right: 8px;\n font-size: 9px;\n font-weight: 600;\n color: var(--mj-text-muted);\n background: var(--mj-bg-surface-sunken);\n padding: 2px 6px;\n border-radius: 3px;\n letter-spacing: 0.5px;\n z-index: 10;\n}\n\n.artifact-modal-card.system-artifact[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-text-muted);\n box-shadow: var(--mj-shadow-md);\n}\n\n.artifact-card-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 16px;\n cursor: pointer;\n}\n\n.artifact-card-header[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.artifact-modal-card[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-brand-primary);\n box-shadow: var(--mj-shadow-md);\n transform: translateY(-2px);\n}\n\n.artifact-modal-icon[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-radius: 10px;\n color: var(--mj-brand-primary);\n flex-shrink: 0;\n}\n\n.artifact-modal-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 18px;\n}\n\n.artifact-modal-info[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.artifact-modal-title[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin-bottom: 4px;\n}\n\n.artifact-modal-meta[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-secondary);\n}\n\n.artifact-modal-action[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n transition: color 0.2s;\n}\n\n.artifact-modal-card[_ngcontent-%COMP%]:hover .artifact-modal-action[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.expand-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n border: none;\n background: transparent;\n color: var(--mj-text-secondary);\n cursor: pointer;\n border-radius: 6px;\n transition: all 0.2s;\n}\n.expand-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-brand-primary);\n}\n\n.artifact-versions-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n padding: 0 1rem 1rem 1rem;\n background: var(--mj-bg-surface-sunken);\n}\n\n.artifact-version-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 16px 12px 68px;\n cursor: pointer;\n transition: background 0.15s;\n}\n.artifact-version-item[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n}\n.artifact-version-item[_ngcontent-%COMP%] .version-badge[_ngcontent-%COMP%] {\n display: inline-block;\n padding: 4px 8px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n font-size: 12px;\n font-weight: 600;\n font-family: monospace;\n border-radius: 4px;\n}\n.artifact-version-item[_ngcontent-%COMP%] .version-open-text[_ngcontent-%COMP%] {\n flex: 1;\n font-size: 13px;\n color: var(--mj-text-secondary);\n}\n.artifact-version-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n font-size: 12px;\n}\n.artifact-version-item[_ngcontent-%COMP%]:hover .version-badge[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n.artifact-version-item[_ngcontent-%COMP%]:hover .version-open-text[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n.artifact-version-item[_ngcontent-%COMP%]:hover i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.loading-peripheral-content[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 16px 24px;\n background: var(--mj-bg-surface-card);\n border: 2px solid var(--mj-border-default);\n border-radius: 12px;\n box-shadow: var(--mj-shadow-md);\n color: var(--mj-text-secondary);\n font-size: 14px;\n font-weight: 500;\n}\n.loading-peripheral-content[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 20px;\n color: var(--mj-brand-primary);\n}\n\n@keyframes _ngcontent-%COMP%_fadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n.conversation-loading-state[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n height: 100%;\n width: 100%;\n}\n\n.loading-content[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n padding-top: 20px;\n gap: 16px;\n color: var(--mj-text-secondary);\n font-size: 15px;\n}\n.loading-content[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 32px;\n color: var(--mj-brand-primary);\n}\n.loading-content[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n font-weight: 500;\n}\n\n\n@media (max-width: 768px) {\n .chat-header[_ngcontent-%COMP%] {\n padding: 8px 12px;\n gap: 6px;\n flex-direction: row;\n flex-wrap: wrap;\n align-items: center;\n position: relative;\n }\n .chat-info[_ngcontent-%COMP%] {\n flex-direction: row;\n align-items: center;\n gap: 8px;\n flex: 1;\n min-width: 0;\n order: 1;\n }\n .chat-title-bar[_ngcontent-%COMP%] {\n flex: 1;\n }\n .chat-title[_ngcontent-%COMP%] {\n font-size: 15px;\n font-weight: 700;\n }\n \n .chat-title-crumb.path-middle[_ngcontent-%COMP%] {\n display: none;\n }\n .chat-title-ellipsis[_ngcontent-%COMP%]:not(.collapses-wide) {\n display: flex;\n }\n .project-tag[_ngcontent-%COMP%] {\n margin-left: 0;\n font-size: 10px;\n padding: 3px 8px;\n height: 24px;\n display: none; \n }\n .test-indicator[_ngcontent-%COMP%] {\n margin-left: 0;\n font-size: 10px;\n padding: 3px 8px;\n height: 24px;\n }\n \n .chat-actions-buttons[_ngcontent-%COMP%] {\n order: 2;\n flex-shrink: 0;\n }\n .chat-actions-buttons[_ngcontent-%COMP%] .action-btn[_ngcontent-%COMP%] {\n padding: 6px 8px;\n min-width: auto;\n }\n .chat-actions-buttons[_ngcontent-%COMP%] .action-btn[_ngcontent-%COMP%] .btn-label[_ngcontent-%COMP%] {\n display: none;\n }\n .chat-actions[_ngcontent-%COMP%] {\n flex-wrap: nowrap;\n }\n .chat-members[_ngcontent-%COMP%], \n .artifact-indicator[_ngcontent-%COMP%] {\n padding: 5px 7px;\n font-size: 13px;\n }\n .action-btn[_ngcontent-%COMP%] {\n padding: 6px 8px;\n font-size: 12px;\n }\n .ambient-agent-indicator[_ngcontent-%COMP%] {\n font-size: 12px;\n padding: 4px 8px;\n }\n .project-selector-modal[_ngcontent-%COMP%] {\n width: min(95vw, 600px);\n height: auto;\n }\n .artifacts-modal[_ngcontent-%COMP%] {\n width: min(95vw, 700px);\n }\n .artifacts-grid[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n }\n .chat-input-container[_ngcontent-%COMP%] {\n padding: 0 0.75rem 0.75rem 0.75rem;\n }\n .scroll-to-bottom-icon[_ngcontent-%COMP%] {\n bottom: 16px;\n width: 36px;\n height: 36px;\n }\n \n .chat-content-area[_ngcontent-%COMP%] {\n position: relative;\n }\n .chat-artifact-pane[_ngcontent-%COMP%] {\n position: fixed;\n left: 0;\n right: 0;\n top: 56px; \n bottom: 0;\n width: 100% !important;\n z-index: 100;\n background: var(--mj-bg-surface-card);\n }\n .resize-handle[_ngcontent-%COMP%] {\n display: none;\n }\n}\n\n@media (max-width: 480px) {\n .chat-header[_ngcontent-%COMP%] {\n padding: 6px 8px;\n gap: 4px;\n }\n .chat-title[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 700;\n }\n .project-tag[_ngcontent-%COMP%] {\n font-size: 9px;\n padding: 2px 6px;\n height: 20px;\n display: none;\n }\n .test-indicator[_ngcontent-%COMP%] {\n font-size: 9px;\n padding: 2px 6px;\n height: 20px;\n }\n .chat-members[_ngcontent-%COMP%], \n .artifact-indicator[_ngcontent-%COMP%] {\n padding: 4px 8px;\n font-size: 11px;\n }\n .action-btn[_ngcontent-%COMP%] {\n padding: 5px 7px;\n font-size: 11px;\n }\n .ambient-agent-indicator[_ngcontent-%COMP%] {\n font-size: 11px;\n padding: 3px 6px;\n }\n .project-selector-modal[_ngcontent-%COMP%], \n .artifacts-modal[_ngcontent-%COMP%] {\n width: 100vw;\n height: 100vh;\n border-radius: 0;\n }\n .chat-input-container[_ngcontent-%COMP%] {\n padding: 0 0.5rem 0.5rem 0.5rem;\n }\n .scroll-to-bottom-icon[_ngcontent-%COMP%] {\n bottom: 12px;\n width: 32px;\n height: 32px;\n }\n .scroll-to-bottom-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n }\n}\n\n\n.artifact-picker-overlay[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background: var(--mj-bg-overlay);\n z-index: 999;\n}\n\n.artifact-picker-panel[_ngcontent-%COMP%] {\n position: fixed;\n right: 0;\n top: 0;\n width: 360px;\n height: 100%;\n background: var(--mj-bg-surface);\n border-left: 1px solid var(--mj-border-default);\n z-index: 1000;\n display: flex;\n flex-direction: column;\n box-shadow: -4px 0 12px rgba(0, 0, 0, 0.1);\n animation: _ngcontent-%COMP%_slideInRight 0.2s ease-out;\n}\n\n@keyframes _ngcontent-%COMP%_slideInRight {\n from { transform: translateX(100%); }\n to { transform: translateX(0); }\n}\n\n.artifact-picker-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.artifact-picker-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.artifact-picker-close[_ngcontent-%COMP%] {\n background: none;\n border: none;\n cursor: pointer;\n padding: 4px 8px;\n color: var(--mj-text-muted);\n border-radius: 4px;\n}\n\n.artifact-picker-close[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n\n.artifact-picker-body[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n padding: 12px;\n}\n\n.artifact-picker-empty[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 40px 20px;\n text-align: center;\n color: var(--mj-text-muted);\n gap: 8px;\n}\n\n.artifact-picker-hint[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-disabled);\n}\n\n.artifact-picker-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.artifact-picker-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 10px 12px;\n border: 1px solid var(--mj-border-subtle);\n border-radius: 6px;\n background: var(--mj-bg-surface-card);\n cursor: pointer;\n text-align: left;\n width: 100%;\n transition: background 0.15s, border-color 0.15s;\n}\n\n.artifact-picker-item[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n border-color: var(--mj-brand-primary);\n}\n\n.artifact-picker-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 20px;\n width: 24px;\n text-align: center;\n flex-shrink: 0;\n}\n\n.artifact-picker-item[_ngcontent-%COMP%] i.fa-file-pdf[_ngcontent-%COMP%] { color: var(--mj-status-error); }\n.artifact-picker-item[_ngcontent-%COMP%] i.fa-file-excel[_ngcontent-%COMP%] { color: var(--mj-status-success); }\n.artifact-picker-item[_ngcontent-%COMP%] i.fa-file-word[_ngcontent-%COMP%] { color: var(--mj-brand-primary); }\n.artifact-picker-item[_ngcontent-%COMP%] i.fa-file[_ngcontent-%COMP%] { color: var(--mj-text-muted); }\n\n.artifact-picker-item-info[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n min-width: 0;\n}\n\n.artifact-picker-item-name[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.artifact-picker-item-meta[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-muted);\n}\n\n\n\n\n\n.voice-call-pill[_ngcontent-%COMP%] {\n position: absolute;\n right: 18px;\n bottom: 18px;\n z-index: 49; \n display: flex;\n align-items: center;\n gap: 10px;\n padding: 9px 16px 9px 13px;\n border-radius: var(--mj-radius-full, 9999px);\n border: 1px solid var(--mj-border-strong);\n background: var(--mj-bg-surface-elevated, var(--mj-bg-surface));\n color: var(--mj-text-primary);\n font-family: inherit;\n cursor: pointer;\n box-shadow: 0 8px 24px color-mix(in srgb, var(--mj-brand-primary) 18%, transparent);\n transition: border-color 150ms ease, box-shadow 150ms ease, transform 150ms ease;\n}\n.voice-call-pill[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 10px 28px color-mix(in srgb, var(--mj-brand-primary) 28%, transparent);\n transform: translateY(-1px);\n}\n.voice-call-pill[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n color: var(--mj-brand-primary);\n}\n.voice-call-pill__pulse[_ngcontent-%COMP%] {\n width: 9px;\n height: 9px;\n border-radius: 50%;\n background: var(--mj-status-success);\n flex-shrink: 0;\n animation: _ngcontent-%COMP%_voice-pill-pulse 1.6s ease-in-out infinite;\n}\n.voice-call-pill__text[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n line-height: 1.25;\n}\n.voice-call-pill__name[_ngcontent-%COMP%] {\n font-size: 12.5px;\n font-weight: 700;\n}\n.voice-call-pill__hint[_ngcontent-%COMP%] {\n font-size: 10.5px;\n color: var(--mj-text-muted);\n}\n@keyframes _ngcontent-%COMP%_voice-pill-pulse {\n 0%, 100% {\n box-shadow: 0 0 0 0 color-mix(in srgb, var(--mj-status-success) 45%, transparent);\n }\n 50% {\n box-shadow: 0 0 0 5px color-mix(in srgb, var(--mj-status-success) 0%, transparent);\n }\n}\n\n\n.fork-view-bar[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n padding: var(--mj-space-2) var(--mj-space-4);\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n}\n.fork-composer-hint[_ngcontent-%COMP%] {\n padding: var(--mj-space-1) var(--mj-space-4) 0;\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n}\n.chat-actions-buttons[_ngcontent-%COMP%] > .forks-button[_ngcontent-%COMP%] .forks-count[_ngcontent-%COMP%] {\n margin-left: var(--mj-space-1);\n padding: 0 var(--mj-space-2);\n border-radius: var(--mj-radius-full);\n background: var(--mj-brand-primary);\n color: var(--mj-brand-on-primary);\n font-size: var(--mj-text-xs);\n font-weight: 600;\n}\n.chat-actions-buttons[_ngcontent-%COMP%] > .forks-button.active[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n.chat-actions-buttons[_ngcontent-%COMP%] > .remote-browser-toggle-btn.active[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n.remote-browser-url-input[_ngcontent-%COMP%] {\n width: 220px;\n max-width: 38vw;\n height: 28px;\n padding: 0 10px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font-size: 12px;\n font-family: var(--mj-font-family-mono);\n}\n.remote-browser-url-input[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--mj-border-focus);\n}"] });
9333
10193
  }
9334
10194
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ConversationChatAreaComponent, [{
9335
10195
  type: Component,
9336
- args: [{ standalone: false, selector: 'mj-conversation-chat-area', template: "<div class=\"chat-area\">\n <!-- agentPresence slot \u2014 sticky top, anchored with the header. Per Matt's\n 06-10 design: persistent presence indicator (Sid's face + live voice\n state). Off by default; opt in via [showAgentCharacter]. When a\n consumer projects an `mjChatSlot=\"agentPresence\"` template, it\n replaces the default presence component. -->\n @if (showAgentCharacter) {\n <div class=\"chat-agent-presence\" [class.chat-agent-presence--prominent]=\"agentCharacterConfig?.voiceStateMode === 'prominent'\">\n @if (slotTemplate('agentPresence'); as t) {\n <ng-container *ngTemplateOutlet=\"t; context: {\n $implicit: agentCharacterConfig,\n state: agentCharacterConfig?.state ?? 'idle',\n agentName: agentCharacterConfig?.characterName,\n avatarUrl: agentCharacterConfig?.avatarUrl,\n mode: agentCharacterConfig?.voiceStateMode ?? 'subtle'\n }\"></ng-container>\n } @else {\n <mj-chat-agent-presence-default\n [State]=\"agentCharacterConfig?.state ?? 'idle'\"\n [AgentName]=\"agentCharacterConfig?.characterName\"\n [AvatarUrl]=\"agentCharacterConfig?.avatarUrl\"\n [Mode]=\"agentCharacterConfig?.voiceStateMode ?? 'subtle'\">\n </mj-chat-agent-presence-default>\n }\n </div>\n }\n\n <!-- header slot \u2014 replaces the entire chat-header chrome (title, badges,\n export/share/agent-picker buttons). When projected, the consumer owns\n the entire header rendering; the default chrome below is bypassed\n wholesale. Context exposes the minimal IMJChatHeaderComponent shape;\n consumers needing more app state should bind to chat-area inputs\n directly via @ViewChild or wrap the whole component. -->\n @if (slotTemplate('header'); as t) {\n <ng-container *ngTemplateOutlet=\"t; context: {\n $implicit: conversation,\n conversationTitle: conversation?.Name ?? null,\n sharedBy: sharedByBadge?.display ?? null,\n artifactCount: artifactCountDisplay,\n showArtifactIndicator: showArtifactIndicator\n }\"></ng-container>\n } @else if (conversation || HasPreConversationHeader) {\n <!-- Default header \u2014 also renders BEFORE a conversation exists when the\n embedder has pre-conversation chrome to surface (currently just the\n mode picker \u2014 agent / share / export / members / artifacts all\n require a conversation row and stay hidden). Lets embedded surfaces\n like the Form Builder cockpit show the mode picker above the\n empty-state on a fresh chat instead of waiting for the first\n message to round-trip. -->\n <div class=\"chat-header\" (keydown.escape)=\"OnViewEscape($event)\">\n <div class=\"chat-info\" [class.with-sidebar-toggle]=\"showSidebarToggle\">\n @if (showSidebarToggle) {\n <button class=\"sidebar-toggle-btn\"\n (click)=\"sidebarToggleClicked.emit()\"\n title=\"Show conversations\">\n <i class=\"fas fa-table-columns\"></i>\n </button>\n }\n @if (conversation) {\n <ng-container *ngTemplateOutlet=\"titleBar\"></ng-container>\n }\n @if (sharedByBadge) {\n <span class=\"shared-by-badge\" [title]=\"sharedByBadge.fullTooltip\">\n <i class=\"fas fa-share-nodes\"></i>\n <span>Shared by {{ sharedByBadge.display }}</span>\n </span>\n }\n @if (conversation?.ProjectID) {\n <button class=\"project-tag\" (click)=\"openProjectSelector()\" [attr.title]=\"EffectiveReadOnly ? 'Project' : 'Assign to project'\">\n <i class=\"fas fa-folder\"></i>\n <span>{{ conversation!.Project || 'Project' }}</span>\n </button>\n }\n @if (conversation?.TestRunID) {\n <button class=\"test-indicator\" (click)=\"viewTestRun(conversation!.TestRunID!)\" title=\"View Test Run\">\n <i class=\"fas fa-flask\"></i>\n <span>Test</span>\n </button>\n }\n </div>\n <div class=\"chat-actions chat-actions-buttons\">\n @if (ForkSummaries.length > 0) {\n <button mjButton #forksButton Variant=\"flat\" Size=\"sm\" class=\"forks-button\" [class.active]=\"ShowForksPopover\"\n aria-haspopup=\"dialog\" [attr.aria-expanded]=\"ShowForksPopover\" [attr.aria-controls]=\"ShowForksPopover ? ForksPopoverID : null\"\n (click)=\"ToggleForksPopover()\" title=\"Forks in this conversation\">\n <i class=\"fa-solid fa-code-branch\"></i>\n <span class=\"btn-label\">Forks</span>\n <span class=\"forks-count\">{{ ForkSummaries.length }}</span>\n </button>\n }\n @if (allowPinning && pinnedMessageCount > 0) {\n <button class=\"pin-chip\" [class.active]=\"showPinsPanel\" (click)=\"TogglePinsPanel()\" title=\"View pinned messages\">\n <i class=\"fas fa-thumbtack\"></i>\n <span class=\"pin-chip-count\">{{ pinnedMessageCount }}</span>\n </button>\n }\n @if (showArtifactIndicator && artifactCountDisplay > 0) {\n <button class=\"artifact-indicator\" (click)=\"viewArtifacts()\" title=\"View artifacts\">\n <i class=\"fas fa-cube\"></i>\n <span class=\"artifact-badge\">{{ artifactCountDisplay }}</span>\n </button>\n }\n @if (memberCount > 1) {\n <button class=\"chat-members\" (click)=\"toggleMembersModal()\" title=\"View members\">\n <i class=\"fas fa-users\"></i>\n <span class=\"members-badge\">{{ memberCount }}</span>\n </button>\n }\n @if (!overlayMode && showAgentModePicker && ModePickerTargetAgentId && !EffectiveReadOnly) {\n <!-- Per-agent mode/quality picker (Draft / Standard / High).\n Targets the agent the next non-mention message will route\n to. Auto-hides when that agent has fewer than 2 configured\n presets. Choice persists per-user, per-agent via\n UserInfoEngine; emits the picked configuration ID up so\n <mj-message-input> can forward it on the next route.\n Hidden in overlayMode (the compact chat overlay): the\n mode dropdown wastes the narrow top-right space there. -->\n <mj-conversation-mode-picker\n [AgentID]=\"ModePickerTargetAgentId\"\n [Disabled]=\"isProcessing\"\n (PresetChanged)=\"OnAgentModePresetChanged($event)\">\n </mj-conversation-mode-picker>\n }\n @if (showAgentPicker && conversation) {\n <!-- Per-conversation default-agent pin. When set, non-mention\n messages route to this agent instead of Sage. Persists to\n MJConversationEntity.DefaultAgentID. Hidden when no\n conversation is loaded or when the embedder disables it. -->\n <mj-conversation-agent-picker\n [Conversation]=\"conversation\"\n [CurrentUser]=\"currentUser\"\n [AllowedAgentIDs]=\"AllowedAgentIDs\"\n [Disabled]=\"EffectiveReadOnly\">\n </mj-conversation-agent-picker>\n }\n @if (showExportButton) {\n <button mjButton variant=\"flat\" size=\"sm\" (click)=\"exportConversation()\" [title]=\"exportButtonLabel + ' conversation'\">\n <i [class]=\"exportButtonIcon\"></i>\n <span class=\"btn-label\">{{ exportButtonLabel }}</span>\n </button>\n }\n @if (showShareButton && canShareConversation) {\n <button mjButton variant=\"flat\" size=\"sm\"\n [class.shared]=\"isShared\"\n (click)=\"shareConversation()\"\n [title]=\"isShared ? 'Manage sharing' : 'Share conversation'\">\n <i class=\"fas fa-share-nodes\"></i>\n <span class=\"btn-label\">Share</span>\n </button>\n }\n <!-- headerActions slot \u2014 ADDITIVE host buttons rendered after the stock\n actions (unlike the `header` slot, which replaces the whole header\n and therefore never reaches this branch). For visual parity,\n projected buttons should use mjButton variant=\"flat\" size=\"sm\". -->\n @if (slotTemplate('headerActions'); as t) {\n <ng-container *ngTemplateOutlet=\"t; context: {\n $implicit: conversation,\n conversationId: conversationId,\n isProcessing: isProcessing\n }\"></ng-container>\n }\n </div>\n </div>\n }\n\n <!-- Header title. Main: the conversation name. A fork: the path, the conversation and each parent fork\n (each opens its view; the parent is the way back), then the open fork with its kind icon. Past three\n entries, and on narrow screens, the middle crumbs collapse into an ellipsis that opens the forks list.\n The current name can be renamed in place. -->\n <ng-template #titleBar>\n <div class=\"chat-title-bar\">\n @if (OpenView.Kind === 'Main') {\n <ng-container *ngTemplateOutlet=\"titleName\"></ng-container>\n } @else {\n <nav class=\"chat-title-path\" aria-label=\"Breadcrumb\">\n <ol class=\"chat-title-crumbs\">\n @for (parent of HeaderPath.Parents; track $index) {\n @if ($index === 1) {\n <li class=\"chat-title-crumb chat-title-ellipsis\" [class.collapses-wide]=\"HeaderPath.CollapsesWide\">\n <button mjButton Variant=\"flat\" Size=\"sm\" type=\"button\" (click)=\"ShowWholePath()\" aria-label=\"Show the whole path\" title=\"Show the whole path\">\u2026</button>\n <i class=\"fa-solid fa-chevron-right chat-title-sep\" aria-hidden=\"true\"></i>\n </li>\n }\n <li class=\"chat-title-crumb\" [class.path-middle]=\"parent.IsMiddle\" [class.collapsed-wide]=\"parent.CollapsedWide\">\n <button mjButton Variant=\"flat\" Size=\"sm\" type=\"button\" (click)=\"OpenCrumb(parent.Crumb)\" [title]=\"'Back to ' + parent.Crumb.Label\">\n <span class=\"chat-title-crumb-label\">{{ parent.Crumb.Label }}</span>\n </button>\n <i class=\"fa-solid fa-chevron-right chat-title-sep\" aria-hidden=\"true\"></i>\n </li>\n }\n <li class=\"chat-title-current\" aria-current=\"page\">\n <i [class]=\"'chat-title-kind ' + OpenViewIcon\" [attr.data-kind]=\"OpenViewKind\" aria-hidden=\"true\"></i>\n <ng-container *ngTemplateOutlet=\"titleName\"></ng-container>\n </li>\n </ol>\n </nav>\n }\n </div>\n </ng-template>\n\n <!-- The current name and its rename button; the inline field while renaming -->\n <ng-template #titleName>\n @if (IsRenamingTitle) {\n <input\n #titleNameInput\n type=\"text\"\n class=\"chat-title-input\"\n maxlength=\"255\"\n [attr.aria-label]=\"TitleRenameLabel\"\n [(ngModel)]=\"TitleRenameText\"\n (keydown.enter)=\"$event.preventDefault(); SaveTitleRename(true)\"\n (keydown.escape)=\"$event.preventDefault(); $event.stopPropagation(); CancelTitleRename()\"\n (blur)=\"SaveTitleRename()\" />\n } @else {\n <h2 class=\"chat-title\" [title]=\"HeaderTitle\">{{ HeaderTitle }}</h2>\n @if (CanRenameTitle) {\n <button mjButton #titleRenameButton Variant=\"icon\" Size=\"sm\" type=\"button\" class=\"chat-title-rename\" (click)=\"StartTitleRename()\" [attr.aria-label]=\"TitleRenameLabel\" [title]=\"TitleRenameLabel\">\n <i class=\"fa-solid fa-pen\" aria-hidden=\"true\"></i>\n </button>\n }\n }\n </ng-template>\n\n <!-- Messages and Artifact Split Layout \u2014 restructures into [stage | rail]\n when isDemonstrationActive (per Matt's 06-10 design). The .demonstration-mode\n class drives the CSS Grid switch; the stage container renders only when the\n slot is projected AND the host opts in via [showDemonstrationSurface]. -->\n <div class=\"chat-content-area\" [class.demonstration-mode]=\"isDemonstrationActive\">\n <!-- demonstrationSurface stage \u2014 takes the main pane; messages shrink to\n a side rail (or move below on mobile). Off unless both\n [showDemonstrationSurface] is true AND a slot template is projected. -->\n @if (isDemonstrationActive) {\n <div class=\"chat-demonstration-stage\">\n <ng-container *ngTemplateOutlet=\"slotTemplate('demonstrationSurface'); context: {\n $implicit: demonstrationSurfaceContent,\n content: demonstrationSurfaceContent,\n visible: showDemonstrationSurface\n }\"></ng-container>\n </div>\n }\n\n <!-- Messages Pane -->\n <div class=\"chat-messages-pane\"\n [class.full-width]=\"!showArtifactPanel && !SelectedTaskGraphPanel\"\n [class.hidden]=\"isArtifactPaneMaximized\">\n @if (isLoadingConversation) {\n <!-- Loading State - checked FIRST to prevent empty state flash. The branch\n always short-circuits the panes below; showLoadingState only controls\n whether the built-in spinner renders (hosts with their own loading\n chrome set it false and get a blank pane instead). -->\n @if (showLoadingState) {\n <div class=\"conversation-loading-state\">\n <mj-loading text=\"Loading conversation...\" size=\"large\"></mj-loading>\n </div>\n }\n } @else if ((isNewConversation || !conversationId) && !suppressNewConversationEmptyState) {\n <!-- emptyState slot \u2014 when a consumer projects mjChatSlot=\"emptyState\",\n they take over the entire empty-state region (including any send\n affordance \u2014 the slot interface doesn't include a sendMessage\n output, so consumers handle send via their own input). When no\n slot is projected, the rich built-in <mj-conversation-empty-state>\n renders with its own greeting, prompt chips, and message input.\n emptyStateConfig (when supplied) takes precedence over the legacy\n [emptyStateGreeting] string for backwards compatibility. -->\n @if (ReadOnly) {\n <div class=\"read-only-banner\" role=\"status\">\n <i class=\"fas fa-eye\"></i>\n <span>{{ ReadOnlyMessage || 'You have view-only access to this conversation.' }}</span>\n </div>\n } @else if (slotTemplate('emptyState'); as t) {\n <ng-container *ngTemplateOutlet=\"t; context: {\n $implicit: emptyStateConfig,\n greeting: emptyStateConfig?.greeting ?? emptyStateGreeting,\n subtext: emptyStateConfig?.subtext,\n suggestedPrompts: emptyStateConfig?.suggestedPrompts ?? []\n }\"></ng-container>\n } @else {\n <mj-conversation-empty-state\n [currentUser]=\"currentUser\"\n [initialDraft]=\"GetInitialDraftFor(null)\"\n (initialDraftApplied)=\"OnComposerDraftApplied()\"\n (DraftStateChanged)=\"OnDraftStateChanged(null, $event)\"\n (ComposerBlurred)=\"OnComposerBlurred()\"\n [disabled]=\"isProcessing\"\n [showSidebarToggle]=\"showSidebarToggle\"\n [overlayMode]=\"overlayMode\"\n [greeting]=\"emptyStateConfig?.greeting ?? emptyStateGreeting\"\n [showSuggestedPrompts]=\"showSuggestedPrompts\"\n [enableAttachments]=\"enableAttachments && allowAttachments\"\n [enableMentions]=\"allowMentions\"\n [enableAgentMentions]=\"allowAgentMentions\"\n [enableEntityMentions]=\"allowEntityMentions\"\n [enableSkillCommands]=\"allowSkillCommands\"\n [AllowedAgentIDs]=\"AllowedAgentIDs\"\n [MentionPeople]=\"MentionPeople\"\n [ComposerExtraTemplate]=\"slotTemplate('composerExtra')\"\n [maxAttachments]=\"maxAttachments\"\n [maxAttachmentSizeBytes]=\"maxAttachmentSizeBytes\"\n [acceptedFileTypes]=\"acceptedFileTypes\"\n (sidebarToggleClicked)=\"sidebarToggleClicked.emit()\"\n (messageSent)=\"onEmptyStateMessageSent($event)\">\n </mj-conversation-empty-state>\n }\n } @else if ((isNewConversation || !conversationId) && suppressNewConversationEmptyState) {\n <!-- Pre-conversation normal-view: empty message list + emptyStateMode input.\n Used when host (e.g. Form Builder cockpit) wants the header + mode picker\n visible on first open instead of the centered welcome card. First send\n routes through onEmptyStateMessageSent which creates the conversation. -->\n <div class=\"chat-messages-wrapper\">\n <div class=\"chat-messages-container\"></div>\n <div class=\"chat-input-container\">\n @if (ReadOnly) {\n <div class=\"read-only-banner\" role=\"status\">\n <i class=\"fas fa-eye\"></i>\n <span>{{ ReadOnlyMessage || 'You have view-only access to this conversation.' }}</span>\n </div>\n } @else {\n <!-- composerExtra slot \u2014 host UI directly above the composer (IMJChatComposerExtraContext). -->\n @if (slotTemplate('composerExtra'); as t) {\n <div class=\"chat-composer-extra\">\n <ng-container *ngTemplateOutlet=\"t; context: {\n $implicit: conversation,\n ConversationId: conversationId,\n IsProcessing: isProcessing\n }\"></ng-container>\n </div>\n }\n <div class=\"message-input-container-wrapper\">\n <mj-message-input\n #emptyStateInput\n [emptyStateMode]=\"true\"\n [initialDraft]=\"GetInitialDraftFor(null)\"\n (initialDraftApplied)=\"OnComposerDraftApplied()\"\n (DraftStateChanged)=\"OnDraftStateChanged(null, $event)\"\n (ComposerBlurred)=\"OnComposerBlurred()\"\n [currentUser]=\"currentUser\"\n [disabled]=\"isProcessing\"\n [ReadOnly]=\"EffectiveReadOnly\"\n [appContext]=\"appContext\"\n [applicationId]=\"applicationId\"\n [defaultAgentId]=\"defaultAgentId\"\n [enableAttachments]=\"enableAttachments && allowAttachments\"\n [enableMentions]=\"allowMentions\"\n [enableAgentMentions]=\"allowAgentMentions\"\n [enableEntityMentions]=\"allowEntityMentions\"\n [enableSkillCommands]=\"allowSkillCommands\"\n [enablePlanMode]=\"allowPlanMode\"\n [enableRealtime]=\"allowRealtime\"\n [AllowedAgentIDs]=\"AllowedAgentIDs\"\n [MentionPeople]=\"MentionPeople\"\n [maxAttachments]=\"maxAttachments\"\n [maxAttachmentSizeBytes]=\"maxAttachmentSizeBytes\"\n [acceptedFileTypes]=\"acceptedFileTypes\"\n (emptyStateSubmit)=\"onEmptyStateMessageSent($event)\">\n </mj-message-input>\n </div>\n }\n </div>\n </div>\n } @else {\n <!-- Normal Message View -->\n <div class=\"chat-messages-wrapper\">\n @if (OpenView.Kind !== 'Main' && slotTemplate('header')) {\n <!-- A host header replaces the default one, so the fork title shows above the transcript. -->\n <div class=\"fork-view-bar\" role=\"region\" aria-label=\"Fork\" (keydown.escape)=\"OnViewEscape($event)\">\n <ng-container *ngTemplateOutlet=\"titleBar\"></ng-container>\n </div>\n }\n <!-- Upload Indicator Overlay (centered in conversation area) -->\n @if (isUploadingAttachments) {\n <div class=\"upload-indicator-overlay\">\n <mj-loading [text]=\"uploadingMessage\" size=\"medium\"></mj-loading>\n </div>\n }\n <div class=\"chat-messages-container\" #scrollContainer (scroll)=\"checkScroll()\" (keydown.escape)=\"OnViewEscape($event)\">\n <mj-conversation-message-list\n [showEmptyFill]=\"showEmptyFill\"\n [showDateNavigation]=\"showDateNavigation\"\n [showAgentRunDetails]=\"showAgentRunDetails\"\n [showReactions]=\"showReactions\"\n [showMessageRating]=\"showMessageRating\"\n [allowPinning]=\"allowPinning && !EffectiveReadOnly\"\n [allowMessageEdit]=\"allowMessageEdit && !EffectiveReadOnly\"\n [allowMessageDelete]=\"allowMessageDelete && !EffectiveReadOnly\"\n [ReadOnly]=\"EffectiveReadOnly\"\n [AllowStopRun]=\"AllowStopRun\"\n [InFlightCount]=\"InFlightCount\"\n [assistantDisplayName]=\"assistantDisplayName\"\n [assistantAvatarUrl]=\"assistantAvatarUrl\"\n [messages]=\"DisplayMessages\"\n [HasMoreAbove]=\"ListHasMoreAbove\"\n [IsLoadingOlder]=\"isLoadingOlderMessages\"\n [ScrollRoot]=\"messageScrollRoot\"\n (OlderRequested)=\"onOlderMessagesRequested()\"\n (DateJumpRequested)=\"onDateJumpRequested($event)\"\n [conversation]=\"conversation\"\n [currentUser]=\"currentUser\"\n [isProcessing]=\"isProcessing\"\n [artifactMap]=\"effectiveArtifactsMap\"\n [agentRunMap]=\"agentRunsByDetailId\"\n [ratingsMap]=\"ratingsByDetailId\"\n [userAvatarMap]=\"userAvatarMap\"\n [attachmentsMap]=\"attachmentsByDetailId\"\n [messageRendererTemplate]=\"slotTemplate('messageRenderer')\"\n [messageExtraTemplate]=\"slotTemplate('messageExtra')\"\n [sessionMetaMap]=\"realtimeSessionMetaMap\"\n [ForkChipMap]=\"ForkChipMap\"\n [ForkLayout]=\"ForkLayout\"\n [CanFork]=\"CanFork\"\n [InPlaceTurn]=\"InPlaceTurn\"\n (ForkOpenRequested)=\"OnForkOpenRequested($event)\"\n (EditResendRequested)=\"OnEditResendRequested($event)\"\n (RegenerateRequested)=\"OnRegenerateRequested($event)\"\n (ResendInPlaceRequested)=\"OnResendInPlaceRequested($event)\"\n (ForkRequested)=\"OnForkRequested($event)\"\n (realtimeSessionOpenRequested)=\"OpenRealtimeSessionReview($event)\"\n (deleteMessage)=\"onDeleteMessage($event)\"\n (BeforeStopClicked)=\"BeforeStopClicked.emit($event)\"\n (StopMessage)=\"OnStopMessage($event)\"\n (testFeedbackMessage)=\"onTestFeedbackMessage($event)\"\n (artifactClicked)=\"onArtifactClicked($event)\"\n (messageEdited)=\"onMessageEdited($event)\"\n (openEntityRecord)=\"onOpenEntityRecord($event)\"\n (suggestedResponseSelected)=\"onSuggestedResponseSelected($event)\"\n (attachmentClicked)=\"onAttachmentClicked($event)\"\n (diagnosticRequested)=\"onDiagnosticRequested($event)\"\n (LivenessCheckRequested)=\"OnLivenessCheckRequested($event)\"\n (messagePinToggled)=\"onMessagePinToggled($event)\"\n (beforeResponseFormSubmitted)=\"beforeResponseFormSubmitted.emit($event)\"\n (afterResponseFormSubmitted)=\"afterResponseFormSubmitted.emit($event)\"\n (TaskGraphPanelRequested)=\"OnTaskGraphPanelRequested($event)\"\n (ScrollToMessageRequested)=\"OnJumpToMessage($event)\">\n </mj-conversation-message-list>\n\n <!-- Scroll to Bottom Icon (positioned within scroll container for proper centering) -->\n @if (showScrollToBottomIcon && DisplayMessages.length > 0) {\n <span class=\"scroll-to-bottom-icon\" style=\"left: 50%;\"\n (click)=\"scrollToBottomAnimate()\">\n <i class=\"fas fa-arrow-down\"></i>\n </span>\n }\n </div>\n\n <!-- Fixed Input Area -->\n <div class=\"chat-input-container\">\n @if (isLoadingPeripheralData) {\n <!-- Loading State -->\n <div class=\"loading-peripheral-placeholder\">\n <mj-loading text=\"Loading conversation data...\" size=\"medium\"></mj-loading>\n </div>\n } @else if (ReadOnly) {\n <div class=\"read-only-banner\" role=\"status\">\n <i class=\"fas fa-eye\"></i>\n <span>{{ ReadOnlyMessage || 'You have view-only access to this conversation.' }}</span>\n </div>\n } @else {\n @if (isReadOnlyView) {\n <div class=\"read-only-banner\" role=\"status\">\n <i class=\"fas fa-eye\"></i>\n <span>You have view-only access to this conversation.</span>\n </div>\n }\n <!-- composerExtra slot \u2014 host UI directly above the composer (IMJChatComposerExtraContext). -->\n @if (slotTemplate('composerExtra'); as t) {\n <div class=\"chat-composer-extra\">\n <ng-container *ngTemplateOutlet=\"t; context: {\n $implicit: conversation,\n ConversationId: conversationId,\n IsProcessing: isProcessing\n }\"></ng-container>\n </div>\n }\n <!-- Input Component - Multiple instances cached, only one visible -->\n <div class=\"message-input-container-wrapper\">\n @for (inputRef of getCachedInputs(); track inputRef.conversationId) {\n <mj-message-input\n #messageInput\n [hidden]=\"inputRef.conversationId !== conversationId\"\n [initialDraft]=\"GetInitialDraftFor(inputRef.conversationId)\"\n (DraftStateChanged)=\"OnDraftStateChanged(inputRef.conversationId, $event)\"\n (ComposerBlurred)=\"OnComposerBlurred()\"\n [conversationId]=\"inputRef.conversationId\"\n [conversationName]=\"inputRef.conversationName\"\n [currentUser]=\"currentUser\"\n [conversationHistory]=\"inputRef.conversationId === conversationId ? messages : []\"\n [artifactsByDetailId]=\"inputRef.conversationId === conversationId ? artifactsByDetailId : emptyArtifactsMap\"\n [systemArtifactsByDetailId]=\"inputRef.conversationId === conversationId ? systemArtifactsByDetailId : emptyArtifactsMap\"\n [agentRunsByDetailId]=\"inputRef.conversationId === conversationId ? agentRunsByDetailId : emptyAgentRunsMap\"\n [appContext]=\"appContext\"\n [applicationId]=\"applicationId\"\n [defaultAgentId]=\"defaultAgentId\"\n [conversationDefaultAgentId]=\"inputRef.conversationId === conversationId ? (conversation?.DefaultAgentID ?? null) : null\"\n [agentConfigurationPresetId]=\"inputRef.conversationId === conversationId ? ActiveAgentConfigurationPresetId : null\"\n [AgentReplyMode]=\"AgentReplyMode\"\n [AllowedAgentIDs]=\"AllowedAgentIDs\"\n [MentionPeople]=\"MentionPeople\"\n [AgentHistoryFrom]=\"AgentHistoryFrom\"\n [TargetBranchID]=\"TargetBranchIdFor(inputRef.conversationId)\"\n [ResolveTargetBranch]=\"inputRef.conversationId === conversationId ? ResolveComposerBranch : null\"\n [AgentTurnHandler]=\"AgentTurnHandler\"\n [AutoNameConversation]=\"AutoNameConversation\"\n [EnableDecisionRouting]=\"EnableDecisionRouting\"\n [inProgressMessageIds]=\"inputRef.conversationId === conversationId ? inProgressMessageIds : emptyInProgressIds\"\n [disabled]=\"isProcessing || isReadOnlyView\"\n [ReadOnly]=\"EffectiveReadOnly\"\n [enableAttachments]=\"enableAttachments && allowAttachments\"\n [enableMentions]=\"allowMentions\"\n [enableAgentMentions]=\"allowAgentMentions\"\n [enableEntityMentions]=\"allowEntityMentions\"\n [enableSkillCommands]=\"allowSkillCommands\"\n [enablePlanMode]=\"allowPlanMode\"\n [enableRealtime]=\"allowRealtime && OpenView.Kind !== 'DraftFork'\"\n [Placeholder]=\"ComposerPlaceholderFor(inputRef.conversationId)\"\n [SendSlotMode]=\"inputRef.conversationId === conversationId ? SendSlotMode : 'send'\"\n [StopCount]=\"inputRef.conversationId === conversationId ? StopCount : 0\"\n [StopLabel]=\"StopLabel\"\n [StatusText]=\"inputRef.conversationId === conversationId ? StatusText : null\"\n [StatusElapsed]=\"inputRef.conversationId === conversationId ? StatusElapsed : null\"\n (StopClicked)=\"OnComposerStopClicked()\"\n [maxAttachments]=\"maxAttachments\"\n [maxAttachmentSizeBytes]=\"maxAttachmentSizeBytes\"\n [acceptedFileTypes]=\"acceptedFileTypes\"\n [initialMessage]=\"shouldDeliverPendingMessageTo(inputRef.conversationId) ? pendingMessage : null\"\n [initialAttachments]=\"shouldDeliverPendingMessageTo(inputRef.conversationId) ? pendingAttachments : null\"\n (initialMessageAutoSendStarted)=\"onInitialMessageAutoSendStarted($event)\"\n (initialMessageAutoSendFailed)=\"onInitialMessageAutoSendFailed($event)\"\n (messageSent)=\"onMessageSent($event)\"\n (MessageStreamed)=\"OnMessageStreamed($event)\"\n (agentResponse)=\"onAgentResponse($event)\"\n (agentRunDetected)=\"onAgentRunDetected($event)\"\n (agentRunUpdate)=\"onAgentRunUpdate($event)\"\n (messageComplete)=\"onMessageComplete($event)\"\n (artifactCreated)=\"onArtifactCreated($event)\"\n (conversationRenamed)=\"onConversationRenamed($event)\"\n (intentCheckStarted)=\"onIntentCheckStarted($event)\"\n (intentCheckCompleted)=\"onIntentCheckCompleted($event)\"\n (beforeAgentTurn)=\"beforeAgentTurn.emit($event)\"\n (afterAgentTurn)=\"afterAgentTurn.emit($event)\"\n (uploadStateChanged)=\"onUploadStateChanged($event)\">\n </mj-message-input>\n }\n </div>\n @if (ComposerHint) {\n <div class=\"fork-composer-hint\">{{ ComposerHint }}</div>\n }\n }\n </div>\n </div>\n }\n </div>\n\n <!-- Artifact Viewer Pane -->\n @if (showArtifactPanel && selectedArtifactId) {\n @if (!isArtifactPaneMaximized) {\n <div class=\"resize-handle\" (mousedown)=\"onResizeStart($event)\" (touchstart)=\"onResizeTouchStart($event)\"></div>\n }\n <div class=\"chat-artifact-pane\"\n [style.width.%]=\"artifactPaneWidth\"\n [class.maximized]=\"isArtifactPaneMaximized\">\n <mj-artifact-viewer-panel\n [artifactId]=\"selectedArtifactId\"\n [currentUser]=\"currentUser\"\n [environmentId]=\"environmentId\"\n [versionNumber]=\"selectedVersionNumber\"\n [viewContext]=\"'conversation'\"\n [Scope]=\"ArtifactViewerScope\"\n [canShare]=\"canShareSelectedArtifact\"\n [canEdit]=\"canEditSelectedArtifact\"\n [isMaximized]=\"isArtifactPaneMaximized\"\n [refreshTrigger]=\"artifactViewerRefresh$\"\n (closed)=\"onCloseArtifactPanel()\"\n (saveToCollectionRequested)=\"onSaveToCollectionRequested($event)\"\n (navigateToLink)=\"onArtifactLinkNavigation($event)\"\n (shareRequested)=\"onArtifactShareRequested($event)\"\n (maximizeToggled)=\"toggleMaximizeArtifactPane()\"\n (openEntityRecord)=\"onOpenEntityRecord($event)\"\n (navigationRequest)=\"onNavigationRequest($event)\"\n (analyzeRequested)=\"OnAnalyzeArtifact($event)\"\n (applyFormRequested)=\"OnApplyFormRequested($event)\">\n </mj-artifact-viewer-panel>\n </div>\n }\n\n <!-- Task Graph Run Viewer Pane -->\n @if (SelectedTaskGraphPanel) {\n @if (!isArtifactPaneMaximized) {\n <div class=\"resize-handle\" (mousedown)=\"onResizeStart($event)\" (touchstart)=\"onResizeTouchStart($event)\"></div>\n }\n <div class=\"chat-artifact-pane chat-task-graph-pane\"\n [style.width.%]=\"artifactPaneWidth\"\n [class.maximized]=\"isArtifactPaneMaximized\">\n <div class=\"task-graph-pane-header\">\n <div class=\"task-graph-pane-title-group\">\n <span class=\"task-graph-pane-icon\">\n <i class=\"fa-solid fa-diagram-project\"></i>\n </span>\n <div class=\"task-graph-pane-titles\">\n <span class=\"task-graph-pane-title\">{{ SelectedTaskGraphPanel.workflowTitle }}</span>\n <span class=\"task-graph-pane-subtitle\">Interactive Task Graph &amp; Step Inspector</span>\n </div>\n </div>\n <div class=\"task-graph-pane-actions\">\n <button\n type=\"button\"\n class=\"task-graph-pane-save-btn\"\n [disabled]=\"IsSavingTaskGraphWorkflow || !taskGraphRunView.Spec?.tasks?.length\"\n (click)=\"OnSaveTaskGraphAsWorkflow(taskGraphRunView.Spec)\"\n title=\"Save this task graph as a reusable Draft Flow Agent workflow\">\n <i class=\"fa-solid\" [class.fa-spinner]=\"IsSavingTaskGraphWorkflow\" [class.fa-spin]=\"IsSavingTaskGraphWorkflow\" [class.fa-floppy-disk]=\"!IsSavingTaskGraphWorkflow\"></i>\n <span>{{ IsSavingTaskGraphWorkflow ? 'Saving\u2026' : 'Save as Workflow' }}</span>\n </button>\n <button\n type=\"button\"\n class=\"task-graph-pane-btn\"\n (click)=\"toggleMaximizeArtifactPane()\"\n [title]=\"isArtifactPaneMaximized ? 'Restore panel size' : 'Maximize panel'\">\n <i class=\"fa-solid\" [class.fa-compress]=\"isArtifactPaneMaximized\" [class.fa-expand]=\"!isArtifactPaneMaximized\"></i>\n </button>\n <button\n type=\"button\"\n class=\"task-graph-pane-btn\"\n (click)=\"OnCloseTaskGraphPanel()\"\n title=\"Close Task Graph panel\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n </div>\n <div class=\"task-graph-pane-body\">\n <mj-task-graph-run-view\n #taskGraphRunView\n [ParentTaskID]=\"SelectedTaskGraphPanel.parentTaskId\"\n [WorkflowName]=\"SelectedTaskGraphPanel.workflowTitle\"\n [LiveUpdates]=\"true\"\n [ShowVariables]=\"true\"\n [Height]=\"'100%'\">\n </mj-task-graph-run-view>\n </div>\n </div>\n }\n\n <!-- Artifact Share Modal -->\n <mj-artifact-share-modal\n [isOpen]=\"isArtifactShareModalOpen\"\n [artifact]=\"artifactToShare\"\n [currentUser]=\"currentUser\"\n (saved)=\"onArtifactShared()\"\n (cancelled)=\"onArtifactShareModalClose()\">\n </mj-artifact-share-modal>\n\n <!-- Pinned Messages Panel (overlay) -->\n @if (allowPinning && showPinsPanel) {\n <mj-pinned-messages-panel\n [pinnedMessages]=\"pinnedMessages\"\n [isLoading]=\"isLoadingPins\"\n [AllowUnpin]=\"!EffectiveReadOnly\"\n (closed)=\"showPinsPanel = false\"\n (jumpRequested)=\"onJumpToMessage($event)\"\n (unpinRequested)=\"onUnpinFromPanel($event)\">\n </mj-pinned-messages-panel>\n }\n\n @if (ShowForksPopover) {\n <mj-conversation-forks-popover\n [PanelID]=\"ForksPopoverID\"\n [Summaries]=\"ForkSummaries\"\n [CurrentUserID]=\"CurrentUser.ID\"\n (ForkSelected)=\"OnForkSelectedFromList($event)\"\n (Closed)=\"CloseForksPopover()\">\n </mj-conversation-forks-popover>\n }\n </div>\n\n <!-- Live voice \"call mode\" overlay \u2014 fills this conversation panel in place\n (header + thread + composer) while a realtime session is active. When the\n call is MINIMIZED (e.g. a dev link navigated to a record) the overlay HIDES\n (not destroyed \u2014 its merged session state must survive), the session stays\n fully live, and a floating \"on call\" pill offers the way back.\n ALSO hosted in SESSION REVIEW mode (RealtimeReview set, no live call): the\n overlay renders what went down in a PAST session, with a \"Start live session\"\n button that resumes it as a new call. -->\n @if ((RealtimeSession.Active$ | async) || RealtimeReview) {\n <mj-realtime-session-overlay\n [AgentName]=\"realtimeOverlayAgentName\"\n [Hidden]=\"(RealtimeSession.Minimized$ | async) === true\"\n [CurrentUser]=\"currentUser\"\n [EnvironmentID]=\"environmentId\"\n [ReviewData]=\"RealtimeReview\"\n [AllowStartLive]=\"CanStartVoiceFromReview\"\n [Chrome]=\"overlayMode ? 'orb' : 'auto'\"\n [Compact]=\"overlayMode\"\n [ShowDevLinks]=\"!overlayMode\"\n [ShowDensityPicker]=\"!overlayMode\"\n (NavigateRequest)=\"onRealtimeNavigateRequest($event)\"\n (StartLiveRequested)=\"onReviewStartLive($event)\"\n (ReviewClosed)=\"onReviewClosed()\">\n </mj-realtime-session-overlay>\n @if (RealtimeSession.Minimized$ | async) {\n <button type=\"button\" class=\"voice-call-pill\" (click)=\"RealtimeSession.SetMinimized(false)\"\n title=\"Return to the live call\" aria-label=\"Return to the live call\">\n <span class=\"voice-call-pill__pulse\" aria-hidden=\"true\"></span>\n <i class=\"fa-solid fa-phone-volume\" aria-hidden=\"true\"></i>\n <span class=\"voice-call-pill__text\">\n <span class=\"voice-call-pill__name\">On call \u00B7 {{ RealtimeSession.CurrentAgentName }}</span>\n <span class=\"voice-call-pill__hint\">Tap to return</span>\n </span>\n </button>\n }\n }\n</div>\n\n<!-- Export Modal -->\n<!-- [branding] is bound BEFORE [isVisible] deliberately: Angular sets inputs in\n template order within a change-detection pass, and the modal's isVisible setter\n reads `branding` to default its \"Include branding\" checkbox on a fresh open. -->\n<mj-export-modal\n [branding]=\"exportBranding\"\n [isVisible]=\"showExportModal\"\n [conversation]=\"conversation || undefined\"\n [Scope]=\"ExportScope\"\n [currentUser]=\"currentUser\"\n (cancelled)=\"onExportModalCancelled()\"\n (exported)=\"onExportModalComplete()\">\n</mj-export-modal>\n\n<!-- Share Dialog (generic, shared with dashboards) -->\n<mj-resource-share-dialog\n [Visible]=\"showShareModal\"\n [Context]=\"shareContext\"\n [Adapter]=\"shareAdapter\"\n (Result)=\"onShareDialogResult($event)\">\n</mj-resource-share-dialog>\n\n<!-- Members Modal -->\n<mj-members-modal\n [isVisible]=\"showMembersModal\"\n [conversation]=\"conversation || undefined\"\n [currentUser]=\"currentUser\"\n (cancelled)=\"showMembersModal = false\"\n (membersChanged)=\"showMembersModal = false\">\n</mj-members-modal>\n\n<!-- Project Selector Modal -->\n@if (showProjectSelector && conversation) {\n <div class=\"modal-overlay\" (click)=\"showProjectSelector = false\">\n <div class=\"modal-content project-selector-modal\" (click)=\"$event.stopPropagation()\">\n <div class=\"modal-header\">\n <h3>Assign Project</h3>\n <button class=\"modal-close-btn\" (click)=\"showProjectSelector = false\">\n <i class=\"fas fa-times\"></i>\n </button>\n </div>\n <div class=\"modal-body\">\n <mj-project-selector\n [environmentId]=\"environmentId\"\n [currentUser]=\"currentUser\"\n [selectedProjectId]=\"conversation.ProjectID\"\n (projectSelected)=\"onProjectSelected($event)\">\n </mj-project-selector>\n </div>\n </div>\n </div>\n}\n\n<!-- Artifacts Modal -->\n@if (showArtifactsModal) {\n <div class=\"modal-overlay\" (click)=\"showArtifactsModal = false\">\n <div class=\"modal-content artifacts-modal\" (click)=\"$event.stopPropagation()\">\n <div class=\"modal-header\">\n <h3>Conversation Artifacts</h3>\n <div class=\"modal-header-actions\">\n @if (hasSystemArtifacts) {\n <button class=\"toggle-system-btn\"\n [class.active]=\"showSystemArtifacts\"\n (click)=\"toggleSystemArtifacts()\"\n title=\"Toggle system artifacts visibility\">\n <i class=\"fas fa-cog\"></i>\n <span>{{ showSystemArtifacts ? 'Hide' : 'Show' }} System</span>\n </button>\n }\n <button class=\"modal-close-btn\" (click)=\"showArtifactsModal = false\">\n <i class=\"fas fa-times\"></i>\n </button>\n </div>\n </div>\n <div class=\"modal-body artifacts-grid\">\n @if (artifactsByDetailId.size === 0) {\n <mj-empty-state\n class=\"artifacts-empty-fill\"\n Icon=\"fa-solid fa-cube\"\n Title=\"No artifacts in this conversation yet\" />\n }\n @for (artifact of getArtifactsArray(); track artifact.artifactId) {\n <div class=\"artifact-modal-card\"\n [class.expanded]=\"expandedArtifactId === artifact.artifactId\"\n [class.system-artifact]=\"artifact.visibility === 'System Only'\">\n <!-- Main card header - click to open latest version -->\n <div class=\"artifact-card-header\" (click)=\"openArtifactFromModal(artifact.artifactId)\">\n <div class=\"artifact-modal-icon\">\n <i class=\"fas fa-file-code\"></i>\n </div>\n <div class=\"artifact-modal-info\">\n <div class=\"artifact-modal-title\">{{artifact.name}}</div>\n <div class=\"artifact-modal-meta\">\n @if (artifact.versionCount > 1) {\n {{artifact.versionCount}} versions\n } @else {\n 1 version\n }\n </div>\n </div>\n @if (artifact.versionCount > 1) {\n <button class=\"expand-btn\" (click)=\"toggleArtifactExpansion(artifact.artifactId, $event)\">\n <i class=\"fas\" [class.fa-chevron-down]=\"expandedArtifactId !== artifact.artifactId\"\n [class.fa-chevron-up]=\"expandedArtifactId === artifact.artifactId\"></i>\n </button>\n }\n <div class=\"artifact-modal-action\">\n <i class=\"fas fa-external-link-alt\"></i>\n </div>\n </div>\n\n <!-- Expanded version list -->\n @if (expandedArtifactId === artifact.artifactId && artifact.versionCount > 1) {\n <div class=\"artifact-versions-list\">\n @for (version of artifact.versions; track version.versionId) {\n <div class=\"artifact-version-item\" (click)=\"openArtifactFromModal(artifact.artifactId, version.versionNumber); $event.stopPropagation()\">\n <span class=\"version-badge\">v{{version.versionNumber}}</span>\n <span class=\"version-open-text\">Open this version</span>\n <i class=\"fas fa-arrow-right\"></i>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n </div>\n </div>\n}\n\n<!-- Collection Picker Modal -->\n@if (showCollectionPicker) {\n <mj-artifact-collection-picker-modal\n [isOpen]=\"showCollectionPicker\"\n [environmentId]=\"environmentId\"\n [currentUser]=\"currentUser\"\n [excludeCollectionIds]=\"collectionPickerExcludedIds\"\n [artifactVersionId]=\"collectionPickerVersionId\"\n [artifactName]=\"collectionPickerArtifactName\"\n [artifactVersionNumber]=\"collectionPickerVersionNumber\"\n (completed)=\"onCollectionPickerCompleted($event)\"\n (cancelled)=\"onCollectionPickerCancelled()\">\n </mj-artifact-collection-picker-modal>\n}\n\n<!-- Test Feedback Dialog -->\n@if (testFeedbackDialogData) {\n <mj-test-feedback-dialog\n [data]=\"testFeedbackDialogData\"\n [visible]=\"showTestFeedbackDialog\"\n (closed)=\"onTestFeedbackDialogClosed($event)\">\n </mj-test-feedback-dialog>\n}\n\n<!-- Image Viewer Modal -->\n@if (showImageViewer) {\n <mj-image-viewer\n [imageUrl]=\"selectedImageUrl\"\n [alt]=\"selectedImageAlt\"\n [fileName]=\"selectedImageFileName\"\n [visible]=\"showImageViewer\"\n (closed)=\"onImageViewerClosed()\">\n </mj-image-viewer>\n}\n", styles: [":host {\n display: flex;\n width: 100%;\n height: 100%;\n}\n\n.chat-area {\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n overflow: hidden;\n /* Positioned context for the in-place realtime \"call mode\" overlay (absolute inset:0) */\n position: relative;\n}\n\n.chat-header {\n flex-shrink: 0;\n padding: 12px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n display: flex;\n justify-content: space-between;\n align-items: center;\n gap: 16px;\n background: var(--mj-bg-surface-card);\n z-index: 10;\n box-shadow: var(--mj-shadow-sm);\n}\n\n/* agentPresence slot \u2014 sticky top, anchored with the header. Per Matt's\n 06-10 placement design: persistent presence indicator above the messages.\n Renders only when [showAgentCharacter] is true, so existing embeds see no\n layout change. The prominent variant grows toward a centered presence\n (per Matt: \"can grow larger toward a centered presence\"). */\n.chat-agent-presence {\n flex-shrink: 0;\n padding: 8px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-card);\n display: flex;\n align-items: center;\n z-index: 11;\n}\n\n.chat-agent-presence--prominent {\n padding: 16px 20px;\n justify-content: center;\n}\n\n.chat-info {\n display: flex;\n align-items: center;\n gap: 12px;\n flex: 1;\n min-width: 0;\n}\n\n/* Sidebar toggle button in header */\n.sidebar-toggle-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n background: transparent;\n border: none;\n border-radius: 6px;\n cursor: pointer;\n transition: all 0.15s ease;\n flex-shrink: 0;\n}\n\n.sidebar-toggle-btn:hover {\n background: color-mix(in srgb, var(--mj-text-primary) 8%, transparent);\n}\n\n.sidebar-toggle-btn:active {\n background: color-mix(in srgb, var(--mj-text-primary) 12%, transparent);\n}\n\n.sidebar-toggle-btn i {\n color: var(--mj-text-secondary);\n font-size: 18px;\n transition: color 0.15s ease;\n}\n\n.sidebar-toggle-btn:hover i {\n color: var(--mj-text-primary);\n}\n\n/* Header title: the conversation name in Main; in a fork, the path ending in the open fork */\n.chat-title-bar {\n display: flex;\n align-items: center;\n gap: var(--mj-space-1);\n flex: 0 1 auto;\n min-width: 0;\n}\n\n.chat-title {\n flex: 0 1 auto;\n min-width: 0;\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.chat-title-path {\n min-width: 0;\n}\n\n.chat-title-crumbs {\n display: flex;\n align-items: center;\n gap: var(--mj-space-1);\n min-width: 0;\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n/* Parent crumbs shrink first, down to 80px each; the current entry keeps 120px before it truncates */\n.chat-title-crumb {\n display: flex;\n flex: 0 100 auto;\n align-items: center;\n gap: var(--mj-space-1);\n min-width: 80px;\n}\n\n.chat-title-crumb.chat-title-ellipsis {\n flex: 0 0 auto;\n min-width: 0;\n}\n\n.chat-title-crumb > button {\n min-width: 0;\n color: var(--mj-text-muted);\n font-size: var(--mj-text-sm);\n font-weight: 500;\n}\n\n.chat-title-crumb-label {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n/* Past three entries the crumbs between the first and the parent collapse into the ellipsis */\n.chat-title-crumb.collapsed-wide,\n.chat-title-ellipsis:not(.collapses-wide) {\n display: none;\n}\n\n.chat-title-sep {\n flex-shrink: 0;\n font-size: 12px;\n color: var(--mj-border-strong);\n}\n\n.chat-title-current {\n display: flex;\n flex: 0 1 auto;\n align-items: center;\n gap: var(--mj-space-1);\n min-width: 120px;\n}\n\n.chat-title-kind {\n flex-shrink: 0;\n margin: 0 var(--mj-space-1);\n color: var(--mj-status-info);\n}\n\n.chat-title-kind[data-kind='Edit'] {\n color: var(--mj-status-warning);\n}\n\n.chat-title-kind[data-kind='Regenerate'] {\n color: var(--mj-brand-tertiary);\n}\n\n.chat-title-bar .chat-title-rename {\n flex-shrink: 0;\n color: var(--mj-text-muted);\n opacity: 0.6;\n transition: opacity 0.15s ease, color 0.15s ease;\n}\n\n.chat-title-bar:hover .chat-title-rename,\n.chat-title-bar .chat-title-rename:focus-visible {\n color: var(--mj-text-primary);\n opacity: 1;\n}\n\n.chat-title-input {\n flex: 0 1 360px;\n min-width: 120px;\n padding: var(--mj-space-1) var(--mj-space-2);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font: inherit;\n font-size: 16px;\n font-weight: 600;\n}\n\n.chat-title-input:focus-visible {\n outline: none;\n border-color: var(--mj-brand-primary);\n box-shadow: var(--mj-focus-ring);\n}\n\n.shared-by-badge {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 3px 10px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n color: var(--mj-brand-primary);\n border-radius: 999px;\n font-size: 12px;\n font-weight: 500;\n flex-shrink: 0;\n max-width: 240px;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.shared-by-badge i {\n font-size: 10px;\n}\n\n.shared-by-badge span {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.project-tag {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n border-radius: 16px;\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-text-muted);\n cursor: pointer;\n transition: all 0.2s;\n height: 28px;\n margin-left: 12px;\n}\n\n.project-tag:hover {\n background: var(--mj-border-default);\n border-color: var(--mj-text-muted);\n}\n\n.project-tag i {\n font-size: 10px;\n}\n\n.test-indicator {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n background: color-mix(in srgb, var(--mj-status-warning) 10%, var(--mj-bg-surface));\n border: 1px solid var(--mj-status-warning);\n border-radius: 16px;\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-status-warning);\n cursor: pointer;\n transition: all 0.2s;\n height: 28px;\n margin-left: 8px;\n}\n\n.test-indicator:hover {\n background: color-mix(in srgb, var(--mj-status-warning) 20%, var(--mj-bg-surface));\n border-color: var(--mj-status-warning);\n}\n\n.test-indicator i {\n font-size: 10px;\n}\n\n/* Pinned messages chip in chat header */\n.pin-chip {\n display: flex;\n align-items: center;\n gap: 5px;\n padding: 5px 10px;\n background: color-mix(in srgb, var(--mj-status-warning) 12%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-status-warning) 45%, transparent);\n border-radius: 20px;\n color: var(--mj-status-warning-text, var(--mj-status-warning));\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s;\n}\n\n.pin-chip i {\n font-size: 11px;\n}\n\n.pin-chip:hover,\n.pin-chip.active {\n background: color-mix(in srgb, var(--mj-status-warning) 20%, var(--mj-bg-surface));\n border-color: var(--mj-status-warning);\n}\n\n.pin-chip-count {\n font-size: 12px;\n font-weight: 700;\n}\n\n.chat-members,\n.artifact-indicator {\n display: flex;\n align-items: center;\n justify-content: center;\n position: relative;\n padding: 6px 8px;\n background: transparent;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n font-size: 14px;\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: all 150ms ease;\n}\n\n.chat-members:hover,\n.artifact-indicator:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n}\n\n/* Badge overlay for artifact and member counts */\n.artifact-badge,\n.members-badge {\n position: absolute;\n top: -6px;\n right: -6px;\n min-width: 16px;\n height: 16px;\n padding: 0 4px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n font-size: 10px;\n font-weight: 600;\n border-radius: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n line-height: 1;\n}\n\n.members-badge {\n background: var(--mj-brand-primary);\n}\n\n.ambient-agent-indicator {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n font-size: 13px;\n color: var(--mj-text-secondary);\n animation: pulse 2s ease-in-out infinite;\n}\n\n.ambient-agent-indicator i {\n color: var(--mj-brand-primary);\n}\n\n@keyframes pulse {\n 0%, 100% {\n opacity: 1;\n }\n 50% {\n opacity: 0.7;\n }\n}\n.chat-actions {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.action-btn {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 12px;\n background: transparent;\n border: 1px solid var(--mj-border-default);\n cursor: pointer;\n border-radius: 6px;\n font-size: 13px;\n color: var(--mj-text-secondary);\n transition: all 150ms ease;\n}\n\n.action-btn:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n}\n\n.share-btn.shared {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-color: var(--mj-brand-primary-hover);\n color: var(--mj-brand-primary-hover);\n}\n\n.share-btn.shared:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary-hover);\n}\n\n.chat-content-area {\n flex: 1;\n min-height: 0;\n overflow: hidden;\n display: flex;\n flex-direction: row;\n position: relative;\n}\n\n.chat-messages-pane {\n height: 100%;\n display: flex;\n flex-direction: column;\n min-width: min(300px, 100%); /* Respect container bounds while maintaining minimum */\n overflow: hidden;\n transition: width 0.3s ease;\n}\n\n.chat-messages-pane.full-width {\n width: 100%;\n}\n\n.chat-messages-pane:not(.full-width) {\n flex: 1;\n}\n\n.chat-messages-pane.hidden {\n display: none;\n}\n\n.resize-handle {\n width: 4px;\n background: transparent;\n cursor: col-resize;\n flex-shrink: 0;\n position: relative;\n transition: background-color 0.2s;\n}\n\n.resize-handle:hover {\n background: var(--mj-brand-primary);\n}\n\n.resize-handle::before {\n content: \"\";\n position: absolute;\n left: -4px;\n right: -4px;\n top: 0;\n bottom: 0;\n}\n\n.chat-artifact-pane {\n height: 100%;\n display: flex;\n flex-direction: column;\n background: var(--mj-bg-surface-sunken);\n overflow: hidden;\n flex-shrink: 0;\n}\n\n.chat-artifact-pane.maximized {\n width: 100% !important;\n}\n\n.chat-artifact-pane > mj-artifact-viewer-panel {\n display: flex;\n flex: 1;\n min-height: 0;\n overflow: hidden;\n}\n\n.chat-task-graph-pane {\n background: var(--mj-bg-surface);\n border-left: 1px solid var(--mj-border-default);\n}\n\n.task-graph-pane-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n padding: 12px 16px;\n background: var(--mj-bg-surface-card);\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n\n.task-graph-pane-title-group {\n display: flex;\n align-items: center;\n gap: 10px;\n min-width: 0;\n}\n\n.task-graph-pane-icon {\n width: 32px;\n height: 32px;\n border-radius: 8px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, transparent);\n color: var(--mj-brand-primary);\n font-size: 14px;\n flex-shrink: 0;\n}\n\n.task-graph-pane-titles {\n display: flex;\n flex-direction: column;\n gap: 1px;\n min-width: 0;\n}\n\n.task-graph-pane-title {\n font-size: 13.5px;\n font-weight: 600;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.task-graph-pane-subtitle {\n font-size: 11px;\n color: var(--mj-text-muted);\n}\n\n.task-graph-pane-actions {\n display: flex;\n align-items: center;\n gap: 6px;\n flex-shrink: 0;\n}\n\n.task-graph-pane-save-btn {\n height: 30px;\n padding: 0 10px;\n border-radius: 6px;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n font-weight: 500;\n border: 1px solid var(--mj-brand-primary);\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse, #ffffff);\n cursor: pointer;\n transition: opacity 0.15s ease, filter 0.15s ease;\n}\n\n.task-graph-pane-save-btn:hover:not(:disabled) {\n filter: brightness(1.06);\n}\n\n.task-graph-pane-save-btn:disabled {\n opacity: 0.55;\n cursor: not-allowed;\n}\n\n.task-graph-pane-btn {\n width: 30px;\n height: 30px;\n border-radius: 6px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border: 1px solid var(--mj-border-subtle);\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease;\n}\n\n.task-graph-pane-btn:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n border-color: var(--mj-border-default);\n}\n\n.task-graph-pane-body {\n flex: 1;\n width: 100%;\n min-height: 0;\n min-width: 0;\n padding: 12px 16px 16px;\n box-sizing: border-box;\n overflow: hidden;\n display: flex;\n flex-direction: column;\n}\n\n.task-graph-pane-body > mj-task-graph-run-view {\n display: flex;\n flex-direction: column;\n flex: 1;\n width: 100%;\n min-height: 0;\n min-width: 0;\n overflow: hidden;\n}\n\n.chat-messages-wrapper {\n flex: 1;\n display: flex;\n flex-direction: column;\n min-height: 0;\n overflow: hidden;\n position: relative; /* For upload overlay positioning */\n}\n\n/* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n demonstrationSurface layout-mode (Matt's 06-10 placement design)\n \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n When .chat-content-area gets .demonstration-mode, the layout flips\n from \"messages pane (+ optional artifact pane)\" to \"stage + side rail\":\n - stage (.chat-demonstration-stage) \u2014 left, flexible, holds the\n consumer's projected demonstrationSurface slot template\n - rail (.chat-messages-pane) \u2014 right, fixed-width 320px, holds the\n messages list + composer (\"the conversation as a companion rail\")\n On mobile (\u2264768px) the same two stack vertically (stage above, rail\n below) per Matt's note about mobile. The rail intentionally keeps the\n composer inside it \u2014 Matt's design refers to the conversation rail\n inclusively (messages + composer together), not as separate regions.\n*/\n.chat-demonstration-stage {\n height: 100%;\n display: flex;\n flex-direction: column;\n overflow: auto;\n background: var(--mj-bg-surface);\n border-right: 1px solid var(--mj-border-default);\n flex: 1;\n min-width: 0;\n}\n\n.chat-content-area.demonstration-mode .chat-messages-pane,\n.chat-content-area.demonstration-mode .chat-messages-pane.full-width {\n flex: 0 0 320px;\n width: 320px;\n min-width: 0;\n}\n\n@media (max-width: 768px) {\n .chat-content-area.demonstration-mode {\n flex-direction: column;\n }\n\n .chat-content-area.demonstration-mode .chat-demonstration-stage {\n flex: 1 1 60%;\n border-right: none;\n border-bottom: 1px solid var(--mj-border-default);\n height: auto;\n }\n\n .chat-content-area.demonstration-mode .chat-messages-pane,\n .chat-content-area.demonstration-mode .chat-messages-pane.full-width {\n flex: 1 1 40%;\n width: 100%;\n height: auto;\n }\n}\n\n/* Upload indicator overlay - centered in conversation area */\n.upload-indicator-overlay {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 1rem 1.5rem;\n background: color-mix(in srgb, var(--mj-bg-surface-card) 95%, transparent);\n border-radius: 12px;\n box-shadow: var(--mj-shadow-md);\n z-index: 100;\n pointer-events: none;\n}\n\n.chat-messages-container {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n background: var(--mj-bg-surface-card);\n min-height: 0;\n position: relative;\n}\n\n.scroll-to-bottom-icon {\n position: sticky;\n bottom: 21px;\n left: 50%;\n transform: translateX(-50%);\n width: 40px;\n height: 40px;\n margin-top: -40px;\n margin-left: auto;\n margin-right: auto;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n box-shadow: var(--mj-shadow-md);\n transition: all 0.2s ease;\n z-index: 100;\n pointer-events: auto;\n}\n\n.scroll-to-bottom-icon:hover {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-brand-primary);\n transform: translateX(-50%) translateY(-2px);\n box-shadow: color-mix(in srgb, var(--mj-brand-primary) 20%, transparent) 0 4px 12px;\n}\n\n.scroll-to-bottom-icon i {\n color: var(--mj-text-secondary);\n font-size: 16px;\n transition: color 0.2s;\n}\n\n.scroll-to-bottom-icon:hover i {\n color: var(--mj-brand-primary);\n}\n\n.chat-input-container {\n flex-shrink: 0;\n background: var(--mj-bg-surface-card);\n padding: 0 1.25rem 1.25rem 1.25rem;\n overflow: visible;\n}\n\n/* composerExtra slot: host UI directly above the composer. Spacing only; the host styles its content. */\n.chat-composer-extra {\n margin-bottom: 0.5rem;\n}\n\n.read-only-banner {\n display: flex;\n align-items: center;\n gap: 8px;\n margin: 0 1.25rem 0.5rem 1.25rem;\n padding: 8px 12px;\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, transparent);\n color: var(--mj-text-secondary);\n border-radius: 6px;\n font-size: 12px;\n}\n\n.read-only-banner i {\n color: var(--mj-brand-primary);\n font-size: 12px;\n}\n\n.loading-peripheral-placeholder {\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: 140px;\n padding: 24px;\n background: color-mix(in srgb, var(--mj-bg-surface-card) 50%, transparent);\n backdrop-filter: blur(2px);\n border-radius: 12px;\n margin: 12px;\n animation: fadeIn 0.2s ease-in-out;\n}\n\n.modal-overlay {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: var(--mj-bg-overlay);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n}\n\n.modal-content {\n background: var(--mj-bg-surface-card);\n border-radius: 8px;\n box-shadow: var(--mj-shadow-md);\n max-width: 90vw;\n max-height: 90vh;\n display: flex;\n flex-direction: column;\n}\n\n.project-selector-modal {\n width: 600px;\n height: 500px;\n}\n\n.modal-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.modal-header h3 {\n margin: 0;\n font-size: 18px;\n font-weight: 600;\n}\n\n.modal-header-actions {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.toggle-system-btn {\n display: flex;\n align-items: center;\n gap: 6px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n cursor: pointer;\n color: var(--mj-text-secondary);\n padding: 6px 12px;\n border-radius: 6px;\n font-size: 13px;\n font-weight: 500;\n transition: all 0.2s;\n}\n\n.toggle-system-btn:hover {\n background: var(--mj-border-default);\n border-color: var(--mj-border-default);\n color: var(--mj-text-primary);\n}\n\n.toggle-system-btn.active {\n background: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.toggle-system-btn.active:hover {\n background: var(--mj-brand-primary-hover);\n border-color: var(--mj-brand-primary-hover);\n}\n\n.toggle-system-btn i {\n font-size: 12px;\n}\n\n.modal-close-btn {\n background: none;\n border: none;\n cursor: pointer;\n color: var(--mj-text-secondary);\n padding: 4px 8px;\n border-radius: 4px;\n transition: all 0.2s;\n}\n\n.modal-close-btn:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n}\n\n.modal-body {\n flex: 1;\n overflow: auto;\n padding: 20px;\n}\n\n.artifacts-modal {\n width: 700px;\n max-height: 600px;\n}\n\n.artifacts-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));\n gap: 16px;\n}\n\n/* Empty-state spans the full artifacts grid */\n.artifacts-empty-fill {\n grid-column: 1/-1;\n}\n\n.artifact-modal-card {\n display: flex;\n flex-direction: column;\n background: var(--mj-bg-surface-card);\n border: 1.5px solid var(--mj-border-default);\n border-radius: 12px;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n overflow: hidden;\n}\n\n.artifact-modal-card.expanded {\n border-color: var(--mj-brand-primary);\n}\n\n.artifact-modal-card.system-artifact {\n opacity: 0.85;\n border-color: var(--mj-border-default);\n border-style: dashed;\n position: relative;\n}\n\n.artifact-modal-card.system-artifact::before {\n content: \"SYSTEM\";\n position: absolute;\n top: 8px;\n right: 8px;\n font-size: 9px;\n font-weight: 600;\n color: var(--mj-text-muted);\n background: var(--mj-bg-surface-sunken);\n padding: 2px 6px;\n border-radius: 3px;\n letter-spacing: 0.5px;\n z-index: 10;\n}\n\n.artifact-modal-card.system-artifact:hover {\n border-color: var(--mj-text-muted);\n box-shadow: var(--mj-shadow-md);\n}\n\n.artifact-card-header {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 16px;\n cursor: pointer;\n}\n\n.artifact-card-header:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.artifact-modal-card:hover {\n border-color: var(--mj-brand-primary);\n box-shadow: var(--mj-shadow-md);\n transform: translateY(-2px);\n}\n\n.artifact-modal-icon {\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-radius: 10px;\n color: var(--mj-brand-primary);\n flex-shrink: 0;\n}\n\n.artifact-modal-icon i {\n font-size: 18px;\n}\n\n.artifact-modal-info {\n flex: 1;\n min-width: 0;\n}\n\n.artifact-modal-title {\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin-bottom: 4px;\n}\n\n.artifact-modal-meta {\n font-size: 12px;\n color: var(--mj-text-secondary);\n}\n\n.artifact-modal-action {\n color: var(--mj-text-muted);\n transition: color 0.2s;\n}\n\n.artifact-modal-card:hover .artifact-modal-action {\n color: var(--mj-brand-primary);\n}\n\n.expand-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n border: none;\n background: transparent;\n color: var(--mj-text-secondary);\n cursor: pointer;\n border-radius: 6px;\n transition: all 0.2s;\n}\n.expand-btn:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-brand-primary);\n}\n\n.artifact-versions-list {\n display: flex;\n flex-direction: column;\n padding: 0 1rem 1rem 1rem;\n background: var(--mj-bg-surface-sunken);\n}\n\n.artifact-version-item {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 16px 12px 68px;\n cursor: pointer;\n transition: background 0.15s;\n}\n.artifact-version-item:hover {\n background: var(--mj-bg-surface-sunken);\n}\n.artifact-version-item .version-badge {\n display: inline-block;\n padding: 4px 8px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n font-size: 12px;\n font-weight: 600;\n font-family: monospace;\n border-radius: 4px;\n}\n.artifact-version-item .version-open-text {\n flex: 1;\n font-size: 13px;\n color: var(--mj-text-secondary);\n}\n.artifact-version-item i {\n color: var(--mj-text-muted);\n font-size: 12px;\n}\n.artifact-version-item:hover .version-badge {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n.artifact-version-item:hover .version-open-text {\n color: var(--mj-brand-primary);\n}\n.artifact-version-item:hover i {\n color: var(--mj-brand-primary);\n}\n\n.loading-peripheral-content {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 16px 24px;\n background: var(--mj-bg-surface-card);\n border: 2px solid var(--mj-border-default);\n border-radius: 12px;\n box-shadow: var(--mj-shadow-md);\n color: var(--mj-text-secondary);\n font-size: 14px;\n font-weight: 500;\n}\n.loading-peripheral-content i {\n font-size: 20px;\n color: var(--mj-brand-primary);\n}\n\n@keyframes fadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n.conversation-loading-state {\n display: flex;\n align-items: center;\n justify-content: center;\n height: 100%;\n width: 100%;\n}\n\n.loading-content {\n display: flex;\n flex-direction: column;\n align-items: center;\n padding-top: 20px;\n gap: 16px;\n color: var(--mj-text-secondary);\n font-size: 15px;\n}\n.loading-content i {\n font-size: 32px;\n color: var(--mj-brand-primary);\n}\n.loading-content span {\n font-weight: 500;\n}\n\n/* Mobile adjustments: 481px - 768px */\n@media (max-width: 768px) {\n .chat-header {\n padding: 8px 12px;\n gap: 6px;\n flex-direction: row;\n flex-wrap: wrap;\n align-items: center;\n position: relative;\n }\n .chat-info {\n flex-direction: row;\n align-items: center;\n gap: 8px;\n flex: 1;\n min-width: 0;\n order: 1;\n }\n .chat-title-bar {\n flex: 1;\n }\n .chat-title {\n font-size: 15px;\n font-weight: 700;\n }\n /* The path keeps the first crumb and the current entry; every middle crumb collapses into the ellipsis */\n .chat-title-crumb.path-middle {\n display: none;\n }\n .chat-title-ellipsis:not(.collapses-wide) {\n display: flex;\n }\n .project-tag {\n margin-left: 0;\n font-size: 10px;\n padding: 3px 8px;\n height: 24px;\n display: none; /* Hide on mobile to save space */\n }\n .test-indicator {\n margin-left: 0;\n font-size: 10px;\n padding: 3px 8px;\n height: 24px;\n }\n /* Action buttons - icon only on mobile */\n .chat-actions-buttons {\n order: 2;\n flex-shrink: 0;\n }\n .chat-actions-buttons .action-btn {\n padding: 6px 8px;\n min-width: auto;\n }\n .chat-actions-buttons .action-btn .btn-label {\n display: none;\n }\n .chat-actions {\n flex-wrap: nowrap;\n }\n .chat-members,\n .artifact-indicator {\n padding: 5px 7px;\n font-size: 13px;\n }\n .action-btn {\n padding: 6px 8px;\n font-size: 12px;\n }\n .ambient-agent-indicator {\n font-size: 12px;\n padding: 4px 8px;\n }\n .project-selector-modal {\n width: min(95vw, 600px);\n height: auto;\n }\n .artifacts-modal {\n width: min(95vw, 700px);\n }\n .artifacts-grid {\n grid-template-columns: 1fr;\n }\n .chat-input-container {\n padding: 0 0.75rem 0.75rem 0.75rem;\n }\n .scroll-to-bottom-icon {\n bottom: 16px;\n width: 36px;\n height: 36px;\n }\n /* Artifact pane - full width overlay on mobile, overlapping header */\n .chat-content-area {\n position: relative;\n }\n .chat-artifact-pane {\n position: fixed;\n left: 0;\n right: 0;\n top: 56px; /* 48px nav + 8px dark strip above blue border */\n bottom: 0;\n width: 100% !important;\n z-index: 100;\n background: var(--mj-bg-surface-card);\n }\n .resize-handle {\n display: none;\n }\n}\n/* Small Phone adjustments: <= 480px */\n@media (max-width: 480px) {\n .chat-header {\n padding: 6px 8px;\n gap: 4px;\n }\n .chat-title {\n font-size: 14px;\n font-weight: 700;\n }\n .project-tag {\n font-size: 9px;\n padding: 2px 6px;\n height: 20px;\n display: none;\n }\n .test-indicator {\n font-size: 9px;\n padding: 2px 6px;\n height: 20px;\n }\n .chat-members,\n .artifact-indicator {\n padding: 4px 8px;\n font-size: 11px;\n }\n .action-btn {\n padding: 5px 7px;\n font-size: 11px;\n }\n .ambient-agent-indicator {\n font-size: 11px;\n padding: 3px 6px;\n }\n .project-selector-modal,\n .artifacts-modal {\n width: 100vw;\n height: 100vh;\n border-radius: 0;\n }\n .chat-input-container {\n padding: 0 0.5rem 0.5rem 0.5rem;\n }\n .scroll-to-bottom-icon {\n bottom: 12px;\n width: 32px;\n height: 32px;\n }\n .scroll-to-bottom-icon i {\n font-size: 14px;\n }\n}\n\n/* Artifact Picker Panel */\n.artifact-picker-overlay {\n position: fixed;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background: var(--mj-bg-overlay);\n z-index: 999;\n}\n\n.artifact-picker-panel {\n position: fixed;\n right: 0;\n top: 0;\n width: 360px;\n height: 100%;\n background: var(--mj-bg-surface);\n border-left: 1px solid var(--mj-border-default);\n z-index: 1000;\n display: flex;\n flex-direction: column;\n box-shadow: -4px 0 12px rgba(0, 0, 0, 0.1);\n animation: slideInRight 0.2s ease-out;\n}\n\n@keyframes slideInRight {\n from { transform: translateX(100%); }\n to { transform: translateX(0); }\n}\n\n.artifact-picker-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.artifact-picker-header h3 {\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.artifact-picker-close {\n background: none;\n border: none;\n cursor: pointer;\n padding: 4px 8px;\n color: var(--mj-text-muted);\n border-radius: 4px;\n}\n\n.artifact-picker-close:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n\n.artifact-picker-body {\n flex: 1;\n overflow-y: auto;\n padding: 12px;\n}\n\n.artifact-picker-empty {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 40px 20px;\n text-align: center;\n color: var(--mj-text-muted);\n gap: 8px;\n}\n\n.artifact-picker-hint {\n font-size: 12px;\n color: var(--mj-text-disabled);\n}\n\n.artifact-picker-list {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.artifact-picker-item {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 10px 12px;\n border: 1px solid var(--mj-border-subtle);\n border-radius: 6px;\n background: var(--mj-bg-surface-card);\n cursor: pointer;\n text-align: left;\n width: 100%;\n transition: background 0.15s, border-color 0.15s;\n}\n\n.artifact-picker-item:hover {\n background: var(--mj-bg-surface-hover);\n border-color: var(--mj-brand-primary);\n}\n\n.artifact-picker-item i {\n font-size: 20px;\n width: 24px;\n text-align: center;\n flex-shrink: 0;\n}\n\n.artifact-picker-item i.fa-file-pdf { color: var(--mj-status-error); }\n.artifact-picker-item i.fa-file-excel { color: var(--mj-status-success); }\n.artifact-picker-item i.fa-file-word { color: var(--mj-brand-primary); }\n.artifact-picker-item i.fa-file { color: var(--mj-text-muted); }\n\n.artifact-picker-item-info {\n display: flex;\n flex-direction: column;\n min-width: 0;\n}\n\n.artifact-picker-item-name {\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.artifact-picker-item-meta {\n font-size: 11px;\n color: var(--mj-text-muted);\n}\n\n/* ---------- Floating \"on call\" pill (minimized realtime voice session) ----------\n Shown bottom-right of the chat panel while the live call overlay is minimized\n (e.g. after a gear-gated dev link navigated to a record). The mic + session stay\n live; tapping the pill restores the full call overlay. */\n.voice-call-pill {\n position: absolute;\n right: 18px;\n bottom: 18px;\n z-index: 49; /* just under the full call overlay (z-index 50) */\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 9px 16px 9px 13px;\n border-radius: var(--mj-radius-full, 9999px);\n border: 1px solid var(--mj-border-strong);\n background: var(--mj-bg-surface-elevated, var(--mj-bg-surface));\n color: var(--mj-text-primary);\n font-family: inherit;\n cursor: pointer;\n box-shadow: 0 8px 24px color-mix(in srgb, var(--mj-brand-primary) 18%, transparent);\n transition: border-color 150ms ease, box-shadow 150ms ease, transform 150ms ease;\n}\n.voice-call-pill:hover {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 10px 28px color-mix(in srgb, var(--mj-brand-primary) 28%, transparent);\n transform: translateY(-1px);\n}\n.voice-call-pill i {\n font-size: 14px;\n color: var(--mj-brand-primary);\n}\n.voice-call-pill__pulse {\n width: 9px;\n height: 9px;\n border-radius: 50%;\n background: var(--mj-status-success);\n flex-shrink: 0;\n animation: voice-pill-pulse 1.6s ease-in-out infinite;\n}\n.voice-call-pill__text {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n line-height: 1.25;\n}\n.voice-call-pill__name {\n font-size: 12.5px;\n font-weight: 700;\n}\n.voice-call-pill__hint {\n font-size: 10.5px;\n color: var(--mj-text-muted);\n}\n@keyframes voice-pill-pulse {\n 0%, 100% {\n box-shadow: 0 0 0 0 color-mix(in srgb, var(--mj-status-success) 45%, transparent);\n }\n 50% {\n box-shadow: 0 0 0 5px color-mix(in srgb, var(--mj-status-success) 0%, transparent);\n }\n}\n\n/* The fork title above the transcript, shown only when a host header replaces the default one */\n.fork-view-bar {\n display: flex;\n align-items: center;\n padding: var(--mj-space-2) var(--mj-space-4);\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n}\n.fork-composer-hint {\n padding: var(--mj-space-1) var(--mj-space-4) 0;\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n}\n.chat-actions-buttons > .forks-button .forks-count {\n margin-left: var(--mj-space-1);\n padding: 0 var(--mj-space-2);\n border-radius: var(--mj-radius-full);\n background: var(--mj-brand-primary);\n color: var(--mj-brand-on-primary);\n font-size: var(--mj-text-xs);\n font-weight: 600;\n}\n.chat-actions-buttons > .forks-button.active {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n"] }]
10196
+ args: [{ standalone: false, selector: 'mj-conversation-chat-area', template: "<div class=\"chat-area\">\n <!-- agentPresence slot \u2014 sticky top, anchored with the header. Per Matt's\n 06-10 design: persistent presence indicator (Sid's face + live voice\n state). Off by default; opt in via [showAgentCharacter]. When a\n consumer projects an `mjChatSlot=\"agentPresence\"` template, it\n replaces the default presence component. -->\n @if (showAgentCharacter) {\n <div class=\"chat-agent-presence\" [class.chat-agent-presence--prominent]=\"agentCharacterConfig?.voiceStateMode === 'prominent'\">\n @if (slotTemplate('agentPresence'); as t) {\n <ng-container *ngTemplateOutlet=\"t; context: {\n $implicit: agentCharacterConfig,\n state: agentCharacterConfig?.state ?? 'idle',\n agentName: agentCharacterConfig?.characterName,\n avatarUrl: agentCharacterConfig?.avatarUrl,\n mode: agentCharacterConfig?.voiceStateMode ?? 'subtle'\n }\"></ng-container>\n } @else {\n <mj-chat-agent-presence-default\n [State]=\"agentCharacterConfig?.state ?? 'idle'\"\n [AgentName]=\"agentCharacterConfig?.characterName\"\n [AvatarUrl]=\"agentCharacterConfig?.avatarUrl\"\n [Mode]=\"agentCharacterConfig?.voiceStateMode ?? 'subtle'\">\n </mj-chat-agent-presence-default>\n }\n </div>\n }\n\n <!-- header slot \u2014 replaces the entire chat-header chrome (title, badges,\n export/share/agent-picker buttons). When projected, the consumer owns\n the entire header rendering; the default chrome below is bypassed\n wholesale. Context exposes the minimal IMJChatHeaderComponent shape;\n consumers needing more app state should bind to chat-area inputs\n directly via @ViewChild or wrap the whole component. -->\n @if (slotTemplate('header'); as t) {\n <ng-container *ngTemplateOutlet=\"t; context: {\n $implicit: conversation,\n conversationTitle: conversation?.Name ?? null,\n sharedBy: sharedByBadge?.display ?? null,\n artifactCount: artifactCountDisplay,\n showArtifactIndicator: showArtifactIndicator\n }\"></ng-container>\n } @else if (conversation || HasPreConversationHeader) {\n <!-- Default header \u2014 also renders BEFORE a conversation exists when the\n embedder has pre-conversation chrome to surface (currently just the\n mode picker \u2014 agent / share / export / members / artifacts all\n require a conversation row and stay hidden). Lets embedded surfaces\n like the Form Builder cockpit show the mode picker above the\n empty-state on a fresh chat instead of waiting for the first\n message to round-trip. -->\n <div class=\"chat-header\" (keydown.escape)=\"OnViewEscape($event)\">\n <div class=\"chat-info\" [class.with-sidebar-toggle]=\"showSidebarToggle\">\n @if (showSidebarToggle) {\n <button class=\"sidebar-toggle-btn\"\n (click)=\"sidebarToggleClicked.emit()\"\n title=\"Show conversations\">\n <i class=\"fas fa-table-columns\"></i>\n </button>\n }\n @if (conversation) {\n <ng-container *ngTemplateOutlet=\"titleBar\"></ng-container>\n @if (CurrentOwnerAgent) {\n <span class=\"with-chip\" [style.--agent-accent]=\"CurrentOwnerAccentVar\">\n <span class=\"dot\" aria-hidden=\"true\"></span>\n <span>with <b>{{ CurrentOwnerAgentName }}</b></span>\n </span>\n }\n }\n @if (sharedByBadge) {\n <span class=\"shared-by-badge\" [title]=\"sharedByBadge.fullTooltip\">\n <i class=\"fas fa-share-nodes\"></i>\n <span>Shared by {{ sharedByBadge.display }}</span>\n </span>\n }\n @if (conversation?.ProjectID) {\n <button class=\"project-tag\" (click)=\"openProjectSelector()\" [attr.title]=\"EffectiveReadOnly ? 'Project' : 'Assign to project'\">\n <i class=\"fas fa-folder\"></i>\n <span>{{ conversation!.Project || 'Project' }}</span>\n </button>\n }\n @if (conversation?.TestRunID) {\n <button class=\"test-indicator\" (click)=\"viewTestRun(conversation!.TestRunID!)\" title=\"View Test Run\">\n <i class=\"fas fa-flask\"></i>\n <span>Test</span>\n </button>\n }\n </div>\n <div class=\"chat-actions chat-actions-buttons\">\n @if (ForkSummaries.length > 0) {\n <button mjButton #forksButton Variant=\"flat\" Size=\"sm\" class=\"forks-button\" [class.active]=\"ShowForksPopover\"\n aria-haspopup=\"dialog\" [attr.aria-expanded]=\"ShowForksPopover\" [attr.aria-controls]=\"ShowForksPopover ? ForksPopoverID : null\"\n (click)=\"ToggleForksPopover()\" title=\"Forks in this conversation\">\n <i class=\"fa-solid fa-code-branch\"></i>\n <span class=\"btn-label\">Forks</span>\n <span class=\"forks-count\">{{ ForkSummaries.length }}</span>\n </button>\n }\n @if (allowPinning && pinnedMessageCount > 0) {\n <button class=\"pin-chip\" [class.active]=\"showPinsPanel\" (click)=\"TogglePinsPanel()\" title=\"View pinned messages\">\n <i class=\"fas fa-thumbtack\"></i>\n <span class=\"pin-chip-count\">{{ pinnedMessageCount }}</span>\n </button>\n }\n @if (showArtifactIndicator && artifactCountDisplay > 0) {\n <button class=\"artifact-indicator\" (click)=\"viewArtifacts()\" title=\"View artifacts\">\n <i class=\"fas fa-cube\"></i>\n <span class=\"artifact-badge\">{{ artifactCountDisplay }}</span>\n </button>\n }\n @if (AllowRemoteBrowser && conversation) {\n <button mjButton variant=\"flat\" size=\"sm\"\n class=\"remote-browser-toggle-btn\"\n [class.active]=\"ShowRemoteBrowserPanel || IsRemoteBrowserLive\"\n (click)=\"ToggleRemoteBrowserPanel()\"\n [title]=\"ShowRemoteBrowserPanel ? 'Hide Browser' : IsRemoteBrowserLive ? 'Show Browser (running)' : 'Open Browser'\">\n <i class=\"fa-solid fa-globe\"></i>\n <span class=\"btn-label\">Browser</span>\n </button>\n }\n @if (memberCount > 1) {\n <button class=\"chat-members\" (click)=\"toggleMembersModal()\" title=\"View members\">\n <i class=\"fas fa-users\"></i>\n <span class=\"members-badge\">{{ memberCount }}</span>\n </button>\n }\n @if (!overlayMode && showAgentModePicker && ModePickerTargetAgentId && !EffectiveReadOnly) {\n <!-- Per-agent mode/quality picker (Draft / Standard / High).\n Targets the agent the next non-mention message will route\n to. Auto-hides when that agent has fewer than 2 configured\n presets. Choice persists per-user, per-agent via\n UserInfoEngine; emits the picked configuration ID up so\n <mj-message-input> can forward it on the next route.\n Hidden in overlayMode (the compact chat overlay): the\n mode dropdown wastes the narrow top-right space there. -->\n <mj-conversation-mode-picker\n [AgentID]=\"ModePickerTargetAgentId\"\n [Disabled]=\"isProcessing\"\n (PresetChanged)=\"OnAgentModePresetChanged($event)\">\n </mj-conversation-mode-picker>\n }\n @if (showAgentPicker && conversation) {\n <!-- Per-conversation default-agent pin. When set, non-mention\n messages route to this agent instead of Sage. Persists to\n MJConversationEntity.DefaultAgentID. Hidden when no\n conversation is loaded or when the embedder disables it. -->\n <mj-conversation-agent-picker\n [Conversation]=\"conversation\"\n [CurrentUser]=\"currentUser\"\n [AllowedAgentIDs]=\"AllowedAgentIDs\"\n [Disabled]=\"EffectiveReadOnly\">\n </mj-conversation-agent-picker>\n }\n @if (showExportButton) {\n <button mjButton variant=\"flat\" size=\"sm\" (click)=\"exportConversation()\" [title]=\"exportButtonLabel + ' conversation'\">\n <i [class]=\"exportButtonIcon\"></i>\n <span class=\"btn-label\">{{ exportButtonLabel }}</span>\n </button>\n }\n @if (showShareButton && canShareConversation) {\n <button mjButton variant=\"flat\" size=\"sm\"\n [class.shared]=\"isShared\"\n (click)=\"shareConversation()\"\n [title]=\"isShared ? 'Manage sharing' : 'Share conversation'\">\n <i class=\"fas fa-share-nodes\"></i>\n <span class=\"btn-label\">Share</span>\n </button>\n }\n <!-- headerActions slot \u2014 ADDITIVE host buttons rendered after the stock\n actions (unlike the `header` slot, which replaces the whole header\n and therefore never reaches this branch). For visual parity,\n projected buttons should use mjButton variant=\"flat\" size=\"sm\". -->\n @if (slotTemplate('headerActions'); as t) {\n <ng-container *ngTemplateOutlet=\"t; context: {\n $implicit: conversation,\n conversationId: conversationId,\n isProcessing: isProcessing\n }\"></ng-container>\n }\n </div>\n </div>\n }\n\n <!-- Header title. Main: the conversation name. A fork: the path, the conversation and each parent fork\n (each opens its view; the parent is the way back), then the open fork with its kind icon. Past three\n entries, and on narrow screens, the middle crumbs collapse into an ellipsis that opens the forks list.\n The current name can be renamed in place. -->\n <ng-template #titleBar>\n <div class=\"chat-title-bar\">\n @if (OpenView.Kind === 'Main') {\n <ng-container *ngTemplateOutlet=\"titleName\"></ng-container>\n } @else {\n <nav class=\"chat-title-path\" aria-label=\"Breadcrumb\">\n <ol class=\"chat-title-crumbs\">\n @for (parent of HeaderPath.Parents; track $index) {\n @if ($index === 1) {\n <li class=\"chat-title-crumb chat-title-ellipsis\" [class.collapses-wide]=\"HeaderPath.CollapsesWide\">\n <button mjButton Variant=\"flat\" Size=\"sm\" type=\"button\" (click)=\"ShowWholePath()\" aria-label=\"Show the whole path\" title=\"Show the whole path\">\u2026</button>\n <i class=\"fa-solid fa-chevron-right chat-title-sep\" aria-hidden=\"true\"></i>\n </li>\n }\n <li class=\"chat-title-crumb\" [class.path-middle]=\"parent.IsMiddle\" [class.collapsed-wide]=\"parent.CollapsedWide\">\n <button mjButton Variant=\"flat\" Size=\"sm\" type=\"button\" (click)=\"OpenCrumb(parent.Crumb)\" [title]=\"'Back to ' + parent.Crumb.Label\">\n <span class=\"chat-title-crumb-label\">{{ parent.Crumb.Label }}</span>\n </button>\n <i class=\"fa-solid fa-chevron-right chat-title-sep\" aria-hidden=\"true\"></i>\n </li>\n }\n <li class=\"chat-title-current\" aria-current=\"page\">\n <i [class]=\"'chat-title-kind ' + OpenViewIcon\" [attr.data-kind]=\"OpenViewKind\" aria-hidden=\"true\"></i>\n <ng-container *ngTemplateOutlet=\"titleName\"></ng-container>\n </li>\n </ol>\n </nav>\n }\n </div>\n </ng-template>\n\n <!-- The current name and its rename button; the inline field while renaming -->\n <ng-template #titleName>\n @if (IsRenamingTitle) {\n <input\n #titleNameInput\n type=\"text\"\n class=\"chat-title-input\"\n maxlength=\"255\"\n [attr.aria-label]=\"TitleRenameLabel\"\n [(ngModel)]=\"TitleRenameText\"\n (keydown.enter)=\"$event.preventDefault(); SaveTitleRename(true)\"\n (keydown.escape)=\"$event.preventDefault(); $event.stopPropagation(); CancelTitleRename()\"\n (blur)=\"SaveTitleRename()\" />\n } @else {\n <h2 class=\"chat-title\" [title]=\"HeaderTitle\">{{ HeaderTitle }}</h2>\n @if (CanRenameTitle) {\n <button mjButton #titleRenameButton Variant=\"icon\" Size=\"sm\" type=\"button\" class=\"chat-title-rename\" (click)=\"StartTitleRename()\" [attr.aria-label]=\"TitleRenameLabel\" [title]=\"TitleRenameLabel\">\n <i class=\"fa-solid fa-pen\" aria-hidden=\"true\"></i>\n </button>\n }\n }\n </ng-template>\n\n <!-- Messages and Artifact Split Layout \u2014 restructures into [stage | rail]\n when isDemonstrationActive (per Matt's 06-10 design). The .demonstration-mode\n class drives the CSS Grid switch; the stage container renders only when the\n slot is projected AND the host opts in via [showDemonstrationSurface]. -->\n <div class=\"chat-content-area\" [class.demonstration-mode]=\"isDemonstrationActive\">\n <!-- demonstrationSurface stage \u2014 takes the main pane; messages shrink to\n a side rail (or move below on mobile). Off unless both\n [showDemonstrationSurface] is true AND a slot template is projected. -->\n @if (isDemonstrationActive) {\n <div class=\"chat-demonstration-stage\">\n <ng-container *ngTemplateOutlet=\"slotTemplate('demonstrationSurface'); context: {\n $implicit: demonstrationSurfaceContent,\n content: demonstrationSurfaceContent,\n visible: showDemonstrationSurface\n }\"></ng-container>\n </div>\n }\n\n <!-- Messages Pane -->\n <div class=\"chat-messages-pane\"\n [class.full-width]=\"!showArtifactPanel && !SelectedTaskGraphPanel && !ShowRemoteBrowserPanel\"\n [class.hidden]=\"isArtifactPaneMaximized\">\n @if (isLoadingConversation) {\n <!-- Loading State - checked FIRST to prevent empty state flash. The branch\n always short-circuits the panes below; showLoadingState only controls\n whether the built-in spinner renders (hosts with their own loading\n chrome set it false and get a blank pane instead). -->\n @if (showLoadingState) {\n <div class=\"conversation-loading-state\">\n <mj-loading text=\"Loading conversation...\" size=\"large\"></mj-loading>\n </div>\n }\n } @else if ((isNewConversation || !conversationId) && !suppressNewConversationEmptyState) {\n <!-- emptyState slot \u2014 when a consumer projects mjChatSlot=\"emptyState\",\n they take over the entire empty-state region (including any send\n affordance \u2014 the slot interface doesn't include a sendMessage\n output, so consumers handle send via their own input). When no\n slot is projected, the rich built-in <mj-conversation-empty-state>\n renders with its own greeting, prompt chips, and message input.\n emptyStateConfig (when supplied) takes precedence over the legacy\n [emptyStateGreeting] string for backwards compatibility. -->\n @if (ReadOnly) {\n <div class=\"read-only-banner\" role=\"status\">\n <i class=\"fas fa-eye\"></i>\n <span>{{ ReadOnlyMessage || 'You have view-only access to this conversation.' }}</span>\n </div>\n } @else if (slotTemplate('emptyState'); as t) {\n <ng-container *ngTemplateOutlet=\"t; context: {\n $implicit: emptyStateConfig,\n greeting: emptyStateConfig?.greeting ?? emptyStateGreeting,\n subtext: emptyStateConfig?.subtext,\n suggestedPrompts: emptyStateConfig?.suggestedPrompts ?? []\n }\"></ng-container>\n } @else {\n <mj-conversation-empty-state\n [currentUser]=\"currentUser\"\n [initialDraft]=\"GetInitialDraftFor(null)\"\n (initialDraftApplied)=\"OnComposerDraftApplied()\"\n (DraftStateChanged)=\"OnDraftStateChanged(null, $event)\"\n (ComposerBlurred)=\"OnComposerBlurred()\"\n [disabled]=\"isProcessing\"\n [showSidebarToggle]=\"showSidebarToggle\"\n [overlayMode]=\"overlayMode\"\n [greeting]=\"emptyStateConfig?.greeting ?? emptyStateGreeting\"\n [showSuggestedPrompts]=\"showSuggestedPrompts\"\n [enableAttachments]=\"enableAttachments && allowAttachments\"\n [enableMentions]=\"allowMentions\"\n [enableAgentMentions]=\"allowAgentMentions\"\n [enableEntityMentions]=\"allowEntityMentions\"\n [enableSkillCommands]=\"allowSkillCommands\"\n [AllowedAgentIDs]=\"AllowedAgentIDs\"\n [MentionPeople]=\"MentionPeople\"\n [ComposerExtraTemplate]=\"slotTemplate('composerExtra')\"\n [maxAttachments]=\"maxAttachments\"\n [maxAttachmentSizeBytes]=\"maxAttachmentSizeBytes\"\n [acceptedFileTypes]=\"acceptedFileTypes\"\n (sidebarToggleClicked)=\"sidebarToggleClicked.emit()\"\n (messageSent)=\"onEmptyStateMessageSent($event)\">\n </mj-conversation-empty-state>\n }\n } @else if ((isNewConversation || !conversationId) && suppressNewConversationEmptyState) {\n <!-- Pre-conversation normal-view: empty message list + emptyStateMode input.\n Used when host (e.g. Form Builder cockpit) wants the header + mode picker\n visible on first open instead of the centered welcome card. First send\n routes through onEmptyStateMessageSent which creates the conversation. -->\n <div class=\"chat-messages-wrapper\">\n <div class=\"chat-messages-container\"></div>\n <div class=\"chat-input-container\">\n @if (ReadOnly) {\n <div class=\"read-only-banner\" role=\"status\">\n <i class=\"fas fa-eye\"></i>\n <span>{{ ReadOnlyMessage || 'You have view-only access to this conversation.' }}</span>\n </div>\n } @else {\n <!-- composerExtra slot \u2014 host UI directly above the composer (IMJChatComposerExtraContext). -->\n @if (slotTemplate('composerExtra'); as t) {\n <div class=\"chat-composer-extra\">\n <ng-container *ngTemplateOutlet=\"t; context: {\n $implicit: conversation,\n ConversationId: conversationId,\n IsProcessing: isProcessing\n }\"></ng-container>\n </div>\n }\n <div class=\"message-input-container-wrapper\">\n <mj-message-input\n #emptyStateInput\n [emptyStateMode]=\"true\"\n [initialDraft]=\"GetInitialDraftFor(null)\"\n (initialDraftApplied)=\"OnComposerDraftApplied()\"\n (DraftStateChanged)=\"OnDraftStateChanged(null, $event)\"\n (ComposerBlurred)=\"OnComposerBlurred()\"\n [currentUser]=\"currentUser\"\n [disabled]=\"isProcessing\"\n [ReadOnly]=\"EffectiveReadOnly\"\n [appContext]=\"appContext\"\n [applicationId]=\"applicationId\"\n [defaultAgentId]=\"defaultAgentId\"\n [enableAttachments]=\"enableAttachments && allowAttachments\"\n [enableMentions]=\"allowMentions\"\n [enableAgentMentions]=\"allowAgentMentions\"\n [enableEntityMentions]=\"allowEntityMentions\"\n [enableSkillCommands]=\"allowSkillCommands\"\n [enablePlanMode]=\"allowPlanMode\"\n [enableRealtime]=\"allowRealtime\"\n [AllowedAgentIDs]=\"AllowedAgentIDs\"\n [MentionPeople]=\"MentionPeople\"\n [maxAttachments]=\"maxAttachments\"\n [maxAttachmentSizeBytes]=\"maxAttachmentSizeBytes\"\n [acceptedFileTypes]=\"acceptedFileTypes\"\n (emptyStateSubmit)=\"onEmptyStateMessageSent($event)\">\n </mj-message-input>\n </div>\n }\n </div>\n </div>\n } @else {\n <!-- Normal Message View -->\n <div class=\"chat-messages-wrapper\">\n @if (OpenView.Kind !== 'Main' && slotTemplate('header')) {\n <!-- A host header replaces the default one, so the fork title shows above the transcript. -->\n <div class=\"fork-view-bar\" role=\"region\" aria-label=\"Fork\" (keydown.escape)=\"OnViewEscape($event)\">\n <ng-container *ngTemplateOutlet=\"titleBar\"></ng-container>\n </div>\n }\n <!-- Upload Indicator Overlay (centered in conversation area) -->\n @if (isUploadingAttachments) {\n <div class=\"upload-indicator-overlay\">\n <mj-loading [text]=\"uploadingMessage\" size=\"medium\"></mj-loading>\n </div>\n }\n <div class=\"chat-messages-container\" #scrollContainer (scroll)=\"checkScroll()\" (keydown.escape)=\"OnViewEscape($event)\">\n <mj-conversation-message-list\n [showEmptyFill]=\"showEmptyFill\"\n [showDateNavigation]=\"showDateNavigation\"\n [showAgentRunDetails]=\"showAgentRunDetails\"\n [showReactions]=\"showReactions\"\n [showMessageRating]=\"showMessageRating\"\n [allowPinning]=\"allowPinning && !EffectiveReadOnly\"\n [allowMessageEdit]=\"allowMessageEdit && !EffectiveReadOnly\"\n [allowMessageDelete]=\"allowMessageDelete && !EffectiveReadOnly\"\n [ReadOnly]=\"EffectiveReadOnly\"\n [AllowStopRun]=\"AllowStopRun\"\n [InFlightCount]=\"InFlightCount\"\n [assistantDisplayName]=\"assistantDisplayName\"\n [assistantAvatarUrl]=\"assistantAvatarUrl\"\n [messages]=\"DisplayMessages\"\n [HasMoreAbove]=\"ListHasMoreAbove\"\n [IsLoadingOlder]=\"isLoadingOlderMessages\"\n [ScrollRoot]=\"messageScrollRoot\"\n (OlderRequested)=\"onOlderMessagesRequested()\"\n (DateJumpRequested)=\"onDateJumpRequested($event)\"\n [conversation]=\"conversation\"\n [currentUser]=\"currentUser\"\n [isProcessing]=\"isProcessing\"\n [artifactMap]=\"effectiveArtifactsMap\"\n [agentRunMap]=\"agentRunsByDetailId\"\n [HandoffMap]=\"HandoffsByDetailId\"\n [ratingsMap]=\"ratingsByDetailId\"\n [userAvatarMap]=\"userAvatarMap\"\n [attachmentsMap]=\"attachmentsByDetailId\"\n [messageRendererTemplate]=\"slotTemplate('messageRenderer')\"\n [messageExtraTemplate]=\"slotTemplate('messageExtra')\"\n [sessionMetaMap]=\"realtimeSessionMetaMap\"\n [ForkChipMap]=\"ForkChipMap\"\n [ForkLayout]=\"ForkLayout\"\n [CanFork]=\"CanFork\"\n [InPlaceTurn]=\"InPlaceTurn\"\n (ForkOpenRequested)=\"OnForkOpenRequested($event)\"\n (EditResendRequested)=\"OnEditResendRequested($event)\"\n (RegenerateRequested)=\"OnRegenerateRequested($event)\"\n (ResendInPlaceRequested)=\"OnResendInPlaceRequested($event)\"\n (ForkRequested)=\"OnForkRequested($event)\"\n (realtimeSessionOpenRequested)=\"OpenRealtimeSessionReview($event)\"\n (deleteMessage)=\"onDeleteMessage($event)\"\n (BeforeStopClicked)=\"BeforeStopClicked.emit($event)\"\n (StopMessage)=\"OnStopMessage($event)\"\n (testFeedbackMessage)=\"onTestFeedbackMessage($event)\"\n (artifactClicked)=\"onArtifactClicked($event)\"\n (messageEdited)=\"onMessageEdited($event)\"\n (openEntityRecord)=\"onOpenEntityRecord($event)\"\n (suggestedResponseSelected)=\"onSuggestedResponseSelected($event)\"\n (attachmentClicked)=\"onAttachmentClicked($event)\"\n (diagnosticRequested)=\"onDiagnosticRequested($event)\"\n (LivenessCheckRequested)=\"OnLivenessCheckRequested($event)\"\n (messagePinToggled)=\"onMessagePinToggled($event)\"\n (beforeResponseFormSubmitted)=\"beforeResponseFormSubmitted.emit($event)\"\n (afterResponseFormSubmitted)=\"afterResponseFormSubmitted.emit($event)\"\n (TaskGraphPanelRequested)=\"OnTaskGraphPanelRequested($event)\"\n (ScrollToMessageRequested)=\"OnJumpToMessage($event)\">\n </mj-conversation-message-list>\n\n <!-- Scroll to Bottom Icon (positioned within scroll container for proper centering) -->\n @if (showScrollToBottomIcon && DisplayMessages.length > 0) {\n <span class=\"scroll-to-bottom-icon\" style=\"left: 50%;\"\n (click)=\"scrollToBottomAnimate()\">\n <i class=\"fas fa-arrow-down\"></i>\n </span>\n }\n </div>\n\n <!-- Fixed Input Area -->\n <div class=\"chat-input-container\">\n @if (isLoadingPeripheralData) {\n <!-- Loading State -->\n <div class=\"loading-peripheral-placeholder\">\n <mj-loading text=\"Loading conversation data...\" size=\"medium\"></mj-loading>\n </div>\n } @else if (ReadOnly) {\n <div class=\"read-only-banner\" role=\"status\">\n <i class=\"fas fa-eye\"></i>\n <span>{{ ReadOnlyMessage || 'You have view-only access to this conversation.' }}</span>\n </div>\n } @else {\n @if (isReadOnlyView) {\n <div class=\"read-only-banner\" role=\"status\">\n <i class=\"fas fa-eye\"></i>\n <span>You have view-only access to this conversation.</span>\n </div>\n }\n <!-- composerExtra slot \u2014 host UI directly above the composer (IMJChatComposerExtraContext). -->\n @if (slotTemplate('composerExtra'); as t) {\n <div class=\"chat-composer-extra\">\n <ng-container *ngTemplateOutlet=\"t; context: {\n $implicit: conversation,\n ConversationId: conversationId,\n IsProcessing: isProcessing\n }\"></ng-container>\n </div>\n }\n <!-- Input Component - Multiple instances cached, only one visible -->\n <div class=\"message-input-container-wrapper\">\n @for (inputRef of getCachedInputs(); track NormalizeCachedInputId(inputRef.conversationId)) {\n <mj-message-input\n #messageInput\n [hidden]=\"inputRef.conversationId !== conversationId\"\n [initialDraft]=\"GetInitialDraftFor(inputRef.conversationId)\"\n (DraftStateChanged)=\"OnDraftStateChanged(inputRef.conversationId, $event)\"\n (ComposerBlurred)=\"OnComposerBlurred()\"\n [conversationId]=\"inputRef.conversationId\"\n [conversationName]=\"inputRef.conversationName\"\n [currentUser]=\"currentUser\"\n [conversationHistory]=\"inputRef.conversationId === conversationId ? messages : []\"\n [artifactsByDetailId]=\"inputRef.conversationId === conversationId ? artifactsByDetailId : emptyArtifactsMap\"\n [systemArtifactsByDetailId]=\"inputRef.conversationId === conversationId ? systemArtifactsByDetailId : emptyArtifactsMap\"\n [agentRunsByDetailId]=\"inputRef.conversationId === conversationId ? agentRunsByDetailId : emptyAgentRunsMap\"\n [appContext]=\"EffectiveAppContext\"\n [applicationId]=\"applicationId\"\n [defaultAgentId]=\"defaultAgentId\"\n [conversationDefaultAgentId]=\"inputRef.conversationId === conversationId ? (conversation?.DefaultAgentID ?? null) : null\"\n [agentConfigurationPresetId]=\"inputRef.conversationId === conversationId ? ActiveAgentConfigurationPresetId : null\"\n [AgentReplyMode]=\"AgentReplyMode\"\n [AllowedAgentIDs]=\"AllowedAgentIDs\"\n [MentionPeople]=\"MentionPeople\"\n [AgentHistoryFrom]=\"AgentHistoryFrom\"\n [TargetBranchID]=\"TargetBranchIdFor(inputRef.conversationId)\"\n [ResolveTargetBranch]=\"inputRef.conversationId === conversationId ? ResolveComposerBranch : null\"\n [AgentTurnHandler]=\"AgentTurnHandler\"\n [AutoNameConversation]=\"AutoNameConversation\"\n [EnableDecisionRouting]=\"EnableDecisionRouting\"\n [inProgressMessageIds]=\"inputRef.conversationId === conversationId ? inProgressMessageIds : emptyInProgressIds\"\n [disabled]=\"isProcessing || isReadOnlyView\"\n [ReadOnly]=\"EffectiveReadOnly\"\n [enableAttachments]=\"enableAttachments && allowAttachments\"\n [enableMentions]=\"allowMentions\"\n [enableAgentMentions]=\"allowAgentMentions\"\n [enableEntityMentions]=\"allowEntityMentions\"\n [enableSkillCommands]=\"allowSkillCommands\"\n [enablePlanMode]=\"allowPlanMode\"\n [enableRealtime]=\"allowRealtime && OpenView.Kind !== 'DraftFork'\"\n [Placeholder]=\"ComposerPlaceholderFor(inputRef.conversationId)\"\n [SendSlotMode]=\"inputRef.conversationId === conversationId ? SendSlotMode : 'send'\"\n [StopCount]=\"inputRef.conversationId === conversationId ? StopCount : 0\"\n [StopLabel]=\"StopLabel\"\n [StatusText]=\"inputRef.conversationId === conversationId ? StatusText : null\"\n [StatusElapsed]=\"inputRef.conversationId === conversationId ? StatusElapsed : null\"\n (StopClicked)=\"OnComposerStopClicked()\"\n [maxAttachments]=\"maxAttachments\"\n [maxAttachmentSizeBytes]=\"maxAttachmentSizeBytes\"\n [acceptedFileTypes]=\"acceptedFileTypes\"\n [initialMessage]=\"shouldDeliverPendingMessageTo(inputRef.conversationId) ? pendingMessage : null\"\n [initialAttachments]=\"shouldDeliverPendingMessageTo(inputRef.conversationId) ? pendingAttachments : null\"\n (initialMessageAutoSendStarted)=\"onInitialMessageAutoSendStarted($event)\"\n (initialMessageAutoSendFailed)=\"onInitialMessageAutoSendFailed($event)\"\n (messageSent)=\"onMessageSent($event)\"\n (MessageStreamed)=\"OnMessageStreamed($event)\"\n (agentResponse)=\"onAgentResponse($event)\"\n (agentRunDetected)=\"onAgentRunDetected($event)\"\n (agentRunUpdate)=\"onAgentRunUpdate($event)\"\n (messageComplete)=\"onMessageComplete($event)\"\n (artifactCreated)=\"onArtifactCreated($event)\"\n (conversationRenamed)=\"onConversationRenamed($event)\"\n (intentCheckStarted)=\"onIntentCheckStarted($event)\"\n (intentCheckCompleted)=\"onIntentCheckCompleted($event)\"\n (beforeAgentTurn)=\"beforeAgentTurn.emit($event)\"\n (afterAgentTurn)=\"afterAgentTurn.emit($event)\"\n (uploadStateChanged)=\"onUploadStateChanged($event)\">\n </mj-message-input>\n }\n </div>\n @if (ComposerHint) {\n <div class=\"fork-composer-hint\">{{ ComposerHint }}</div>\n }\n }\n </div>\n </div>\n }\n </div>\n\n <!-- Artifact Viewer Pane -->\n @if (showArtifactPanel && selectedArtifactId) {\n @if (!isArtifactPaneMaximized) {\n <div class=\"resize-handle\" (mousedown)=\"onResizeStart($event)\" (touchstart)=\"onResizeTouchStart($event)\"></div>\n }\n <div class=\"chat-artifact-pane\"\n [style.width.%]=\"artifactPaneWidth\"\n [class.maximized]=\"isArtifactPaneMaximized\">\n <mj-artifact-viewer-panel\n [artifactId]=\"selectedArtifactId\"\n [currentUser]=\"currentUser\"\n [environmentId]=\"environmentId\"\n [versionNumber]=\"selectedVersionNumber\"\n [viewContext]=\"'conversation'\"\n [Scope]=\"ArtifactViewerScope\"\n [canShare]=\"canShareSelectedArtifact\"\n [canEdit]=\"canEditSelectedArtifact\"\n [isMaximized]=\"isArtifactPaneMaximized\"\n [refreshTrigger]=\"artifactViewerRefresh$\"\n (closed)=\"onCloseArtifactPanel()\"\n (saveToCollectionRequested)=\"onSaveToCollectionRequested($event)\"\n (navigateToLink)=\"onArtifactLinkNavigation($event)\"\n (shareRequested)=\"onArtifactShareRequested($event)\"\n (maximizeToggled)=\"toggleMaximizeArtifactPane()\"\n (openEntityRecord)=\"onOpenEntityRecord($event)\"\n (navigationRequest)=\"onNavigationRequest($event)\"\n (analyzeRequested)=\"OnAnalyzeArtifact($event)\"\n (applyFormRequested)=\"OnApplyFormRequested($event)\">\n </mj-artifact-viewer-panel>\n </div>\n }\n\n <!-- Task Graph Run Viewer Pane -->\n @if (SelectedTaskGraphPanel) {\n @if (!isArtifactPaneMaximized) {\n <div class=\"resize-handle\" (mousedown)=\"onResizeStart($event)\" (touchstart)=\"onResizeTouchStart($event)\"></div>\n }\n <div class=\"chat-artifact-pane chat-task-graph-pane\"\n [style.width.%]=\"artifactPaneWidth\"\n [class.maximized]=\"isArtifactPaneMaximized\">\n <div class=\"task-graph-pane-header\">\n <div class=\"task-graph-pane-title-group\">\n <span class=\"task-graph-pane-icon\">\n <i class=\"fa-solid fa-diagram-project\"></i>\n </span>\n <div class=\"task-graph-pane-titles\">\n <span class=\"task-graph-pane-title\">{{ SelectedTaskGraphPanel.workflowTitle }}</span>\n <span class=\"task-graph-pane-subtitle\">Interactive Task Graph &amp; Step Inspector</span>\n </div>\n </div>\n <div class=\"task-graph-pane-actions\">\n <button\n type=\"button\"\n class=\"task-graph-pane-save-btn\"\n [disabled]=\"IsSavingTaskGraphWorkflow || !taskGraphRunView.Spec?.tasks?.length\"\n (click)=\"OnSaveTaskGraphAsWorkflow(taskGraphRunView.Spec)\"\n title=\"Save this task graph as a reusable Draft Flow Agent workflow\">\n <i class=\"fa-solid\" [class.fa-spinner]=\"IsSavingTaskGraphWorkflow\" [class.fa-spin]=\"IsSavingTaskGraphWorkflow\" [class.fa-floppy-disk]=\"!IsSavingTaskGraphWorkflow\"></i>\n <span>{{ IsSavingTaskGraphWorkflow ? 'Saving\u2026' : 'Save as Workflow' }}</span>\n </button>\n <button\n type=\"button\"\n class=\"task-graph-pane-btn\"\n (click)=\"toggleMaximizeArtifactPane()\"\n [title]=\"isArtifactPaneMaximized ? 'Restore panel size' : 'Maximize panel'\">\n <i class=\"fa-solid\" [class.fa-compress]=\"isArtifactPaneMaximized\" [class.fa-expand]=\"!isArtifactPaneMaximized\"></i>\n </button>\n <button\n type=\"button\"\n class=\"task-graph-pane-btn\"\n (click)=\"OnCloseTaskGraphPanel()\"\n title=\"Close Task Graph panel\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n </div>\n <div class=\"task-graph-pane-body\">\n <mj-task-graph-run-view\n #taskGraphRunView\n [ParentTaskID]=\"SelectedTaskGraphPanel.parentTaskId\"\n [WorkflowName]=\"SelectedTaskGraphPanel.workflowTitle\"\n [LiveUpdates]=\"true\"\n [ShowVariables]=\"true\"\n [Height]=\"'100%'\">\n </mj-task-graph-run-view>\n </div>\n </div>\n }\n\n <!-- Remote Browser Side Pane -->\n @if (ShowRemoteBrowserPanel) {\n @if (!isArtifactPaneMaximized) {\n <div class=\"resize-handle\" (mousedown)=\"onResizeStart($event)\" (touchstart)=\"onResizeTouchStart($event)\"></div>\n }\n <div class=\"chat-artifact-pane chat-task-graph-pane chat-remote-browser-pane\"\n [style.width.%]=\"artifactPaneWidth\"\n [class.maximized]=\"isArtifactPaneMaximized\">\n <div class=\"task-graph-pane-header\">\n <div class=\"task-graph-pane-title-group\">\n <span class=\"task-graph-pane-icon\">\n <i class=\"fa-solid fa-globe\"></i>\n </span>\n <div class=\"task-graph-pane-titles\">\n <span class=\"task-graph-pane-title\">Remote Browser</span>\n <span class=\"task-graph-pane-subtitle\">Shared live browser workspace</span>\n </div>\n </div>\n <div class=\"task-graph-pane-actions\">\n <input\n type=\"text\"\n class=\"remote-browser-url-input\"\n placeholder=\"Enter URL or domain\u2026\"\n [(ngModel)]=\"RemoteBrowserUrlInput\"\n (keydown.enter)=\"$event.preventDefault(); NavigateRemoteBrowserFromInput()\" />\n <button\n type=\"button\"\n class=\"task-graph-pane-save-btn\"\n [disabled]=\"IsRemoteBrowserNavigating || !RemoteBrowserUrlInput.trim()\"\n (click)=\"NavigateRemoteBrowserFromInput()\"\n title=\"Navigate to URL\">\n <i class=\"fa-solid\" [class.fa-spinner]=\"IsRemoteBrowserNavigating\" [class.fa-spin]=\"IsRemoteBrowserNavigating\" [class.fa-arrow-right]=\"!IsRemoteBrowserNavigating\"></i>\n <span>Go</span>\n </button>\n <button\n type=\"button\"\n class=\"task-graph-pane-btn\"\n (click)=\"toggleMaximizeArtifactPane()\"\n [title]=\"isArtifactPaneMaximized ? 'Restore panel size' : 'Maximize panel'\">\n <i class=\"fa-solid\" [class.fa-compress]=\"isArtifactPaneMaximized\" [class.fa-expand]=\"!isArtifactPaneMaximized\"></i>\n </button>\n <button\n type=\"button\"\n class=\"task-graph-pane-btn\"\n (click)=\"CloseRemoteBrowserPanel()\"\n title=\"Close Browser panel\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n </div>\n <div class=\"task-graph-pane-body\">\n <mj-realtime-remote-browser-surface\n #conversationRemoteBrowserSurface>\n </mj-realtime-remote-browser-surface>\n </div>\n </div>\n }\n\n <!-- Artifact Share Modal -->\n <mj-artifact-share-modal\n [isOpen]=\"isArtifactShareModalOpen\"\n [artifact]=\"artifactToShare\"\n [currentUser]=\"currentUser\"\n (saved)=\"onArtifactShared()\"\n (cancelled)=\"onArtifactShareModalClose()\">\n </mj-artifact-share-modal>\n\n <!-- Pinned Messages Panel (overlay) -->\n @if (allowPinning && showPinsPanel) {\n <mj-pinned-messages-panel\n [pinnedMessages]=\"pinnedMessages\"\n [isLoading]=\"isLoadingPins\"\n [AllowUnpin]=\"!EffectiveReadOnly\"\n (closed)=\"showPinsPanel = false\"\n (jumpRequested)=\"onJumpToMessage($event)\"\n (unpinRequested)=\"onUnpinFromPanel($event)\">\n </mj-pinned-messages-panel>\n }\n\n @if (ShowForksPopover) {\n <mj-conversation-forks-popover\n [PanelID]=\"ForksPopoverID\"\n [Summaries]=\"ForkSummaries\"\n [CurrentUserID]=\"CurrentUser.ID\"\n (ForkSelected)=\"OnForkSelectedFromList($event)\"\n (Closed)=\"CloseForksPopover()\">\n </mj-conversation-forks-popover>\n }\n </div>\n\n <!-- Live voice \"call mode\" overlay \u2014 fills this conversation panel in place\n (header + thread + composer) while a realtime session is active. When the\n call is MINIMIZED (e.g. a dev link navigated to a record) the overlay HIDES\n (not destroyed \u2014 its merged session state must survive), the session stays\n fully live, and a floating \"on call\" pill offers the way back.\n ALSO hosted in SESSION REVIEW mode (RealtimeReview set, no live call): the\n overlay renders what went down in a PAST session, with a \"Start live session\"\n button that resumes it as a new call. -->\n @if ((RealtimeSession.Active$ | async) || RealtimeReview) {\n <mj-realtime-session-overlay\n [AgentName]=\"realtimeOverlayAgentName\"\n [Hidden]=\"(RealtimeSession.Minimized$ | async) === true\"\n [CurrentUser]=\"currentUser\"\n [EnvironmentID]=\"environmentId\"\n [ReviewData]=\"RealtimeReview\"\n [AllowStartLive]=\"CanStartVoiceFromReview\"\n [Chrome]=\"overlayMode ? 'orb' : 'auto'\"\n [Compact]=\"overlayMode\"\n [ShowDevLinks]=\"!overlayMode\"\n [ShowDensityPicker]=\"!overlayMode\"\n (NavigateRequest)=\"onRealtimeNavigateRequest($event)\"\n (StartLiveRequested)=\"onReviewStartLive($event)\"\n (ReviewClosed)=\"onReviewClosed()\">\n </mj-realtime-session-overlay>\n @if (RealtimeSession.Minimized$ | async) {\n <button type=\"button\" class=\"voice-call-pill\" (click)=\"RealtimeSession.SetMinimized(false)\"\n title=\"Return to the live call\" aria-label=\"Return to the live call\">\n <span class=\"voice-call-pill__pulse\" aria-hidden=\"true\"></span>\n <i class=\"fa-solid fa-phone-volume\" aria-hidden=\"true\"></i>\n <span class=\"voice-call-pill__text\">\n <span class=\"voice-call-pill__name\">On call \u00B7 {{ RealtimeSession.CurrentAgentName }}</span>\n <span class=\"voice-call-pill__hint\">Tap to return</span>\n </span>\n </button>\n }\n }\n</div>\n\n<!-- Export Modal -->\n<!-- [branding] is bound BEFORE [isVisible] deliberately: Angular sets inputs in\n template order within a change-detection pass, and the modal's isVisible setter\n reads `branding` to default its \"Include branding\" checkbox on a fresh open. -->\n<mj-export-modal\n [branding]=\"exportBranding\"\n [isVisible]=\"showExportModal\"\n [conversation]=\"conversation || undefined\"\n [Scope]=\"ExportScope\"\n [currentUser]=\"currentUser\"\n (cancelled)=\"onExportModalCancelled()\"\n (exported)=\"onExportModalComplete()\">\n</mj-export-modal>\n\n<!-- Share Dialog (generic, shared with dashboards) -->\n<mj-resource-share-dialog\n [Visible]=\"showShareModal\"\n [Context]=\"shareContext\"\n [Adapter]=\"shareAdapter\"\n (Result)=\"onShareDialogResult($event)\">\n</mj-resource-share-dialog>\n\n<!-- Members Modal -->\n<mj-members-modal\n [isVisible]=\"showMembersModal\"\n [conversation]=\"conversation || undefined\"\n [currentUser]=\"currentUser\"\n (cancelled)=\"showMembersModal = false\"\n (membersChanged)=\"showMembersModal = false\">\n</mj-members-modal>\n\n<!-- Project Selector Modal -->\n@if (showProjectSelector && conversation) {\n <div class=\"modal-overlay\" (click)=\"showProjectSelector = false\">\n <div class=\"modal-content project-selector-modal\" (click)=\"$event.stopPropagation()\">\n <div class=\"modal-header\">\n <h3>Assign Project</h3>\n <button class=\"modal-close-btn\" (click)=\"showProjectSelector = false\">\n <i class=\"fas fa-times\"></i>\n </button>\n </div>\n <div class=\"modal-body\">\n <mj-project-selector\n [environmentId]=\"environmentId\"\n [currentUser]=\"currentUser\"\n [selectedProjectId]=\"conversation.ProjectID\"\n (projectSelected)=\"onProjectSelected($event)\">\n </mj-project-selector>\n </div>\n </div>\n </div>\n}\n\n<!-- Artifacts Modal -->\n@if (showArtifactsModal) {\n <div class=\"modal-overlay\" (click)=\"showArtifactsModal = false\">\n <div class=\"modal-content artifacts-modal\" (click)=\"$event.stopPropagation()\">\n <div class=\"modal-header\">\n <h3>Conversation Artifacts</h3>\n <div class=\"modal-header-actions\">\n @if (hasSystemArtifacts) {\n <button class=\"toggle-system-btn\"\n [class.active]=\"showSystemArtifacts\"\n (click)=\"toggleSystemArtifacts()\"\n title=\"Toggle system artifacts visibility\">\n <i class=\"fas fa-cog\"></i>\n <span>{{ showSystemArtifacts ? 'Hide' : 'Show' }} System</span>\n </button>\n }\n <button class=\"modal-close-btn\" (click)=\"showArtifactsModal = false\">\n <i class=\"fas fa-times\"></i>\n </button>\n </div>\n </div>\n <div class=\"modal-body artifacts-grid\">\n @if (artifactsByDetailId.size === 0) {\n <mj-empty-state\n class=\"artifacts-empty-fill\"\n Icon=\"fa-solid fa-cube\"\n Title=\"No artifacts in this conversation yet\" />\n }\n @for (artifact of getArtifactsArray(); track artifact.artifactId) {\n <div class=\"artifact-modal-card\"\n [class.expanded]=\"expandedArtifactId === artifact.artifactId\"\n [class.system-artifact]=\"artifact.visibility === 'System Only'\">\n <!-- Main card header - click to open latest version -->\n <div class=\"artifact-card-header\" (click)=\"openArtifactFromModal(artifact.artifactId)\">\n <div class=\"artifact-modal-icon\">\n <i class=\"fas fa-file-code\"></i>\n </div>\n <div class=\"artifact-modal-info\">\n <div class=\"artifact-modal-title\">{{artifact.name}}</div>\n <div class=\"artifact-modal-meta\">\n @if (artifact.versionCount > 1) {\n {{artifact.versionCount}} versions\n } @else {\n 1 version\n }\n </div>\n </div>\n @if (artifact.versionCount > 1) {\n <button class=\"expand-btn\" (click)=\"toggleArtifactExpansion(artifact.artifactId, $event)\">\n <i class=\"fas\" [class.fa-chevron-down]=\"expandedArtifactId !== artifact.artifactId\"\n [class.fa-chevron-up]=\"expandedArtifactId === artifact.artifactId\"></i>\n </button>\n }\n <div class=\"artifact-modal-action\">\n <i class=\"fas fa-external-link-alt\"></i>\n </div>\n </div>\n\n <!-- Expanded version list -->\n @if (expandedArtifactId === artifact.artifactId && artifact.versionCount > 1) {\n <div class=\"artifact-versions-list\">\n @for (version of artifact.versions; track version.versionId) {\n <div class=\"artifact-version-item\" (click)=\"openArtifactFromModal(artifact.artifactId, version.versionNumber); $event.stopPropagation()\">\n <span class=\"version-badge\">v{{version.versionNumber}}</span>\n <span class=\"version-open-text\">Open this version</span>\n <i class=\"fas fa-arrow-right\"></i>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n </div>\n </div>\n}\n\n<!-- Collection Picker Modal -->\n@if (showCollectionPicker) {\n <mj-artifact-collection-picker-modal\n [isOpen]=\"showCollectionPicker\"\n [environmentId]=\"environmentId\"\n [currentUser]=\"currentUser\"\n [excludeCollectionIds]=\"collectionPickerExcludedIds\"\n [artifactVersionId]=\"collectionPickerVersionId\"\n [artifactName]=\"collectionPickerArtifactName\"\n [artifactVersionNumber]=\"collectionPickerVersionNumber\"\n (completed)=\"onCollectionPickerCompleted($event)\"\n (cancelled)=\"onCollectionPickerCancelled()\">\n </mj-artifact-collection-picker-modal>\n}\n\n<!-- Test Feedback Dialog -->\n@if (testFeedbackDialogData) {\n <mj-test-feedback-dialog\n [data]=\"testFeedbackDialogData\"\n [visible]=\"showTestFeedbackDialog\"\n (closed)=\"onTestFeedbackDialogClosed($event)\">\n </mj-test-feedback-dialog>\n}\n\n<!-- Image Viewer Modal -->\n@if (showImageViewer) {\n <mj-image-viewer\n [imageUrl]=\"selectedImageUrl\"\n [alt]=\"selectedImageAlt\"\n [fileName]=\"selectedImageFileName\"\n [visible]=\"showImageViewer\"\n (closed)=\"onImageViewerClosed()\">\n </mj-image-viewer>\n}\n", styles: [":host {\n display: flex;\n width: 100%;\n height: 100%;\n}\n\n.chat-area {\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n overflow: hidden;\n /* Positioned context for the in-place realtime \"call mode\" overlay (absolute inset:0) */\n position: relative;\n}\n\n.chat-header {\n flex-shrink: 0;\n padding: 12px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n display: flex;\n justify-content: space-between;\n align-items: center;\n gap: 16px;\n background: var(--mj-bg-surface-card);\n z-index: 10;\n box-shadow: var(--mj-shadow-sm);\n}\n\n/* agentPresence slot \u2014 sticky top, anchored with the header. Per Matt's\n 06-10 placement design: persistent presence indicator above the messages.\n Renders only when [showAgentCharacter] is true, so existing embeds see no\n layout change. The prominent variant grows toward a centered presence\n (per Matt: \"can grow larger toward a centered presence\"). */\n.chat-agent-presence {\n flex-shrink: 0;\n padding: 8px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-card);\n display: flex;\n align-items: center;\n z-index: 11;\n}\n\n.chat-agent-presence--prominent {\n padding: 16px 20px;\n justify-content: center;\n}\n\n.chat-info {\n display: flex;\n align-items: center;\n gap: 12px;\n flex: 1;\n min-width: 0;\n}\n\n/* Sidebar toggle button in header */\n.sidebar-toggle-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n background: transparent;\n border: none;\n border-radius: 6px;\n cursor: pointer;\n transition: all 0.15s ease;\n flex-shrink: 0;\n}\n\n.sidebar-toggle-btn:hover {\n background: color-mix(in srgb, var(--mj-text-primary) 8%, transparent);\n}\n\n.sidebar-toggle-btn:active {\n background: color-mix(in srgb, var(--mj-text-primary) 12%, transparent);\n}\n\n.sidebar-toggle-btn i {\n color: var(--mj-text-secondary);\n font-size: 18px;\n transition: color 0.15s ease;\n}\n\n.sidebar-toggle-btn:hover i {\n color: var(--mj-text-primary);\n}\n\n/* Header title: the conversation name in Main; in a fork, the path ending in the open fork */\n.chat-title-bar {\n display: flex;\n align-items: center;\n gap: var(--mj-space-1);\n flex: 0 1 auto;\n min-width: 0;\n}\n\n.chat-title {\n flex: 0 1 auto;\n min-width: 0;\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.chat-title-path {\n min-width: 0;\n}\n\n.chat-title-crumbs {\n display: flex;\n align-items: center;\n gap: var(--mj-space-1);\n min-width: 0;\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n/* Parent crumbs shrink first, down to 80px each; the current entry keeps 120px before it truncates */\n.chat-title-crumb {\n display: flex;\n flex: 0 100 auto;\n align-items: center;\n gap: var(--mj-space-1);\n min-width: 80px;\n}\n\n.chat-title-crumb.chat-title-ellipsis {\n flex: 0 0 auto;\n min-width: 0;\n}\n\n.chat-title-crumb > button {\n min-width: 0;\n color: var(--mj-text-muted);\n font-size: var(--mj-text-sm);\n font-weight: 500;\n}\n\n.chat-title-crumb-label {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n/* Past three entries the crumbs between the first and the parent collapse into the ellipsis */\n.chat-title-crumb.collapsed-wide,\n.chat-title-ellipsis:not(.collapses-wide) {\n display: none;\n}\n\n.chat-title-sep {\n flex-shrink: 0;\n font-size: 12px;\n color: var(--mj-border-strong);\n}\n\n.chat-title-current {\n display: flex;\n flex: 0 1 auto;\n align-items: center;\n gap: var(--mj-space-1);\n min-width: 120px;\n}\n\n.chat-title-kind {\n flex-shrink: 0;\n margin: 0 var(--mj-space-1);\n color: var(--mj-status-info);\n}\n\n.chat-title-kind[data-kind='Edit'] {\n color: var(--mj-status-warning);\n}\n\n.chat-title-kind[data-kind='Regenerate'] {\n color: var(--mj-brand-tertiary);\n}\n\n.chat-title-bar .chat-title-rename {\n flex-shrink: 0;\n color: var(--mj-text-muted);\n opacity: 0.6;\n transition: opacity 0.15s ease, color 0.15s ease;\n}\n\n.chat-title-bar:hover .chat-title-rename,\n.chat-title-bar .chat-title-rename:focus-visible {\n color: var(--mj-text-primary);\n opacity: 1;\n}\n\n.chat-title-input {\n flex: 0 1 360px;\n min-width: 120px;\n padding: var(--mj-space-1) var(--mj-space-2);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font: inherit;\n font-size: 16px;\n font-weight: 600;\n}\n\n.chat-title-input:focus-visible {\n outline: none;\n border-color: var(--mj-brand-primary);\n box-shadow: var(--mj-focus-ring);\n}\n\n.with-chip {\n display: inline-flex;\n align-items: center;\n gap: var(--mj-space-1-5);\n padding: 2px var(--mj-space-2);\n border-radius: var(--mj-radius-full);\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-subtle);\n color: var(--mj-text-secondary);\n font-size: var(--mj-text-xs);\n line-height: var(--mj-leading-tight);\n flex-shrink: 0;\n}\n\n.with-chip .dot {\n width: 6px;\n height: 6px;\n border-radius: var(--mj-radius-full);\n background: var(--agent-accent, var(--mj-brand-primary));\n transition: background-color 240ms cubic-bezier(0.22, 1, 0.36, 1);\n flex-shrink: 0;\n}\n\n.with-chip b {\n color: var(--mj-text-primary);\n font-weight: var(--mj-font-semibold);\n}\n\n@media (prefers-reduced-motion: reduce) {\n .with-chip .dot {\n transition: none;\n }\n}\n\n.shared-by-badge {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 3px 10px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n color: var(--mj-brand-primary);\n border-radius: 999px;\n font-size: 12px;\n font-weight: 500;\n flex-shrink: 0;\n max-width: 240px;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.shared-by-badge i {\n font-size: 10px;\n}\n\n.shared-by-badge span {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.project-tag {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n border-radius: 16px;\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-text-muted);\n cursor: pointer;\n transition: all 0.2s;\n height: 28px;\n margin-left: 12px;\n}\n\n.project-tag:hover {\n background: var(--mj-border-default);\n border-color: var(--mj-text-muted);\n}\n\n.project-tag i {\n font-size: 10px;\n}\n\n.test-indicator {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n background: color-mix(in srgb, var(--mj-status-warning) 10%, var(--mj-bg-surface));\n border: 1px solid var(--mj-status-warning);\n border-radius: 16px;\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-status-warning);\n cursor: pointer;\n transition: all 0.2s;\n height: 28px;\n margin-left: 8px;\n}\n\n.test-indicator:hover {\n background: color-mix(in srgb, var(--mj-status-warning) 20%, var(--mj-bg-surface));\n border-color: var(--mj-status-warning);\n}\n\n.test-indicator i {\n font-size: 10px;\n}\n\n/* Pinned messages chip in chat header */\n.pin-chip {\n display: flex;\n align-items: center;\n gap: 5px;\n padding: 5px 10px;\n background: color-mix(in srgb, var(--mj-status-warning) 12%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-status-warning) 45%, transparent);\n border-radius: 20px;\n color: var(--mj-status-warning-text, var(--mj-status-warning));\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s;\n}\n\n.pin-chip i {\n font-size: 11px;\n}\n\n.pin-chip:hover,\n.pin-chip.active {\n background: color-mix(in srgb, var(--mj-status-warning) 20%, var(--mj-bg-surface));\n border-color: var(--mj-status-warning);\n}\n\n.pin-chip-count {\n font-size: 12px;\n font-weight: 700;\n}\n\n.chat-members,\n.artifact-indicator {\n display: flex;\n align-items: center;\n justify-content: center;\n position: relative;\n padding: 6px 8px;\n background: transparent;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n font-size: 14px;\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: all 150ms ease;\n}\n\n.chat-members:hover,\n.artifact-indicator:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n}\n\n/* Badge overlay for artifact and member counts */\n.artifact-badge,\n.members-badge {\n position: absolute;\n top: -6px;\n right: -6px;\n min-width: 16px;\n height: 16px;\n padding: 0 4px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n font-size: 10px;\n font-weight: 600;\n border-radius: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n line-height: 1;\n}\n\n.members-badge {\n background: var(--mj-brand-primary);\n}\n\n.ambient-agent-indicator {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n font-size: 13px;\n color: var(--mj-text-secondary);\n animation: pulse 2s ease-in-out infinite;\n}\n\n.ambient-agent-indicator i {\n color: var(--mj-brand-primary);\n}\n\n@keyframes pulse {\n 0%, 100% {\n opacity: 1;\n }\n 50% {\n opacity: 0.7;\n }\n}\n.chat-actions {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.action-btn {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 12px;\n background: transparent;\n border: 1px solid var(--mj-border-default);\n cursor: pointer;\n border-radius: 6px;\n font-size: 13px;\n color: var(--mj-text-secondary);\n transition: all 150ms ease;\n}\n\n.action-btn:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n}\n\n.share-btn.shared {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-color: var(--mj-brand-primary-hover);\n color: var(--mj-brand-primary-hover);\n}\n\n.share-btn.shared:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary-hover);\n}\n\n.chat-content-area {\n flex: 1;\n min-height: 0;\n overflow: hidden;\n display: flex;\n flex-direction: row;\n position: relative;\n}\n\n.chat-messages-pane {\n height: 100%;\n display: flex;\n flex-direction: column;\n min-width: min(300px, 100%); /* Respect container bounds while maintaining minimum */\n overflow: hidden;\n transition: width 0.3s ease;\n}\n\n.chat-messages-pane.full-width {\n width: 100%;\n}\n\n.chat-messages-pane:not(.full-width) {\n flex: 1;\n}\n\n.chat-messages-pane.hidden {\n display: none;\n}\n\n.resize-handle {\n width: 4px;\n background: transparent;\n cursor: col-resize;\n flex-shrink: 0;\n position: relative;\n transition: background-color 0.2s;\n}\n\n.resize-handle:hover {\n background: var(--mj-brand-primary);\n}\n\n.resize-handle::before {\n content: \"\";\n position: absolute;\n left: -4px;\n right: -4px;\n top: 0;\n bottom: 0;\n}\n\n.chat-artifact-pane {\n height: 100%;\n display: flex;\n flex-direction: column;\n background: var(--mj-bg-surface-sunken);\n overflow: hidden;\n flex-shrink: 0;\n}\n\n.chat-artifact-pane.maximized {\n width: 100% !important;\n}\n\n.chat-artifact-pane > mj-artifact-viewer-panel {\n display: flex;\n flex: 1;\n min-height: 0;\n overflow: hidden;\n}\n\n.chat-task-graph-pane {\n background: var(--mj-bg-surface);\n border-left: 1px solid var(--mj-border-default);\n}\n\n.task-graph-pane-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n padding: 12px 16px;\n background: var(--mj-bg-surface-card);\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n\n.task-graph-pane-title-group {\n display: flex;\n align-items: center;\n gap: 10px;\n min-width: 0;\n}\n\n.task-graph-pane-icon {\n width: 32px;\n height: 32px;\n border-radius: 8px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, transparent);\n color: var(--mj-brand-primary);\n font-size: 14px;\n flex-shrink: 0;\n}\n\n.task-graph-pane-titles {\n display: flex;\n flex-direction: column;\n gap: 1px;\n min-width: 0;\n}\n\n.task-graph-pane-title {\n font-size: 13.5px;\n font-weight: 600;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.task-graph-pane-subtitle {\n font-size: 11px;\n color: var(--mj-text-muted);\n}\n\n.task-graph-pane-actions {\n display: flex;\n align-items: center;\n gap: 6px;\n flex-shrink: 0;\n}\n\n.task-graph-pane-save-btn {\n height: 30px;\n padding: 0 10px;\n border-radius: 6px;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n font-weight: 500;\n border: 1px solid var(--mj-brand-primary);\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse, #ffffff);\n cursor: pointer;\n transition: opacity 0.15s ease, filter 0.15s ease;\n}\n\n.task-graph-pane-save-btn:hover:not(:disabled) {\n filter: brightness(1.06);\n}\n\n.task-graph-pane-save-btn:disabled {\n opacity: 0.55;\n cursor: not-allowed;\n}\n\n.task-graph-pane-btn {\n width: 30px;\n height: 30px;\n border-radius: 6px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border: 1px solid var(--mj-border-subtle);\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease;\n}\n\n.task-graph-pane-btn:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n border-color: var(--mj-border-default);\n}\n\n.task-graph-pane-body {\n flex: 1;\n width: 100%;\n min-height: 0;\n min-width: 0;\n padding: 12px 16px 16px;\n box-sizing: border-box;\n overflow: hidden;\n display: flex;\n flex-direction: column;\n}\n\n.task-graph-pane-body > mj-task-graph-run-view {\n display: flex;\n flex-direction: column;\n flex: 1;\n width: 100%;\n min-height: 0;\n min-width: 0;\n overflow: hidden;\n}\n\n.chat-messages-wrapper {\n flex: 1;\n display: flex;\n flex-direction: column;\n min-height: 0;\n overflow: hidden;\n position: relative; /* For upload overlay positioning */\n}\n\n/* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n demonstrationSurface layout-mode (Matt's 06-10 placement design)\n \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n When .chat-content-area gets .demonstration-mode, the layout flips\n from \"messages pane (+ optional artifact pane)\" to \"stage + side rail\":\n - stage (.chat-demonstration-stage) \u2014 left, flexible, holds the\n consumer's projected demonstrationSurface slot template\n - rail (.chat-messages-pane) \u2014 right, fixed-width 320px, holds the\n messages list + composer (\"the conversation as a companion rail\")\n On mobile (\u2264768px) the same two stack vertically (stage above, rail\n below) per Matt's note about mobile. The rail intentionally keeps the\n composer inside it \u2014 Matt's design refers to the conversation rail\n inclusively (messages + composer together), not as separate regions.\n*/\n.chat-demonstration-stage {\n height: 100%;\n display: flex;\n flex-direction: column;\n overflow: auto;\n background: var(--mj-bg-surface);\n border-right: 1px solid var(--mj-border-default);\n flex: 1;\n min-width: 0;\n}\n\n.chat-content-area.demonstration-mode .chat-messages-pane,\n.chat-content-area.demonstration-mode .chat-messages-pane.full-width {\n flex: 0 0 320px;\n width: 320px;\n min-width: 0;\n}\n\n@media (max-width: 768px) {\n .chat-content-area.demonstration-mode {\n flex-direction: column;\n }\n\n .chat-content-area.demonstration-mode .chat-demonstration-stage {\n flex: 1 1 60%;\n border-right: none;\n border-bottom: 1px solid var(--mj-border-default);\n height: auto;\n }\n\n .chat-content-area.demonstration-mode .chat-messages-pane,\n .chat-content-area.demonstration-mode .chat-messages-pane.full-width {\n flex: 1 1 40%;\n width: 100%;\n height: auto;\n }\n}\n\n/* Upload indicator overlay - centered in conversation area */\n.upload-indicator-overlay {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 1rem 1.5rem;\n background: color-mix(in srgb, var(--mj-bg-surface-card) 95%, transparent);\n border-radius: 12px;\n box-shadow: var(--mj-shadow-md);\n z-index: 100;\n pointer-events: none;\n}\n\n.chat-messages-container {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n background: var(--mj-bg-surface-card);\n min-height: 0;\n position: relative;\n}\n\n.scroll-to-bottom-icon {\n position: sticky;\n bottom: 21px;\n left: 50%;\n transform: translateX(-50%);\n width: 40px;\n height: 40px;\n margin-top: -40px;\n margin-left: auto;\n margin-right: auto;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n box-shadow: var(--mj-shadow-md);\n transition: all 0.2s ease;\n z-index: 100;\n pointer-events: auto;\n}\n\n.scroll-to-bottom-icon:hover {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-brand-primary);\n transform: translateX(-50%) translateY(-2px);\n box-shadow: color-mix(in srgb, var(--mj-brand-primary) 20%, transparent) 0 4px 12px;\n}\n\n.scroll-to-bottom-icon i {\n color: var(--mj-text-secondary);\n font-size: 16px;\n transition: color 0.2s;\n}\n\n.scroll-to-bottom-icon:hover i {\n color: var(--mj-brand-primary);\n}\n\n.chat-input-container {\n flex-shrink: 0;\n background: var(--mj-bg-surface-card);\n padding: 0 1.25rem 1.25rem 1.25rem;\n overflow: visible;\n}\n\n/* composerExtra slot: host UI directly above the composer. Spacing only; the host styles its content. */\n.chat-composer-extra {\n margin-bottom: 0.5rem;\n}\n\n.read-only-banner {\n display: flex;\n align-items: center;\n gap: 8px;\n margin: 0 1.25rem 0.5rem 1.25rem;\n padding: 8px 12px;\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, transparent);\n color: var(--mj-text-secondary);\n border-radius: 6px;\n font-size: 12px;\n}\n\n.read-only-banner i {\n color: var(--mj-brand-primary);\n font-size: 12px;\n}\n\n.loading-peripheral-placeholder {\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: 140px;\n padding: 24px;\n background: color-mix(in srgb, var(--mj-bg-surface-card) 50%, transparent);\n backdrop-filter: blur(2px);\n border-radius: 12px;\n margin: 12px;\n animation: fadeIn 0.2s ease-in-out;\n}\n\n.modal-overlay {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: var(--mj-bg-overlay);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n}\n\n.modal-content {\n background: var(--mj-bg-surface-card);\n border-radius: 8px;\n box-shadow: var(--mj-shadow-md);\n max-width: 90vw;\n max-height: 90vh;\n display: flex;\n flex-direction: column;\n}\n\n.project-selector-modal {\n width: 600px;\n height: 500px;\n}\n\n.modal-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.modal-header h3 {\n margin: 0;\n font-size: 18px;\n font-weight: 600;\n}\n\n.modal-header-actions {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.toggle-system-btn {\n display: flex;\n align-items: center;\n gap: 6px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n cursor: pointer;\n color: var(--mj-text-secondary);\n padding: 6px 12px;\n border-radius: 6px;\n font-size: 13px;\n font-weight: 500;\n transition: all 0.2s;\n}\n\n.toggle-system-btn:hover {\n background: var(--mj-border-default);\n border-color: var(--mj-border-default);\n color: var(--mj-text-primary);\n}\n\n.toggle-system-btn.active {\n background: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.toggle-system-btn.active:hover {\n background: var(--mj-brand-primary-hover);\n border-color: var(--mj-brand-primary-hover);\n}\n\n.toggle-system-btn i {\n font-size: 12px;\n}\n\n.modal-close-btn {\n background: none;\n border: none;\n cursor: pointer;\n color: var(--mj-text-secondary);\n padding: 4px 8px;\n border-radius: 4px;\n transition: all 0.2s;\n}\n\n.modal-close-btn:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n}\n\n.modal-body {\n flex: 1;\n overflow: auto;\n padding: 20px;\n}\n\n.artifacts-modal {\n width: 700px;\n max-height: 600px;\n}\n\n.artifacts-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));\n gap: 16px;\n}\n\n/* Empty-state spans the full artifacts grid */\n.artifacts-empty-fill {\n grid-column: 1/-1;\n}\n\n.artifact-modal-card {\n display: flex;\n flex-direction: column;\n background: var(--mj-bg-surface-card);\n border: 1.5px solid var(--mj-border-default);\n border-radius: 12px;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n overflow: hidden;\n}\n\n.artifact-modal-card.expanded {\n border-color: var(--mj-brand-primary);\n}\n\n.artifact-modal-card.system-artifact {\n opacity: 0.85;\n border-color: var(--mj-border-default);\n border-style: dashed;\n position: relative;\n}\n\n.artifact-modal-card.system-artifact::before {\n content: \"SYSTEM\";\n position: absolute;\n top: 8px;\n right: 8px;\n font-size: 9px;\n font-weight: 600;\n color: var(--mj-text-muted);\n background: var(--mj-bg-surface-sunken);\n padding: 2px 6px;\n border-radius: 3px;\n letter-spacing: 0.5px;\n z-index: 10;\n}\n\n.artifact-modal-card.system-artifact:hover {\n border-color: var(--mj-text-muted);\n box-shadow: var(--mj-shadow-md);\n}\n\n.artifact-card-header {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 16px;\n cursor: pointer;\n}\n\n.artifact-card-header:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.artifact-modal-card:hover {\n border-color: var(--mj-brand-primary);\n box-shadow: var(--mj-shadow-md);\n transform: translateY(-2px);\n}\n\n.artifact-modal-icon {\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-radius: 10px;\n color: var(--mj-brand-primary);\n flex-shrink: 0;\n}\n\n.artifact-modal-icon i {\n font-size: 18px;\n}\n\n.artifact-modal-info {\n flex: 1;\n min-width: 0;\n}\n\n.artifact-modal-title {\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin-bottom: 4px;\n}\n\n.artifact-modal-meta {\n font-size: 12px;\n color: var(--mj-text-secondary);\n}\n\n.artifact-modal-action {\n color: var(--mj-text-muted);\n transition: color 0.2s;\n}\n\n.artifact-modal-card:hover .artifact-modal-action {\n color: var(--mj-brand-primary);\n}\n\n.expand-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n border: none;\n background: transparent;\n color: var(--mj-text-secondary);\n cursor: pointer;\n border-radius: 6px;\n transition: all 0.2s;\n}\n.expand-btn:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-brand-primary);\n}\n\n.artifact-versions-list {\n display: flex;\n flex-direction: column;\n padding: 0 1rem 1rem 1rem;\n background: var(--mj-bg-surface-sunken);\n}\n\n.artifact-version-item {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 16px 12px 68px;\n cursor: pointer;\n transition: background 0.15s;\n}\n.artifact-version-item:hover {\n background: var(--mj-bg-surface-sunken);\n}\n.artifact-version-item .version-badge {\n display: inline-block;\n padding: 4px 8px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n font-size: 12px;\n font-weight: 600;\n font-family: monospace;\n border-radius: 4px;\n}\n.artifact-version-item .version-open-text {\n flex: 1;\n font-size: 13px;\n color: var(--mj-text-secondary);\n}\n.artifact-version-item i {\n color: var(--mj-text-muted);\n font-size: 12px;\n}\n.artifact-version-item:hover .version-badge {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n.artifact-version-item:hover .version-open-text {\n color: var(--mj-brand-primary);\n}\n.artifact-version-item:hover i {\n color: var(--mj-brand-primary);\n}\n\n.loading-peripheral-content {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 16px 24px;\n background: var(--mj-bg-surface-card);\n border: 2px solid var(--mj-border-default);\n border-radius: 12px;\n box-shadow: var(--mj-shadow-md);\n color: var(--mj-text-secondary);\n font-size: 14px;\n font-weight: 500;\n}\n.loading-peripheral-content i {\n font-size: 20px;\n color: var(--mj-brand-primary);\n}\n\n@keyframes fadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n.conversation-loading-state {\n display: flex;\n align-items: center;\n justify-content: center;\n height: 100%;\n width: 100%;\n}\n\n.loading-content {\n display: flex;\n flex-direction: column;\n align-items: center;\n padding-top: 20px;\n gap: 16px;\n color: var(--mj-text-secondary);\n font-size: 15px;\n}\n.loading-content i {\n font-size: 32px;\n color: var(--mj-brand-primary);\n}\n.loading-content span {\n font-weight: 500;\n}\n\n/* Mobile adjustments: 481px - 768px */\n@media (max-width: 768px) {\n .chat-header {\n padding: 8px 12px;\n gap: 6px;\n flex-direction: row;\n flex-wrap: wrap;\n align-items: center;\n position: relative;\n }\n .chat-info {\n flex-direction: row;\n align-items: center;\n gap: 8px;\n flex: 1;\n min-width: 0;\n order: 1;\n }\n .chat-title-bar {\n flex: 1;\n }\n .chat-title {\n font-size: 15px;\n font-weight: 700;\n }\n /* The path keeps the first crumb and the current entry; every middle crumb collapses into the ellipsis */\n .chat-title-crumb.path-middle {\n display: none;\n }\n .chat-title-ellipsis:not(.collapses-wide) {\n display: flex;\n }\n .project-tag {\n margin-left: 0;\n font-size: 10px;\n padding: 3px 8px;\n height: 24px;\n display: none; /* Hide on mobile to save space */\n }\n .test-indicator {\n margin-left: 0;\n font-size: 10px;\n padding: 3px 8px;\n height: 24px;\n }\n /* Action buttons - icon only on mobile */\n .chat-actions-buttons {\n order: 2;\n flex-shrink: 0;\n }\n .chat-actions-buttons .action-btn {\n padding: 6px 8px;\n min-width: auto;\n }\n .chat-actions-buttons .action-btn .btn-label {\n display: none;\n }\n .chat-actions {\n flex-wrap: nowrap;\n }\n .chat-members,\n .artifact-indicator {\n padding: 5px 7px;\n font-size: 13px;\n }\n .action-btn {\n padding: 6px 8px;\n font-size: 12px;\n }\n .ambient-agent-indicator {\n font-size: 12px;\n padding: 4px 8px;\n }\n .project-selector-modal {\n width: min(95vw, 600px);\n height: auto;\n }\n .artifacts-modal {\n width: min(95vw, 700px);\n }\n .artifacts-grid {\n grid-template-columns: 1fr;\n }\n .chat-input-container {\n padding: 0 0.75rem 0.75rem 0.75rem;\n }\n .scroll-to-bottom-icon {\n bottom: 16px;\n width: 36px;\n height: 36px;\n }\n /* Artifact pane - full width overlay on mobile, overlapping header */\n .chat-content-area {\n position: relative;\n }\n .chat-artifact-pane {\n position: fixed;\n left: 0;\n right: 0;\n top: 56px; /* 48px nav + 8px dark strip above blue border */\n bottom: 0;\n width: 100% !important;\n z-index: 100;\n background: var(--mj-bg-surface-card);\n }\n .resize-handle {\n display: none;\n }\n}\n/* Small Phone adjustments: <= 480px */\n@media (max-width: 480px) {\n .chat-header {\n padding: 6px 8px;\n gap: 4px;\n }\n .chat-title {\n font-size: 14px;\n font-weight: 700;\n }\n .project-tag {\n font-size: 9px;\n padding: 2px 6px;\n height: 20px;\n display: none;\n }\n .test-indicator {\n font-size: 9px;\n padding: 2px 6px;\n height: 20px;\n }\n .chat-members,\n .artifact-indicator {\n padding: 4px 8px;\n font-size: 11px;\n }\n .action-btn {\n padding: 5px 7px;\n font-size: 11px;\n }\n .ambient-agent-indicator {\n font-size: 11px;\n padding: 3px 6px;\n }\n .project-selector-modal,\n .artifacts-modal {\n width: 100vw;\n height: 100vh;\n border-radius: 0;\n }\n .chat-input-container {\n padding: 0 0.5rem 0.5rem 0.5rem;\n }\n .scroll-to-bottom-icon {\n bottom: 12px;\n width: 32px;\n height: 32px;\n }\n .scroll-to-bottom-icon i {\n font-size: 14px;\n }\n}\n\n/* Artifact Picker Panel */\n.artifact-picker-overlay {\n position: fixed;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background: var(--mj-bg-overlay);\n z-index: 999;\n}\n\n.artifact-picker-panel {\n position: fixed;\n right: 0;\n top: 0;\n width: 360px;\n height: 100%;\n background: var(--mj-bg-surface);\n border-left: 1px solid var(--mj-border-default);\n z-index: 1000;\n display: flex;\n flex-direction: column;\n box-shadow: -4px 0 12px rgba(0, 0, 0, 0.1);\n animation: slideInRight 0.2s ease-out;\n}\n\n@keyframes slideInRight {\n from { transform: translateX(100%); }\n to { transform: translateX(0); }\n}\n\n.artifact-picker-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.artifact-picker-header h3 {\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.artifact-picker-close {\n background: none;\n border: none;\n cursor: pointer;\n padding: 4px 8px;\n color: var(--mj-text-muted);\n border-radius: 4px;\n}\n\n.artifact-picker-close:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n\n.artifact-picker-body {\n flex: 1;\n overflow-y: auto;\n padding: 12px;\n}\n\n.artifact-picker-empty {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 40px 20px;\n text-align: center;\n color: var(--mj-text-muted);\n gap: 8px;\n}\n\n.artifact-picker-hint {\n font-size: 12px;\n color: var(--mj-text-disabled);\n}\n\n.artifact-picker-list {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.artifact-picker-item {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 10px 12px;\n border: 1px solid var(--mj-border-subtle);\n border-radius: 6px;\n background: var(--mj-bg-surface-card);\n cursor: pointer;\n text-align: left;\n width: 100%;\n transition: background 0.15s, border-color 0.15s;\n}\n\n.artifact-picker-item:hover {\n background: var(--mj-bg-surface-hover);\n border-color: var(--mj-brand-primary);\n}\n\n.artifact-picker-item i {\n font-size: 20px;\n width: 24px;\n text-align: center;\n flex-shrink: 0;\n}\n\n.artifact-picker-item i.fa-file-pdf { color: var(--mj-status-error); }\n.artifact-picker-item i.fa-file-excel { color: var(--mj-status-success); }\n.artifact-picker-item i.fa-file-word { color: var(--mj-brand-primary); }\n.artifact-picker-item i.fa-file { color: var(--mj-text-muted); }\n\n.artifact-picker-item-info {\n display: flex;\n flex-direction: column;\n min-width: 0;\n}\n\n.artifact-picker-item-name {\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.artifact-picker-item-meta {\n font-size: 11px;\n color: var(--mj-text-muted);\n}\n\n/* ---------- Floating \"on call\" pill (minimized realtime voice session) ----------\n Shown bottom-right of the chat panel while the live call overlay is minimized\n (e.g. after a gear-gated dev link navigated to a record). The mic + session stay\n live; tapping the pill restores the full call overlay. */\n.voice-call-pill {\n position: absolute;\n right: 18px;\n bottom: 18px;\n z-index: 49; /* just under the full call overlay (z-index 50) */\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 9px 16px 9px 13px;\n border-radius: var(--mj-radius-full, 9999px);\n border: 1px solid var(--mj-border-strong);\n background: var(--mj-bg-surface-elevated, var(--mj-bg-surface));\n color: var(--mj-text-primary);\n font-family: inherit;\n cursor: pointer;\n box-shadow: 0 8px 24px color-mix(in srgb, var(--mj-brand-primary) 18%, transparent);\n transition: border-color 150ms ease, box-shadow 150ms ease, transform 150ms ease;\n}\n.voice-call-pill:hover {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 10px 28px color-mix(in srgb, var(--mj-brand-primary) 28%, transparent);\n transform: translateY(-1px);\n}\n.voice-call-pill i {\n font-size: 14px;\n color: var(--mj-brand-primary);\n}\n.voice-call-pill__pulse {\n width: 9px;\n height: 9px;\n border-radius: 50%;\n background: var(--mj-status-success);\n flex-shrink: 0;\n animation: voice-pill-pulse 1.6s ease-in-out infinite;\n}\n.voice-call-pill__text {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n line-height: 1.25;\n}\n.voice-call-pill__name {\n font-size: 12.5px;\n font-weight: 700;\n}\n.voice-call-pill__hint {\n font-size: 10.5px;\n color: var(--mj-text-muted);\n}\n@keyframes voice-pill-pulse {\n 0%, 100% {\n box-shadow: 0 0 0 0 color-mix(in srgb, var(--mj-status-success) 45%, transparent);\n }\n 50% {\n box-shadow: 0 0 0 5px color-mix(in srgb, var(--mj-status-success) 0%, transparent);\n }\n}\n\n/* The fork title above the transcript, shown only when a host header replaces the default one */\n.fork-view-bar {\n display: flex;\n align-items: center;\n padding: var(--mj-space-2) var(--mj-space-4);\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n}\n.fork-composer-hint {\n padding: var(--mj-space-1) var(--mj-space-4) 0;\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n}\n.chat-actions-buttons > .forks-button .forks-count {\n margin-left: var(--mj-space-1);\n padding: 0 var(--mj-space-2);\n border-radius: var(--mj-radius-full);\n background: var(--mj-brand-primary);\n color: var(--mj-brand-on-primary);\n font-size: var(--mj-text-xs);\n font-weight: 600;\n}\n.chat-actions-buttons > .forks-button.active {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n.chat-actions-buttons > .remote-browser-toggle-btn.active {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n.remote-browser-url-input {\n width: 220px;\n max-width: 38vw;\n height: 28px;\n padding: 0 10px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font-size: 12px;\n font-family: var(--mj-font-family-mono);\n}\n.remote-browser-url-input:focus {\n outline: none;\n border-color: var(--mj-border-focus);\n}\n"] }]
9337
10197
  }], () => [{ type: i1.AgentStateService }, { type: i2.ConversationLivenessDomService }, { type: i3.ConversationAgentService }, { type: i4.ActiveTasksService }, { type: i0.ChangeDetectorRef }, { type: i5.ArtifactPermissionService }, { type: i6.ConversationAttachmentService }, { type: i7.ConversationStreamingService }, { type: i8.DialogService }, { type: i9.ConversationBridgeService }, { type: i10.AnalyzeArtifactService }, { type: i11.UICommandHandlerService }, { type: i10.InteractiveFormApplyService }, { type: i12.AgentClientService }], { EnvironmentId: [{
9338
10198
  type: Input
9339
10199
  }], environmentId: [{
@@ -9384,6 +10244,8 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
9384
10244
  type: Input
9385
10245
  }], AllowForking: [{
9386
10246
  type: Input
10247
+ }], AllowRemoteBrowser: [{
10248
+ type: Input
9387
10249
  }], AllowStopRun: [{
9388
10250
  type: Input
9389
10251
  }], ShowEmptyFill: [{
@@ -9685,6 +10547,9 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
9685
10547
  }], chatSlotChildren: [{
9686
10548
  type: ContentChildren,
9687
10549
  args: [ChatSlotDirective]
10550
+ }], ConversationRemoteBrowserSurface: [{
10551
+ type: ViewChild,
10552
+ args: ['conversationRemoteBrowserSurface']
9688
10553
  }], messageListComponent: [{
9689
10554
  type: ViewChild,
9690
10555
  args: [MessageListComponent]
@@ -9697,6 +10562,10 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
9697
10562
  }], forksButton: [{
9698
10563
  type: ViewChild,
9699
10564
  args: ['forksButton', { read: ElementRef }]
10565
+ }], CollapseThreadReplies: [{
10566
+ type: Input
10567
+ }], ThreadReplyRevealRequested: [{
10568
+ type: Output
9700
10569
  }] }); })();
9701
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ConversationChatAreaComponent, { className: "ConversationChatAreaComponent", filePath: "src/lib/components/conversation/conversation-chat-area.component.ts", lineNumber: 201 }); })();
10570
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ConversationChatAreaComponent, { className: "ConversationChatAreaComponent", filePath: "src/lib/components/conversation/conversation-chat-area.component.ts", lineNumber: 217 }); })();
9702
10571
  //# sourceMappingURL=conversation-chat-area.component.js.map