@memberjunction/ng-conversations 6.2.0-edge.6 → 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.
- package/dist/lib/components/collection/collection-view.component.d.ts.map +1 -1
- package/dist/lib/components/collection/collection-view.component.js +1 -0
- package/dist/lib/components/collection/collection-view.component.js.map +1 -1
- package/dist/lib/components/conversation/conversation-chat-area.component.d.ts +174 -2
- package/dist/lib/components/conversation/conversation-chat-area.component.d.ts.map +1 -1
- package/dist/lib/components/conversation/conversation-chat-area.component.js +1266 -443
- package/dist/lib/components/conversation/conversation-chat-area.component.js.map +1 -1
- package/dist/lib/components/conversation/conversation-mode-picker.component.js +2 -2
- package/dist/lib/components/conversation/conversation-mode-picker.component.js.map +1 -1
- package/dist/lib/components/conversation/conversation-remote-browser-controller.d.ts +109 -0
- package/dist/lib/components/conversation/conversation-remote-browser-controller.d.ts.map +1 -0
- package/dist/lib/components/conversation/conversation-remote-browser-controller.js +298 -0
- package/dist/lib/components/conversation/conversation-remote-browser-controller.js.map +1 -0
- package/dist/lib/components/message/agent-handoff-card.component.d.ts +102 -0
- package/dist/lib/components/message/agent-handoff-card.component.d.ts.map +1 -0
- package/dist/lib/components/message/agent-handoff-card.component.js +439 -0
- package/dist/lib/components/message/agent-handoff-card.component.js.map +1 -0
- package/dist/lib/components/message/message-input.component.d.ts +80 -53
- package/dist/lib/components/message/message-input.component.d.ts.map +1 -1
- package/dist/lib/components/message/message-input.component.js +381 -277
- package/dist/lib/components/message/message-input.component.js.map +1 -1
- package/dist/lib/components/message/message-item.component.d.ts +18 -1
- package/dist/lib/components/message/message-item.component.d.ts.map +1 -1
- package/dist/lib/components/message/message-item.component.js +548 -426
- package/dist/lib/components/message/message-item.component.js.map +1 -1
- package/dist/lib/components/message/message-list.component.d.ts +8 -1
- package/dist/lib/components/message/message-list.component.d.ts.map +1 -1
- package/dist/lib/components/message/message-list.component.js +40 -2
- package/dist/lib/components/message/message-list.component.js.map +1 -1
- package/dist/lib/components/realtime/interactive-component/run-view-component-artifact-source.js +1 -1
- package/dist/lib/components/realtime/interactive-component/run-view-component-artifact-source.js.map +1 -1
- package/dist/lib/components/realtime/media/media-channel-state.d.ts +5 -0
- package/dist/lib/components/realtime/media/media-channel-state.d.ts.map +1 -1
- package/dist/lib/components/realtime/media/media-channel-state.js +27 -1
- package/dist/lib/components/realtime/media/media-channel-state.js.map +1 -1
- package/dist/lib/components/realtime/media/media-channel.d.ts.map +1 -1
- package/dist/lib/components/realtime/media/media-channel.js +7 -2
- package/dist/lib/components/realtime/media/media-channel.js.map +1 -1
- package/dist/lib/components/realtime/media/realtime-media-surface.component.d.ts +19 -2
- package/dist/lib/components/realtime/media/realtime-media-surface.component.d.ts.map +1 -1
- package/dist/lib/components/realtime/media/realtime-media-surface.component.js +59 -10
- package/dist/lib/components/realtime/media/realtime-media-surface.component.js.map +1 -1
- package/dist/lib/components/realtime/realtime-agent-banner.component.d.ts +17 -6
- package/dist/lib/components/realtime/realtime-agent-banner.component.d.ts.map +1 -1
- package/dist/lib/components/realtime/realtime-agent-banner.component.js +61 -27
- package/dist/lib/components/realtime/realtime-agent-banner.component.js.map +1 -1
- package/dist/lib/components/realtime/realtime-composer.component.d.ts +26 -3
- package/dist/lib/components/realtime/realtime-composer.component.d.ts.map +1 -1
- package/dist/lib/components/realtime/realtime-composer.component.js +196 -102
- package/dist/lib/components/realtime/realtime-composer.component.js.map +1 -1
- package/dist/lib/components/realtime/realtime-session-overlay.component.d.ts +53 -15
- package/dist/lib/components/realtime/realtime-session-overlay.component.d.ts.map +1 -1
- package/dist/lib/components/realtime/realtime-session-overlay.component.js +125 -51
- package/dist/lib/components/realtime/realtime-session-overlay.component.js.map +1 -1
- package/dist/lib/components/realtime/realtime-ui-config.d.ts +9 -12
- package/dist/lib/components/realtime/realtime-ui-config.d.ts.map +1 -1
- package/dist/lib/components/realtime/realtime-ui-config.js +38 -18
- package/dist/lib/components/realtime/realtime-ui-config.js.map +1 -1
- package/dist/lib/components/realtime/remote-browser/remote-browser-channel.d.ts.map +1 -1
- package/dist/lib/components/realtime/remote-browser/remote-browser-channel.js +27 -4
- package/dist/lib/components/realtime/remote-browser/remote-browser-channel.js.map +1 -1
- package/dist/lib/components/realtime/remote-browser/remote-browser-tools.d.ts +8 -2
- package/dist/lib/components/realtime/remote-browser/remote-browser-tools.d.ts.map +1 -1
- package/dist/lib/components/realtime/remote-browser/remote-browser-tools.js +51 -10
- package/dist/lib/components/realtime/remote-browser/remote-browser-tools.js.map +1 -1
- package/dist/lib/components/realtime/whiteboard/whiteboard-channel-config.d.ts +46 -0
- package/dist/lib/components/realtime/whiteboard/whiteboard-channel-config.d.ts.map +1 -0
- package/dist/lib/components/realtime/whiteboard/whiteboard-channel-config.js +64 -0
- package/dist/lib/components/realtime/whiteboard/whiteboard-channel-config.js.map +1 -0
- package/dist/lib/components/realtime/whiteboard/whiteboard-channel.d.ts +131 -9
- package/dist/lib/components/realtime/whiteboard/whiteboard-channel.d.ts.map +1 -1
- package/dist/lib/components/realtime/whiteboard/whiteboard-channel.js +347 -38
- package/dist/lib/components/realtime/whiteboard/whiteboard-channel.js.map +1 -1
- package/dist/lib/conversations.module.d.ts +2 -1
- package/dist/lib/conversations.module.d.ts.map +1 -1
- package/dist/lib/conversations.module.js +9 -4
- package/dist/lib/conversations.module.js.map +1 -1
- package/dist/lib/events/chat-events.d.ts +5 -4
- package/dist/lib/events/chat-events.d.ts.map +1 -1
- package/dist/lib/events/chat-events.js +2 -2
- package/dist/lib/events/chat-events.js.map +1 -1
- package/dist/lib/models/agent-turn.model.d.ts +11 -7
- package/dist/lib/models/agent-turn.model.d.ts.map +1 -1
- package/dist/lib/models/agent-turn.model.js.map +1 -1
- package/dist/lib/services/active-tasks.service.d.ts +5 -0
- package/dist/lib/services/active-tasks.service.d.ts.map +1 -1
- package/dist/lib/services/active-tasks.service.js +16 -0
- package/dist/lib/services/active-tasks.service.js.map +1 -1
- package/dist/lib/services/agent-state.service.d.ts.map +1 -1
- package/dist/lib/services/agent-state.service.js +7 -1
- package/dist/lib/services/agent-state.service.js.map +1 -1
- package/dist/lib/services/artifact-permission.service.d.ts.map +1 -1
- package/dist/lib/services/artifact-permission.service.js +2 -0
- package/dist/lib/services/artifact-permission.service.js.map +1 -1
- package/dist/lib/services/artifact-state.service.d.ts.map +1 -1
- package/dist/lib/services/artifact-state.service.js +1 -0
- package/dist/lib/services/artifact-state.service.js.map +1 -1
- package/dist/lib/services/collection-permission.service.d.ts.map +1 -1
- package/dist/lib/services/collection-permission.service.js +1 -0
- package/dist/lib/services/collection-permission.service.js.map +1 -1
- package/dist/lib/services/conversation-agent.service.d.ts +1 -4
- package/dist/lib/services/conversation-agent.service.d.ts.map +1 -1
- package/dist/lib/services/conversation-agent.service.js +7 -45
- package/dist/lib/services/conversation-agent.service.js.map +1 -1
- package/dist/lib/services/realtime-session-review.service.d.ts +2 -1
- package/dist/lib/services/realtime-session-review.service.d.ts.map +1 -1
- package/dist/lib/services/realtime-session-review.service.js.map +1 -1
- package/dist/lib/services/search.service.d.ts.map +1 -1
- package/dist/lib/services/search.service.js +1 -0
- package/dist/lib/services/search.service.js.map +1 -1
- package/dist/lib/utils/agent-handoff-map.d.ts +52 -0
- package/dist/lib/utils/agent-handoff-map.d.ts.map +1 -0
- package/dist/lib/utils/agent-handoff-map.js +270 -0
- package/dist/lib/utils/agent-handoff-map.js.map +1 -0
- package/dist/lib/utils/agent-turn-routing.d.ts +62 -7
- package/dist/lib/utils/agent-turn-routing.d.ts.map +1 -1
- package/dist/lib/utils/agent-turn-routing.js +147 -6
- package/dist/lib/utils/agent-turn-routing.js.map +1 -1
- package/dist/lib/utils/decision-routing.d.ts +17 -9
- package/dist/lib/utils/decision-routing.d.ts.map +1 -1
- package/dist/lib/utils/decision-routing.js +23 -14
- package/dist/lib/utils/decision-routing.js.map +1 -1
- package/dist/lib/utils/thread-replies.d.ts +34 -0
- package/dist/lib/utils/thread-replies.d.ts.map +1 -0
- package/dist/lib/utils/thread-replies.js +49 -0
- package/dist/lib/utils/thread-replies.js.map +1 -0
- package/dist/public-api.d.ts +5 -0
- package/dist/public-api.d.ts.map +1 -1
- package/dist/public-api.js +5 -0
- package/dist/public-api.js.map +1 -1
- 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';
|
|
@@ -29,10 +30,15 @@ import { MessageListComponent } from '../message/message-list.component';
|
|
|
29
30
|
import { IsForkPointOrEarlier } from '../../utils/conversation-branching';
|
|
30
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';
|
|
31
32
|
import { DecideArtifactPanelAction, SnapshotArtifactVersions } from '../../utils/artifact-panel-action';
|
|
32
|
-
import {
|
|
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';
|
|
33
38
|
// PR 2c — Widget extension surface
|
|
34
39
|
import { ChatSlotDirective } from '../../directives/chat-slot.directive';
|
|
35
40
|
import { ConversationCallStartOptions } from '../realtime/capture/realtime-capture-channel';
|
|
41
|
+
import { ConversationRemoteBrowserController } from './conversation-remote-browser-controller';
|
|
36
42
|
import { DescribeCallFailureNotice } from '../realtime/realtime-call-failure-notice';
|
|
37
43
|
import { BeforeToolInvokedEventArgs, AfterToolInvokedEventArgs, BeforeStopClickedEventArgs, AfterStopClickedEventArgs, SessionStartedEventArgs, SessionChannelStateChangedEventArgs, SessionEndedEventArgs, } from '../../events/chat-events';
|
|
38
44
|
import * as i0 from "@angular/core";
|
|
@@ -59,50 +65,52 @@ import * as i20 from "../collection/artifact-collection-picker-modal.component";
|
|
|
59
65
|
import * as i21 from "../artifact/artifact-share-modal.component";
|
|
60
66
|
import * as i22 from "../slots/mj-chat-agent-presence-default.component";
|
|
61
67
|
import * as i23 from "../realtime/realtime-session-overlay.component";
|
|
62
|
-
import * as i24 from "../
|
|
63
|
-
import * as i25 from "../message/message-
|
|
64
|
-
import * as i26 from "
|
|
65
|
-
import * as i27 from "./conversation-
|
|
66
|
-
import * as i28 from "./conversation-
|
|
67
|
-
import * as i29 from "
|
|
68
|
-
import * as i30 from "../
|
|
69
|
-
import * as i31 from "../
|
|
70
|
-
import * as i32 from "../
|
|
71
|
-
import * as i33 from "
|
|
72
|
-
import * as i34 from "./
|
|
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";
|
|
73
80
|
const _c0 = ["scrollContainer"];
|
|
74
|
-
const _c1 = ["
|
|
75
|
-
const _c2 = ["
|
|
76
|
-
const _c3 = ["
|
|
77
|
-
const _c4 = ["
|
|
78
|
-
const _c5 =
|
|
79
|
-
const _c6 = (a0, a1, a2, a3, a4) => ({ $implicit: a0,
|
|
80
|
-
const _c7 = (a0, a1, a2) => ({ $implicit: a0,
|
|
81
|
-
const _c8 = (a0, a1, a2) => ({ $implicit: a0,
|
|
82
|
-
const _c9 = () =>
|
|
83
|
-
const _c10 = (
|
|
84
|
-
const _c11 = (a0, a1, a2) => ({ $implicit: a0,
|
|
85
|
-
const
|
|
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); }
|
|
86
94
|
const _forTrack1 = ($index, $item) => $item.artifactId;
|
|
87
95
|
const _forTrack2 = ($index, $item) => $item.versionId;
|
|
88
96
|
function ConversationChatAreaComponent_Conditional_1_Conditional_1_ng_container_0_Template(rf, ctx) { if (rf & 1) {
|
|
89
97
|
i0.ɵɵelementContainer(0);
|
|
90
98
|
} }
|
|
91
99
|
function ConversationChatAreaComponent_Conditional_1_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
92
|
-
i0.ɵɵtemplate(0, ConversationChatAreaComponent_Conditional_1_Conditional_1_ng_container_0_Template, 1, 0, "ng-container",
|
|
100
|
+
i0.ɵɵtemplate(0, ConversationChatAreaComponent_Conditional_1_Conditional_1_ng_container_0_Template, 1, 0, "ng-container", 29);
|
|
93
101
|
} if (rf & 2) {
|
|
94
102
|
const ctx_r0 = i0.ɵɵnextContext(2);
|
|
95
|
-
i0.ɵɵproperty("ngTemplateOutlet", ctx)("ngTemplateOutletContext", i0.ɵɵpureFunction5(2,
|
|
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"));
|
|
96
104
|
} }
|
|
97
105
|
function ConversationChatAreaComponent_Conditional_1_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
98
|
-
i0.ɵɵelement(0, "mj-chat-agent-presence-default",
|
|
106
|
+
i0.ɵɵelement(0, "mj-chat-agent-presence-default", 28);
|
|
99
107
|
} if (rf & 2) {
|
|
100
108
|
const ctx_r0 = i0.ɵɵnextContext(2);
|
|
101
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");
|
|
102
110
|
} }
|
|
103
111
|
function ConversationChatAreaComponent_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
104
|
-
i0.ɵɵelementStart(0, "div",
|
|
105
|
-
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",
|
|
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);
|
|
106
114
|
i0.ɵɵelementEnd();
|
|
107
115
|
} if (rf & 2) {
|
|
108
116
|
let tmp_4_0;
|
|
@@ -115,31 +123,48 @@ function ConversationChatAreaComponent_Conditional_2_ng_container_0_Template(rf,
|
|
|
115
123
|
i0.ɵɵelementContainer(0);
|
|
116
124
|
} }
|
|
117
125
|
function ConversationChatAreaComponent_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
118
|
-
i0.ɵɵtemplate(0, ConversationChatAreaComponent_Conditional_2_ng_container_0_Template, 1, 0, "ng-container",
|
|
126
|
+
i0.ɵɵtemplate(0, ConversationChatAreaComponent_Conditional_2_ng_container_0_Template, 1, 0, "ng-container", 29);
|
|
119
127
|
} if (rf & 2) {
|
|
120
128
|
const ctx_r0 = i0.ɵɵnextContext();
|
|
121
|
-
i0.ɵɵproperty("ngTemplateOutlet", ctx)("ngTemplateOutletContext", i0.ɵɵpureFunction5(2,
|
|
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));
|
|
122
130
|
} }
|
|
123
131
|
function ConversationChatAreaComponent_Conditional_3_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
124
132
|
const _r3 = i0.ɵɵgetCurrentView();
|
|
125
|
-
i0.ɵɵelementStart(0, "button",
|
|
133
|
+
i0.ɵɵelementStart(0, "button", 46);
|
|
126
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()); });
|
|
127
|
-
i0.ɵɵelement(1, "i",
|
|
135
|
+
i0.ɵɵelement(1, "i", 47);
|
|
128
136
|
i0.ɵɵelementEnd();
|
|
129
137
|
} }
|
|
130
138
|
function ConversationChatAreaComponent_Conditional_3_Conditional_3_ng_container_0_Template(rf, ctx) { if (rf & 1) {
|
|
131
139
|
i0.ɵɵelementContainer(0);
|
|
132
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
|
+
} }
|
|
133
155
|
function ConversationChatAreaComponent_Conditional_3_Conditional_3_Template(rf, ctx) { if (rf & 1) {
|
|
134
|
-
i0.ɵɵtemplate(0, ConversationChatAreaComponent_Conditional_3_Conditional_3_ng_container_0_Template, 1, 0, "ng-container",
|
|
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);
|
|
135
158
|
} if (rf & 2) {
|
|
136
|
-
i0.ɵɵnextContext(2);
|
|
159
|
+
const ctx_r0 = i0.ɵɵnextContext(2);
|
|
137
160
|
const titleBar_r4 = i0.ɵɵreference(5);
|
|
138
161
|
i0.ɵɵproperty("ngTemplateOutlet", titleBar_r4);
|
|
162
|
+
i0.ɵɵadvance();
|
|
163
|
+
i0.ɵɵconditional(ctx_r0.CurrentOwnerAgent ? 1 : -1);
|
|
139
164
|
} }
|
|
140
165
|
function ConversationChatAreaComponent_Conditional_3_Conditional_4_Template(rf, ctx) { if (rf & 1) {
|
|
141
|
-
i0.ɵɵelementStart(0, "span",
|
|
142
|
-
i0.ɵɵelement(1, "i",
|
|
166
|
+
i0.ɵɵelementStart(0, "span", 33);
|
|
167
|
+
i0.ɵɵelement(1, "i", 52);
|
|
143
168
|
i0.ɵɵelementStart(2, "span");
|
|
144
169
|
i0.ɵɵtext(3);
|
|
145
170
|
i0.ɵɵelementEnd()();
|
|
@@ -151,9 +176,9 @@ function ConversationChatAreaComponent_Conditional_3_Conditional_4_Template(rf,
|
|
|
151
176
|
} }
|
|
152
177
|
function ConversationChatAreaComponent_Conditional_3_Conditional_5_Template(rf, ctx) { if (rf & 1) {
|
|
153
178
|
const _r5 = i0.ɵɵgetCurrentView();
|
|
154
|
-
i0.ɵɵelementStart(0, "button",
|
|
179
|
+
i0.ɵɵelementStart(0, "button", 53);
|
|
155
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()); });
|
|
156
|
-
i0.ɵɵelement(1, "i",
|
|
181
|
+
i0.ɵɵelement(1, "i", 54);
|
|
157
182
|
i0.ɵɵelementStart(2, "span");
|
|
158
183
|
i0.ɵɵtext(3);
|
|
159
184
|
i0.ɵɵelementEnd()();
|
|
@@ -165,22 +190,22 @@ function ConversationChatAreaComponent_Conditional_3_Conditional_5_Template(rf,
|
|
|
165
190
|
} }
|
|
166
191
|
function ConversationChatAreaComponent_Conditional_3_Conditional_6_Template(rf, ctx) { if (rf & 1) {
|
|
167
192
|
const _r6 = i0.ɵɵgetCurrentView();
|
|
168
|
-
i0.ɵɵelementStart(0, "button",
|
|
193
|
+
i0.ɵɵelementStart(0, "button", 55);
|
|
169
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)); });
|
|
170
|
-
i0.ɵɵelement(1, "i",
|
|
195
|
+
i0.ɵɵelement(1, "i", 56);
|
|
171
196
|
i0.ɵɵelementStart(2, "span");
|
|
172
197
|
i0.ɵɵtext(3, "Test");
|
|
173
198
|
i0.ɵɵelementEnd()();
|
|
174
199
|
} }
|
|
175
200
|
function ConversationChatAreaComponent_Conditional_3_Conditional_8_Template(rf, ctx) { if (rf & 1) {
|
|
176
201
|
const _r7 = i0.ɵɵgetCurrentView();
|
|
177
|
-
i0.ɵɵelementStart(0, "button",
|
|
202
|
+
i0.ɵɵelementStart(0, "button", 57, 2);
|
|
178
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()); });
|
|
179
|
-
i0.ɵɵelement(2, "i",
|
|
180
|
-
i0.ɵɵelementStart(3, "span",
|
|
204
|
+
i0.ɵɵelement(2, "i", 58);
|
|
205
|
+
i0.ɵɵelementStart(3, "span", 59);
|
|
181
206
|
i0.ɵɵtext(4, "Forks");
|
|
182
207
|
i0.ɵɵelementEnd();
|
|
183
|
-
i0.ɵɵelementStart(5, "span",
|
|
208
|
+
i0.ɵɵelementStart(5, "span", 60);
|
|
184
209
|
i0.ɵɵtext(6);
|
|
185
210
|
i0.ɵɵelementEnd()();
|
|
186
211
|
} if (rf & 2) {
|
|
@@ -192,10 +217,10 @@ function ConversationChatAreaComponent_Conditional_3_Conditional_8_Template(rf,
|
|
|
192
217
|
} }
|
|
193
218
|
function ConversationChatAreaComponent_Conditional_3_Conditional_9_Template(rf, ctx) { if (rf & 1) {
|
|
194
219
|
const _r8 = i0.ɵɵgetCurrentView();
|
|
195
|
-
i0.ɵɵelementStart(0, "button",
|
|
220
|
+
i0.ɵɵelementStart(0, "button", 61);
|
|
196
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()); });
|
|
197
|
-
i0.ɵɵelement(1, "i",
|
|
198
|
-
i0.ɵɵelementStart(2, "span",
|
|
222
|
+
i0.ɵɵelement(1, "i", 62);
|
|
223
|
+
i0.ɵɵelementStart(2, "span", 63);
|
|
199
224
|
i0.ɵɵtext(3);
|
|
200
225
|
i0.ɵɵelementEnd()();
|
|
201
226
|
} if (rf & 2) {
|
|
@@ -206,10 +231,10 @@ function ConversationChatAreaComponent_Conditional_3_Conditional_9_Template(rf,
|
|
|
206
231
|
} }
|
|
207
232
|
function ConversationChatAreaComponent_Conditional_3_Conditional_10_Template(rf, ctx) { if (rf & 1) {
|
|
208
233
|
const _r9 = i0.ɵɵgetCurrentView();
|
|
209
|
-
i0.ɵɵelementStart(0, "button",
|
|
234
|
+
i0.ɵɵelementStart(0, "button", 64);
|
|
210
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()); });
|
|
211
|
-
i0.ɵɵelement(1, "i",
|
|
212
|
-
i0.ɵɵelementStart(2, "span",
|
|
236
|
+
i0.ɵɵelement(1, "i", 65);
|
|
237
|
+
i0.ɵɵelementStart(2, "span", 66);
|
|
213
238
|
i0.ɵɵtext(3);
|
|
214
239
|
i0.ɵɵelementEnd()();
|
|
215
240
|
} if (rf & 2) {
|
|
@@ -219,10 +244,23 @@ function ConversationChatAreaComponent_Conditional_3_Conditional_10_Template(rf,
|
|
|
219
244
|
} }
|
|
220
245
|
function ConversationChatAreaComponent_Conditional_3_Conditional_11_Template(rf, ctx) { if (rf & 1) {
|
|
221
246
|
const _r10 = i0.ɵɵgetCurrentView();
|
|
222
|
-
i0.ɵɵelementStart(0, "button",
|
|
223
|
-
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.
|
|
224
|
-
i0.ɵɵelement(1, "i",
|
|
225
|
-
i0.ɵɵelementStart(2, "span",
|
|
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);
|
|
226
264
|
i0.ɵɵtext(3);
|
|
227
265
|
i0.ɵɵelementEnd()();
|
|
228
266
|
} if (rf & 2) {
|
|
@@ -230,27 +268,27 @@ function ConversationChatAreaComponent_Conditional_3_Conditional_11_Template(rf,
|
|
|
230
268
|
i0.ɵɵadvance(3);
|
|
231
269
|
i0.ɵɵtextInterpolate(ctx_r0.memberCount);
|
|
232
270
|
} }
|
|
233
|
-
function
|
|
234
|
-
const
|
|
235
|
-
i0.ɵɵelementStart(0, "mj-conversation-mode-picker",
|
|
236
|
-
i0.ɵɵlistener("PresetChanged", function
|
|
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)); });
|
|
237
275
|
i0.ɵɵelementEnd();
|
|
238
276
|
} if (rf & 2) {
|
|
239
277
|
const ctx_r0 = i0.ɵɵnextContext(2);
|
|
240
278
|
i0.ɵɵproperty("AgentID", ctx_r0.ModePickerTargetAgentId)("Disabled", ctx_r0.isProcessing);
|
|
241
279
|
} }
|
|
242
|
-
function
|
|
243
|
-
i0.ɵɵelement(0, "mj-conversation-agent-picker",
|
|
280
|
+
function ConversationChatAreaComponent_Conditional_3_Conditional_14_Template(rf, ctx) { if (rf & 1) {
|
|
281
|
+
i0.ɵɵelement(0, "mj-conversation-agent-picker", 43);
|
|
244
282
|
} if (rf & 2) {
|
|
245
283
|
const ctx_r0 = i0.ɵɵnextContext(2);
|
|
246
284
|
i0.ɵɵproperty("Conversation", ctx_r0.conversation)("CurrentUser", ctx_r0.currentUser)("AllowedAgentIDs", ctx_r0.AllowedAgentIDs)("Disabled", ctx_r0.EffectiveReadOnly);
|
|
247
285
|
} }
|
|
248
|
-
function
|
|
249
|
-
const
|
|
250
|
-
i0.ɵɵelementStart(0, "button",
|
|
251
|
-
i0.ɵɵlistener("click", function
|
|
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()); });
|
|
252
290
|
i0.ɵɵelement(1, "i");
|
|
253
|
-
i0.ɵɵelementStart(2, "span",
|
|
291
|
+
i0.ɵɵelementStart(2, "span", 59);
|
|
254
292
|
i0.ɵɵtext(3);
|
|
255
293
|
i0.ɵɵelementEnd()();
|
|
256
294
|
} if (rf & 2) {
|
|
@@ -261,12 +299,12 @@ function ConversationChatAreaComponent_Conditional_3_Conditional_14_Template(rf,
|
|
|
261
299
|
i0.ɵɵadvance(2);
|
|
262
300
|
i0.ɵɵtextInterpolate(ctx_r0.exportButtonLabel);
|
|
263
301
|
} }
|
|
264
|
-
function
|
|
265
|
-
const
|
|
266
|
-
i0.ɵɵelementStart(0, "button",
|
|
267
|
-
i0.ɵɵlistener("click", function
|
|
268
|
-
i0.ɵɵelement(1, "i",
|
|
269
|
-
i0.ɵɵelementStart(2, "span",
|
|
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);
|
|
270
308
|
i0.ɵɵtext(3, "Share");
|
|
271
309
|
i0.ɵɵelementEnd()();
|
|
272
310
|
} if (rf & 2) {
|
|
@@ -274,39 +312,40 @@ function ConversationChatAreaComponent_Conditional_3_Conditional_15_Template(rf,
|
|
|
274
312
|
i0.ɵɵclassProp("shared", ctx_r0.isShared);
|
|
275
313
|
i0.ɵɵproperty("title", ctx_r0.isShared ? "Manage sharing" : "Share conversation");
|
|
276
314
|
} }
|
|
277
|
-
function
|
|
315
|
+
function ConversationChatAreaComponent_Conditional_3_Conditional_17_ng_container_0_Template(rf, ctx) { if (rf & 1) {
|
|
278
316
|
i0.ɵɵelementContainer(0);
|
|
279
317
|
} }
|
|
280
|
-
function
|
|
281
|
-
i0.ɵɵtemplate(0,
|
|
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);
|
|
282
320
|
} if (rf & 2) {
|
|
283
321
|
const ctx_r0 = i0.ɵɵnextContext(2);
|
|
284
|
-
i0.ɵɵproperty("ngTemplateOutlet", ctx)("ngTemplateOutletContext", i0.ɵɵpureFunction3(2,
|
|
322
|
+
i0.ɵɵproperty("ngTemplateOutlet", ctx)("ngTemplateOutletContext", i0.ɵɵpureFunction3(2, _c8, ctx_r0.conversation, ctx_r0.conversationId, ctx_r0.isProcessing));
|
|
285
323
|
} }
|
|
286
324
|
function ConversationChatAreaComponent_Conditional_3_Template(rf, ctx) { if (rf & 1) {
|
|
287
325
|
const _r2 = i0.ɵɵgetCurrentView();
|
|
288
|
-
i0.ɵɵelementStart(0, "div",
|
|
326
|
+
i0.ɵɵelementStart(0, "div", 30);
|
|
289
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)); });
|
|
290
|
-
i0.ɵɵelementStart(1, "div",
|
|
291
|
-
i0.ɵɵconditionalCreate(2, ConversationChatAreaComponent_Conditional_3_Conditional_2_Template, 2, 0, "button",
|
|
292
|
-
i0.ɵɵconditionalCreate(3, ConversationChatAreaComponent_Conditional_3_Conditional_3_Template,
|
|
293
|
-
i0.ɵɵconditionalCreate(4, ConversationChatAreaComponent_Conditional_3_Conditional_4_Template, 4, 2, "span",
|
|
294
|
-
i0.ɵɵconditionalCreate(5, ConversationChatAreaComponent_Conditional_3_Conditional_5_Template, 4, 2, "button",
|
|
295
|
-
i0.ɵɵconditionalCreate(6, ConversationChatAreaComponent_Conditional_3_Conditional_6_Template, 4, 0, "button",
|
|
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);
|
|
296
334
|
i0.ɵɵelementEnd();
|
|
297
|
-
i0.ɵɵelementStart(7, "div",
|
|
298
|
-
i0.ɵɵconditionalCreate(8, ConversationChatAreaComponent_Conditional_3_Conditional_8_Template, 7, 5, "button",
|
|
299
|
-
i0.ɵɵconditionalCreate(9, ConversationChatAreaComponent_Conditional_3_Conditional_9_Template, 4, 3, "button",
|
|
300
|
-
i0.ɵɵconditionalCreate(10, ConversationChatAreaComponent_Conditional_3_Conditional_10_Template, 4, 1, "button",
|
|
301
|
-
i0.ɵɵconditionalCreate(11, ConversationChatAreaComponent_Conditional_3_Conditional_11_Template, 4,
|
|
302
|
-
i0.ɵɵconditionalCreate(12, ConversationChatAreaComponent_Conditional_3_Conditional_12_Template,
|
|
303
|
-
i0.ɵɵconditionalCreate(13, ConversationChatAreaComponent_Conditional_3_Conditional_13_Template, 1,
|
|
304
|
-
i0.ɵɵconditionalCreate(14, ConversationChatAreaComponent_Conditional_3_Conditional_14_Template,
|
|
305
|
-
i0.ɵɵconditionalCreate(15, ConversationChatAreaComponent_Conditional_3_Conditional_15_Template, 4,
|
|
306
|
-
i0.ɵɵconditionalCreate(16, ConversationChatAreaComponent_Conditional_3_Conditional_16_Template,
|
|
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");
|
|
307
346
|
i0.ɵɵelementEnd()();
|
|
308
347
|
} if (rf & 2) {
|
|
309
|
-
let
|
|
348
|
+
let tmp_18_0;
|
|
310
349
|
const ctx_r0 = i0.ɵɵnextContext();
|
|
311
350
|
i0.ɵɵadvance();
|
|
312
351
|
i0.ɵɵclassProp("with-sidebar-toggle", ctx_r0.showSidebarToggle);
|
|
@@ -327,85 +366,87 @@ function ConversationChatAreaComponent_Conditional_3_Template(rf, ctx) { if (rf
|
|
|
327
366
|
i0.ɵɵadvance();
|
|
328
367
|
i0.ɵɵconditional(ctx_r0.showArtifactIndicator && ctx_r0.artifactCountDisplay > 0 ? 10 : -1);
|
|
329
368
|
i0.ɵɵadvance();
|
|
330
|
-
i0.ɵɵconditional(ctx_r0.
|
|
369
|
+
i0.ɵɵconditional(ctx_r0.AllowRemoteBrowser && ctx_r0.conversation ? 11 : -1);
|
|
370
|
+
i0.ɵɵadvance();
|
|
371
|
+
i0.ɵɵconditional(ctx_r0.memberCount > 1 ? 12 : -1);
|
|
331
372
|
i0.ɵɵadvance();
|
|
332
|
-
i0.ɵɵconditional(!ctx_r0.overlayMode && ctx_r0.showAgentModePicker && ctx_r0.ModePickerTargetAgentId && !ctx_r0.EffectiveReadOnly ?
|
|
373
|
+
i0.ɵɵconditional(!ctx_r0.overlayMode && ctx_r0.showAgentModePicker && ctx_r0.ModePickerTargetAgentId && !ctx_r0.EffectiveReadOnly ? 13 : -1);
|
|
333
374
|
i0.ɵɵadvance();
|
|
334
|
-
i0.ɵɵconditional(ctx_r0.showAgentPicker && ctx_r0.conversation ?
|
|
375
|
+
i0.ɵɵconditional(ctx_r0.showAgentPicker && ctx_r0.conversation ? 14 : -1);
|
|
335
376
|
i0.ɵɵadvance();
|
|
336
|
-
i0.ɵɵconditional(ctx_r0.showExportButton ?
|
|
377
|
+
i0.ɵɵconditional(ctx_r0.showExportButton ? 15 : -1);
|
|
337
378
|
i0.ɵɵadvance();
|
|
338
|
-
i0.ɵɵconditional(ctx_r0.showShareButton && ctx_r0.canShareConversation ?
|
|
379
|
+
i0.ɵɵconditional(ctx_r0.showShareButton && ctx_r0.canShareConversation ? 16 : -1);
|
|
339
380
|
i0.ɵɵadvance();
|
|
340
|
-
i0.ɵɵconditional((
|
|
381
|
+
i0.ɵɵconditional((tmp_18_0 = ctx_r0.slotTemplate("headerActions")) ? 17 : -1, tmp_18_0);
|
|
341
382
|
} }
|
|
342
383
|
function ConversationChatAreaComponent_ng_template_4_Conditional_1_ng_container_0_Template(rf, ctx) { if (rf & 1) {
|
|
343
384
|
i0.ɵɵelementContainer(0);
|
|
344
385
|
} }
|
|
345
386
|
function ConversationChatAreaComponent_ng_template_4_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
346
|
-
i0.ɵɵtemplate(0, ConversationChatAreaComponent_ng_template_4_Conditional_1_ng_container_0_Template, 1, 0, "ng-container",
|
|
387
|
+
i0.ɵɵtemplate(0, ConversationChatAreaComponent_ng_template_4_Conditional_1_ng_container_0_Template, 1, 0, "ng-container", 48);
|
|
347
388
|
} if (rf & 2) {
|
|
348
389
|
i0.ɵɵnextContext(2);
|
|
349
|
-
const
|
|
350
|
-
i0.ɵɵproperty("ngTemplateOutlet",
|
|
390
|
+
const titleName_r15 = i0.ɵɵreference(7);
|
|
391
|
+
i0.ɵɵproperty("ngTemplateOutlet", titleName_r15);
|
|
351
392
|
} }
|
|
352
393
|
function ConversationChatAreaComponent_ng_template_4_Conditional_2_For_3_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
353
|
-
const
|
|
354
|
-
i0.ɵɵelementStart(0, "li",
|
|
355
|
-
i0.ɵɵlistener("click", function ConversationChatAreaComponent_ng_template_4_Conditional_2_For_3_Conditional_0_Template_button_click_1_listener() { i0.ɵɵrestoreView(
|
|
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()); });
|
|
356
397
|
i0.ɵɵtext(2, "\u2026");
|
|
357
398
|
i0.ɵɵelementEnd();
|
|
358
|
-
i0.ɵɵelement(3, "i",
|
|
399
|
+
i0.ɵɵelement(3, "i", 83);
|
|
359
400
|
i0.ɵɵelementEnd();
|
|
360
401
|
} if (rf & 2) {
|
|
361
402
|
const ctx_r0 = i0.ɵɵnextContext(4);
|
|
362
403
|
i0.ɵɵclassProp("collapses-wide", ctx_r0.HeaderPath.CollapsesWide);
|
|
363
404
|
} }
|
|
364
405
|
function ConversationChatAreaComponent_ng_template_4_Conditional_2_For_3_Template(rf, ctx) { if (rf & 1) {
|
|
365
|
-
const
|
|
366
|
-
i0.ɵɵconditionalCreate(0, ConversationChatAreaComponent_ng_template_4_Conditional_2_For_3_Conditional_0_Template, 4, 2, "li",
|
|
367
|
-
i0.ɵɵelementStart(1, "li",
|
|
368
|
-
i0.ɵɵlistener("click", function ConversationChatAreaComponent_ng_template_4_Conditional_2_For_3_Template_button_click_2_listener() { const
|
|
369
|
-
i0.ɵɵelementStart(3, "span",
|
|
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);
|
|
370
411
|
i0.ɵɵtext(4);
|
|
371
412
|
i0.ɵɵelementEnd()();
|
|
372
|
-
i0.ɵɵelement(5, "i",
|
|
413
|
+
i0.ɵɵelement(5, "i", 83);
|
|
373
414
|
i0.ɵɵelementEnd();
|
|
374
415
|
} if (rf & 2) {
|
|
375
|
-
const
|
|
376
|
-
const $
|
|
377
|
-
i0.ɵɵconditional($
|
|
416
|
+
const parent_r18 = ctx.$implicit;
|
|
417
|
+
const $index_r19 = ctx.$index;
|
|
418
|
+
i0.ɵɵconditional($index_r19 === 1 ? 0 : -1);
|
|
378
419
|
i0.ɵɵadvance();
|
|
379
|
-
i0.ɵɵclassProp("path-middle",
|
|
420
|
+
i0.ɵɵclassProp("path-middle", parent_r18.IsMiddle)("collapsed-wide", parent_r18.CollapsedWide);
|
|
380
421
|
i0.ɵɵadvance();
|
|
381
|
-
i0.ɵɵproperty("title", "Back to " +
|
|
422
|
+
i0.ɵɵproperty("title", "Back to " + parent_r18.Crumb.Label);
|
|
382
423
|
i0.ɵɵadvance(2);
|
|
383
|
-
i0.ɵɵtextInterpolate(
|
|
424
|
+
i0.ɵɵtextInterpolate(parent_r18.Crumb.Label);
|
|
384
425
|
} }
|
|
385
426
|
function ConversationChatAreaComponent_ng_template_4_Conditional_2_ng_container_6_Template(rf, ctx) { if (rf & 1) {
|
|
386
427
|
i0.ɵɵelementContainer(0);
|
|
387
428
|
} }
|
|
388
429
|
function ConversationChatAreaComponent_ng_template_4_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
389
|
-
i0.ɵɵelementStart(0, "nav",
|
|
430
|
+
i0.ɵɵelementStart(0, "nav", 75)(1, "ol", 76);
|
|
390
431
|
i0.ɵɵrepeaterCreate(2, ConversationChatAreaComponent_ng_template_4_Conditional_2_For_3_Template, 6, 7, null, null, i0.ɵɵrepeaterTrackByIndex);
|
|
391
|
-
i0.ɵɵelementStart(4, "li",
|
|
392
|
-
i0.ɵɵelement(5, "i",
|
|
393
|
-
i0.ɵɵtemplate(6, ConversationChatAreaComponent_ng_template_4_Conditional_2_ng_container_6_Template, 1, 0, "ng-container",
|
|
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);
|
|
394
435
|
i0.ɵɵelementEnd()()();
|
|
395
436
|
} if (rf & 2) {
|
|
396
437
|
const ctx_r0 = i0.ɵɵnextContext(2);
|
|
397
|
-
const
|
|
438
|
+
const titleName_r15 = i0.ɵɵreference(7);
|
|
398
439
|
i0.ɵɵadvance(2);
|
|
399
440
|
i0.ɵɵrepeater(ctx_r0.HeaderPath.Parents);
|
|
400
441
|
i0.ɵɵadvance(3);
|
|
401
442
|
i0.ɵɵclassMap("chat-title-kind " + ctx_r0.OpenViewIcon);
|
|
402
443
|
i0.ɵɵattribute("data-kind", ctx_r0.OpenViewKind);
|
|
403
444
|
i0.ɵɵadvance();
|
|
404
|
-
i0.ɵɵproperty("ngTemplateOutlet",
|
|
445
|
+
i0.ɵɵproperty("ngTemplateOutlet", titleName_r15);
|
|
405
446
|
} }
|
|
406
447
|
function ConversationChatAreaComponent_ng_template_4_Template(rf, ctx) { if (rf & 1) {
|
|
407
|
-
i0.ɵɵelementStart(0, "div",
|
|
408
|
-
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",
|
|
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);
|
|
409
450
|
i0.ɵɵelementEnd();
|
|
410
451
|
} if (rf & 2) {
|
|
411
452
|
const ctx_r0 = i0.ɵɵnextContext();
|
|
@@ -413,10 +454,10 @@ function ConversationChatAreaComponent_ng_template_4_Template(rf, ctx) { if (rf
|
|
|
413
454
|
i0.ɵɵconditional(ctx_r0.OpenView.Kind === "Main" ? 1 : 2);
|
|
414
455
|
} }
|
|
415
456
|
function ConversationChatAreaComponent_ng_template_6_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
416
|
-
const
|
|
417
|
-
i0.ɵɵelementStart(0, "input",
|
|
418
|
-
i0.ɵɵtwoWayListener("ngModelChange", function ConversationChatAreaComponent_ng_template_6_Conditional_0_Template_input_ngModelChange_0_listener($event) { i0.ɵɵrestoreView(
|
|
419
|
-
i0.ɵɵlistener("keydown.enter", function ConversationChatAreaComponent_ng_template_6_Conditional_0_Template_input_keydown_enter_0_listener($event) { i0.ɵɵrestoreView(
|
|
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()); });
|
|
420
461
|
i0.ɵɵelementEnd();
|
|
421
462
|
} if (rf & 2) {
|
|
422
463
|
const ctx_r0 = i0.ɵɵnextContext(2);
|
|
@@ -424,10 +465,10 @@ function ConversationChatAreaComponent_ng_template_6_Conditional_0_Template(rf,
|
|
|
424
465
|
i0.ɵɵattribute("aria-label", ctx_r0.TitleRenameLabel);
|
|
425
466
|
} }
|
|
426
467
|
function ConversationChatAreaComponent_ng_template_6_Conditional_1_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
427
|
-
const
|
|
428
|
-
i0.ɵɵelementStart(0, "button",
|
|
429
|
-
i0.ɵɵlistener("click", function ConversationChatAreaComponent_ng_template_6_Conditional_1_Conditional_2_Template_button_click_0_listener() { i0.ɵɵrestoreView(
|
|
430
|
-
i0.ɵɵelement(2, "i",
|
|
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);
|
|
431
472
|
i0.ɵɵelementEnd();
|
|
432
473
|
} if (rf & 2) {
|
|
433
474
|
const ctx_r0 = i0.ɵɵnextContext(3);
|
|
@@ -435,10 +476,10 @@ function ConversationChatAreaComponent_ng_template_6_Conditional_1_Conditional_2
|
|
|
435
476
|
i0.ɵɵattribute("aria-label", ctx_r0.TitleRenameLabel);
|
|
436
477
|
} }
|
|
437
478
|
function ConversationChatAreaComponent_ng_template_6_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
438
|
-
i0.ɵɵelementStart(0, "h2",
|
|
479
|
+
i0.ɵɵelementStart(0, "h2", 88);
|
|
439
480
|
i0.ɵɵtext(1);
|
|
440
481
|
i0.ɵɵelementEnd();
|
|
441
|
-
i0.ɵɵconditionalCreate(2, ConversationChatAreaComponent_ng_template_6_Conditional_1_Conditional_2_Template, 3, 2, "button",
|
|
482
|
+
i0.ɵɵconditionalCreate(2, ConversationChatAreaComponent_ng_template_6_Conditional_1_Conditional_2_Template, 3, 2, "button", 89);
|
|
442
483
|
} if (rf & 2) {
|
|
443
484
|
const ctx_r0 = i0.ɵɵnextContext(2);
|
|
444
485
|
i0.ɵɵproperty("title", ctx_r0.HeaderTitle);
|
|
@@ -448,7 +489,7 @@ function ConversationChatAreaComponent_ng_template_6_Conditional_1_Template(rf,
|
|
|
448
489
|
i0.ɵɵconditional(ctx_r0.CanRenameTitle ? 2 : -1);
|
|
449
490
|
} }
|
|
450
491
|
function ConversationChatAreaComponent_ng_template_6_Template(rf, ctx) { if (rf & 1) {
|
|
451
|
-
i0.ɵɵconditionalCreate(0, ConversationChatAreaComponent_ng_template_6_Conditional_0_Template, 2, 2, "input",
|
|
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);
|
|
452
493
|
} if (rf & 2) {
|
|
453
494
|
const ctx_r0 = i0.ɵɵnextContext();
|
|
454
495
|
i0.ɵɵconditional(ctx_r0.IsRenamingTitle ? 0 : 1);
|
|
@@ -457,28 +498,28 @@ function ConversationChatAreaComponent_Conditional_9_ng_container_1_Template(rf,
|
|
|
457
498
|
i0.ɵɵelementContainer(0);
|
|
458
499
|
} }
|
|
459
500
|
function ConversationChatAreaComponent_Conditional_9_Template(rf, ctx) { if (rf & 1) {
|
|
460
|
-
i0.ɵɵelementStart(0, "div",
|
|
461
|
-
i0.ɵɵtemplate(1, ConversationChatAreaComponent_Conditional_9_ng_container_1_Template, 1, 0, "ng-container",
|
|
501
|
+
i0.ɵɵelementStart(0, "div", 14);
|
|
502
|
+
i0.ɵɵtemplate(1, ConversationChatAreaComponent_Conditional_9_ng_container_1_Template, 1, 0, "ng-container", 29);
|
|
462
503
|
i0.ɵɵelementEnd();
|
|
463
504
|
} if (rf & 2) {
|
|
464
505
|
const ctx_r0 = i0.ɵɵnextContext();
|
|
465
506
|
i0.ɵɵadvance();
|
|
466
|
-
i0.ɵɵproperty("ngTemplateOutlet", ctx_r0.slotTemplate("demonstrationSurface"))("ngTemplateOutletContext", i0.ɵɵpureFunction3(2,
|
|
507
|
+
i0.ɵɵproperty("ngTemplateOutlet", ctx_r0.slotTemplate("demonstrationSurface"))("ngTemplateOutletContext", i0.ɵɵpureFunction3(2, _c9, ctx_r0.demonstrationSurfaceContent, ctx_r0.demonstrationSurfaceContent, ctx_r0.showDemonstrationSurface));
|
|
467
508
|
} }
|
|
468
509
|
function ConversationChatAreaComponent_Conditional_11_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
469
|
-
i0.ɵɵelementStart(0, "div",
|
|
470
|
-
i0.ɵɵelement(1, "mj-loading",
|
|
510
|
+
i0.ɵɵelementStart(0, "div", 92);
|
|
511
|
+
i0.ɵɵelement(1, "mj-loading", 93);
|
|
471
512
|
i0.ɵɵelementEnd();
|
|
472
513
|
} }
|
|
473
514
|
function ConversationChatAreaComponent_Conditional_11_Template(rf, ctx) { if (rf & 1) {
|
|
474
|
-
i0.ɵɵconditionalCreate(0, ConversationChatAreaComponent_Conditional_11_Conditional_0_Template, 2, 0, "div",
|
|
515
|
+
i0.ɵɵconditionalCreate(0, ConversationChatAreaComponent_Conditional_11_Conditional_0_Template, 2, 0, "div", 92);
|
|
475
516
|
} if (rf & 2) {
|
|
476
517
|
const ctx_r0 = i0.ɵɵnextContext();
|
|
477
518
|
i0.ɵɵconditional(ctx_r0.showLoadingState ? 0 : -1);
|
|
478
519
|
} }
|
|
479
520
|
function ConversationChatAreaComponent_Conditional_12_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
480
|
-
i0.ɵɵelementStart(0, "div",
|
|
481
|
-
i0.ɵɵelement(1, "i",
|
|
521
|
+
i0.ɵɵelementStart(0, "div", 94);
|
|
522
|
+
i0.ɵɵelement(1, "i", 96);
|
|
482
523
|
i0.ɵɵelementStart(2, "span");
|
|
483
524
|
i0.ɵɵtext(3);
|
|
484
525
|
i0.ɵɵelementEnd()();
|
|
@@ -491,30 +532,30 @@ function ConversationChatAreaComponent_Conditional_12_Conditional_1_ng_container
|
|
|
491
532
|
i0.ɵɵelementContainer(0);
|
|
492
533
|
} }
|
|
493
534
|
function ConversationChatAreaComponent_Conditional_12_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
494
|
-
i0.ɵɵtemplate(0, ConversationChatAreaComponent_Conditional_12_Conditional_1_ng_container_0_Template, 1, 0, "ng-container",
|
|
535
|
+
i0.ɵɵtemplate(0, ConversationChatAreaComponent_Conditional_12_Conditional_1_ng_container_0_Template, 1, 0, "ng-container", 29);
|
|
495
536
|
} if (rf & 2) {
|
|
496
537
|
const ctx_r0 = i0.ɵɵnextContext(2);
|
|
497
|
-
i0.ɵɵproperty("ngTemplateOutlet", ctx)("ngTemplateOutletContext", i0.ɵɵpureFunction4(3,
|
|
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)));
|
|
498
539
|
} }
|
|
499
540
|
function ConversationChatAreaComponent_Conditional_12_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
500
|
-
const
|
|
501
|
-
i0.ɵɵelementStart(0, "mj-conversation-empty-state",
|
|
502
|
-
i0.ɵɵlistener("initialDraftApplied", function ConversationChatAreaComponent_Conditional_12_Conditional_2_Template_mj_conversation_empty_state_initialDraftApplied_0_listener() { i0.ɵɵrestoreView(
|
|
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)); });
|
|
503
544
|
i0.ɵɵelementEnd();
|
|
504
545
|
} if (rf & 2) {
|
|
505
546
|
const ctx_r0 = i0.ɵɵnextContext(2);
|
|
506
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);
|
|
507
548
|
} }
|
|
508
549
|
function ConversationChatAreaComponent_Conditional_12_Template(rf, ctx) { if (rf & 1) {
|
|
509
|
-
i0.ɵɵconditionalCreate(0, ConversationChatAreaComponent_Conditional_12_Conditional_0_Template, 4, 1, "div",
|
|
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);
|
|
510
551
|
} if (rf & 2) {
|
|
511
552
|
let tmp_3_0;
|
|
512
553
|
const ctx_r0 = i0.ɵɵnextContext();
|
|
513
554
|
i0.ɵɵconditional(ctx_r0.ReadOnly ? 0 : (tmp_3_0 = ctx_r0.slotTemplate("emptyState")) ? 1 : 2, tmp_3_0);
|
|
514
555
|
} }
|
|
515
556
|
function ConversationChatAreaComponent_Conditional_13_Conditional_3_Template(rf, ctx) { if (rf & 1) {
|
|
516
|
-
i0.ɵɵelementStart(0, "div",
|
|
517
|
-
i0.ɵɵelement(1, "i",
|
|
557
|
+
i0.ɵɵelementStart(0, "div", 94);
|
|
558
|
+
i0.ɵɵelement(1, "i", 96);
|
|
518
559
|
i0.ɵɵelementStart(2, "span");
|
|
519
560
|
i0.ɵɵtext(3);
|
|
520
561
|
i0.ɵɵelementEnd()();
|
|
@@ -527,19 +568,19 @@ function ConversationChatAreaComponent_Conditional_13_Conditional_4_Conditional_
|
|
|
527
568
|
i0.ɵɵelementContainer(0);
|
|
528
569
|
} }
|
|
529
570
|
function ConversationChatAreaComponent_Conditional_13_Conditional_4_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
530
|
-
i0.ɵɵelementStart(0, "div",
|
|
531
|
-
i0.ɵɵtemplate(1, ConversationChatAreaComponent_Conditional_13_Conditional_4_Conditional_0_ng_container_1_Template, 1, 0, "ng-container",
|
|
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);
|
|
532
573
|
i0.ɵɵelementEnd();
|
|
533
574
|
} if (rf & 2) {
|
|
534
575
|
const ctx_r0 = i0.ɵɵnextContext(3);
|
|
535
576
|
i0.ɵɵadvance();
|
|
536
|
-
i0.ɵɵproperty("ngTemplateOutlet", ctx)("ngTemplateOutletContext", i0.ɵɵpureFunction3(2,
|
|
577
|
+
i0.ɵɵproperty("ngTemplateOutlet", ctx)("ngTemplateOutletContext", i0.ɵɵpureFunction3(2, _c12, ctx_r0.conversation, ctx_r0.conversationId, ctx_r0.isProcessing));
|
|
537
578
|
} }
|
|
538
579
|
function ConversationChatAreaComponent_Conditional_13_Conditional_4_Template(rf, ctx) { if (rf & 1) {
|
|
539
|
-
const
|
|
540
|
-
i0.ɵɵconditionalCreate(0, ConversationChatAreaComponent_Conditional_13_Conditional_4_Conditional_0_Template, 2, 6, "div",
|
|
541
|
-
i0.ɵɵelementStart(1, "div",
|
|
542
|
-
i0.ɵɵlistener("initialDraftApplied", function ConversationChatAreaComponent_Conditional_13_Conditional_4_Template_mj_message_input_initialDraftApplied_2_listener() { i0.ɵɵrestoreView(
|
|
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)); });
|
|
543
584
|
i0.ɵɵelementEnd()();
|
|
544
585
|
} if (rf & 2) {
|
|
545
586
|
let tmp_5_0;
|
|
@@ -549,10 +590,10 @@ function ConversationChatAreaComponent_Conditional_13_Conditional_4_Template(rf,
|
|
|
549
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);
|
|
550
591
|
} }
|
|
551
592
|
function ConversationChatAreaComponent_Conditional_13_Template(rf, ctx) { if (rf & 1) {
|
|
552
|
-
i0.ɵɵelementStart(0, "div",
|
|
553
|
-
i0.ɵɵelement(1, "div",
|
|
554
|
-
i0.ɵɵelementStart(2, "div",
|
|
555
|
-
i0.ɵɵconditionalCreate(3, ConversationChatAreaComponent_Conditional_13_Conditional_3_Template, 4, 1, "div",
|
|
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);
|
|
556
597
|
i0.ɵɵelementEnd()();
|
|
557
598
|
} if (rf & 2) {
|
|
558
599
|
const ctx_r0 = i0.ɵɵnextContext();
|
|
@@ -563,10 +604,10 @@ function ConversationChatAreaComponent_Conditional_14_Conditional_1_ng_container
|
|
|
563
604
|
i0.ɵɵelementContainer(0);
|
|
564
605
|
} }
|
|
565
606
|
function ConversationChatAreaComponent_Conditional_14_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
566
|
-
const
|
|
567
|
-
i0.ɵɵelementStart(0, "div",
|
|
568
|
-
i0.ɵɵlistener("keydown.escape", function ConversationChatAreaComponent_Conditional_14_Conditional_1_Template_div_keydown_escape_0_listener($event) { i0.ɵɵrestoreView(
|
|
569
|
-
i0.ɵɵtemplate(1, ConversationChatAreaComponent_Conditional_14_Conditional_1_ng_container_1_Template, 1, 0, "ng-container",
|
|
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);
|
|
570
611
|
i0.ɵɵelementEnd();
|
|
571
612
|
} if (rf & 2) {
|
|
572
613
|
i0.ɵɵnextContext(2);
|
|
@@ -575,8 +616,8 @@ function ConversationChatAreaComponent_Conditional_14_Conditional_1_Template(rf,
|
|
|
575
616
|
i0.ɵɵproperty("ngTemplateOutlet", titleBar_r4);
|
|
576
617
|
} }
|
|
577
618
|
function ConversationChatAreaComponent_Conditional_14_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
578
|
-
i0.ɵɵelementStart(0, "div",
|
|
579
|
-
i0.ɵɵelement(1, "mj-loading",
|
|
619
|
+
i0.ɵɵelementStart(0, "div", 104);
|
|
620
|
+
i0.ɵɵelement(1, "mj-loading", 110);
|
|
580
621
|
i0.ɵɵelementEnd();
|
|
581
622
|
} if (rf & 2) {
|
|
582
623
|
const ctx_r0 = i0.ɵɵnextContext(2);
|
|
@@ -584,20 +625,20 @@ function ConversationChatAreaComponent_Conditional_14_Conditional_2_Template(rf,
|
|
|
584
625
|
i0.ɵɵproperty("text", ctx_r0.uploadingMessage);
|
|
585
626
|
} }
|
|
586
627
|
function ConversationChatAreaComponent_Conditional_14_Conditional_6_Template(rf, ctx) { if (rf & 1) {
|
|
587
|
-
const
|
|
588
|
-
i0.ɵɵelementStart(0, "span",
|
|
589
|
-
i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_14_Conditional_6_Template_span_click_0_listener() { i0.ɵɵrestoreView(
|
|
590
|
-
i0.ɵɵelement(1, "i",
|
|
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);
|
|
591
632
|
i0.ɵɵelementEnd();
|
|
592
633
|
} }
|
|
593
634
|
function ConversationChatAreaComponent_Conditional_14_Conditional_8_Template(rf, ctx) { if (rf & 1) {
|
|
594
|
-
i0.ɵɵelementStart(0, "div",
|
|
595
|
-
i0.ɵɵelement(1, "mj-loading",
|
|
635
|
+
i0.ɵɵelementStart(0, "div", 108);
|
|
636
|
+
i0.ɵɵelement(1, "mj-loading", 113);
|
|
596
637
|
i0.ɵɵelementEnd();
|
|
597
638
|
} }
|
|
598
639
|
function ConversationChatAreaComponent_Conditional_14_Conditional_9_Template(rf, ctx) { if (rf & 1) {
|
|
599
|
-
i0.ɵɵelementStart(0, "div",
|
|
600
|
-
i0.ɵɵelement(1, "i",
|
|
640
|
+
i0.ɵɵelementStart(0, "div", 94);
|
|
641
|
+
i0.ɵɵelement(1, "i", 96);
|
|
601
642
|
i0.ɵɵelementStart(2, "span");
|
|
602
643
|
i0.ɵɵtext(3);
|
|
603
644
|
i0.ɵɵelementEnd()();
|
|
@@ -607,8 +648,8 @@ function ConversationChatAreaComponent_Conditional_14_Conditional_9_Template(rf,
|
|
|
607
648
|
i0.ɵɵtextInterpolate(ctx_r0.ReadOnlyMessage || "You have view-only access to this conversation.");
|
|
608
649
|
} }
|
|
609
650
|
function ConversationChatAreaComponent_Conditional_14_Conditional_10_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
610
|
-
i0.ɵɵelementStart(0, "div",
|
|
611
|
-
i0.ɵɵelement(1, "i",
|
|
651
|
+
i0.ɵɵelementStart(0, "div", 94);
|
|
652
|
+
i0.ɵɵelement(1, "i", 96);
|
|
612
653
|
i0.ɵɵelementStart(2, "span");
|
|
613
654
|
i0.ɵɵtext(3, "You have view-only access to this conversation.");
|
|
614
655
|
i0.ɵɵelementEnd()();
|
|
@@ -617,26 +658,26 @@ function ConversationChatAreaComponent_Conditional_14_Conditional_10_Conditional
|
|
|
617
658
|
i0.ɵɵelementContainer(0);
|
|
618
659
|
} }
|
|
619
660
|
function ConversationChatAreaComponent_Conditional_14_Conditional_10_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
620
|
-
i0.ɵɵelementStart(0, "div",
|
|
621
|
-
i0.ɵɵtemplate(1, ConversationChatAreaComponent_Conditional_14_Conditional_10_Conditional_1_ng_container_1_Template, 1, 0, "ng-container",
|
|
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);
|
|
622
663
|
i0.ɵɵelementEnd();
|
|
623
664
|
} if (rf & 2) {
|
|
624
665
|
const ctx_r0 = i0.ɵɵnextContext(3);
|
|
625
666
|
i0.ɵɵadvance();
|
|
626
|
-
i0.ɵɵproperty("ngTemplateOutlet", ctx)("ngTemplateOutletContext", i0.ɵɵpureFunction3(2,
|
|
667
|
+
i0.ɵɵproperty("ngTemplateOutlet", ctx)("ngTemplateOutletContext", i0.ɵɵpureFunction3(2, _c12, ctx_r0.conversation, ctx_r0.conversationId, ctx_r0.isProcessing));
|
|
627
668
|
} }
|
|
628
669
|
function ConversationChatAreaComponent_Conditional_14_Conditional_10_For_4_Template(rf, ctx) { if (rf & 1) {
|
|
629
|
-
const
|
|
630
|
-
i0.ɵɵelementStart(0, "mj-message-input",
|
|
631
|
-
i0.ɵɵlistener("DraftStateChanged", function ConversationChatAreaComponent_Conditional_14_Conditional_10_For_4_Template_mj_message_input_DraftStateChanged_0_listener($event) { const
|
|
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)); });
|
|
632
673
|
i0.ɵɵelementEnd();
|
|
633
674
|
} if (rf & 2) {
|
|
634
|
-
const
|
|
675
|
+
const inputRef_r28 = ctx.$implicit;
|
|
635
676
|
const ctx_r0 = i0.ɵɵnextContext(3);
|
|
636
|
-
i0.ɵɵproperty("hidden",
|
|
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);
|
|
637
678
|
} }
|
|
638
679
|
function ConversationChatAreaComponent_Conditional_14_Conditional_10_Conditional_5_Template(rf, ctx) { if (rf & 1) {
|
|
639
|
-
i0.ɵɵelementStart(0, "div",
|
|
680
|
+
i0.ɵɵelementStart(0, "div", 115);
|
|
640
681
|
i0.ɵɵtext(1);
|
|
641
682
|
i0.ɵɵelementEnd();
|
|
642
683
|
} if (rf & 2) {
|
|
@@ -645,12 +686,12 @@ function ConversationChatAreaComponent_Conditional_14_Conditional_10_Conditional
|
|
|
645
686
|
i0.ɵɵtextInterpolate(ctx_r0.ComposerHint);
|
|
646
687
|
} }
|
|
647
688
|
function ConversationChatAreaComponent_Conditional_14_Conditional_10_Template(rf, ctx) { if (rf & 1) {
|
|
648
|
-
i0.ɵɵconditionalCreate(0, ConversationChatAreaComponent_Conditional_14_Conditional_10_Conditional_0_Template, 4, 0, "div",
|
|
649
|
-
i0.ɵɵconditionalCreate(1, ConversationChatAreaComponent_Conditional_14_Conditional_10_Conditional_1_Template, 2, 6, "div",
|
|
650
|
-
i0.ɵɵelementStart(2, "div",
|
|
651
|
-
i0.ɵɵrepeaterCreate(3, ConversationChatAreaComponent_Conditional_14_Conditional_10_For_4_Template, 2, 45, "mj-message-input",
|
|
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);
|
|
652
693
|
i0.ɵɵelementEnd();
|
|
653
|
-
i0.ɵɵconditionalCreate(5, ConversationChatAreaComponent_Conditional_14_Conditional_10_Conditional_5_Template, 2, 1, "div",
|
|
694
|
+
i0.ɵɵconditionalCreate(5, ConversationChatAreaComponent_Conditional_14_Conditional_10_Conditional_5_Template, 2, 1, "div", 115);
|
|
654
695
|
} if (rf & 2) {
|
|
655
696
|
let tmp_6_0;
|
|
656
697
|
const ctx_r0 = i0.ɵɵnextContext(2);
|
|
@@ -663,19 +704,19 @@ function ConversationChatAreaComponent_Conditional_14_Conditional_10_Template(rf
|
|
|
663
704
|
i0.ɵɵconditional(ctx_r0.ComposerHint ? 5 : -1);
|
|
664
705
|
} }
|
|
665
706
|
function ConversationChatAreaComponent_Conditional_14_Template(rf, ctx) { if (rf & 1) {
|
|
666
|
-
const
|
|
667
|
-
i0.ɵɵelementStart(0, "div",
|
|
668
|
-
i0.ɵɵconditionalCreate(1, ConversationChatAreaComponent_Conditional_14_Conditional_1_Template, 2, 1, "div",
|
|
669
|
-
i0.ɵɵconditionalCreate(2, ConversationChatAreaComponent_Conditional_14_Conditional_2_Template, 2, 1, "div",
|
|
670
|
-
i0.ɵɵelementStart(3, "div",
|
|
671
|
-
i0.ɵɵlistener("scroll", function ConversationChatAreaComponent_Conditional_14_Template_div_scroll_3_listener() { i0.ɵɵrestoreView(
|
|
672
|
-
i0.ɵɵelementStart(5, "mj-conversation-message-list",
|
|
673
|
-
i0.ɵɵlistener("OlderRequested", function ConversationChatAreaComponent_Conditional_14_Template_mj_conversation_message_list_OlderRequested_5_listener() { i0.ɵɵrestoreView(
|
|
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)); });
|
|
674
715
|
i0.ɵɵelementEnd();
|
|
675
|
-
i0.ɵɵconditionalCreate(6, ConversationChatAreaComponent_Conditional_14_Conditional_6_Template, 2, 0, "span",
|
|
716
|
+
i0.ɵɵconditionalCreate(6, ConversationChatAreaComponent_Conditional_14_Conditional_6_Template, 2, 0, "span", 107);
|
|
676
717
|
i0.ɵɵelementEnd();
|
|
677
|
-
i0.ɵɵelementStart(7, "div",
|
|
678
|
-
i0.ɵɵconditionalCreate(8, ConversationChatAreaComponent_Conditional_14_Conditional_8_Template, 2, 0, "div",
|
|
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);
|
|
679
720
|
i0.ɵɵelementEnd()();
|
|
680
721
|
} if (rf & 2) {
|
|
681
722
|
const ctx_r0 = i0.ɵɵnextContext();
|
|
@@ -684,23 +725,23 @@ function ConversationChatAreaComponent_Conditional_14_Template(rf, ctx) { if (rf
|
|
|
684
725
|
i0.ɵɵadvance();
|
|
685
726
|
i0.ɵɵconditional(ctx_r0.isUploadingAttachments ? 2 : -1);
|
|
686
727
|
i0.ɵɵadvance(3);
|
|
687
|
-
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);
|
|
688
729
|
i0.ɵɵadvance();
|
|
689
730
|
i0.ɵɵconditional(ctx_r0.showScrollToBottomIcon && ctx_r0.DisplayMessages.length > 0 ? 6 : -1);
|
|
690
731
|
i0.ɵɵadvance(2);
|
|
691
732
|
i0.ɵɵconditional(ctx_r0.isLoadingPeripheralData ? 8 : ctx_r0.ReadOnly ? 9 : 10);
|
|
692
733
|
} }
|
|
693
734
|
function ConversationChatAreaComponent_Conditional_15_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
694
|
-
const
|
|
695
|
-
i0.ɵɵelementStart(0, "div",
|
|
696
|
-
i0.ɵɵlistener("mousedown", function ConversationChatAreaComponent_Conditional_15_Conditional_0_Template_div_mousedown_0_listener($event) { i0.ɵɵrestoreView(
|
|
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)); });
|
|
697
738
|
i0.ɵɵelementEnd();
|
|
698
739
|
} }
|
|
699
740
|
function ConversationChatAreaComponent_Conditional_15_Template(rf, ctx) { if (rf & 1) {
|
|
700
|
-
const
|
|
701
|
-
i0.ɵɵconditionalCreate(0, ConversationChatAreaComponent_Conditional_15_Conditional_0_Template, 1, 0, "div",
|
|
702
|
-
i0.ɵɵelementStart(1, "div",
|
|
703
|
-
i0.ɵɵlistener("closed", function ConversationChatAreaComponent_Conditional_15_Template_mj_artifact_viewer_panel_closed_2_listener() { i0.ɵɵrestoreView(
|
|
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)); });
|
|
704
745
|
i0.ɵɵelementEnd()();
|
|
705
746
|
} if (rf & 2) {
|
|
706
747
|
const ctx_r0 = i0.ɵɵnextContext();
|
|
@@ -712,42 +753,42 @@ function ConversationChatAreaComponent_Conditional_15_Template(rf, ctx) { if (rf
|
|
|
712
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$);
|
|
713
754
|
} }
|
|
714
755
|
function ConversationChatAreaComponent_Conditional_16_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
715
|
-
const
|
|
716
|
-
i0.ɵɵelementStart(0, "div",
|
|
717
|
-
i0.ɵɵlistener("mousedown", function ConversationChatAreaComponent_Conditional_16_Conditional_0_Template_div_mousedown_0_listener($event) { i0.ɵɵrestoreView(
|
|
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)); });
|
|
718
759
|
i0.ɵɵelementEnd();
|
|
719
760
|
} }
|
|
720
761
|
function ConversationChatAreaComponent_Conditional_16_Template(rf, ctx) { if (rf & 1) {
|
|
721
|
-
const
|
|
722
|
-
i0.ɵɵconditionalCreate(0, ConversationChatAreaComponent_Conditional_16_Conditional_0_Template, 1, 0, "div",
|
|
723
|
-
i0.ɵɵelementStart(1, "div",
|
|
724
|
-
i0.ɵɵelement(5, "i",
|
|
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);
|
|
725
766
|
i0.ɵɵelementEnd();
|
|
726
|
-
i0.ɵɵelementStart(6, "div",
|
|
767
|
+
i0.ɵɵelementStart(6, "div", 126)(7, "span", 127);
|
|
727
768
|
i0.ɵɵtext(8);
|
|
728
769
|
i0.ɵɵelementEnd();
|
|
729
|
-
i0.ɵɵelementStart(9, "span",
|
|
770
|
+
i0.ɵɵelementStart(9, "span", 128);
|
|
730
771
|
i0.ɵɵtext(10, "Interactive Task Graph & Step Inspector");
|
|
731
772
|
i0.ɵɵelementEnd()()();
|
|
732
|
-
i0.ɵɵelementStart(11, "div",
|
|
733
|
-
i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_16_Template_button_click_12_listener() { i0.ɵɵrestoreView(
|
|
734
|
-
i0.ɵɵelement(13, "i",
|
|
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);
|
|
735
776
|
i0.ɵɵelementStart(14, "span");
|
|
736
777
|
i0.ɵɵtext(15);
|
|
737
778
|
i0.ɵɵelementEnd()();
|
|
738
|
-
i0.ɵɵelementStart(16, "button",
|
|
739
|
-
i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_16_Template_button_click_16_listener() { i0.ɵɵrestoreView(
|
|
740
|
-
i0.ɵɵelement(17, "i",
|
|
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);
|
|
741
782
|
i0.ɵɵelementEnd();
|
|
742
|
-
i0.ɵɵelementStart(18, "button",
|
|
743
|
-
i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_16_Template_button_click_18_listener() { i0.ɵɵrestoreView(
|
|
744
|
-
i0.ɵɵelement(19, "i",
|
|
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);
|
|
745
786
|
i0.ɵɵelementEnd()()();
|
|
746
|
-
i0.ɵɵelementStart(20, "div",
|
|
747
|
-
i0.ɵɵelement(21, "mj-task-graph-run-view",
|
|
787
|
+
i0.ɵɵelementStart(20, "div", 135);
|
|
788
|
+
i0.ɵɵelement(21, "mj-task-graph-run-view", 136, 8);
|
|
748
789
|
i0.ɵɵelementEnd()();
|
|
749
790
|
} if (rf & 2) {
|
|
750
|
-
const
|
|
791
|
+
const taskGraphRunView_r33 = i0.ɵɵreference(22);
|
|
751
792
|
const ctx_r0 = i0.ɵɵnextContext();
|
|
752
793
|
i0.ɵɵconditional(!ctx_r0.isArtifactPaneMaximized ? 0 : -1);
|
|
753
794
|
i0.ɵɵadvance();
|
|
@@ -756,7 +797,7 @@ function ConversationChatAreaComponent_Conditional_16_Template(rf, ctx) { if (rf
|
|
|
756
797
|
i0.ɵɵadvance(7);
|
|
757
798
|
i0.ɵɵtextInterpolate(ctx_r0.SelectedTaskGraphPanel.workflowTitle);
|
|
758
799
|
i0.ɵɵadvance(4);
|
|
759
|
-
i0.ɵɵproperty("disabled", ctx_r0.IsSavingTaskGraphWorkflow || !(
|
|
800
|
+
i0.ɵɵproperty("disabled", ctx_r0.IsSavingTaskGraphWorkflow || !(taskGraphRunView_r33.Spec == null ? null : taskGraphRunView_r33.Spec.tasks == null ? null : taskGraphRunView_r33.Spec.tasks.length));
|
|
760
801
|
i0.ɵɵadvance();
|
|
761
802
|
i0.ɵɵclassProp("fa-spinner", ctx_r0.IsSavingTaskGraphWorkflow)("fa-spin", ctx_r0.IsSavingTaskGraphWorkflow)("fa-floppy-disk", !ctx_r0.IsSavingTaskGraphWorkflow);
|
|
762
803
|
i0.ɵɵadvance(2);
|
|
@@ -768,33 +809,89 @@ function ConversationChatAreaComponent_Conditional_16_Template(rf, ctx) { if (rf
|
|
|
768
809
|
i0.ɵɵadvance(4);
|
|
769
810
|
i0.ɵɵproperty("ParentTaskID", ctx_r0.SelectedTaskGraphPanel.parentTaskId)("WorkflowName", ctx_r0.SelectedTaskGraphPanel.workflowTitle)("LiveUpdates", true)("ShowVariables", true)("Height", "100%");
|
|
770
811
|
} }
|
|
771
|
-
function
|
|
772
|
-
const
|
|
773
|
-
i0.ɵɵelementStart(0, "
|
|
774
|
-
i0.ɵɵlistener("
|
|
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);
|
|
775
823
|
i0.ɵɵelementEnd();
|
|
824
|
+
i0.ɵɵelementStart(6, "div", 126)(7, "span", 127);
|
|
825
|
+
i0.ɵɵtext(8, "Remote Browser");
|
|
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()();
|
|
776
851
|
} if (rf & 2) {
|
|
777
852
|
const ctx_r0 = i0.ɵɵnextContext();
|
|
778
|
-
i0.ɵɵ
|
|
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);
|
|
779
867
|
} }
|
|
780
868
|
function ConversationChatAreaComponent_Conditional_19_Template(rf, ctx) { if (rf & 1) {
|
|
781
|
-
const
|
|
782
|
-
i0.ɵɵelementStart(0, "mj-
|
|
783
|
-
i0.ɵɵlistener("
|
|
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()); });
|
|
784
881
|
i0.ɵɵelementEnd();
|
|
785
882
|
} if (rf & 2) {
|
|
786
883
|
const ctx_r0 = i0.ɵɵnextContext();
|
|
787
884
|
i0.ɵɵproperty("PanelID", ctx_r0.ForksPopoverID)("Summaries", ctx_r0.ForkSummaries)("CurrentUserID", ctx_r0.CurrentUser.ID);
|
|
788
885
|
} }
|
|
789
|
-
function
|
|
790
|
-
const
|
|
791
|
-
i0.ɵɵelementStart(0, "button",
|
|
792
|
-
i0.ɵɵlistener("click", function
|
|
793
|
-
i0.ɵɵelement(1, "span",
|
|
794
|
-
i0.ɵɵelementStart(3, "span",
|
|
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);
|
|
795
892
|
i0.ɵɵtext(5);
|
|
796
893
|
i0.ɵɵelementEnd();
|
|
797
|
-
i0.ɵɵelementStart(6, "span",
|
|
894
|
+
i0.ɵɵelementStart(6, "span", 150);
|
|
798
895
|
i0.ɵɵtext(7, "Tap to return");
|
|
799
896
|
i0.ɵɵelementEnd()()();
|
|
800
897
|
} if (rf & 2) {
|
|
@@ -802,13 +899,13 @@ function ConversationChatAreaComponent_Conditional_20_Conditional_2_Template(rf,
|
|
|
802
899
|
i0.ɵɵadvance(5);
|
|
803
900
|
i0.ɵɵtextInterpolate1("On call \u00B7 ", ctx_r0.RealtimeSession.CurrentAgentName);
|
|
804
901
|
} }
|
|
805
|
-
function
|
|
806
|
-
const
|
|
807
|
-
i0.ɵɵelementStart(0, "mj-realtime-session-overlay",
|
|
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);
|
|
808
905
|
i0.ɵɵpipe(1, "async");
|
|
809
|
-
i0.ɵɵlistener("NavigateRequest", function
|
|
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()); });
|
|
810
907
|
i0.ɵɵelementEnd();
|
|
811
|
-
i0.ɵɵconditionalCreate(2,
|
|
908
|
+
i0.ɵɵconditionalCreate(2, ConversationChatAreaComponent_Conditional_21_Conditional_2_Template, 8, 1, "button", 144);
|
|
812
909
|
i0.ɵɵpipe(3, "async");
|
|
813
910
|
} if (rf & 2) {
|
|
814
911
|
const ctx_r0 = i0.ɵɵnextContext();
|
|
@@ -816,32 +913,32 @@ function ConversationChatAreaComponent_Conditional_20_Template(rf, ctx) { if (rf
|
|
|
816
913
|
i0.ɵɵadvance(2);
|
|
817
914
|
i0.ɵɵconditional(i0.ɵɵpipeBind1(3, 13, ctx_r0.RealtimeSession.Minimized$) ? 2 : -1);
|
|
818
915
|
} }
|
|
819
|
-
function
|
|
820
|
-
const
|
|
821
|
-
i0.ɵɵelementStart(0, "div",
|
|
822
|
-
i0.ɵɵlistener("click", function
|
|
823
|
-
i0.ɵɵelementStart(1, "div",
|
|
824
|
-
i0.ɵɵlistener("click", function
|
|
825
|
-
i0.ɵɵelementStart(2, "div",
|
|
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");
|
|
826
923
|
i0.ɵɵtext(4, "Assign Project");
|
|
827
924
|
i0.ɵɵelementEnd();
|
|
828
|
-
i0.ɵɵelementStart(5, "button",
|
|
829
|
-
i0.ɵɵlistener("click", function
|
|
830
|
-
i0.ɵɵelement(6, "i",
|
|
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);
|
|
831
928
|
i0.ɵɵelementEnd()();
|
|
832
|
-
i0.ɵɵelementStart(7, "div",
|
|
833
|
-
i0.ɵɵlistener("projectSelected", function
|
|
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)); });
|
|
834
931
|
i0.ɵɵelementEnd()()()();
|
|
835
932
|
} if (rf & 2) {
|
|
836
933
|
const ctx_r0 = i0.ɵɵnextContext();
|
|
837
934
|
i0.ɵɵadvance(8);
|
|
838
935
|
i0.ɵɵproperty("environmentId", ctx_r0.environmentId)("currentUser", ctx_r0.currentUser)("selectedProjectId", ctx_r0.conversation.ProjectID);
|
|
839
936
|
} }
|
|
840
|
-
function
|
|
841
|
-
const
|
|
842
|
-
i0.ɵɵelementStart(0, "button",
|
|
843
|
-
i0.ɵɵlistener("click", function
|
|
844
|
-
i0.ɵɵelement(1, "i",
|
|
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);
|
|
845
942
|
i0.ɵɵelementStart(2, "span");
|
|
846
943
|
i0.ɵɵtext(3);
|
|
847
944
|
i0.ɵɵelementEnd()();
|
|
@@ -851,106 +948,106 @@ function ConversationChatAreaComponent_Conditional_26_Conditional_6_Template(rf,
|
|
|
851
948
|
i0.ɵɵadvance(3);
|
|
852
949
|
i0.ɵɵtextInterpolate1("", ctx_r0.showSystemArtifacts ? "Hide" : "Show", " System");
|
|
853
950
|
} }
|
|
854
|
-
function
|
|
855
|
-
i0.ɵɵelement(0, "mj-empty-state",
|
|
951
|
+
function ConversationChatAreaComponent_Conditional_27_Conditional_10_Template(rf, ctx) { if (rf & 1) {
|
|
952
|
+
i0.ɵɵelement(0, "mj-empty-state", 162);
|
|
856
953
|
} }
|
|
857
|
-
function
|
|
954
|
+
function ConversationChatAreaComponent_Conditional_27_For_12_Conditional_8_Template(rf, ctx) { if (rf & 1) {
|
|
858
955
|
i0.ɵɵtext(0);
|
|
859
956
|
} if (rf & 2) {
|
|
860
|
-
const
|
|
861
|
-
i0.ɵɵtextInterpolate1(" ",
|
|
957
|
+
const artifact_r44 = i0.ɵɵnextContext().$implicit;
|
|
958
|
+
i0.ɵɵtextInterpolate1(" ", artifact_r44.versionCount, " versions ");
|
|
862
959
|
} }
|
|
863
|
-
function
|
|
960
|
+
function ConversationChatAreaComponent_Conditional_27_For_12_Conditional_9_Template(rf, ctx) { if (rf & 1) {
|
|
864
961
|
i0.ɵɵtext(0, " 1 version ");
|
|
865
962
|
} }
|
|
866
|
-
function
|
|
867
|
-
const
|
|
868
|
-
i0.ɵɵelementStart(0, "button",
|
|
869
|
-
i0.ɵɵlistener("click", function
|
|
870
|
-
i0.ɵɵelement(1, "i",
|
|
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);
|
|
871
968
|
i0.ɵɵelementEnd();
|
|
872
969
|
} if (rf & 2) {
|
|
873
|
-
const
|
|
970
|
+
const artifact_r44 = i0.ɵɵnextContext().$implicit;
|
|
874
971
|
const ctx_r0 = i0.ɵɵnextContext(2);
|
|
875
972
|
i0.ɵɵadvance();
|
|
876
|
-
i0.ɵɵclassProp("fa-chevron-down", ctx_r0.expandedArtifactId !==
|
|
973
|
+
i0.ɵɵclassProp("fa-chevron-down", ctx_r0.expandedArtifactId !== artifact_r44.artifactId)("fa-chevron-up", ctx_r0.expandedArtifactId === artifact_r44.artifactId);
|
|
877
974
|
} }
|
|
878
|
-
function
|
|
879
|
-
const
|
|
880
|
-
i0.ɵɵelementStart(0, "div",
|
|
881
|
-
i0.ɵɵlistener("click", function
|
|
882
|
-
i0.ɵɵelementStart(1, "span",
|
|
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);
|
|
883
980
|
i0.ɵɵtext(2);
|
|
884
981
|
i0.ɵɵelementEnd();
|
|
885
|
-
i0.ɵɵelementStart(3, "span",
|
|
982
|
+
i0.ɵɵelementStart(3, "span", 182);
|
|
886
983
|
i0.ɵɵtext(4, "Open this version");
|
|
887
984
|
i0.ɵɵelementEnd();
|
|
888
|
-
i0.ɵɵelement(5, "i",
|
|
985
|
+
i0.ɵɵelement(5, "i", 183);
|
|
889
986
|
i0.ɵɵelementEnd();
|
|
890
987
|
} if (rf & 2) {
|
|
891
|
-
const
|
|
988
|
+
const version_r47 = ctx.$implicit;
|
|
892
989
|
i0.ɵɵadvance(2);
|
|
893
|
-
i0.ɵɵtextInterpolate1("v",
|
|
990
|
+
i0.ɵɵtextInterpolate1("v", version_r47.versionNumber);
|
|
894
991
|
} }
|
|
895
|
-
function
|
|
896
|
-
i0.ɵɵelementStart(0, "div",
|
|
897
|
-
i0.ɵɵrepeaterCreate(1,
|
|
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);
|
|
898
995
|
i0.ɵɵelementEnd();
|
|
899
996
|
} if (rf & 2) {
|
|
900
|
-
const
|
|
997
|
+
const artifact_r44 = i0.ɵɵnextContext().$implicit;
|
|
901
998
|
i0.ɵɵadvance();
|
|
902
|
-
i0.ɵɵrepeater(
|
|
999
|
+
i0.ɵɵrepeater(artifact_r44.versions);
|
|
903
1000
|
} }
|
|
904
|
-
function
|
|
905
|
-
const
|
|
906
|
-
i0.ɵɵelementStart(0, "div",
|
|
907
|
-
i0.ɵɵlistener("click", function
|
|
908
|
-
i0.ɵɵelementStart(2, "div",
|
|
909
|
-
i0.ɵɵelement(3, "i",
|
|
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);
|
|
910
1007
|
i0.ɵɵelementEnd();
|
|
911
|
-
i0.ɵɵelementStart(4, "div",
|
|
1008
|
+
i0.ɵɵelementStart(4, "div", 170)(5, "div", 171);
|
|
912
1009
|
i0.ɵɵtext(6);
|
|
913
1010
|
i0.ɵɵelementEnd();
|
|
914
|
-
i0.ɵɵelementStart(7, "div",
|
|
915
|
-
i0.ɵɵconditionalCreate(8,
|
|
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);
|
|
916
1013
|
i0.ɵɵelementEnd()();
|
|
917
|
-
i0.ɵɵconditionalCreate(10,
|
|
918
|
-
i0.ɵɵelementStart(11, "div",
|
|
919
|
-
i0.ɵɵelement(12, "i",
|
|
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);
|
|
920
1017
|
i0.ɵɵelementEnd()();
|
|
921
|
-
i0.ɵɵconditionalCreate(13,
|
|
1018
|
+
i0.ɵɵconditionalCreate(13, ConversationChatAreaComponent_Conditional_27_For_12_Conditional_13_Template, 3, 0, "div", 176);
|
|
922
1019
|
i0.ɵɵelementEnd();
|
|
923
1020
|
} if (rf & 2) {
|
|
924
|
-
const
|
|
1021
|
+
const artifact_r44 = ctx.$implicit;
|
|
925
1022
|
const ctx_r0 = i0.ɵɵnextContext(2);
|
|
926
|
-
i0.ɵɵclassProp("expanded", ctx_r0.expandedArtifactId ===
|
|
1023
|
+
i0.ɵɵclassProp("expanded", ctx_r0.expandedArtifactId === artifact_r44.artifactId)("system-artifact", artifact_r44.visibility === "System Only");
|
|
927
1024
|
i0.ɵɵadvance(6);
|
|
928
|
-
i0.ɵɵtextInterpolate(
|
|
1025
|
+
i0.ɵɵtextInterpolate(artifact_r44.name);
|
|
929
1026
|
i0.ɵɵadvance(2);
|
|
930
|
-
i0.ɵɵconditional(
|
|
1027
|
+
i0.ɵɵconditional(artifact_r44.versionCount > 1 ? 8 : 9);
|
|
931
1028
|
i0.ɵɵadvance(2);
|
|
932
|
-
i0.ɵɵconditional(
|
|
1029
|
+
i0.ɵɵconditional(artifact_r44.versionCount > 1 ? 10 : -1);
|
|
933
1030
|
i0.ɵɵadvance(3);
|
|
934
|
-
i0.ɵɵconditional(ctx_r0.expandedArtifactId ===
|
|
1031
|
+
i0.ɵɵconditional(ctx_r0.expandedArtifactId === artifact_r44.artifactId && artifact_r44.versionCount > 1 ? 13 : -1);
|
|
935
1032
|
} }
|
|
936
|
-
function
|
|
937
|
-
const
|
|
938
|
-
i0.ɵɵelementStart(0, "div",
|
|
939
|
-
i0.ɵɵlistener("click", function
|
|
940
|
-
i0.ɵɵelementStart(1, "div",
|
|
941
|
-
i0.ɵɵlistener("click", function
|
|
942
|
-
i0.ɵɵelementStart(2, "div",
|
|
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");
|
|
943
1040
|
i0.ɵɵtext(4, "Conversation Artifacts");
|
|
944
1041
|
i0.ɵɵelementEnd();
|
|
945
|
-
i0.ɵɵelementStart(5, "div",
|
|
946
|
-
i0.ɵɵconditionalCreate(6,
|
|
947
|
-
i0.ɵɵelementStart(7, "button",
|
|
948
|
-
i0.ɵɵlistener("click", function
|
|
949
|
-
i0.ɵɵelement(8, "i",
|
|
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);
|
|
950
1047
|
i0.ɵɵelementEnd()()();
|
|
951
|
-
i0.ɵɵelementStart(9, "div",
|
|
952
|
-
i0.ɵɵconditionalCreate(10,
|
|
953
|
-
i0.ɵɵrepeaterCreate(11,
|
|
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);
|
|
954
1051
|
i0.ɵɵelementEnd()()();
|
|
955
1052
|
} if (rf & 2) {
|
|
956
1053
|
const ctx_r0 = i0.ɵɵnextContext();
|
|
@@ -961,28 +1058,28 @@ function ConversationChatAreaComponent_Conditional_26_Template(rf, ctx) { if (rf
|
|
|
961
1058
|
i0.ɵɵadvance();
|
|
962
1059
|
i0.ɵɵrepeater(ctx_r0.getArtifactsArray());
|
|
963
1060
|
} }
|
|
964
|
-
function
|
|
965
|
-
const
|
|
966
|
-
i0.ɵɵelementStart(0, "mj-artifact-collection-picker-modal",
|
|
967
|
-
i0.ɵɵlistener("completed", function
|
|
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()); });
|
|
968
1065
|
i0.ɵɵelementEnd();
|
|
969
1066
|
} if (rf & 2) {
|
|
970
1067
|
const ctx_r0 = i0.ɵɵnextContext();
|
|
971
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);
|
|
972
1069
|
} }
|
|
973
|
-
function
|
|
974
|
-
const
|
|
975
|
-
i0.ɵɵelementStart(0, "mj-test-feedback-dialog",
|
|
976
|
-
i0.ɵɵlistener("closed", function
|
|
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)); });
|
|
977
1074
|
i0.ɵɵelementEnd();
|
|
978
1075
|
} if (rf & 2) {
|
|
979
1076
|
const ctx_r0 = i0.ɵɵnextContext();
|
|
980
1077
|
i0.ɵɵproperty("data", ctx_r0.testFeedbackDialogData)("visible", ctx_r0.showTestFeedbackDialog);
|
|
981
1078
|
} }
|
|
982
|
-
function
|
|
983
|
-
const
|
|
984
|
-
i0.ɵɵelementStart(0, "mj-image-viewer",
|
|
985
|
-
i0.ɵɵlistener("closed", function
|
|
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()); });
|
|
986
1083
|
i0.ɵɵelementEnd();
|
|
987
1084
|
} if (rf & 2) {
|
|
988
1085
|
const ctx_r0 = i0.ɵɵnextContext();
|
|
@@ -990,6 +1087,7 @@ function ConversationChatAreaComponent_Conditional_29_Template(rf, ctx) { if (rf
|
|
|
990
1087
|
} }
|
|
991
1088
|
/** `MJ: Resource Types.ID` for Conversations. */
|
|
992
1089
|
const CONVERSATIONS_RESOURCE_TYPE_ID = '81D4BC3D-9FEB-EF11-B01A-286B35C04427';
|
|
1090
|
+
const EMPTY_THREAD_REPLY_ROOTS = new UUIDMap();
|
|
993
1091
|
/** Run statuses that mean the run is over, for the run-list fallback. `Paused` is still working. */
|
|
994
1092
|
const RUN_LIST_TERMINAL_STATUSES = ['Completed', 'AwaitingFeedback', 'Failed', 'Cancelled'];
|
|
995
1093
|
/** Default width (percentage) for the artifact viewer pane */
|
|
@@ -1087,7 +1185,16 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
1087
1185
|
set conversationId(value) {
|
|
1088
1186
|
this.ConversationId = value;
|
|
1089
1187
|
}
|
|
1090
|
-
|
|
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
|
+
}
|
|
1091
1198
|
/** @deprecated Use {@link Conversation}. */
|
|
1092
1199
|
set conversation(value) {
|
|
1093
1200
|
this.Conversation = value;
|
|
@@ -1214,6 +1321,12 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
1214
1321
|
* that authorization to a role to stop the server creating forks as well.
|
|
1215
1322
|
*/
|
|
1216
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;
|
|
1217
1330
|
/**
|
|
1218
1331
|
* Host-level cap for stopping and continuing agent runs: the composer's Stop and Stop all, the
|
|
1219
1332
|
* Stop pill on an in-progress reply, the Continue button on a stopped reply, and the "Continue,
|
|
@@ -1808,11 +1921,100 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
1808
1921
|
return this.ShowAgentModePicker && !!this.ModePickerTargetAgentId;
|
|
1809
1922
|
}
|
|
1810
1923
|
get ModePickerTargetAgentId() {
|
|
1811
|
-
return this.
|
|
1924
|
+
return this.CurrentOwnerAgent?.ID
|
|
1925
|
+
?? this.Conversation?.DefaultAgentID
|
|
1812
1926
|
?? this.DefaultAgentId
|
|
1813
1927
|
?? this.conversationManagerAgent?.ID
|
|
1814
1928
|
?? null;
|
|
1815
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
|
+
}
|
|
1816
2018
|
/**
|
|
1817
2019
|
* Mode picker emitted a new selection. Store it; the next message's
|
|
1818
2020
|
* route picks it up via `<mj-message-input>`'s
|
|
@@ -2271,7 +2473,7 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
2271
2473
|
*/
|
|
2272
2474
|
initialDraftSnapshots = new Map();
|
|
2273
2475
|
GetInitialDraftFor(conversationId) {
|
|
2274
|
-
const key = conversationId ? conversationId
|
|
2476
|
+
const key = conversationId ? NormalizeUUID(conversationId) : 'new';
|
|
2275
2477
|
if (!this.initialDraftSnapshots.has(key)) {
|
|
2276
2478
|
let snapshot;
|
|
2277
2479
|
if (this._composerAgentMention) {
|
|
@@ -2306,14 +2508,17 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
2306
2508
|
}
|
|
2307
2509
|
// New/unsaved conversations render the empty-state composer; established ones
|
|
2308
2510
|
// use the active cached input. Both resolve the agent to a pill.
|
|
2309
|
-
const
|
|
2511
|
+
const activeInput = this.getActiveMessageInputComponent() ??
|
|
2512
|
+
this.messageInputComponents?.last ??
|
|
2513
|
+
this.messageInputComponents?.first;
|
|
2514
|
+
const target = this.emptyStateComponent ? 'empty-state' : activeInput ? 'active-input' : null;
|
|
2310
2515
|
if (attempt === 0 || attempt % 10 === 0 || target) {
|
|
2311
2516
|
console.log(`[Omnibar→Chat] chat-area apply('${agentName}') attempt ${attempt}: target=${target ?? 'none-mounted'}`);
|
|
2312
2517
|
}
|
|
2313
2518
|
const insert = this.emptyStateComponent
|
|
2314
2519
|
? this.emptyStateComponent.InsertAgentMention(agentName, true)
|
|
2315
|
-
:
|
|
2316
|
-
?
|
|
2520
|
+
: activeInput
|
|
2521
|
+
? activeInput.InsertAgentMention(agentName, true)
|
|
2317
2522
|
: null;
|
|
2318
2523
|
if (insert) {
|
|
2319
2524
|
void insert.then((applied) => {
|
|
@@ -2424,6 +2629,13 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
2424
2629
|
reconcileInFlight = null;
|
|
2425
2630
|
/** Reason for one more reconcile pass, requested while a pass was running. */
|
|
2426
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;
|
|
2427
2639
|
IsProcessing = false;
|
|
2428
2640
|
/** @deprecated Use {@link IsProcessing}. */
|
|
2429
2641
|
get isProcessing() {
|
|
@@ -2554,6 +2766,44 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
2554
2766
|
}
|
|
2555
2767
|
ShowArtifactPanel = false;
|
|
2556
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
|
+
}
|
|
2557
2807
|
/** @deprecated Use {@link ShowArtifactPanel}. */
|
|
2558
2808
|
get showArtifactPanel() {
|
|
2559
2809
|
return this.ShowArtifactPanel;
|
|
@@ -2770,6 +3020,12 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
2770
3020
|
set agentRunsByDetailId(value) {
|
|
2771
3021
|
this.AgentRunsByDetailId = value;
|
|
2772
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();
|
|
2773
3029
|
/**
|
|
2774
3030
|
* Ratings by conversation detail ID (parsed from RatingsJSON)
|
|
2775
3031
|
*/
|
|
@@ -3640,12 +3896,7 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
3640
3896
|
// runtime itself, which closes the call surface with it: say why, or the call just vanishes.
|
|
3641
3897
|
this.RealtimeSession.SessionEnded$
|
|
3642
3898
|
.pipe(takeUntil(this.destroy$))
|
|
3643
|
-
.subscribe((ended) =>
|
|
3644
|
-
if (ended.reason === 'error') {
|
|
3645
|
-
const notice = DescribeCallFailureNotice(this.RealtimeSession.LastStartError, this.RealtimeSession.LastSessionError);
|
|
3646
|
-
MJNotificationService.Instance.CreateSimpleNotification(notice, 'error', 6000);
|
|
3647
|
-
}
|
|
3648
|
-
});
|
|
3899
|
+
.subscribe((ended) => this.notifyIfCallFailed(ended.reason));
|
|
3649
3900
|
let voiceWasActive = false;
|
|
3650
3901
|
this.RealtimeSession.Active$
|
|
3651
3902
|
.pipe(takeUntil(this.destroy$))
|
|
@@ -3795,7 +4046,7 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
3795
4046
|
this.resetComponentState(conversationId);
|
|
3796
4047
|
await this.decideAndApplyArtifactPanel(artifactBaseline, conversationId);
|
|
3797
4048
|
this.messages = [...this.messages];
|
|
3798
|
-
this.followTranscript('new');
|
|
4049
|
+
this.followTranscript('new', newlyLoaded);
|
|
3799
4050
|
this.cdr.detectChanges();
|
|
3800
4051
|
}
|
|
3801
4052
|
else {
|
|
@@ -3966,11 +4217,19 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
3966
4217
|
for (const id of [...(this._stopFallbackTimers?.keys() ?? [])]) {
|
|
3967
4218
|
this.clearStopFallbackTimer(id);
|
|
3968
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
|
+
}
|
|
3969
4225
|
// Remove resize listeners
|
|
3970
|
-
window
|
|
3971
|
-
|
|
3972
|
-
|
|
3973
|
-
|
|
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();
|
|
3974
4233
|
}
|
|
3975
4234
|
isActiveConversation(conversationId) {
|
|
3976
4235
|
return UUIDsEqual(conversationId, this.ConversationId);
|
|
@@ -3987,6 +4246,13 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
3987
4246
|
this.clearTurnTracking();
|
|
3988
4247
|
this.ShowArtifactPanel = false;
|
|
3989
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
|
+
}
|
|
3990
4256
|
this.SelectedArtifactId = null;
|
|
3991
4257
|
this.SelectedVersionNumber = undefined;
|
|
3992
4258
|
this.CanShareSelectedArtifact = false;
|
|
@@ -4027,6 +4293,8 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
4027
4293
|
this.ForkSummaries = [];
|
|
4028
4294
|
this.ShowForksPopover = false;
|
|
4029
4295
|
this.IsRenamingTitle = false;
|
|
4296
|
+
this.HandoffsByDetailId = new Map();
|
|
4297
|
+
this.handoffStepsByRunId?.clear();
|
|
4030
4298
|
if (this.forkSummaryRefreshTimer) {
|
|
4031
4299
|
clearTimeout(this.forkSummaryRefreshTimer);
|
|
4032
4300
|
this.forkSummaryRefreshTimer = null;
|
|
@@ -4060,12 +4328,7 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
4060
4328
|
if ((this.ArtifactsByDetailId?.size ?? 0) === 0 && this.artifactMapConversationId === null) {
|
|
4061
4329
|
this.artifactMapConversationId = conversationId;
|
|
4062
4330
|
}
|
|
4063
|
-
|
|
4064
|
-
this.messageInputMetadataCache.set(conversationId, {
|
|
4065
|
-
conversationId: conversationId,
|
|
4066
|
-
conversationName: this.Conversation?.Name || null
|
|
4067
|
-
});
|
|
4068
|
-
}
|
|
4331
|
+
this.touchMessageInputCache(conversationId);
|
|
4069
4332
|
// Only show loading spinner if the engine doesn't have cached data for this conversation.
|
|
4070
4333
|
// This prevents the "no messages" flash when switching between conversations.
|
|
4071
4334
|
const hasCachedMessages = this.engine.HasCachedDetails(conversationId);
|
|
@@ -4129,6 +4392,108 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
4129
4392
|
}
|
|
4130
4393
|
_cachedInputsArray = [];
|
|
4131
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
|
+
}
|
|
4132
4497
|
/**
|
|
4133
4498
|
* Returns array of cached message-input metadata for rendering.
|
|
4134
4499
|
* This allows multiple message-input components to exist simultaneously (hidden)
|
|
@@ -4170,10 +4535,10 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
4170
4535
|
* we need to find the one that matches the current conversationId.
|
|
4171
4536
|
*/
|
|
4172
4537
|
getActiveMessageInputComponent() {
|
|
4173
|
-
if (!this.
|
|
4538
|
+
if (!this.ConversationId) {
|
|
4174
4539
|
return undefined;
|
|
4175
4540
|
}
|
|
4176
|
-
return this.
|
|
4541
|
+
return this.findMessageInputComponent(this.ConversationId);
|
|
4177
4542
|
}
|
|
4178
4543
|
async loadMessages(conversationId, loadToken) {
|
|
4179
4544
|
try {
|
|
@@ -4327,7 +4692,7 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
4327
4692
|
if (!this.isActiveConversationLoad(conversationId, loadToken)) {
|
|
4328
4693
|
return;
|
|
4329
4694
|
}
|
|
4330
|
-
this.windowStore.SetPinnedCount(result.Success ? result.TotalRowCount : 0);
|
|
4695
|
+
this.windowStore.SetPinnedCount(result.Success ? result.TotalRowCount ?? 0 : 0);
|
|
4331
4696
|
}
|
|
4332
4697
|
/**
|
|
4333
4698
|
* Hydrates the pins panel's rows — first panel open only.
|
|
@@ -4448,6 +4813,18 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
4448
4813
|
if (sessionMeta.size > 0) {
|
|
4449
4814
|
this.RealtimeSessionMetaMap = new Map([...this.RealtimeSessionMetaMap, ...sessionMeta]);
|
|
4450
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
|
+
}
|
|
4451
4828
|
// A page of OLDER artifacts just entered the map. Any artifact-panel baseline taken before
|
|
4452
4829
|
// this point can no longer be diffed against the map for creations — these arrived from
|
|
4453
4830
|
// history, not from a run. See snapshotArtifactPanelBaseline.
|
|
@@ -4489,6 +4866,7 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
4489
4866
|
this.ArtifactsByDetailId.clear();
|
|
4490
4867
|
this.SystemArtifactsByDetailId.clear();
|
|
4491
4868
|
this.RatingsByDetailId.clear();
|
|
4869
|
+
this.handoffStepsByRunId.clear();
|
|
4492
4870
|
// Copy agent runs from engine (cast to extended type for UI compatibility)
|
|
4493
4871
|
for (const [detailId, agentRun] of cacheEntry.AgentRunsByDetailId) {
|
|
4494
4872
|
this.AgentRunsByDetailId.set(detailId, agentRun);
|
|
@@ -4520,6 +4898,13 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
4520
4898
|
if (!this.isCurrentConversationContext(conversationId, loadToken)) {
|
|
4521
4899
|
return;
|
|
4522
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
|
+
}
|
|
4523
4908
|
// Create new Map references to trigger Angular change detection
|
|
4524
4909
|
this.AgentRunsByDetailId = new Map(this.AgentRunsByDetailId);
|
|
4525
4910
|
this.ArtifactsByDetailId = new Map(this.ArtifactsByDetailId);
|
|
@@ -4542,6 +4927,42 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
4542
4927
|
this.artifactMapConversationId = null;
|
|
4543
4928
|
}
|
|
4544
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
|
+
}
|
|
4545
4966
|
/**
|
|
4546
4967
|
* Loads the `MJ: AI Agent Sessions` rows referenced by the conversation's
|
|
4547
4968
|
* session-stamped details (one batched lookup, narrow fields, only when stamped rows
|
|
@@ -4636,12 +5057,25 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
4636
5057
|
this.replaceDisplayedRow(message);
|
|
4637
5058
|
this.windowStore.ApplyLocalDetail(message);
|
|
4638
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
|
+
}
|
|
4639
5073
|
if (!this.messageListComponent?.RefreshRenderedMessage(message)) {
|
|
4640
5074
|
// The first delta can beat the bubble's own render; the full path handles that one update.
|
|
4641
5075
|
this.ngZone.run(() => void this.OnMessageSent(message));
|
|
4642
5076
|
return;
|
|
4643
5077
|
}
|
|
4644
|
-
this.followTranscript('stream');
|
|
5078
|
+
this.followTranscript('stream', message);
|
|
4645
5079
|
}
|
|
4646
5080
|
/** Drops a landing still queued or retrying, so it cannot resolve after a newer one. */
|
|
4647
5081
|
cancelPendingLanding() {
|
|
@@ -4729,8 +5163,15 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
4729
5163
|
}
|
|
4730
5164
|
}
|
|
4731
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
|
+
}
|
|
4732
5170
|
// Where the viewport goes: a fresh send follows — an in-place update of a message that
|
|
4733
|
-
// is already on screen must not re-run the send path's scroll.
|
|
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
|
+
}
|
|
4734
5175
|
this.followTranscript(upsert.Existed ? 'update' : 'new', message);
|
|
4735
5176
|
// Force change detection — zone.js 0.15 no longer patches graphql-ws WebSocket callbacks,
|
|
4736
5177
|
// so progress updates that arrive via PubSub run outside Angular's zone. Without this,
|
|
@@ -4856,10 +5297,17 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
4856
5297
|
ConversationEngine.Instance.SetAgentRunForDetail(event.conversationId, event.conversationDetailId, newEntity);
|
|
4857
5298
|
}
|
|
4858
5299
|
}
|
|
5300
|
+
await this.loadHandoffStepsForRunIds([existingAgentRun.ID], event.conversationId);
|
|
5301
|
+
if (!this.isActiveConversation(event.conversationId)) {
|
|
5302
|
+
return;
|
|
5303
|
+
}
|
|
4859
5304
|
// Trigger re-render to show updated status
|
|
4860
5305
|
this.messages = [...this.messages];
|
|
4861
5306
|
this.cdr.detectChanges();
|
|
4862
5307
|
}
|
|
5308
|
+
else {
|
|
5309
|
+
this.rebuildHandoffsMap();
|
|
5310
|
+
}
|
|
4863
5311
|
// Reload attachments for this message to pick up newly created media attachments
|
|
4864
5312
|
// (e.g., images generated by agent via Generate Image action)
|
|
4865
5313
|
// This must be done after agent completion because attachments are created by AgentRunner
|
|
@@ -4895,6 +5343,9 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
4895
5343
|
ConversationEngine.Instance.SetAgentRunForDetail(event.conversationId, event.conversationDetailId, event.agentRun);
|
|
4896
5344
|
}
|
|
4897
5345
|
}
|
|
5346
|
+
if (!existingRun || !UUIDsEqual(existingRun.ID, event.agentRun.ID)) {
|
|
5347
|
+
this.rebuildHandoffsMap();
|
|
5348
|
+
}
|
|
4898
5349
|
}
|
|
4899
5350
|
else {
|
|
4900
5351
|
// no agent run, should have agentRunId
|
|
@@ -4950,7 +5401,7 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
4950
5401
|
// Track existing message IDs before reload to identify new messages
|
|
4951
5402
|
const existingMessageIds = new Set(this.messages.map(m => m.ID));
|
|
4952
5403
|
// Merge the refreshed window with existing client-side messages.
|
|
4953
|
-
// Preserves messages added client-side (e.g.,
|
|
5404
|
+
// Preserves messages added client-side (e.g., server-followed handoff rows)
|
|
4954
5405
|
// that haven't been picked up by entity events yet due to timing.
|
|
4955
5406
|
const merged = new Map();
|
|
4956
5407
|
for (const msg of engineDetails) {
|
|
@@ -4966,15 +5417,20 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
4966
5417
|
// Find newly discovered messages (delegated agents)
|
|
4967
5418
|
const newMessages = engineDetails.filter(m => !existingMessageIds.has(m.ID));
|
|
4968
5419
|
// Check engine cache for agent runs on new messages
|
|
5420
|
+
const discoveredRunIds = [];
|
|
4969
5421
|
for (const message of newMessages) {
|
|
4970
5422
|
if (message.AgentID && message.ID) {
|
|
4971
5423
|
const agentRun = this.engine.GetAgentRunForDetail(conversationId, message.ID);
|
|
4972
5424
|
if (agentRun) {
|
|
4973
5425
|
this.AgentRunsByDetailId.set(message.ID, agentRun);
|
|
5426
|
+
if (agentRun.ID) {
|
|
5427
|
+
discoveredRunIds.push(agentRun.ID);
|
|
5428
|
+
}
|
|
4974
5429
|
LogStatusEx({ message: `✅ Found cached agent run for new delegated message ${message.ID}`, verboseOnly: true });
|
|
4975
5430
|
}
|
|
4976
5431
|
}
|
|
4977
5432
|
}
|
|
5433
|
+
await this.loadHandoffStepsForRunIds(discoveredRunIds, conversationId);
|
|
4978
5434
|
LogStatusEx({ message: `✅ Refreshed ${engineDetails.length} messages from engine cache (${newMessages.length} new)`, verboseOnly: true });
|
|
4979
5435
|
}
|
|
4980
5436
|
catch (error) {
|
|
@@ -5614,22 +6070,36 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
5614
6070
|
const view = this.WindowView;
|
|
5615
6071
|
const branches = UUIDsEqual(this.branchRowsConversationId, this.ConversationId) ? (this.branches ?? NO_BRANCHES) : NO_BRANCHES;
|
|
5616
6072
|
const canFork = this.CanFork;
|
|
6073
|
+
const collapseThreads = Boolean(this.CollapseThreadReplies);
|
|
5617
6074
|
const cache = this.inPlaceTurnCache;
|
|
5618
|
-
if (cache &&
|
|
6075
|
+
if (cache &&
|
|
6076
|
+
cache.Messages === messages &&
|
|
6077
|
+
cache.View === view &&
|
|
6078
|
+
cache.Branches === branches &&
|
|
6079
|
+
cache.CanFork === canFork &&
|
|
6080
|
+
cache.CollapseThreads === collapseThreads) {
|
|
5619
6081
|
return cache.Turn;
|
|
5620
6082
|
}
|
|
5621
6083
|
const turn = canFork ? null : this.unblockedLatestTurn(messages, view, branches);
|
|
5622
|
-
this.inPlaceTurnCache = {
|
|
6084
|
+
this.inPlaceTurnCache = {
|
|
6085
|
+
Messages: messages,
|
|
6086
|
+
View: view,
|
|
6087
|
+
Branches: branches,
|
|
6088
|
+
CanFork: canFork,
|
|
6089
|
+
CollapseThreads: collapseThreads,
|
|
6090
|
+
Turn: turn,
|
|
6091
|
+
};
|
|
5623
6092
|
return turn;
|
|
5624
6093
|
}
|
|
5625
6094
|
/** The latest turn of the rows, or null when there is none or a fork depends on its answer rows. */
|
|
5626
6095
|
unblockedLatestTurn(messages, view, branches) {
|
|
5627
|
-
const
|
|
5628
|
-
const
|
|
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;
|
|
5629
6099
|
if (!turn || !user) {
|
|
5630
6100
|
return null;
|
|
5631
6101
|
}
|
|
5632
|
-
return ForkDependsOnRows(user.BranchID ?? null,
|
|
6102
|
+
return ForkDependsOnRows(user.BranchID ?? null, this.turnRowsAfter(messages, user), branches) ? null : turn;
|
|
5633
6103
|
}
|
|
5634
6104
|
/** "Save and resend": the message item saved the new text of the latest user message; reruns its turn in place. */
|
|
5635
6105
|
async OnResendInPlaceRequested(userMessage) {
|
|
@@ -5653,7 +6123,7 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
5653
6123
|
if (!input) {
|
|
5654
6124
|
return;
|
|
5655
6125
|
}
|
|
5656
|
-
const answerRows =
|
|
6126
|
+
const answerRows = this.turnRowsAfter(this.messages ?? [], userMessage);
|
|
5657
6127
|
if (answerRows.some(r => r.Status === 'In-Progress')) {
|
|
5658
6128
|
MJNotificationService.Instance.CreateSimpleNotification('Wait for the current reply to finish', 'error', 3000);
|
|
5659
6129
|
return;
|
|
@@ -5697,6 +6167,23 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
5697
6167
|
this.inPlaceRerunInFlight = false;
|
|
5698
6168
|
}
|
|
5699
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
|
+
}
|
|
5700
6187
|
/**
|
|
5701
6188
|
* Marks each row replaced, one save at a time (parallel saves race on the server's transaction
|
|
5702
6189
|
* counter): `ReplacedAt` set and `HiddenToUser` true; the rows are kept for audit. Takes the saved rows
|
|
@@ -5786,7 +6273,7 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
5786
6273
|
}
|
|
5787
6274
|
/** The nearest earlier User row in the loaded window; null when the window holds none. */
|
|
5788
6275
|
findUserMessageBefore(aiMessage) {
|
|
5789
|
-
const sorted = [...this.
|
|
6276
|
+
const sorted = [...this.displayState().MainFlow].sort((a, b) => a.Sequence - b.Sequence);
|
|
5790
6277
|
const index = sorted.findIndex(m => UUIDsEqual(m.ID, aiMessage.ID));
|
|
5791
6278
|
for (let i = index - 1; i >= 0; i--) {
|
|
5792
6279
|
if (sorted[i].Role === 'User') {
|
|
@@ -5899,6 +6386,17 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
5899
6386
|
get WindowView() {
|
|
5900
6387
|
return this.windowView ?? MAIN_OPEN_VIEW;
|
|
5901
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();
|
|
5902
6400
|
/**
|
|
5903
6401
|
* The rows the message list shows for the window view; the same array until the rows or the view
|
|
5904
6402
|
* change. Main shows every loaded row; a fork shows every inherited row, then its own rows; a draft
|
|
@@ -5911,16 +6409,45 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
5911
6409
|
displayState() {
|
|
5912
6410
|
const messages = this.messages ?? [];
|
|
5913
6411
|
const view = this.WindowView;
|
|
6412
|
+
const collapseThreads = Boolean(this.CollapseThreadReplies);
|
|
5914
6413
|
const cache = this.displayCache;
|
|
5915
|
-
if (cache && cache.Messages === messages && cache.View === view) {
|
|
6414
|
+
if (cache && cache.Messages === messages && cache.View === view && cache.CollapseThreads === collapseThreads) {
|
|
5916
6415
|
return cache;
|
|
5917
6416
|
}
|
|
5918
|
-
const
|
|
5919
|
-
const
|
|
5920
|
-
const
|
|
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
|
+
};
|
|
5921
6430
|
this.displayCache = next;
|
|
5922
6431
|
return next;
|
|
5923
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
|
+
}
|
|
5924
6451
|
/**
|
|
5925
6452
|
* Puts `message` in place of the row with its id in the displayed rows and their split, keeping those
|
|
5926
6453
|
* arrays. They are copies of `messages`, so an entity replaced in place there is replaced here too.
|
|
@@ -5930,6 +6457,7 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
5930
6457
|
if (!cache || cache.Messages !== this.messages) {
|
|
5931
6458
|
return;
|
|
5932
6459
|
}
|
|
6460
|
+
this.replaceRowIn(cache.MainFlow, message);
|
|
5933
6461
|
this.replaceRowIn(cache.Rows, message);
|
|
5934
6462
|
this.replaceRowIn(cache.Split.Inherited, message);
|
|
5935
6463
|
this.replaceRowIn(cache.Split.Own, message);
|
|
@@ -5990,6 +6518,13 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
5990
6518
|
if (stoppedAgent !== undefined) {
|
|
5991
6519
|
return `Continue, or tell ${stoppedAgent ?? 'the agent'} what to do differently`;
|
|
5992
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
|
+
}
|
|
5993
6528
|
}
|
|
5994
6529
|
return MAIN_COMPOSER_PLACEHOLDER;
|
|
5995
6530
|
}
|
|
@@ -6106,7 +6641,8 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
6106
6641
|
if (anchor) {
|
|
6107
6642
|
return anchor;
|
|
6108
6643
|
}
|
|
6109
|
-
const
|
|
6644
|
+
const state = this.displayState();
|
|
6645
|
+
const inherited = view === this.WindowView ? state.Split.Inherited : SplitForkRows(state.MainFlow, view).Inherited;
|
|
6110
6646
|
return inherited.length > 0 ? inherited[inherited.length - 1] : null;
|
|
6111
6647
|
}
|
|
6112
6648
|
/** A short date and time for fork text, in the person's locale. */
|
|
@@ -6292,6 +6828,10 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
6292
6828
|
if (!isCurrent()) {
|
|
6293
6829
|
return;
|
|
6294
6830
|
}
|
|
6831
|
+
await this.loadHandoffStepsForRunIds([agentRun.ID], expectedConversationId, loadToken);
|
|
6832
|
+
if (!isCurrent()) {
|
|
6833
|
+
return;
|
|
6834
|
+
}
|
|
6295
6835
|
}
|
|
6296
6836
|
}
|
|
6297
6837
|
// Reload artifacts for this completed message
|
|
@@ -6330,6 +6870,7 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
6330
6870
|
// The completed message was mutated in place — refresh the window's copy too.
|
|
6331
6871
|
this.windowStore.ApplyLocalDetail(message);
|
|
6332
6872
|
// Force re-render with updated agent run and artifacts
|
|
6873
|
+
this.rebuildHandoffsMap();
|
|
6333
6874
|
this.messages = [...this.messages];
|
|
6334
6875
|
this.cdr.detectChanges();
|
|
6335
6876
|
LogStatusEx({ message: `✅ Completion handled for message ${message.ID}`, verboseOnly: true });
|
|
@@ -6344,6 +6885,8 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
6344
6885
|
if (!finished && completionId) {
|
|
6345
6886
|
this.handledCompletionIds?.delete(completionId);
|
|
6346
6887
|
}
|
|
6888
|
+
// The row was loaded above whatever happened after; if it settled, it is no longer in flight.
|
|
6889
|
+
this.dropSettledFromInFlight();
|
|
6347
6890
|
}
|
|
6348
6891
|
}
|
|
6349
6892
|
async OnAgentResponse(event) {
|
|
@@ -6436,6 +6979,10 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
6436
6979
|
ConversationEngine.Instance.SetAgentRunForDetail(conversationId, conversationDetailId, existingRun);
|
|
6437
6980
|
}
|
|
6438
6981
|
}
|
|
6982
|
+
await this.loadHandoffStepsForRunIds([agentRunId], conversationId);
|
|
6983
|
+
if (!this.isActiveConversation(conversationId)) {
|
|
6984
|
+
return agentRun;
|
|
6985
|
+
}
|
|
6439
6986
|
// Refresh the target message in place when already rendered; fall back to
|
|
6440
6987
|
// shallow array copy only when the message is not yet mounted in the list.
|
|
6441
6988
|
const targetMessage = this.messages.find(m => UUIDsEqual(m.ID, conversationDetailId));
|
|
@@ -7013,14 +7560,13 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
7013
7560
|
// region the list unmounts into spacers — so this button silently did nothing for any pin
|
|
7014
7561
|
// that wasn't already on screen. The list resolves through the timeline key, which a
|
|
7015
7562
|
// spacer shares with the item it stands in for.
|
|
7016
|
-
if (this.
|
|
7017
|
-
this.beaconMessage(messageId);
|
|
7563
|
+
if (this.scrollToMessageOrThreadRoot(messageId)) {
|
|
7018
7564
|
return;
|
|
7019
7565
|
}
|
|
7020
7566
|
// Not in the loaded window. Pins are fetched by their own query precisely so the panel can
|
|
7021
7567
|
// list pins older than the transcript, so this is the EXPECTED case for an old pin, not an
|
|
7022
7568
|
// error — page back until it is loaded, the same way a date jump does.
|
|
7023
|
-
const reached = await this.loadUntilMessageIsWindowed(messageId);
|
|
7569
|
+
const reached = (await this.loadUntilMessageIsWindowed(messageId)) && (await this.loadUntilThreadRootIsWindowed(messageId));
|
|
7024
7570
|
if (!reached) {
|
|
7025
7571
|
MJNotificationService.Instance.CreateSimpleNotification('Could not reach that message — it is further back than this jump loads.', 'info', 3000);
|
|
7026
7572
|
return;
|
|
@@ -7028,10 +7574,7 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
7028
7574
|
// The paging loop deliberately skipped the per-page peripheral rebuild — pay it once,
|
|
7029
7575
|
// here, before asking the list for element positions.
|
|
7030
7576
|
await this.refreshAfterPaging(this.ConversationId);
|
|
7031
|
-
if (this.
|
|
7032
|
-
this.beaconMessage(messageId);
|
|
7033
|
-
}
|
|
7034
|
-
else {
|
|
7577
|
+
if (!this.scrollToMessageOrThreadRoot(messageId)) {
|
|
7035
7578
|
MJNotificationService.Instance.CreateSimpleNotification('Could not find that message in this conversation', 'info', 3000);
|
|
7036
7579
|
}
|
|
7037
7580
|
}
|
|
@@ -7063,6 +7606,10 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
7063
7606
|
return false;
|
|
7064
7607
|
}
|
|
7065
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
|
+
}
|
|
7066
7613
|
if (!this.isActiveConversation(conversationId)) {
|
|
7067
7614
|
return false;
|
|
7068
7615
|
}
|
|
@@ -7073,13 +7620,43 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
7073
7620
|
this.scrollToBottom = false;
|
|
7074
7621
|
this.bottomFollowSuppressedUntil = Date.now() + 1500;
|
|
7075
7622
|
}
|
|
7076
|
-
if (!row || !this.
|
|
7623
|
+
if (!row || !this.scrollToMessageOrThreadRoot(row.ID, 'search-hit-highlight', 2000)) {
|
|
7077
7624
|
MJNotificationService.Instance.CreateSimpleNotification('Could not find that message in this conversation', 'info', 3000);
|
|
7078
7625
|
return false;
|
|
7079
7626
|
}
|
|
7080
|
-
this.beaconMessage(row.ID, 'search-hit-highlight', 2000);
|
|
7081
7627
|
return true;
|
|
7082
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
|
+
}
|
|
7083
7660
|
/**
|
|
7084
7661
|
* Waits until the load of `conversationId` has ended. False when another conversation
|
|
7085
7662
|
* becomes active first or the component is destroyed.
|
|
@@ -7095,12 +7672,39 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
7095
7672
|
}
|
|
7096
7673
|
/** Pages older history until the pinned message `messageId` falls inside the loaded window. */
|
|
7097
7674
|
async loadUntilMessageIsWindowed(messageId) {
|
|
7098
|
-
const target = this.PinnedMessages
|
|
7675
|
+
const target = this.PinnedMessages?.find(p => UUIDsEqual(p.ID, messageId));
|
|
7099
7676
|
if (!target) {
|
|
7100
7677
|
return false; // not a loaded pin — nothing tells us how far back to page
|
|
7101
7678
|
}
|
|
7102
7679
|
return this.loadUntilSequenceIsWindowed(target.Sequence);
|
|
7103
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
|
+
}
|
|
7104
7708
|
/**
|
|
7105
7709
|
* Pages older history until the loaded window reaches back to `sequence`.
|
|
7106
7710
|
*
|
|
@@ -7226,10 +7830,9 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
7226
7830
|
}
|
|
7227
7831
|
// Find this message and all messages after it sorted by Sequence
|
|
7228
7832
|
const sortedMessages = [...this.messages].sort((a, b) => a.Sequence - b.Sequence);
|
|
7229
|
-
const
|
|
7230
|
-
if (
|
|
7833
|
+
const toHide = this.rowsToDeleteFrom(sortedMessages, message.ID);
|
|
7834
|
+
if (toHide.length === 0)
|
|
7231
7835
|
return;
|
|
7232
|
-
const toHide = sortedMessages.slice(targetIndex);
|
|
7233
7836
|
const count = toHide.length;
|
|
7234
7837
|
const confirmed = await this.confirmDialog.confirm({
|
|
7235
7838
|
title: 'Delete Messages',
|
|
@@ -7262,15 +7865,52 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
7262
7865
|
console.error(`Failed to delete ConversationDetail ${e.ID}: ${last?.Message ?? 'unknown error'}`, last?.Error ?? '');
|
|
7263
7866
|
}
|
|
7264
7867
|
}
|
|
7265
|
-
const hideIds = new
|
|
7868
|
+
const hideIds = new UUIDSet(toHide.map(m => m.ID));
|
|
7266
7869
|
// Drop them from the window too, or the next RefreshLatest merge reinstates them.
|
|
7267
|
-
for (const
|
|
7268
|
-
this.windowStore.RemoveDetail(
|
|
7870
|
+
for (const m of toHide) {
|
|
7871
|
+
this.windowStore.RemoveDetail(m.ID);
|
|
7269
7872
|
}
|
|
7270
|
-
this.messages = this.messages.filter(m => !hideIds.
|
|
7873
|
+
this.messages = this.messages.filter(m => !hideIds.Has(m.ID));
|
|
7271
7874
|
this.resetComponentState(this.ConversationId);
|
|
7272
7875
|
this.cdr.detectChanges();
|
|
7273
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
|
+
}
|
|
7274
7914
|
/** @deprecated Use {@link OnDeleteMessage}. */
|
|
7275
7915
|
async onDeleteMessage(message) {
|
|
7276
7916
|
return this.OnDeleteMessage(message);
|
|
@@ -7377,6 +8017,7 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
7377
8017
|
this.SelectedVersionNumber = undefined;
|
|
7378
8018
|
}
|
|
7379
8019
|
this.SelectedTaskGraphPanel = null;
|
|
8020
|
+
this.ShowRemoteBrowserPanel = false;
|
|
7380
8021
|
this.ShowArtifactPanel = true;
|
|
7381
8022
|
// Load permissions for the selected artifact
|
|
7382
8023
|
await this.loadArtifactPermissions(data.artifactId, conversationId, data.artifactId);
|
|
@@ -7401,6 +8042,7 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
7401
8042
|
return;
|
|
7402
8043
|
}
|
|
7403
8044
|
this.ShowArtifactPanel = false;
|
|
8045
|
+
this.ShowRemoteBrowserPanel = false;
|
|
7404
8046
|
this.SelectedArtifactId = null;
|
|
7405
8047
|
this.SelectedTaskGraphPanel = {
|
|
7406
8048
|
parentTaskId: data.parentTaskId,
|
|
@@ -7414,6 +8056,73 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
7414
8056
|
this.resetArtifactPaneSizing();
|
|
7415
8057
|
this.cdr.detectChanges();
|
|
7416
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;
|
|
7417
8126
|
/**
|
|
7418
8127
|
* Persists the currently displayed Task Graph in the chat side-panel as a reusable
|
|
7419
8128
|
* Draft Flow Agent workflow via {@link WorkflowSaveOperation} and opens the new
|
|
@@ -7694,6 +8403,9 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
7694
8403
|
}
|
|
7695
8404
|
OnConversationRenamed(event) {
|
|
7696
8405
|
LogStatusEx({ message: '🎉 Conversation renamed', verboseOnly: true, additionalArgs: [event] });
|
|
8406
|
+
if (event?.conversationId && event.name) {
|
|
8407
|
+
this.syncCachedMessageInputName(event.conversationId, event.name);
|
|
8408
|
+
}
|
|
7697
8409
|
// Pass the event up to workspace component for animation
|
|
7698
8410
|
this.ConversationRenamed.emit(event);
|
|
7699
8411
|
}
|
|
@@ -7964,6 +8676,17 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
7964
8676
|
void this.engine.EnsureConversationLoaded(created, this.CurrentUser);
|
|
7965
8677
|
this.RealtimeConversationReady.emit({ conversationId: created, select: false });
|
|
7966
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
|
+
}
|
|
7967
8690
|
/**
|
|
7968
8691
|
* Post-call hook. Two responsibilities:
|
|
7969
8692
|
* 1. Reload the ACTIVE conversation's timeline so the session that just ended — whose
|
|
@@ -8734,6 +9457,9 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
8734
9457
|
* in flight.
|
|
8735
9458
|
*/
|
|
8736
9459
|
followTranscript(change, message) {
|
|
9460
|
+
if (message && this.collapsedThreadRootId(message) !== null) {
|
|
9461
|
+
return;
|
|
9462
|
+
}
|
|
8737
9463
|
if (change === 'load') {
|
|
8738
9464
|
this.scrollToBottom = true;
|
|
8739
9465
|
return;
|
|
@@ -8777,6 +9503,27 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
8777
9503
|
isSettled(message) {
|
|
8778
9504
|
return message.Status === 'Complete' || message.Status === 'Error';
|
|
8779
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
|
+
}
|
|
8780
9527
|
/**
|
|
8781
9528
|
* Where the viewport goes on a streamed delta, in the same frame as the DOM change so growth and
|
|
8782
9529
|
* scroll paint together. Without ReadReplyFromTop, or for a turn this component never saw open
|
|
@@ -8946,6 +9693,7 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
8946
9693
|
// (prioritizing ParentRunID == null and ContinuationDepth == 0 over continuation
|
|
8947
9694
|
// synthesis runs, and newest __mj_CreatedAt among ties so retried messages use their latest run).
|
|
8948
9695
|
const chosenByDetailId = new Map();
|
|
9696
|
+
const refreshedRunIds = [];
|
|
8949
9697
|
for (const run of result.Results || []) {
|
|
8950
9698
|
const detailId = run.ConversationDetailID;
|
|
8951
9699
|
if (!detailId) {
|
|
@@ -8958,9 +9706,13 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
8958
9706
|
}
|
|
8959
9707
|
for (const [detailId, run] of chosenByDetailId.entries()) {
|
|
8960
9708
|
this.AgentRunsByDetailId.set(detailId, run);
|
|
9709
|
+
if (run.ID) {
|
|
9710
|
+
refreshedRunIds.push(run.ID);
|
|
9711
|
+
}
|
|
8961
9712
|
}
|
|
8962
9713
|
// New map reference so OnPush children re-read it.
|
|
8963
9714
|
this.AgentRunsByDetailId = new Map(this.AgentRunsByDetailId);
|
|
9715
|
+
await this.loadHandoffStepsForRunIds(refreshedRunIds, conversationId, loadToken);
|
|
8964
9716
|
}
|
|
8965
9717
|
/**
|
|
8966
9718
|
* Reconcile in-progress messages against durable server state, on demand.
|
|
@@ -8975,6 +9727,9 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
8975
9727
|
* @param reason What prompted it — carried only for logging.
|
|
8976
9728
|
*/
|
|
8977
9729
|
async ReconcileNow(reason) {
|
|
9730
|
+
if (ConversationChatAreaComponent.TRANSPORT_RECONNECT_REASONS.includes(reason)) {
|
|
9731
|
+
this.reconcileWindowRefreshPending = true;
|
|
9732
|
+
}
|
|
8978
9733
|
if (this.reconcileInFlight) {
|
|
8979
9734
|
this.reconcileRerunReason = reason;
|
|
8980
9735
|
return this.reconcileInFlight;
|
|
@@ -8996,6 +9751,49 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
8996
9751
|
this.reconcileInFlight = null;
|
|
8997
9752
|
}
|
|
8998
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
|
+
}
|
|
8999
9797
|
/** One reconcile pass over the in-progress messages of the active conversation. */
|
|
9000
9798
|
async reconcileOnce(reason) {
|
|
9001
9799
|
const conversationId = this.conversationId;
|
|
@@ -9008,6 +9806,16 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
9008
9806
|
const loadToken = this.conversationLoadToken;
|
|
9009
9807
|
LogStatusEx({ message: `🔁 Reconciling in-progress runs (${reason})`, verboseOnly: true });
|
|
9010
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
|
+
}
|
|
9011
9819
|
await this.refreshAgentRunsForInProgress(conversationId, loadToken);
|
|
9012
9820
|
if (!this.isActiveConversationLoad(conversationId, loadToken)) {
|
|
9013
9821
|
return;
|
|
@@ -9108,6 +9916,8 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
9108
9916
|
* Reconnect to in-progress agent runs whose completion events were missed.
|
|
9109
9917
|
*/
|
|
9110
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();
|
|
9111
9921
|
const inProgressMessages = this.messages.filter(m => m.Status === 'In-Progress' && m.Role === 'AI');
|
|
9112
9922
|
if (inProgressMessages.length === 0) {
|
|
9113
9923
|
return;
|
|
@@ -9211,7 +10021,7 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
9211
10021
|
scrollToMessage(messageId) {
|
|
9212
10022
|
// Wait for DOM to update, then scroll
|
|
9213
10023
|
setTimeout(() => {
|
|
9214
|
-
if (this.
|
|
10024
|
+
if (this.scrollToMessageOrThreadRoot(messageId)) {
|
|
9215
10025
|
return;
|
|
9216
10026
|
}
|
|
9217
10027
|
const messageElement = document.querySelector(`[data-message-id="${messageId}"]`);
|
|
@@ -9287,52 +10097,54 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
9287
10097
|
let _t;
|
|
9288
10098
|
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.chatSlotChildren = _t);
|
|
9289
10099
|
} }, viewQuery: function ConversationChatAreaComponent_Query(rf, ctx) { if (rf & 1) {
|
|
9290
|
-
i0.ɵɵviewQuery(_c0, 5)(ArtifactViewerPanelComponent, 5)(ConversationEmptyStateComponent, 5)(
|
|
10100
|
+
i0.ɵɵviewQuery(_c0, 5)(ArtifactViewerPanelComponent, 5)(ConversationEmptyStateComponent, 5)(_c1, 5)(MessageListComponent, 5)(_c2, 5)(_c3, 5, ElementRef)(_c4, 5, ElementRef)(_c5, 5);
|
|
9291
10101
|
} if (rf & 2) {
|
|
9292
10102
|
let _t;
|
|
9293
10103
|
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.scrollContainerRef = _t.first);
|
|
9294
10104
|
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.artifactViewerComponent = _t.first);
|
|
9295
10105
|
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.emptyStateComponent = _t.first);
|
|
10106
|
+
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.ConversationRemoteBrowserSurface = _t.first);
|
|
9296
10107
|
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.messageListComponent = _t.first);
|
|
9297
10108
|
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.titleNameInput = _t.first);
|
|
9298
10109
|
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.titleRenameButton = _t.first);
|
|
9299
10110
|
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.forksButton = _t.first);
|
|
9300
10111
|
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.messageInputComponents = _t);
|
|
9301
|
-
} }, 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) {
|
|
9302
|
-
i0.ɵɵelementStart(0, "div",
|
|
9303
|
-
i0.ɵɵconditionalCreate(1, ConversationChatAreaComponent_Conditional_1_Template, 3, 3, "div",
|
|
9304
|
-
i0.ɵɵconditionalCreate(2, ConversationChatAreaComponent_Conditional_2_Template, 1, 8, "ng-container")(3, ConversationChatAreaComponent_Conditional_3_Template,
|
|
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);
|
|
9305
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);
|
|
9306
|
-
i0.ɵɵelementStart(8, "div",
|
|
9307
|
-
i0.ɵɵconditionalCreate(9, ConversationChatAreaComponent_Conditional_9_Template, 2, 6, "div",
|
|
9308
|
-
i0.ɵɵelementStart(10, "div",
|
|
9309
|
-
i0.ɵɵconditionalCreate(11, ConversationChatAreaComponent_Conditional_11_Template, 1, 1)(12, ConversationChatAreaComponent_Conditional_12_Template, 3, 1)(13, ConversationChatAreaComponent_Conditional_13_Template, 5, 1, "div",
|
|
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);
|
|
9310
10121
|
i0.ɵɵelementEnd();
|
|
9311
10122
|
i0.ɵɵconditionalCreate(15, ConversationChatAreaComponent_Conditional_15_Template, 3, 15);
|
|
9312
10123
|
i0.ɵɵconditionalCreate(16, ConversationChatAreaComponent_Conditional_16_Template, 23, 24);
|
|
9313
|
-
i0.ɵɵ
|
|
9314
|
-
i0.ɵɵ
|
|
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(); });
|
|
9315
10127
|
i0.ɵɵelementEnd();
|
|
9316
|
-
i0.ɵɵconditionalCreate(
|
|
9317
|
-
i0.ɵɵconditionalCreate(
|
|
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);
|
|
9318
10130
|
i0.ɵɵelementEnd();
|
|
9319
|
-
i0.ɵɵconditionalCreate(
|
|
9320
|
-
i0.ɵɵpipe(
|
|
10131
|
+
i0.ɵɵconditionalCreate(21, ConversationChatAreaComponent_Conditional_21_Template, 4, 15);
|
|
10132
|
+
i0.ɵɵpipe(22, "async");
|
|
9321
10133
|
i0.ɵɵelementEnd();
|
|
9322
|
-
i0.ɵɵelementStart(
|
|
9323
|
-
i0.ɵɵlistener("cancelled", function
|
|
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(); });
|
|
9324
10136
|
i0.ɵɵelementEnd();
|
|
9325
|
-
i0.ɵɵelementStart(
|
|
9326
|
-
i0.ɵɵlistener("Result", function
|
|
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); });
|
|
9327
10139
|
i0.ɵɵelementEnd();
|
|
9328
|
-
i0.ɵɵelementStart(
|
|
9329
|
-
i0.ɵɵlistener("cancelled", function
|
|
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; });
|
|
9330
10142
|
i0.ɵɵelementEnd();
|
|
9331
|
-
i0.ɵɵconditionalCreate(
|
|
9332
|
-
i0.ɵɵconditionalCreate(
|
|
9333
|
-
i0.ɵɵconditionalCreate(
|
|
9334
|
-
i0.ɵɵconditionalCreate(
|
|
9335
|
-
i0.ɵɵconditionalCreate(
|
|
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);
|
|
9336
10148
|
} if (rf & 2) {
|
|
9337
10149
|
let tmp_3_0;
|
|
9338
10150
|
i0.ɵɵadvance();
|
|
@@ -9344,7 +10156,7 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
9344
10156
|
i0.ɵɵadvance();
|
|
9345
10157
|
i0.ɵɵconditional(ctx.isDemonstrationActive ? 9 : -1);
|
|
9346
10158
|
i0.ɵɵadvance();
|
|
9347
|
-
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);
|
|
9348
10160
|
i0.ɵɵadvance();
|
|
9349
10161
|
i0.ɵɵconditional(ctx.isLoadingConversation ? 11 : (ctx.isNewConversation || !ctx.conversationId) && !ctx.suppressNewConversationEmptyState ? 12 : (ctx.isNewConversation || !ctx.conversationId) && ctx.suppressNewConversationEmptyState ? 13 : 14);
|
|
9350
10162
|
i0.ɵɵadvance(4);
|
|
@@ -9352,13 +10164,15 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
9352
10164
|
i0.ɵɵadvance();
|
|
9353
10165
|
i0.ɵɵconditional(ctx.SelectedTaskGraphPanel ? 16 : -1);
|
|
9354
10166
|
i0.ɵɵadvance();
|
|
10167
|
+
i0.ɵɵconditional(ctx.ShowRemoteBrowserPanel ? 17 : -1);
|
|
10168
|
+
i0.ɵɵadvance();
|
|
9355
10169
|
i0.ɵɵproperty("isOpen", ctx.isArtifactShareModalOpen)("artifact", ctx.artifactToShare)("currentUser", ctx.currentUser);
|
|
9356
10170
|
i0.ɵɵadvance();
|
|
9357
|
-
i0.ɵɵconditional(ctx.allowPinning && ctx.showPinsPanel ?
|
|
10171
|
+
i0.ɵɵconditional(ctx.allowPinning && ctx.showPinsPanel ? 19 : -1);
|
|
9358
10172
|
i0.ɵɵadvance();
|
|
9359
|
-
i0.ɵɵconditional(ctx.ShowForksPopover ?
|
|
10173
|
+
i0.ɵɵconditional(ctx.ShowForksPopover ? 20 : -1);
|
|
9360
10174
|
i0.ɵɵadvance();
|
|
9361
|
-
i0.ɵɵconditional(i0.ɵɵpipeBind1(
|
|
10175
|
+
i0.ɵɵconditional(i0.ɵɵpipeBind1(22, 35, ctx.RealtimeSession.Active$) || ctx.RealtimeReview ? 21 : -1);
|
|
9362
10176
|
i0.ɵɵadvance(2);
|
|
9363
10177
|
i0.ɵɵproperty("branding", ctx.exportBranding)("isVisible", ctx.showExportModal)("conversation", ctx.conversation || undefined)("Scope", ctx.ExportScope)("currentUser", ctx.currentUser);
|
|
9364
10178
|
i0.ɵɵadvance();
|
|
@@ -9366,20 +10180,20 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
9366
10180
|
i0.ɵɵadvance();
|
|
9367
10181
|
i0.ɵɵproperty("isVisible", ctx.showMembersModal)("conversation", ctx.conversation || undefined)("currentUser", ctx.currentUser);
|
|
9368
10182
|
i0.ɵɵadvance();
|
|
9369
|
-
i0.ɵɵconditional(ctx.showProjectSelector && ctx.conversation ?
|
|
10183
|
+
i0.ɵɵconditional(ctx.showProjectSelector && ctx.conversation ? 26 : -1);
|
|
9370
10184
|
i0.ɵɵadvance();
|
|
9371
|
-
i0.ɵɵconditional(ctx.showArtifactsModal ?
|
|
10185
|
+
i0.ɵɵconditional(ctx.showArtifactsModal ? 27 : -1);
|
|
9372
10186
|
i0.ɵɵadvance();
|
|
9373
|
-
i0.ɵɵconditional(ctx.showCollectionPicker ?
|
|
10187
|
+
i0.ɵɵconditional(ctx.showCollectionPicker ? 28 : -1);
|
|
9374
10188
|
i0.ɵɵadvance();
|
|
9375
|
-
i0.ɵɵconditional(ctx.testFeedbackDialogData ?
|
|
10189
|
+
i0.ɵɵconditional(ctx.testFeedbackDialogData ? 29 : -1);
|
|
9376
10190
|
i0.ɵɵadvance();
|
|
9377
|
-
i0.ɵɵconditional(ctx.showImageViewer ?
|
|
9378
|
-
} }, 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}"] });
|
|
9379
10193
|
}
|
|
9380
10194
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ConversationChatAreaComponent, [{
|
|
9381
10195
|
type: Component,
|
|
9382
|
-
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 & 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 & 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"] }]
|
|
9383
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: [{
|
|
9384
10198
|
type: Input
|
|
9385
10199
|
}], environmentId: [{
|
|
@@ -9430,6 +10244,8 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
9430
10244
|
type: Input
|
|
9431
10245
|
}], AllowForking: [{
|
|
9432
10246
|
type: Input
|
|
10247
|
+
}], AllowRemoteBrowser: [{
|
|
10248
|
+
type: Input
|
|
9433
10249
|
}], AllowStopRun: [{
|
|
9434
10250
|
type: Input
|
|
9435
10251
|
}], ShowEmptyFill: [{
|
|
@@ -9731,6 +10547,9 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
9731
10547
|
}], chatSlotChildren: [{
|
|
9732
10548
|
type: ContentChildren,
|
|
9733
10549
|
args: [ChatSlotDirective]
|
|
10550
|
+
}], ConversationRemoteBrowserSurface: [{
|
|
10551
|
+
type: ViewChild,
|
|
10552
|
+
args: ['conversationRemoteBrowserSurface']
|
|
9734
10553
|
}], messageListComponent: [{
|
|
9735
10554
|
type: ViewChild,
|
|
9736
10555
|
args: [MessageListComponent]
|
|
@@ -9743,6 +10562,10 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
9743
10562
|
}], forksButton: [{
|
|
9744
10563
|
type: ViewChild,
|
|
9745
10564
|
args: ['forksButton', { read: ElementRef }]
|
|
10565
|
+
}], CollapseThreadReplies: [{
|
|
10566
|
+
type: Input
|
|
10567
|
+
}], ThreadReplyRevealRequested: [{
|
|
10568
|
+
type: Output
|
|
9746
10569
|
}] }); })();
|
|
9747
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ConversationChatAreaComponent, { className: "ConversationChatAreaComponent", filePath: "src/lib/components/conversation/conversation-chat-area.component.ts", lineNumber:
|
|
10570
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ConversationChatAreaComponent, { className: "ConversationChatAreaComponent", filePath: "src/lib/components/conversation/conversation-chat-area.component.ts", lineNumber: 217 }); })();
|
|
9748
10571
|
//# sourceMappingURL=conversation-chat-area.component.js.map
|