@memberjunction/ng-conversations 6.2.0-edge.5 → 6.2.0-edge.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/components/attachment/image-viewer.component.d.ts +3 -1
- package/dist/lib/components/attachment/image-viewer.component.d.ts.map +1 -1
- package/dist/lib/components/attachment/image-viewer.component.js +5 -1
- package/dist/lib/components/attachment/image-viewer.component.js.map +1 -1
- 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 +188 -9
- package/dist/lib/components/conversation/conversation-chat-area.component.d.ts.map +1 -1
- package/dist/lib/components/conversation/conversation-chat-area.component.js +1333 -464
- 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 +126 -59
- package/dist/lib/components/message/message-input.component.d.ts.map +1 -1
- package/dist/lib/components/message/message-input.component.js +559 -554
- package/dist/lib/components/message/message-input.component.js.map +1 -1
- package/dist/lib/components/message/message-item.component.d.ts +34 -2
- package/dist/lib/components/message/message-item.component.d.ts.map +1 -1
- package/dist/lib/components/message/message-item.component.js +678 -520
- package/dist/lib/components/message/message-item.component.js.map +1 -1
- package/dist/lib/components/message/message-list.component.d.ts +13 -1
- package/dist/lib/components/message/message-list.component.d.ts.map +1 -1
- package/dist/lib/components/message/message-list.component.js +92 -39
- package/dist/lib/components/message/message-list.component.js.map +1 -1
- package/dist/lib/components/overlay/chat-overlay.component.d.ts +19 -0
- package/dist/lib/components/overlay/chat-overlay.component.d.ts.map +1 -1
- package/dist/lib/components/overlay/chat-overlay.component.js +125 -13
- package/dist/lib/components/overlay/chat-overlay.component.js.map +1 -1
- package/dist/lib/components/project/project-form-modal.component.js +2 -2
- package/dist/lib/components/project/project-form-modal.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 +22 -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 +160 -98
- package/dist/lib/components/realtime/realtime-agent-banner.component.js.map +1 -1
- package/dist/lib/components/realtime/realtime-call-failure-notice.d.ts +13 -0
- package/dist/lib/components/realtime/realtime-call-failure-notice.d.ts.map +1 -0
- package/dist/lib/components/realtime/realtime-call-failure-notice.js +21 -0
- package/dist/lib/components/realtime/realtime-call-failure-notice.js.map +1 -0
- 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 +226 -120
- package/dist/lib/components/realtime/realtime-composer.component.js.map +1 -1
- package/dist/lib/components/realtime/realtime-session-overlay.component.d.ts +73 -16
- package/dist/lib/components/realtime/realtime-session-overlay.component.d.ts.map +1 -1
- package/dist/lib/components/realtime/realtime-session-overlay.component.js +219 -108
- 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 +34 -5
- 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 +38 -16
- package/dist/lib/services/conversation-agent.service.d.ts.map +1 -1
- package/dist/lib/services/conversation-agent.service.js +57 -71
- package/dist/lib/services/conversation-agent.service.js.map +1 -1
- package/dist/lib/services/conversation-detail-window.store.d.ts +5 -0
- package/dist/lib/services/conversation-detail-window.store.d.ts.map +1 -1
- package/dist/lib/services/conversation-detail-window.store.js +52 -5
- package/dist/lib/services/conversation-detail-window.store.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/realtime-session.service.d.ts.map +1 -1
- package/dist/lib/services/realtime-session.service.js +2 -1
- package/dist/lib/services/realtime-session.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-failure-display.d.ts +14 -0
- package/dist/lib/utils/agent-failure-display.d.ts.map +1 -0
- package/dist/lib/utils/agent-failure-display.js +26 -0
- package/dist/lib/utils/agent-failure-display.js.map +1 -0
- 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/message-list-order.d.ts +13 -0
- package/dist/lib/utils/message-list-order.d.ts.map +1 -0
- package/dist/lib/utils/message-list-order.js +31 -0
- package/dist/lib/utils/message-list-order.js.map +1 -0
- package/dist/lib/utils/pin-state.d.ts +11 -0
- package/dist/lib/utils/pin-state.d.ts.map +1 -0
- package/dist/lib/utils/pin-state.js +9 -0
- package/dist/lib/utils/pin-state.js.map +1 -0
- 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 +6 -0
- package/dist/public-api.d.ts.map +1 -1
- package/dist/public-api.js +6 -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';
|
|
@@ -22,15 +23,23 @@ import { RealtimeSessionReviewService } from '../../services/realtime-session-re
|
|
|
22
23
|
import { GenerateAndApplyConversationName, GenerateAndApplyForkName, SaveForkName } from '../../services/conversation-naming';
|
|
23
24
|
import { CollectRealtimeSessionIDs, MapRealtimeSessionMeta, REALTIME_SESSION_META_FIELDS } from '../../utils/realtime-session-timeline';
|
|
24
25
|
import { ResolveDateJumpTarget, CombineDateJumpOutcome, DescribeDateJumpOutcome, DATE_JUMP_MAX_PAGES } from '../../utils/date-jump';
|
|
26
|
+
import { CompareMessagesByCreatedAt, UpsertMessageById } from '../../utils/message-list-order';
|
|
27
|
+
import { SavePinState } from '../../utils/pin-state';
|
|
25
28
|
import { InjectFrameZone } from '../../util/frame-zone';
|
|
26
29
|
import { MessageListComponent } from '../message/message-list.component';
|
|
27
30
|
import { IsForkPointOrEarlier } from '../../utils/conversation-branching';
|
|
28
31
|
import { BackLabelOf, BuildForkBreadcrumbs, BuildForkHeaderPath, BuildForkMarkerText, BuildForkComposerHint, BuildForkViewLayout, BuildViewForkChipMap, CanForkFrom, FindLatestTurn, FirstOwnRowID, ForkDependsOnRows, IsRowInOpenView, MAIN_COMPOSER_PLACEHOLDER, MAIN_OPEN_VIEW, ParentForkIdOf, ReadBranchIdOf, SameOpenView, SplitForkRows, TurnRowsAfter, FORK_COMPOSER_PLACEHOLDER, ForkInitials, ForkKindIcon, DRAFT_FORK_TITLE } from '../../utils/conversation-forks';
|
|
29
32
|
import { DecideArtifactPanelAction, SnapshotArtifactVersions } from '../../utils/artifact-panel-action';
|
|
30
|
-
import {
|
|
33
|
+
import { GetThreadReplyRoots } from '../../utils/thread-replies';
|
|
34
|
+
import { NormalizeUUID, UUIDsEqual, UUIDSet, UUIDMap, IndexByUUID, IsValidUUID } from '@memberjunction/global';
|
|
35
|
+
import { AgentAccentVar } from '../message/agent-handoff-card.component';
|
|
36
|
+
import { BuildHandoffsByDetailId, LoadHandoffStepsForRuns, } from '../../utils/agent-handoff-map';
|
|
37
|
+
import { FindContinuityAgentMessage } from '../../utils/agent-turn-routing';
|
|
31
38
|
// PR 2c — Widget extension surface
|
|
32
39
|
import { ChatSlotDirective } from '../../directives/chat-slot.directive';
|
|
33
40
|
import { ConversationCallStartOptions } from '../realtime/capture/realtime-capture-channel';
|
|
41
|
+
import { ConversationRemoteBrowserController } from './conversation-remote-browser-controller';
|
|
42
|
+
import { DescribeCallFailureNotice } from '../realtime/realtime-call-failure-notice';
|
|
34
43
|
import { BeforeToolInvokedEventArgs, AfterToolInvokedEventArgs, BeforeStopClickedEventArgs, AfterStopClickedEventArgs, SessionStartedEventArgs, SessionChannelStateChangedEventArgs, SessionEndedEventArgs, } from '../../events/chat-events';
|
|
35
44
|
import * as i0 from "@angular/core";
|
|
36
45
|
import * as i1 from "../../services/agent-state.service";
|
|
@@ -56,50 +65,52 @@ import * as i20 from "../collection/artifact-collection-picker-modal.component";
|
|
|
56
65
|
import * as i21 from "../artifact/artifact-share-modal.component";
|
|
57
66
|
import * as i22 from "../slots/mj-chat-agent-presence-default.component";
|
|
58
67
|
import * as i23 from "../realtime/realtime-session-overlay.component";
|
|
59
|
-
import * as i24 from "../
|
|
60
|
-
import * as i25 from "../message/message-
|
|
61
|
-
import * as i26 from "
|
|
62
|
-
import * as i27 from "./conversation-
|
|
63
|
-
import * as i28 from "./conversation-
|
|
64
|
-
import * as i29 from "
|
|
65
|
-
import * as i30 from "../
|
|
66
|
-
import * as i31 from "../
|
|
67
|
-
import * as i32 from "../
|
|
68
|
-
import * as i33 from "
|
|
69
|
-
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";
|
|
70
80
|
const _c0 = ["scrollContainer"];
|
|
71
|
-
const _c1 = ["
|
|
72
|
-
const _c2 = ["
|
|
73
|
-
const _c3 = ["
|
|
74
|
-
const _c4 = ["
|
|
75
|
-
const _c5 =
|
|
76
|
-
const _c6 = (a0, a1, a2, a3, a4) => ({ $implicit: a0,
|
|
77
|
-
const _c7 = (a0, a1, a2) => ({ $implicit: a0,
|
|
78
|
-
const _c8 = (a0, a1, a2) => ({ $implicit: a0,
|
|
79
|
-
const _c9 = () =>
|
|
80
|
-
const _c10 = (
|
|
81
|
-
const _c11 = (a0, a1, a2) => ({ $implicit: a0,
|
|
82
|
-
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); }
|
|
83
94
|
const _forTrack1 = ($index, $item) => $item.artifactId;
|
|
84
95
|
const _forTrack2 = ($index, $item) => $item.versionId;
|
|
85
96
|
function ConversationChatAreaComponent_Conditional_1_Conditional_1_ng_container_0_Template(rf, ctx) { if (rf & 1) {
|
|
86
97
|
i0.ɵɵelementContainer(0);
|
|
87
98
|
} }
|
|
88
99
|
function ConversationChatAreaComponent_Conditional_1_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
89
|
-
i0.ɵɵtemplate(0, ConversationChatAreaComponent_Conditional_1_Conditional_1_ng_container_0_Template, 1, 0, "ng-container",
|
|
100
|
+
i0.ɵɵtemplate(0, ConversationChatAreaComponent_Conditional_1_Conditional_1_ng_container_0_Template, 1, 0, "ng-container", 29);
|
|
90
101
|
} if (rf & 2) {
|
|
91
102
|
const ctx_r0 = i0.ɵɵnextContext(2);
|
|
92
|
-
i0.ɵɵproperty("ngTemplateOutlet", ctx)("ngTemplateOutletContext", i0.ɵɵpureFunction5(2,
|
|
103
|
+
i0.ɵɵproperty("ngTemplateOutlet", ctx)("ngTemplateOutletContext", i0.ɵɵpureFunction5(2, _c6, ctx_r0.agentCharacterConfig, (ctx_r0.agentCharacterConfig == null ? null : ctx_r0.agentCharacterConfig.state) ?? "idle", ctx_r0.agentCharacterConfig == null ? null : ctx_r0.agentCharacterConfig.characterName, ctx_r0.agentCharacterConfig == null ? null : ctx_r0.agentCharacterConfig.avatarUrl, (ctx_r0.agentCharacterConfig == null ? null : ctx_r0.agentCharacterConfig.voiceStateMode) ?? "subtle"));
|
|
93
104
|
} }
|
|
94
105
|
function ConversationChatAreaComponent_Conditional_1_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
95
|
-
i0.ɵɵelement(0, "mj-chat-agent-presence-default",
|
|
106
|
+
i0.ɵɵelement(0, "mj-chat-agent-presence-default", 28);
|
|
96
107
|
} if (rf & 2) {
|
|
97
108
|
const ctx_r0 = i0.ɵɵnextContext(2);
|
|
98
109
|
i0.ɵɵproperty("State", (ctx_r0.agentCharacterConfig == null ? null : ctx_r0.agentCharacterConfig.state) ?? "idle")("AgentName", ctx_r0.agentCharacterConfig == null ? null : ctx_r0.agentCharacterConfig.characterName)("AvatarUrl", ctx_r0.agentCharacterConfig == null ? null : ctx_r0.agentCharacterConfig.avatarUrl)("Mode", (ctx_r0.agentCharacterConfig == null ? null : ctx_r0.agentCharacterConfig.voiceStateMode) ?? "subtle");
|
|
99
110
|
} }
|
|
100
111
|
function ConversationChatAreaComponent_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
101
|
-
i0.ɵɵelementStart(0, "div",
|
|
102
|
-
i0.ɵɵconditionalCreate(1, ConversationChatAreaComponent_Conditional_1_Conditional_1_Template, 1, 8, "ng-container")(2, ConversationChatAreaComponent_Conditional_1_Conditional_2_Template, 1, 4, "mj-chat-agent-presence-default",
|
|
112
|
+
i0.ɵɵelementStart(0, "div", 27);
|
|
113
|
+
i0.ɵɵconditionalCreate(1, ConversationChatAreaComponent_Conditional_1_Conditional_1_Template, 1, 8, "ng-container")(2, ConversationChatAreaComponent_Conditional_1_Conditional_2_Template, 1, 4, "mj-chat-agent-presence-default", 28);
|
|
103
114
|
i0.ɵɵelementEnd();
|
|
104
115
|
} if (rf & 2) {
|
|
105
116
|
let tmp_4_0;
|
|
@@ -112,31 +123,48 @@ function ConversationChatAreaComponent_Conditional_2_ng_container_0_Template(rf,
|
|
|
112
123
|
i0.ɵɵelementContainer(0);
|
|
113
124
|
} }
|
|
114
125
|
function ConversationChatAreaComponent_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
115
|
-
i0.ɵɵtemplate(0, ConversationChatAreaComponent_Conditional_2_ng_container_0_Template, 1, 0, "ng-container",
|
|
126
|
+
i0.ɵɵtemplate(0, ConversationChatAreaComponent_Conditional_2_ng_container_0_Template, 1, 0, "ng-container", 29);
|
|
116
127
|
} if (rf & 2) {
|
|
117
128
|
const ctx_r0 = i0.ɵɵnextContext();
|
|
118
|
-
i0.ɵɵproperty("ngTemplateOutlet", ctx)("ngTemplateOutletContext", i0.ɵɵpureFunction5(2,
|
|
129
|
+
i0.ɵɵproperty("ngTemplateOutlet", ctx)("ngTemplateOutletContext", i0.ɵɵpureFunction5(2, _c7, ctx_r0.conversation, (ctx_r0.conversation == null ? null : ctx_r0.conversation.Name) ?? null, (ctx_r0.sharedByBadge == null ? null : ctx_r0.sharedByBadge.display) ?? null, ctx_r0.artifactCountDisplay, ctx_r0.showArtifactIndicator));
|
|
119
130
|
} }
|
|
120
131
|
function ConversationChatAreaComponent_Conditional_3_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
121
132
|
const _r3 = i0.ɵɵgetCurrentView();
|
|
122
|
-
i0.ɵɵelementStart(0, "button",
|
|
133
|
+
i0.ɵɵelementStart(0, "button", 46);
|
|
123
134
|
i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_3_Conditional_2_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.sidebarToggleClicked.emit()); });
|
|
124
|
-
i0.ɵɵelement(1, "i",
|
|
135
|
+
i0.ɵɵelement(1, "i", 47);
|
|
125
136
|
i0.ɵɵelementEnd();
|
|
126
137
|
} }
|
|
127
138
|
function ConversationChatAreaComponent_Conditional_3_Conditional_3_ng_container_0_Template(rf, ctx) { if (rf & 1) {
|
|
128
139
|
i0.ɵɵelementContainer(0);
|
|
129
140
|
} }
|
|
141
|
+
function ConversationChatAreaComponent_Conditional_3_Conditional_3_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
142
|
+
i0.ɵɵelementStart(0, "span", 50);
|
|
143
|
+
i0.ɵɵelement(1, "span", 51);
|
|
144
|
+
i0.ɵɵelementStart(2, "span");
|
|
145
|
+
i0.ɵɵtext(3, "with ");
|
|
146
|
+
i0.ɵɵelementStart(4, "b");
|
|
147
|
+
i0.ɵɵtext(5);
|
|
148
|
+
i0.ɵɵelementEnd()()();
|
|
149
|
+
} if (rf & 2) {
|
|
150
|
+
const ctx_r0 = i0.ɵɵnextContext(3);
|
|
151
|
+
i0.ɵɵstyleProp("--agent-accent", ctx_r0.CurrentOwnerAccentVar);
|
|
152
|
+
i0.ɵɵadvance(5);
|
|
153
|
+
i0.ɵɵtextInterpolate(ctx_r0.CurrentOwnerAgentName);
|
|
154
|
+
} }
|
|
130
155
|
function ConversationChatAreaComponent_Conditional_3_Conditional_3_Template(rf, ctx) { if (rf & 1) {
|
|
131
|
-
i0.ɵɵtemplate(0, ConversationChatAreaComponent_Conditional_3_Conditional_3_ng_container_0_Template, 1, 0, "ng-container",
|
|
156
|
+
i0.ɵɵtemplate(0, ConversationChatAreaComponent_Conditional_3_Conditional_3_ng_container_0_Template, 1, 0, "ng-container", 48);
|
|
157
|
+
i0.ɵɵconditionalCreate(1, ConversationChatAreaComponent_Conditional_3_Conditional_3_Conditional_1_Template, 6, 3, "span", 49);
|
|
132
158
|
} if (rf & 2) {
|
|
133
|
-
i0.ɵɵnextContext(2);
|
|
159
|
+
const ctx_r0 = i0.ɵɵnextContext(2);
|
|
134
160
|
const titleBar_r4 = i0.ɵɵreference(5);
|
|
135
161
|
i0.ɵɵproperty("ngTemplateOutlet", titleBar_r4);
|
|
162
|
+
i0.ɵɵadvance();
|
|
163
|
+
i0.ɵɵconditional(ctx_r0.CurrentOwnerAgent ? 1 : -1);
|
|
136
164
|
} }
|
|
137
165
|
function ConversationChatAreaComponent_Conditional_3_Conditional_4_Template(rf, ctx) { if (rf & 1) {
|
|
138
|
-
i0.ɵɵelementStart(0, "span",
|
|
139
|
-
i0.ɵɵelement(1, "i",
|
|
166
|
+
i0.ɵɵelementStart(0, "span", 33);
|
|
167
|
+
i0.ɵɵelement(1, "i", 52);
|
|
140
168
|
i0.ɵɵelementStart(2, "span");
|
|
141
169
|
i0.ɵɵtext(3);
|
|
142
170
|
i0.ɵɵelementEnd()();
|
|
@@ -148,9 +176,9 @@ function ConversationChatAreaComponent_Conditional_3_Conditional_4_Template(rf,
|
|
|
148
176
|
} }
|
|
149
177
|
function ConversationChatAreaComponent_Conditional_3_Conditional_5_Template(rf, ctx) { if (rf & 1) {
|
|
150
178
|
const _r5 = i0.ɵɵgetCurrentView();
|
|
151
|
-
i0.ɵɵelementStart(0, "button",
|
|
179
|
+
i0.ɵɵelementStart(0, "button", 53);
|
|
152
180
|
i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_3_Conditional_5_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r5); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.openProjectSelector()); });
|
|
153
|
-
i0.ɵɵelement(1, "i",
|
|
181
|
+
i0.ɵɵelement(1, "i", 54);
|
|
154
182
|
i0.ɵɵelementStart(2, "span");
|
|
155
183
|
i0.ɵɵtext(3);
|
|
156
184
|
i0.ɵɵelementEnd()();
|
|
@@ -162,22 +190,22 @@ function ConversationChatAreaComponent_Conditional_3_Conditional_5_Template(rf,
|
|
|
162
190
|
} }
|
|
163
191
|
function ConversationChatAreaComponent_Conditional_3_Conditional_6_Template(rf, ctx) { if (rf & 1) {
|
|
164
192
|
const _r6 = i0.ɵɵgetCurrentView();
|
|
165
|
-
i0.ɵɵelementStart(0, "button",
|
|
193
|
+
i0.ɵɵelementStart(0, "button", 55);
|
|
166
194
|
i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_3_Conditional_6_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r6); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.viewTestRun(ctx_r0.conversation.TestRunID)); });
|
|
167
|
-
i0.ɵɵelement(1, "i",
|
|
195
|
+
i0.ɵɵelement(1, "i", 56);
|
|
168
196
|
i0.ɵɵelementStart(2, "span");
|
|
169
197
|
i0.ɵɵtext(3, "Test");
|
|
170
198
|
i0.ɵɵelementEnd()();
|
|
171
199
|
} }
|
|
172
200
|
function ConversationChatAreaComponent_Conditional_3_Conditional_8_Template(rf, ctx) { if (rf & 1) {
|
|
173
201
|
const _r7 = i0.ɵɵgetCurrentView();
|
|
174
|
-
i0.ɵɵelementStart(0, "button",
|
|
202
|
+
i0.ɵɵelementStart(0, "button", 57, 2);
|
|
175
203
|
i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_3_Conditional_8_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r7); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.ToggleForksPopover()); });
|
|
176
|
-
i0.ɵɵelement(2, "i",
|
|
177
|
-
i0.ɵɵelementStart(3, "span",
|
|
204
|
+
i0.ɵɵelement(2, "i", 58);
|
|
205
|
+
i0.ɵɵelementStart(3, "span", 59);
|
|
178
206
|
i0.ɵɵtext(4, "Forks");
|
|
179
207
|
i0.ɵɵelementEnd();
|
|
180
|
-
i0.ɵɵelementStart(5, "span",
|
|
208
|
+
i0.ɵɵelementStart(5, "span", 60);
|
|
181
209
|
i0.ɵɵtext(6);
|
|
182
210
|
i0.ɵɵelementEnd()();
|
|
183
211
|
} if (rf & 2) {
|
|
@@ -189,10 +217,10 @@ function ConversationChatAreaComponent_Conditional_3_Conditional_8_Template(rf,
|
|
|
189
217
|
} }
|
|
190
218
|
function ConversationChatAreaComponent_Conditional_3_Conditional_9_Template(rf, ctx) { if (rf & 1) {
|
|
191
219
|
const _r8 = i0.ɵɵgetCurrentView();
|
|
192
|
-
i0.ɵɵelementStart(0, "button",
|
|
220
|
+
i0.ɵɵelementStart(0, "button", 61);
|
|
193
221
|
i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_3_Conditional_9_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r8); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.TogglePinsPanel()); });
|
|
194
|
-
i0.ɵɵelement(1, "i",
|
|
195
|
-
i0.ɵɵelementStart(2, "span",
|
|
222
|
+
i0.ɵɵelement(1, "i", 62);
|
|
223
|
+
i0.ɵɵelementStart(2, "span", 63);
|
|
196
224
|
i0.ɵɵtext(3);
|
|
197
225
|
i0.ɵɵelementEnd()();
|
|
198
226
|
} if (rf & 2) {
|
|
@@ -203,10 +231,10 @@ function ConversationChatAreaComponent_Conditional_3_Conditional_9_Template(rf,
|
|
|
203
231
|
} }
|
|
204
232
|
function ConversationChatAreaComponent_Conditional_3_Conditional_10_Template(rf, ctx) { if (rf & 1) {
|
|
205
233
|
const _r9 = i0.ɵɵgetCurrentView();
|
|
206
|
-
i0.ɵɵelementStart(0, "button",
|
|
234
|
+
i0.ɵɵelementStart(0, "button", 64);
|
|
207
235
|
i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_3_Conditional_10_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r9); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.viewArtifacts()); });
|
|
208
|
-
i0.ɵɵelement(1, "i",
|
|
209
|
-
i0.ɵɵelementStart(2, "span",
|
|
236
|
+
i0.ɵɵelement(1, "i", 65);
|
|
237
|
+
i0.ɵɵelementStart(2, "span", 66);
|
|
210
238
|
i0.ɵɵtext(3);
|
|
211
239
|
i0.ɵɵelementEnd()();
|
|
212
240
|
} if (rf & 2) {
|
|
@@ -216,10 +244,23 @@ function ConversationChatAreaComponent_Conditional_3_Conditional_10_Template(rf,
|
|
|
216
244
|
} }
|
|
217
245
|
function ConversationChatAreaComponent_Conditional_3_Conditional_11_Template(rf, ctx) { if (rf & 1) {
|
|
218
246
|
const _r10 = i0.ɵɵgetCurrentView();
|
|
219
|
-
i0.ɵɵelementStart(0, "button",
|
|
220
|
-
i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_3_Conditional_11_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r10); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.
|
|
221
|
-
i0.ɵɵelement(1, "i",
|
|
222
|
-
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);
|
|
223
264
|
i0.ɵɵtext(3);
|
|
224
265
|
i0.ɵɵelementEnd()();
|
|
225
266
|
} if (rf & 2) {
|
|
@@ -227,27 +268,27 @@ function ConversationChatAreaComponent_Conditional_3_Conditional_11_Template(rf,
|
|
|
227
268
|
i0.ɵɵadvance(3);
|
|
228
269
|
i0.ɵɵtextInterpolate(ctx_r0.memberCount);
|
|
229
270
|
} }
|
|
230
|
-
function
|
|
231
|
-
const
|
|
232
|
-
i0.ɵɵelementStart(0, "mj-conversation-mode-picker",
|
|
233
|
-
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)); });
|
|
234
275
|
i0.ɵɵelementEnd();
|
|
235
276
|
} if (rf & 2) {
|
|
236
277
|
const ctx_r0 = i0.ɵɵnextContext(2);
|
|
237
278
|
i0.ɵɵproperty("AgentID", ctx_r0.ModePickerTargetAgentId)("Disabled", ctx_r0.isProcessing);
|
|
238
279
|
} }
|
|
239
|
-
function
|
|
240
|
-
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);
|
|
241
282
|
} if (rf & 2) {
|
|
242
283
|
const ctx_r0 = i0.ɵɵnextContext(2);
|
|
243
284
|
i0.ɵɵproperty("Conversation", ctx_r0.conversation)("CurrentUser", ctx_r0.currentUser)("AllowedAgentIDs", ctx_r0.AllowedAgentIDs)("Disabled", ctx_r0.EffectiveReadOnly);
|
|
244
285
|
} }
|
|
245
|
-
function
|
|
246
|
-
const
|
|
247
|
-
i0.ɵɵelementStart(0, "button",
|
|
248
|
-
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()); });
|
|
249
290
|
i0.ɵɵelement(1, "i");
|
|
250
|
-
i0.ɵɵelementStart(2, "span",
|
|
291
|
+
i0.ɵɵelementStart(2, "span", 59);
|
|
251
292
|
i0.ɵɵtext(3);
|
|
252
293
|
i0.ɵɵelementEnd()();
|
|
253
294
|
} if (rf & 2) {
|
|
@@ -258,12 +299,12 @@ function ConversationChatAreaComponent_Conditional_3_Conditional_14_Template(rf,
|
|
|
258
299
|
i0.ɵɵadvance(2);
|
|
259
300
|
i0.ɵɵtextInterpolate(ctx_r0.exportButtonLabel);
|
|
260
301
|
} }
|
|
261
|
-
function
|
|
262
|
-
const
|
|
263
|
-
i0.ɵɵelementStart(0, "button",
|
|
264
|
-
i0.ɵɵlistener("click", function
|
|
265
|
-
i0.ɵɵelement(1, "i",
|
|
266
|
-
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);
|
|
267
308
|
i0.ɵɵtext(3, "Share");
|
|
268
309
|
i0.ɵɵelementEnd()();
|
|
269
310
|
} if (rf & 2) {
|
|
@@ -271,39 +312,40 @@ function ConversationChatAreaComponent_Conditional_3_Conditional_15_Template(rf,
|
|
|
271
312
|
i0.ɵɵclassProp("shared", ctx_r0.isShared);
|
|
272
313
|
i0.ɵɵproperty("title", ctx_r0.isShared ? "Manage sharing" : "Share conversation");
|
|
273
314
|
} }
|
|
274
|
-
function
|
|
315
|
+
function ConversationChatAreaComponent_Conditional_3_Conditional_17_ng_container_0_Template(rf, ctx) { if (rf & 1) {
|
|
275
316
|
i0.ɵɵelementContainer(0);
|
|
276
317
|
} }
|
|
277
|
-
function
|
|
278
|
-
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);
|
|
279
320
|
} if (rf & 2) {
|
|
280
321
|
const ctx_r0 = i0.ɵɵnextContext(2);
|
|
281
|
-
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));
|
|
282
323
|
} }
|
|
283
324
|
function ConversationChatAreaComponent_Conditional_3_Template(rf, ctx) { if (rf & 1) {
|
|
284
325
|
const _r2 = i0.ɵɵgetCurrentView();
|
|
285
|
-
i0.ɵɵelementStart(0, "div",
|
|
326
|
+
i0.ɵɵelementStart(0, "div", 30);
|
|
286
327
|
i0.ɵɵlistener("keydown.escape", function ConversationChatAreaComponent_Conditional_3_Template_div_keydown_escape_0_listener($event) { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.OnViewEscape($event)); });
|
|
287
|
-
i0.ɵɵelementStart(1, "div",
|
|
288
|
-
i0.ɵɵconditionalCreate(2, ConversationChatAreaComponent_Conditional_3_Conditional_2_Template, 2, 0, "button",
|
|
289
|
-
i0.ɵɵconditionalCreate(3, ConversationChatAreaComponent_Conditional_3_Conditional_3_Template,
|
|
290
|
-
i0.ɵɵconditionalCreate(4, ConversationChatAreaComponent_Conditional_3_Conditional_4_Template, 4, 2, "span",
|
|
291
|
-
i0.ɵɵconditionalCreate(5, ConversationChatAreaComponent_Conditional_3_Conditional_5_Template, 4, 2, "button",
|
|
292
|
-
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);
|
|
293
334
|
i0.ɵɵelementEnd();
|
|
294
|
-
i0.ɵɵelementStart(7, "div",
|
|
295
|
-
i0.ɵɵconditionalCreate(8, ConversationChatAreaComponent_Conditional_3_Conditional_8_Template, 7, 5, "button",
|
|
296
|
-
i0.ɵɵconditionalCreate(9, ConversationChatAreaComponent_Conditional_3_Conditional_9_Template, 4, 3, "button",
|
|
297
|
-
i0.ɵɵconditionalCreate(10, ConversationChatAreaComponent_Conditional_3_Conditional_10_Template, 4, 1, "button",
|
|
298
|
-
i0.ɵɵconditionalCreate(11, ConversationChatAreaComponent_Conditional_3_Conditional_11_Template, 4,
|
|
299
|
-
i0.ɵɵconditionalCreate(12, ConversationChatAreaComponent_Conditional_3_Conditional_12_Template,
|
|
300
|
-
i0.ɵɵconditionalCreate(13, ConversationChatAreaComponent_Conditional_3_Conditional_13_Template, 1,
|
|
301
|
-
i0.ɵɵconditionalCreate(14, ConversationChatAreaComponent_Conditional_3_Conditional_14_Template,
|
|
302
|
-
i0.ɵɵconditionalCreate(15, ConversationChatAreaComponent_Conditional_3_Conditional_15_Template, 4,
|
|
303
|
-
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");
|
|
304
346
|
i0.ɵɵelementEnd()();
|
|
305
347
|
} if (rf & 2) {
|
|
306
|
-
let
|
|
348
|
+
let tmp_18_0;
|
|
307
349
|
const ctx_r0 = i0.ɵɵnextContext();
|
|
308
350
|
i0.ɵɵadvance();
|
|
309
351
|
i0.ɵɵclassProp("with-sidebar-toggle", ctx_r0.showSidebarToggle);
|
|
@@ -324,85 +366,87 @@ function ConversationChatAreaComponent_Conditional_3_Template(rf, ctx) { if (rf
|
|
|
324
366
|
i0.ɵɵadvance();
|
|
325
367
|
i0.ɵɵconditional(ctx_r0.showArtifactIndicator && ctx_r0.artifactCountDisplay > 0 ? 10 : -1);
|
|
326
368
|
i0.ɵɵadvance();
|
|
327
|
-
i0.ɵɵconditional(ctx_r0.
|
|
369
|
+
i0.ɵɵconditional(ctx_r0.AllowRemoteBrowser && ctx_r0.conversation ? 11 : -1);
|
|
370
|
+
i0.ɵɵadvance();
|
|
371
|
+
i0.ɵɵconditional(ctx_r0.memberCount > 1 ? 12 : -1);
|
|
328
372
|
i0.ɵɵadvance();
|
|
329
|
-
i0.ɵɵconditional(!ctx_r0.overlayMode && ctx_r0.showAgentModePicker && ctx_r0.ModePickerTargetAgentId && !ctx_r0.EffectiveReadOnly ?
|
|
373
|
+
i0.ɵɵconditional(!ctx_r0.overlayMode && ctx_r0.showAgentModePicker && ctx_r0.ModePickerTargetAgentId && !ctx_r0.EffectiveReadOnly ? 13 : -1);
|
|
330
374
|
i0.ɵɵadvance();
|
|
331
|
-
i0.ɵɵconditional(ctx_r0.showAgentPicker && ctx_r0.conversation ?
|
|
375
|
+
i0.ɵɵconditional(ctx_r0.showAgentPicker && ctx_r0.conversation ? 14 : -1);
|
|
332
376
|
i0.ɵɵadvance();
|
|
333
|
-
i0.ɵɵconditional(ctx_r0.showExportButton ?
|
|
377
|
+
i0.ɵɵconditional(ctx_r0.showExportButton ? 15 : -1);
|
|
334
378
|
i0.ɵɵadvance();
|
|
335
|
-
i0.ɵɵconditional(ctx_r0.showShareButton && ctx_r0.canShareConversation ?
|
|
379
|
+
i0.ɵɵconditional(ctx_r0.showShareButton && ctx_r0.canShareConversation ? 16 : -1);
|
|
336
380
|
i0.ɵɵadvance();
|
|
337
|
-
i0.ɵɵconditional((
|
|
381
|
+
i0.ɵɵconditional((tmp_18_0 = ctx_r0.slotTemplate("headerActions")) ? 17 : -1, tmp_18_0);
|
|
338
382
|
} }
|
|
339
383
|
function ConversationChatAreaComponent_ng_template_4_Conditional_1_ng_container_0_Template(rf, ctx) { if (rf & 1) {
|
|
340
384
|
i0.ɵɵelementContainer(0);
|
|
341
385
|
} }
|
|
342
386
|
function ConversationChatAreaComponent_ng_template_4_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
343
|
-
i0.ɵɵtemplate(0, ConversationChatAreaComponent_ng_template_4_Conditional_1_ng_container_0_Template, 1, 0, "ng-container",
|
|
387
|
+
i0.ɵɵtemplate(0, ConversationChatAreaComponent_ng_template_4_Conditional_1_ng_container_0_Template, 1, 0, "ng-container", 48);
|
|
344
388
|
} if (rf & 2) {
|
|
345
389
|
i0.ɵɵnextContext(2);
|
|
346
|
-
const
|
|
347
|
-
i0.ɵɵproperty("ngTemplateOutlet",
|
|
390
|
+
const titleName_r15 = i0.ɵɵreference(7);
|
|
391
|
+
i0.ɵɵproperty("ngTemplateOutlet", titleName_r15);
|
|
348
392
|
} }
|
|
349
393
|
function ConversationChatAreaComponent_ng_template_4_Conditional_2_For_3_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
350
|
-
const
|
|
351
|
-
i0.ɵɵelementStart(0, "li",
|
|
352
|
-
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()); });
|
|
353
397
|
i0.ɵɵtext(2, "\u2026");
|
|
354
398
|
i0.ɵɵelementEnd();
|
|
355
|
-
i0.ɵɵelement(3, "i",
|
|
399
|
+
i0.ɵɵelement(3, "i", 83);
|
|
356
400
|
i0.ɵɵelementEnd();
|
|
357
401
|
} if (rf & 2) {
|
|
358
402
|
const ctx_r0 = i0.ɵɵnextContext(4);
|
|
359
403
|
i0.ɵɵclassProp("collapses-wide", ctx_r0.HeaderPath.CollapsesWide);
|
|
360
404
|
} }
|
|
361
405
|
function ConversationChatAreaComponent_ng_template_4_Conditional_2_For_3_Template(rf, ctx) { if (rf & 1) {
|
|
362
|
-
const
|
|
363
|
-
i0.ɵɵconditionalCreate(0, ConversationChatAreaComponent_ng_template_4_Conditional_2_For_3_Conditional_0_Template, 4, 2, "li",
|
|
364
|
-
i0.ɵɵelementStart(1, "li",
|
|
365
|
-
i0.ɵɵlistener("click", function ConversationChatAreaComponent_ng_template_4_Conditional_2_For_3_Template_button_click_2_listener() { const
|
|
366
|
-
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);
|
|
367
411
|
i0.ɵɵtext(4);
|
|
368
412
|
i0.ɵɵelementEnd()();
|
|
369
|
-
i0.ɵɵelement(5, "i",
|
|
413
|
+
i0.ɵɵelement(5, "i", 83);
|
|
370
414
|
i0.ɵɵelementEnd();
|
|
371
415
|
} if (rf & 2) {
|
|
372
|
-
const
|
|
373
|
-
const $
|
|
374
|
-
i0.ɵɵconditional($
|
|
416
|
+
const parent_r18 = ctx.$implicit;
|
|
417
|
+
const $index_r19 = ctx.$index;
|
|
418
|
+
i0.ɵɵconditional($index_r19 === 1 ? 0 : -1);
|
|
375
419
|
i0.ɵɵadvance();
|
|
376
|
-
i0.ɵɵclassProp("path-middle",
|
|
420
|
+
i0.ɵɵclassProp("path-middle", parent_r18.IsMiddle)("collapsed-wide", parent_r18.CollapsedWide);
|
|
377
421
|
i0.ɵɵadvance();
|
|
378
|
-
i0.ɵɵproperty("title", "Back to " +
|
|
422
|
+
i0.ɵɵproperty("title", "Back to " + parent_r18.Crumb.Label);
|
|
379
423
|
i0.ɵɵadvance(2);
|
|
380
|
-
i0.ɵɵtextInterpolate(
|
|
424
|
+
i0.ɵɵtextInterpolate(parent_r18.Crumb.Label);
|
|
381
425
|
} }
|
|
382
426
|
function ConversationChatAreaComponent_ng_template_4_Conditional_2_ng_container_6_Template(rf, ctx) { if (rf & 1) {
|
|
383
427
|
i0.ɵɵelementContainer(0);
|
|
384
428
|
} }
|
|
385
429
|
function ConversationChatAreaComponent_ng_template_4_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
386
|
-
i0.ɵɵelementStart(0, "nav",
|
|
430
|
+
i0.ɵɵelementStart(0, "nav", 75)(1, "ol", 76);
|
|
387
431
|
i0.ɵɵrepeaterCreate(2, ConversationChatAreaComponent_ng_template_4_Conditional_2_For_3_Template, 6, 7, null, null, i0.ɵɵrepeaterTrackByIndex);
|
|
388
|
-
i0.ɵɵelementStart(4, "li",
|
|
389
|
-
i0.ɵɵelement(5, "i",
|
|
390
|
-
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);
|
|
391
435
|
i0.ɵɵelementEnd()()();
|
|
392
436
|
} if (rf & 2) {
|
|
393
437
|
const ctx_r0 = i0.ɵɵnextContext(2);
|
|
394
|
-
const
|
|
438
|
+
const titleName_r15 = i0.ɵɵreference(7);
|
|
395
439
|
i0.ɵɵadvance(2);
|
|
396
440
|
i0.ɵɵrepeater(ctx_r0.HeaderPath.Parents);
|
|
397
441
|
i0.ɵɵadvance(3);
|
|
398
442
|
i0.ɵɵclassMap("chat-title-kind " + ctx_r0.OpenViewIcon);
|
|
399
443
|
i0.ɵɵattribute("data-kind", ctx_r0.OpenViewKind);
|
|
400
444
|
i0.ɵɵadvance();
|
|
401
|
-
i0.ɵɵproperty("ngTemplateOutlet",
|
|
445
|
+
i0.ɵɵproperty("ngTemplateOutlet", titleName_r15);
|
|
402
446
|
} }
|
|
403
447
|
function ConversationChatAreaComponent_ng_template_4_Template(rf, ctx) { if (rf & 1) {
|
|
404
|
-
i0.ɵɵelementStart(0, "div",
|
|
405
|
-
i0.ɵɵconditionalCreate(1, ConversationChatAreaComponent_ng_template_4_Conditional_1_Template, 1, 1, "ng-container")(2, ConversationChatAreaComponent_ng_template_4_Conditional_2_Template, 7, 4, "nav",
|
|
448
|
+
i0.ɵɵelementStart(0, "div", 74);
|
|
449
|
+
i0.ɵɵconditionalCreate(1, ConversationChatAreaComponent_ng_template_4_Conditional_1_Template, 1, 1, "ng-container")(2, ConversationChatAreaComponent_ng_template_4_Conditional_2_Template, 7, 4, "nav", 75);
|
|
406
450
|
i0.ɵɵelementEnd();
|
|
407
451
|
} if (rf & 2) {
|
|
408
452
|
const ctx_r0 = i0.ɵɵnextContext();
|
|
@@ -410,10 +454,10 @@ function ConversationChatAreaComponent_ng_template_4_Template(rf, ctx) { if (rf
|
|
|
410
454
|
i0.ɵɵconditional(ctx_r0.OpenView.Kind === "Main" ? 1 : 2);
|
|
411
455
|
} }
|
|
412
456
|
function ConversationChatAreaComponent_ng_template_6_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
413
|
-
const
|
|
414
|
-
i0.ɵɵelementStart(0, "input",
|
|
415
|
-
i0.ɵɵtwoWayListener("ngModelChange", function ConversationChatAreaComponent_ng_template_6_Conditional_0_Template_input_ngModelChange_0_listener($event) { i0.ɵɵrestoreView(
|
|
416
|
-
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()); });
|
|
417
461
|
i0.ɵɵelementEnd();
|
|
418
462
|
} if (rf & 2) {
|
|
419
463
|
const ctx_r0 = i0.ɵɵnextContext(2);
|
|
@@ -421,10 +465,10 @@ function ConversationChatAreaComponent_ng_template_6_Conditional_0_Template(rf,
|
|
|
421
465
|
i0.ɵɵattribute("aria-label", ctx_r0.TitleRenameLabel);
|
|
422
466
|
} }
|
|
423
467
|
function ConversationChatAreaComponent_ng_template_6_Conditional_1_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
424
|
-
const
|
|
425
|
-
i0.ɵɵelementStart(0, "button",
|
|
426
|
-
i0.ɵɵlistener("click", function ConversationChatAreaComponent_ng_template_6_Conditional_1_Conditional_2_Template_button_click_0_listener() { i0.ɵɵrestoreView(
|
|
427
|
-
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);
|
|
428
472
|
i0.ɵɵelementEnd();
|
|
429
473
|
} if (rf & 2) {
|
|
430
474
|
const ctx_r0 = i0.ɵɵnextContext(3);
|
|
@@ -432,10 +476,10 @@ function ConversationChatAreaComponent_ng_template_6_Conditional_1_Conditional_2
|
|
|
432
476
|
i0.ɵɵattribute("aria-label", ctx_r0.TitleRenameLabel);
|
|
433
477
|
} }
|
|
434
478
|
function ConversationChatAreaComponent_ng_template_6_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
435
|
-
i0.ɵɵelementStart(0, "h2",
|
|
479
|
+
i0.ɵɵelementStart(0, "h2", 88);
|
|
436
480
|
i0.ɵɵtext(1);
|
|
437
481
|
i0.ɵɵelementEnd();
|
|
438
|
-
i0.ɵɵconditionalCreate(2, ConversationChatAreaComponent_ng_template_6_Conditional_1_Conditional_2_Template, 3, 2, "button",
|
|
482
|
+
i0.ɵɵconditionalCreate(2, ConversationChatAreaComponent_ng_template_6_Conditional_1_Conditional_2_Template, 3, 2, "button", 89);
|
|
439
483
|
} if (rf & 2) {
|
|
440
484
|
const ctx_r0 = i0.ɵɵnextContext(2);
|
|
441
485
|
i0.ɵɵproperty("title", ctx_r0.HeaderTitle);
|
|
@@ -445,7 +489,7 @@ function ConversationChatAreaComponent_ng_template_6_Conditional_1_Template(rf,
|
|
|
445
489
|
i0.ɵɵconditional(ctx_r0.CanRenameTitle ? 2 : -1);
|
|
446
490
|
} }
|
|
447
491
|
function ConversationChatAreaComponent_ng_template_6_Template(rf, ctx) { if (rf & 1) {
|
|
448
|
-
i0.ɵɵconditionalCreate(0, ConversationChatAreaComponent_ng_template_6_Conditional_0_Template, 2, 2, "input",
|
|
492
|
+
i0.ɵɵconditionalCreate(0, ConversationChatAreaComponent_ng_template_6_Conditional_0_Template, 2, 2, "input", 86)(1, ConversationChatAreaComponent_ng_template_6_Conditional_1_Template, 3, 3);
|
|
449
493
|
} if (rf & 2) {
|
|
450
494
|
const ctx_r0 = i0.ɵɵnextContext();
|
|
451
495
|
i0.ɵɵconditional(ctx_r0.IsRenamingTitle ? 0 : 1);
|
|
@@ -454,28 +498,28 @@ function ConversationChatAreaComponent_Conditional_9_ng_container_1_Template(rf,
|
|
|
454
498
|
i0.ɵɵelementContainer(0);
|
|
455
499
|
} }
|
|
456
500
|
function ConversationChatAreaComponent_Conditional_9_Template(rf, ctx) { if (rf & 1) {
|
|
457
|
-
i0.ɵɵelementStart(0, "div",
|
|
458
|
-
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);
|
|
459
503
|
i0.ɵɵelementEnd();
|
|
460
504
|
} if (rf & 2) {
|
|
461
505
|
const ctx_r0 = i0.ɵɵnextContext();
|
|
462
506
|
i0.ɵɵadvance();
|
|
463
|
-
i0.ɵɵproperty("ngTemplateOutlet", ctx_r0.slotTemplate("demonstrationSurface"))("ngTemplateOutletContext", i0.ɵɵpureFunction3(2,
|
|
507
|
+
i0.ɵɵproperty("ngTemplateOutlet", ctx_r0.slotTemplate("demonstrationSurface"))("ngTemplateOutletContext", i0.ɵɵpureFunction3(2, _c9, ctx_r0.demonstrationSurfaceContent, ctx_r0.demonstrationSurfaceContent, ctx_r0.showDemonstrationSurface));
|
|
464
508
|
} }
|
|
465
509
|
function ConversationChatAreaComponent_Conditional_11_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
466
|
-
i0.ɵɵelementStart(0, "div",
|
|
467
|
-
i0.ɵɵelement(1, "mj-loading",
|
|
510
|
+
i0.ɵɵelementStart(0, "div", 92);
|
|
511
|
+
i0.ɵɵelement(1, "mj-loading", 93);
|
|
468
512
|
i0.ɵɵelementEnd();
|
|
469
513
|
} }
|
|
470
514
|
function ConversationChatAreaComponent_Conditional_11_Template(rf, ctx) { if (rf & 1) {
|
|
471
|
-
i0.ɵɵconditionalCreate(0, ConversationChatAreaComponent_Conditional_11_Conditional_0_Template, 2, 0, "div",
|
|
515
|
+
i0.ɵɵconditionalCreate(0, ConversationChatAreaComponent_Conditional_11_Conditional_0_Template, 2, 0, "div", 92);
|
|
472
516
|
} if (rf & 2) {
|
|
473
517
|
const ctx_r0 = i0.ɵɵnextContext();
|
|
474
518
|
i0.ɵɵconditional(ctx_r0.showLoadingState ? 0 : -1);
|
|
475
519
|
} }
|
|
476
520
|
function ConversationChatAreaComponent_Conditional_12_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
477
|
-
i0.ɵɵelementStart(0, "div",
|
|
478
|
-
i0.ɵɵelement(1, "i",
|
|
521
|
+
i0.ɵɵelementStart(0, "div", 94);
|
|
522
|
+
i0.ɵɵelement(1, "i", 96);
|
|
479
523
|
i0.ɵɵelementStart(2, "span");
|
|
480
524
|
i0.ɵɵtext(3);
|
|
481
525
|
i0.ɵɵelementEnd()();
|
|
@@ -488,30 +532,30 @@ function ConversationChatAreaComponent_Conditional_12_Conditional_1_ng_container
|
|
|
488
532
|
i0.ɵɵelementContainer(0);
|
|
489
533
|
} }
|
|
490
534
|
function ConversationChatAreaComponent_Conditional_12_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
491
|
-
i0.ɵɵtemplate(0, ConversationChatAreaComponent_Conditional_12_Conditional_1_ng_container_0_Template, 1, 0, "ng-container",
|
|
535
|
+
i0.ɵɵtemplate(0, ConversationChatAreaComponent_Conditional_12_Conditional_1_ng_container_0_Template, 1, 0, "ng-container", 29);
|
|
492
536
|
} if (rf & 2) {
|
|
493
537
|
const ctx_r0 = i0.ɵɵnextContext(2);
|
|
494
|
-
i0.ɵɵproperty("ngTemplateOutlet", ctx)("ngTemplateOutletContext", i0.ɵɵpureFunction4(3,
|
|
538
|
+
i0.ɵɵproperty("ngTemplateOutlet", ctx)("ngTemplateOutletContext", i0.ɵɵpureFunction4(3, _c11, ctx_r0.emptyStateConfig, (ctx_r0.emptyStateConfig == null ? null : ctx_r0.emptyStateConfig.greeting) ?? ctx_r0.emptyStateGreeting, ctx_r0.emptyStateConfig == null ? null : ctx_r0.emptyStateConfig.subtext, (ctx_r0.emptyStateConfig == null ? null : ctx_r0.emptyStateConfig.suggestedPrompts) ?? i0.ɵɵpureFunction0(2, _c10)));
|
|
495
539
|
} }
|
|
496
540
|
function ConversationChatAreaComponent_Conditional_12_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
497
|
-
const
|
|
498
|
-
i0.ɵɵelementStart(0, "mj-conversation-empty-state",
|
|
499
|
-
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)); });
|
|
500
544
|
i0.ɵɵelementEnd();
|
|
501
545
|
} if (rf & 2) {
|
|
502
546
|
const ctx_r0 = i0.ɵɵnextContext(2);
|
|
503
547
|
i0.ɵɵproperty("currentUser", ctx_r0.currentUser)("initialDraft", ctx_r0.GetInitialDraftFor(null))("disabled", ctx_r0.isProcessing)("showSidebarToggle", ctx_r0.showSidebarToggle)("overlayMode", ctx_r0.overlayMode)("greeting", (ctx_r0.emptyStateConfig == null ? null : ctx_r0.emptyStateConfig.greeting) ?? ctx_r0.emptyStateGreeting)("showSuggestedPrompts", ctx_r0.showSuggestedPrompts)("enableAttachments", ctx_r0.enableAttachments && ctx_r0.allowAttachments)("enableMentions", ctx_r0.allowMentions)("enableAgentMentions", ctx_r0.allowAgentMentions)("enableEntityMentions", ctx_r0.allowEntityMentions)("enableSkillCommands", ctx_r0.allowSkillCommands)("AllowedAgentIDs", ctx_r0.AllowedAgentIDs)("MentionPeople", ctx_r0.MentionPeople)("ComposerExtraTemplate", ctx_r0.slotTemplate("composerExtra"))("maxAttachments", ctx_r0.maxAttachments)("maxAttachmentSizeBytes", ctx_r0.maxAttachmentSizeBytes)("acceptedFileTypes", ctx_r0.acceptedFileTypes);
|
|
504
548
|
} }
|
|
505
549
|
function ConversationChatAreaComponent_Conditional_12_Template(rf, ctx) { if (rf & 1) {
|
|
506
|
-
i0.ɵɵconditionalCreate(0, ConversationChatAreaComponent_Conditional_12_Conditional_0_Template, 4, 1, "div",
|
|
550
|
+
i0.ɵɵconditionalCreate(0, ConversationChatAreaComponent_Conditional_12_Conditional_0_Template, 4, 1, "div", 94)(1, ConversationChatAreaComponent_Conditional_12_Conditional_1_Template, 1, 8, "ng-container")(2, ConversationChatAreaComponent_Conditional_12_Conditional_2_Template, 1, 18, "mj-conversation-empty-state", 95);
|
|
507
551
|
} if (rf & 2) {
|
|
508
552
|
let tmp_3_0;
|
|
509
553
|
const ctx_r0 = i0.ɵɵnextContext();
|
|
510
554
|
i0.ɵɵconditional(ctx_r0.ReadOnly ? 0 : (tmp_3_0 = ctx_r0.slotTemplate("emptyState")) ? 1 : 2, tmp_3_0);
|
|
511
555
|
} }
|
|
512
556
|
function ConversationChatAreaComponent_Conditional_13_Conditional_3_Template(rf, ctx) { if (rf & 1) {
|
|
513
|
-
i0.ɵɵelementStart(0, "div",
|
|
514
|
-
i0.ɵɵelement(1, "i",
|
|
557
|
+
i0.ɵɵelementStart(0, "div", 94);
|
|
558
|
+
i0.ɵɵelement(1, "i", 96);
|
|
515
559
|
i0.ɵɵelementStart(2, "span");
|
|
516
560
|
i0.ɵɵtext(3);
|
|
517
561
|
i0.ɵɵelementEnd()();
|
|
@@ -524,19 +568,19 @@ function ConversationChatAreaComponent_Conditional_13_Conditional_4_Conditional_
|
|
|
524
568
|
i0.ɵɵelementContainer(0);
|
|
525
569
|
} }
|
|
526
570
|
function ConversationChatAreaComponent_Conditional_13_Conditional_4_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
527
|
-
i0.ɵɵelementStart(0, "div",
|
|
528
|
-
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);
|
|
529
573
|
i0.ɵɵelementEnd();
|
|
530
574
|
} if (rf & 2) {
|
|
531
575
|
const ctx_r0 = i0.ɵɵnextContext(3);
|
|
532
576
|
i0.ɵɵadvance();
|
|
533
|
-
i0.ɵɵproperty("ngTemplateOutlet", ctx)("ngTemplateOutletContext", i0.ɵɵpureFunction3(2,
|
|
577
|
+
i0.ɵɵproperty("ngTemplateOutlet", ctx)("ngTemplateOutletContext", i0.ɵɵpureFunction3(2, _c12, ctx_r0.conversation, ctx_r0.conversationId, ctx_r0.isProcessing));
|
|
534
578
|
} }
|
|
535
579
|
function ConversationChatAreaComponent_Conditional_13_Conditional_4_Template(rf, ctx) { if (rf & 1) {
|
|
536
|
-
const
|
|
537
|
-
i0.ɵɵconditionalCreate(0, ConversationChatAreaComponent_Conditional_13_Conditional_4_Conditional_0_Template, 2, 6, "div",
|
|
538
|
-
i0.ɵɵelementStart(1, "div",
|
|
539
|
-
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)); });
|
|
540
584
|
i0.ɵɵelementEnd()();
|
|
541
585
|
} if (rf & 2) {
|
|
542
586
|
let tmp_5_0;
|
|
@@ -546,10 +590,10 @@ function ConversationChatAreaComponent_Conditional_13_Conditional_4_Template(rf,
|
|
|
546
590
|
i0.ɵɵproperty("emptyStateMode", true)("initialDraft", ctx_r0.GetInitialDraftFor(null))("currentUser", ctx_r0.currentUser)("disabled", ctx_r0.isProcessing)("ReadOnly", ctx_r0.EffectiveReadOnly)("appContext", ctx_r0.appContext)("applicationId", ctx_r0.applicationId)("defaultAgentId", ctx_r0.defaultAgentId)("enableAttachments", ctx_r0.enableAttachments && ctx_r0.allowAttachments)("enableMentions", ctx_r0.allowMentions)("enableAgentMentions", ctx_r0.allowAgentMentions)("enableEntityMentions", ctx_r0.allowEntityMentions)("enableSkillCommands", ctx_r0.allowSkillCommands)("enablePlanMode", ctx_r0.allowPlanMode)("enableRealtime", ctx_r0.allowRealtime)("AllowedAgentIDs", ctx_r0.AllowedAgentIDs)("MentionPeople", ctx_r0.MentionPeople)("maxAttachments", ctx_r0.maxAttachments)("maxAttachmentSizeBytes", ctx_r0.maxAttachmentSizeBytes)("acceptedFileTypes", ctx_r0.acceptedFileTypes);
|
|
547
591
|
} }
|
|
548
592
|
function ConversationChatAreaComponent_Conditional_13_Template(rf, ctx) { if (rf & 1) {
|
|
549
|
-
i0.ɵɵelementStart(0, "div",
|
|
550
|
-
i0.ɵɵelement(1, "div",
|
|
551
|
-
i0.ɵɵelementStart(2, "div",
|
|
552
|
-
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);
|
|
553
597
|
i0.ɵɵelementEnd()();
|
|
554
598
|
} if (rf & 2) {
|
|
555
599
|
const ctx_r0 = i0.ɵɵnextContext();
|
|
@@ -560,10 +604,10 @@ function ConversationChatAreaComponent_Conditional_14_Conditional_1_ng_container
|
|
|
560
604
|
i0.ɵɵelementContainer(0);
|
|
561
605
|
} }
|
|
562
606
|
function ConversationChatAreaComponent_Conditional_14_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
563
|
-
const
|
|
564
|
-
i0.ɵɵelementStart(0, "div",
|
|
565
|
-
i0.ɵɵlistener("keydown.escape", function ConversationChatAreaComponent_Conditional_14_Conditional_1_Template_div_keydown_escape_0_listener($event) { i0.ɵɵrestoreView(
|
|
566
|
-
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);
|
|
567
611
|
i0.ɵɵelementEnd();
|
|
568
612
|
} if (rf & 2) {
|
|
569
613
|
i0.ɵɵnextContext(2);
|
|
@@ -572,8 +616,8 @@ function ConversationChatAreaComponent_Conditional_14_Conditional_1_Template(rf,
|
|
|
572
616
|
i0.ɵɵproperty("ngTemplateOutlet", titleBar_r4);
|
|
573
617
|
} }
|
|
574
618
|
function ConversationChatAreaComponent_Conditional_14_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
575
|
-
i0.ɵɵelementStart(0, "div",
|
|
576
|
-
i0.ɵɵelement(1, "mj-loading",
|
|
619
|
+
i0.ɵɵelementStart(0, "div", 104);
|
|
620
|
+
i0.ɵɵelement(1, "mj-loading", 110);
|
|
577
621
|
i0.ɵɵelementEnd();
|
|
578
622
|
} if (rf & 2) {
|
|
579
623
|
const ctx_r0 = i0.ɵɵnextContext(2);
|
|
@@ -581,20 +625,20 @@ function ConversationChatAreaComponent_Conditional_14_Conditional_2_Template(rf,
|
|
|
581
625
|
i0.ɵɵproperty("text", ctx_r0.uploadingMessage);
|
|
582
626
|
} }
|
|
583
627
|
function ConversationChatAreaComponent_Conditional_14_Conditional_6_Template(rf, ctx) { if (rf & 1) {
|
|
584
|
-
const
|
|
585
|
-
i0.ɵɵelementStart(0, "span",
|
|
586
|
-
i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_14_Conditional_6_Template_span_click_0_listener() { i0.ɵɵrestoreView(
|
|
587
|
-
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);
|
|
588
632
|
i0.ɵɵelementEnd();
|
|
589
633
|
} }
|
|
590
634
|
function ConversationChatAreaComponent_Conditional_14_Conditional_8_Template(rf, ctx) { if (rf & 1) {
|
|
591
|
-
i0.ɵɵelementStart(0, "div",
|
|
592
|
-
i0.ɵɵelement(1, "mj-loading",
|
|
635
|
+
i0.ɵɵelementStart(0, "div", 108);
|
|
636
|
+
i0.ɵɵelement(1, "mj-loading", 113);
|
|
593
637
|
i0.ɵɵelementEnd();
|
|
594
638
|
} }
|
|
595
639
|
function ConversationChatAreaComponent_Conditional_14_Conditional_9_Template(rf, ctx) { if (rf & 1) {
|
|
596
|
-
i0.ɵɵelementStart(0, "div",
|
|
597
|
-
i0.ɵɵelement(1, "i",
|
|
640
|
+
i0.ɵɵelementStart(0, "div", 94);
|
|
641
|
+
i0.ɵɵelement(1, "i", 96);
|
|
598
642
|
i0.ɵɵelementStart(2, "span");
|
|
599
643
|
i0.ɵɵtext(3);
|
|
600
644
|
i0.ɵɵelementEnd()();
|
|
@@ -604,8 +648,8 @@ function ConversationChatAreaComponent_Conditional_14_Conditional_9_Template(rf,
|
|
|
604
648
|
i0.ɵɵtextInterpolate(ctx_r0.ReadOnlyMessage || "You have view-only access to this conversation.");
|
|
605
649
|
} }
|
|
606
650
|
function ConversationChatAreaComponent_Conditional_14_Conditional_10_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
607
|
-
i0.ɵɵelementStart(0, "div",
|
|
608
|
-
i0.ɵɵelement(1, "i",
|
|
651
|
+
i0.ɵɵelementStart(0, "div", 94);
|
|
652
|
+
i0.ɵɵelement(1, "i", 96);
|
|
609
653
|
i0.ɵɵelementStart(2, "span");
|
|
610
654
|
i0.ɵɵtext(3, "You have view-only access to this conversation.");
|
|
611
655
|
i0.ɵɵelementEnd()();
|
|
@@ -614,26 +658,26 @@ function ConversationChatAreaComponent_Conditional_14_Conditional_10_Conditional
|
|
|
614
658
|
i0.ɵɵelementContainer(0);
|
|
615
659
|
} }
|
|
616
660
|
function ConversationChatAreaComponent_Conditional_14_Conditional_10_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
617
|
-
i0.ɵɵelementStart(0, "div",
|
|
618
|
-
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);
|
|
619
663
|
i0.ɵɵelementEnd();
|
|
620
664
|
} if (rf & 2) {
|
|
621
665
|
const ctx_r0 = i0.ɵɵnextContext(3);
|
|
622
666
|
i0.ɵɵadvance();
|
|
623
|
-
i0.ɵɵproperty("ngTemplateOutlet", ctx)("ngTemplateOutletContext", i0.ɵɵpureFunction3(2,
|
|
667
|
+
i0.ɵɵproperty("ngTemplateOutlet", ctx)("ngTemplateOutletContext", i0.ɵɵpureFunction3(2, _c12, ctx_r0.conversation, ctx_r0.conversationId, ctx_r0.isProcessing));
|
|
624
668
|
} }
|
|
625
669
|
function ConversationChatAreaComponent_Conditional_14_Conditional_10_For_4_Template(rf, ctx) { if (rf & 1) {
|
|
626
|
-
const
|
|
627
|
-
i0.ɵɵelementStart(0, "mj-message-input",
|
|
628
|
-
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)); });
|
|
629
673
|
i0.ɵɵelementEnd();
|
|
630
674
|
} if (rf & 2) {
|
|
631
|
-
const
|
|
675
|
+
const inputRef_r28 = ctx.$implicit;
|
|
632
676
|
const ctx_r0 = i0.ɵɵnextContext(3);
|
|
633
|
-
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);
|
|
634
678
|
} }
|
|
635
679
|
function ConversationChatAreaComponent_Conditional_14_Conditional_10_Conditional_5_Template(rf, ctx) { if (rf & 1) {
|
|
636
|
-
i0.ɵɵelementStart(0, "div",
|
|
680
|
+
i0.ɵɵelementStart(0, "div", 115);
|
|
637
681
|
i0.ɵɵtext(1);
|
|
638
682
|
i0.ɵɵelementEnd();
|
|
639
683
|
} if (rf & 2) {
|
|
@@ -642,12 +686,12 @@ function ConversationChatAreaComponent_Conditional_14_Conditional_10_Conditional
|
|
|
642
686
|
i0.ɵɵtextInterpolate(ctx_r0.ComposerHint);
|
|
643
687
|
} }
|
|
644
688
|
function ConversationChatAreaComponent_Conditional_14_Conditional_10_Template(rf, ctx) { if (rf & 1) {
|
|
645
|
-
i0.ɵɵconditionalCreate(0, ConversationChatAreaComponent_Conditional_14_Conditional_10_Conditional_0_Template, 4, 0, "div",
|
|
646
|
-
i0.ɵɵconditionalCreate(1, ConversationChatAreaComponent_Conditional_14_Conditional_10_Conditional_1_Template, 2, 6, "div",
|
|
647
|
-
i0.ɵɵelementStart(2, "div",
|
|
648
|
-
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);
|
|
649
693
|
i0.ɵɵelementEnd();
|
|
650
|
-
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);
|
|
651
695
|
} if (rf & 2) {
|
|
652
696
|
let tmp_6_0;
|
|
653
697
|
const ctx_r0 = i0.ɵɵnextContext(2);
|
|
@@ -660,19 +704,19 @@ function ConversationChatAreaComponent_Conditional_14_Conditional_10_Template(rf
|
|
|
660
704
|
i0.ɵɵconditional(ctx_r0.ComposerHint ? 5 : -1);
|
|
661
705
|
} }
|
|
662
706
|
function ConversationChatAreaComponent_Conditional_14_Template(rf, ctx) { if (rf & 1) {
|
|
663
|
-
const
|
|
664
|
-
i0.ɵɵelementStart(0, "div",
|
|
665
|
-
i0.ɵɵconditionalCreate(1, ConversationChatAreaComponent_Conditional_14_Conditional_1_Template, 2, 1, "div",
|
|
666
|
-
i0.ɵɵconditionalCreate(2, ConversationChatAreaComponent_Conditional_14_Conditional_2_Template, 2, 1, "div",
|
|
667
|
-
i0.ɵɵelementStart(3, "div",
|
|
668
|
-
i0.ɵɵlistener("scroll", function ConversationChatAreaComponent_Conditional_14_Template_div_scroll_3_listener() { i0.ɵɵrestoreView(
|
|
669
|
-
i0.ɵɵelementStart(5, "mj-conversation-message-list",
|
|
670
|
-
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)); });
|
|
671
715
|
i0.ɵɵelementEnd();
|
|
672
|
-
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);
|
|
673
717
|
i0.ɵɵelementEnd();
|
|
674
|
-
i0.ɵɵelementStart(7, "div",
|
|
675
|
-
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);
|
|
676
720
|
i0.ɵɵelementEnd()();
|
|
677
721
|
} if (rf & 2) {
|
|
678
722
|
const ctx_r0 = i0.ɵɵnextContext();
|
|
@@ -681,23 +725,23 @@ function ConversationChatAreaComponent_Conditional_14_Template(rf, ctx) { if (rf
|
|
|
681
725
|
i0.ɵɵadvance();
|
|
682
726
|
i0.ɵɵconditional(ctx_r0.isUploadingAttachments ? 2 : -1);
|
|
683
727
|
i0.ɵɵadvance(3);
|
|
684
|
-
i0.ɵɵproperty("showEmptyFill", ctx_r0.showEmptyFill)("showDateNavigation", ctx_r0.showDateNavigation)("showAgentRunDetails", ctx_r0.showAgentRunDetails)("showReactions", ctx_r0.showReactions)("showMessageRating", ctx_r0.showMessageRating)("allowPinning", ctx_r0.allowPinning && !ctx_r0.EffectiveReadOnly)("allowMessageEdit", ctx_r0.allowMessageEdit && !ctx_r0.EffectiveReadOnly)("allowMessageDelete", ctx_r0.allowMessageDelete && !ctx_r0.EffectiveReadOnly)("ReadOnly", ctx_r0.EffectiveReadOnly)("AllowStopRun", ctx_r0.AllowStopRun)("InFlightCount", ctx_r0.InFlightCount)("assistantDisplayName", ctx_r0.assistantDisplayName)("assistantAvatarUrl", ctx_r0.assistantAvatarUrl)("messages", ctx_r0.DisplayMessages)("HasMoreAbove", ctx_r0.ListHasMoreAbove)("IsLoadingOlder", ctx_r0.isLoadingOlderMessages)("ScrollRoot", ctx_r0.messageScrollRoot)("conversation", ctx_r0.conversation)("currentUser", ctx_r0.currentUser)("isProcessing", ctx_r0.isProcessing)("artifactMap", ctx_r0.effectiveArtifactsMap)("agentRunMap", ctx_r0.agentRunsByDetailId)("ratingsMap", ctx_r0.ratingsByDetailId)("userAvatarMap", ctx_r0.userAvatarMap)("attachmentsMap", ctx_r0.attachmentsByDetailId)("messageRendererTemplate", ctx_r0.slotTemplate("messageRenderer"))("messageExtraTemplate", ctx_r0.slotTemplate("messageExtra"))("sessionMetaMap", ctx_r0.realtimeSessionMetaMap)("ForkChipMap", ctx_r0.ForkChipMap)("ForkLayout", ctx_r0.ForkLayout)("CanFork", ctx_r0.CanFork)("InPlaceTurn", ctx_r0.InPlaceTurn);
|
|
728
|
+
i0.ɵɵproperty("showEmptyFill", ctx_r0.showEmptyFill)("showDateNavigation", ctx_r0.showDateNavigation)("showAgentRunDetails", ctx_r0.showAgentRunDetails)("showReactions", ctx_r0.showReactions)("showMessageRating", ctx_r0.showMessageRating)("allowPinning", ctx_r0.allowPinning && !ctx_r0.EffectiveReadOnly)("allowMessageEdit", ctx_r0.allowMessageEdit && !ctx_r0.EffectiveReadOnly)("allowMessageDelete", ctx_r0.allowMessageDelete && !ctx_r0.EffectiveReadOnly)("ReadOnly", ctx_r0.EffectiveReadOnly)("AllowStopRun", ctx_r0.AllowStopRun)("InFlightCount", ctx_r0.InFlightCount)("assistantDisplayName", ctx_r0.assistantDisplayName)("assistantAvatarUrl", ctx_r0.assistantAvatarUrl)("messages", ctx_r0.DisplayMessages)("HasMoreAbove", ctx_r0.ListHasMoreAbove)("IsLoadingOlder", ctx_r0.isLoadingOlderMessages)("ScrollRoot", ctx_r0.messageScrollRoot)("conversation", ctx_r0.conversation)("currentUser", ctx_r0.currentUser)("isProcessing", ctx_r0.isProcessing)("artifactMap", ctx_r0.effectiveArtifactsMap)("agentRunMap", ctx_r0.agentRunsByDetailId)("HandoffMap", ctx_r0.HandoffsByDetailId)("ratingsMap", ctx_r0.ratingsByDetailId)("userAvatarMap", ctx_r0.userAvatarMap)("attachmentsMap", ctx_r0.attachmentsByDetailId)("messageRendererTemplate", ctx_r0.slotTemplate("messageRenderer"))("messageExtraTemplate", ctx_r0.slotTemplate("messageExtra"))("sessionMetaMap", ctx_r0.realtimeSessionMetaMap)("ForkChipMap", ctx_r0.ForkChipMap)("ForkLayout", ctx_r0.ForkLayout)("CanFork", ctx_r0.CanFork)("InPlaceTurn", ctx_r0.InPlaceTurn);
|
|
685
729
|
i0.ɵɵadvance();
|
|
686
730
|
i0.ɵɵconditional(ctx_r0.showScrollToBottomIcon && ctx_r0.DisplayMessages.length > 0 ? 6 : -1);
|
|
687
731
|
i0.ɵɵadvance(2);
|
|
688
732
|
i0.ɵɵconditional(ctx_r0.isLoadingPeripheralData ? 8 : ctx_r0.ReadOnly ? 9 : 10);
|
|
689
733
|
} }
|
|
690
734
|
function ConversationChatAreaComponent_Conditional_15_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
691
|
-
const
|
|
692
|
-
i0.ɵɵelementStart(0, "div",
|
|
693
|
-
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)); });
|
|
694
738
|
i0.ɵɵelementEnd();
|
|
695
739
|
} }
|
|
696
740
|
function ConversationChatAreaComponent_Conditional_15_Template(rf, ctx) { if (rf & 1) {
|
|
697
|
-
const
|
|
698
|
-
i0.ɵɵconditionalCreate(0, ConversationChatAreaComponent_Conditional_15_Conditional_0_Template, 1, 0, "div",
|
|
699
|
-
i0.ɵɵelementStart(1, "div",
|
|
700
|
-
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)); });
|
|
701
745
|
i0.ɵɵelementEnd()();
|
|
702
746
|
} if (rf & 2) {
|
|
703
747
|
const ctx_r0 = i0.ɵɵnextContext();
|
|
@@ -709,42 +753,42 @@ function ConversationChatAreaComponent_Conditional_15_Template(rf, ctx) { if (rf
|
|
|
709
753
|
i0.ɵɵproperty("artifactId", ctx_r0.selectedArtifactId)("currentUser", ctx_r0.currentUser)("environmentId", ctx_r0.environmentId)("versionNumber", ctx_r0.selectedVersionNumber)("viewContext", "conversation")("Scope", ctx_r0.ArtifactViewerScope)("canShare", ctx_r0.canShareSelectedArtifact)("canEdit", ctx_r0.canEditSelectedArtifact)("isMaximized", ctx_r0.isArtifactPaneMaximized)("refreshTrigger", ctx_r0.artifactViewerRefresh$);
|
|
710
754
|
} }
|
|
711
755
|
function ConversationChatAreaComponent_Conditional_16_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
712
|
-
const
|
|
713
|
-
i0.ɵɵelementStart(0, "div",
|
|
714
|
-
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)); });
|
|
715
759
|
i0.ɵɵelementEnd();
|
|
716
760
|
} }
|
|
717
761
|
function ConversationChatAreaComponent_Conditional_16_Template(rf, ctx) { if (rf & 1) {
|
|
718
|
-
const
|
|
719
|
-
i0.ɵɵconditionalCreate(0, ConversationChatAreaComponent_Conditional_16_Conditional_0_Template, 1, 0, "div",
|
|
720
|
-
i0.ɵɵelementStart(1, "div",
|
|
721
|
-
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);
|
|
722
766
|
i0.ɵɵelementEnd();
|
|
723
|
-
i0.ɵɵelementStart(6, "div",
|
|
767
|
+
i0.ɵɵelementStart(6, "div", 126)(7, "span", 127);
|
|
724
768
|
i0.ɵɵtext(8);
|
|
725
769
|
i0.ɵɵelementEnd();
|
|
726
|
-
i0.ɵɵelementStart(9, "span",
|
|
770
|
+
i0.ɵɵelementStart(9, "span", 128);
|
|
727
771
|
i0.ɵɵtext(10, "Interactive Task Graph & Step Inspector");
|
|
728
772
|
i0.ɵɵelementEnd()()();
|
|
729
|
-
i0.ɵɵelementStart(11, "div",
|
|
730
|
-
i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_16_Template_button_click_12_listener() { i0.ɵɵrestoreView(
|
|
731
|
-
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);
|
|
732
776
|
i0.ɵɵelementStart(14, "span");
|
|
733
777
|
i0.ɵɵtext(15);
|
|
734
778
|
i0.ɵɵelementEnd()();
|
|
735
|
-
i0.ɵɵelementStart(16, "button",
|
|
736
|
-
i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_16_Template_button_click_16_listener() { i0.ɵɵrestoreView(
|
|
737
|
-
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);
|
|
738
782
|
i0.ɵɵelementEnd();
|
|
739
|
-
i0.ɵɵelementStart(18, "button",
|
|
740
|
-
i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_16_Template_button_click_18_listener() { i0.ɵɵrestoreView(
|
|
741
|
-
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);
|
|
742
786
|
i0.ɵɵelementEnd()()();
|
|
743
|
-
i0.ɵɵelementStart(20, "div",
|
|
744
|
-
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);
|
|
745
789
|
i0.ɵɵelementEnd()();
|
|
746
790
|
} if (rf & 2) {
|
|
747
|
-
const
|
|
791
|
+
const taskGraphRunView_r33 = i0.ɵɵreference(22);
|
|
748
792
|
const ctx_r0 = i0.ɵɵnextContext();
|
|
749
793
|
i0.ɵɵconditional(!ctx_r0.isArtifactPaneMaximized ? 0 : -1);
|
|
750
794
|
i0.ɵɵadvance();
|
|
@@ -753,7 +797,7 @@ function ConversationChatAreaComponent_Conditional_16_Template(rf, ctx) { if (rf
|
|
|
753
797
|
i0.ɵɵadvance(7);
|
|
754
798
|
i0.ɵɵtextInterpolate(ctx_r0.SelectedTaskGraphPanel.workflowTitle);
|
|
755
799
|
i0.ɵɵadvance(4);
|
|
756
|
-
i0.ɵɵproperty("disabled", ctx_r0.IsSavingTaskGraphWorkflow || !(
|
|
800
|
+
i0.ɵɵproperty("disabled", ctx_r0.IsSavingTaskGraphWorkflow || !(taskGraphRunView_r33.Spec == null ? null : taskGraphRunView_r33.Spec.tasks == null ? null : taskGraphRunView_r33.Spec.tasks.length));
|
|
757
801
|
i0.ɵɵadvance();
|
|
758
802
|
i0.ɵɵclassProp("fa-spinner", ctx_r0.IsSavingTaskGraphWorkflow)("fa-spin", ctx_r0.IsSavingTaskGraphWorkflow)("fa-floppy-disk", !ctx_r0.IsSavingTaskGraphWorkflow);
|
|
759
803
|
i0.ɵɵadvance(2);
|
|
@@ -765,33 +809,89 @@ function ConversationChatAreaComponent_Conditional_16_Template(rf, ctx) { if (rf
|
|
|
765
809
|
i0.ɵɵadvance(4);
|
|
766
810
|
i0.ɵɵproperty("ParentTaskID", ctx_r0.SelectedTaskGraphPanel.parentTaskId)("WorkflowName", ctx_r0.SelectedTaskGraphPanel.workflowTitle)("LiveUpdates", true)("ShowVariables", true)("Height", "100%");
|
|
767
811
|
} }
|
|
768
|
-
function
|
|
769
|
-
const
|
|
770
|
-
i0.ɵɵelementStart(0, "
|
|
771
|
-
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);
|
|
823
|
+
i0.ɵɵelementEnd();
|
|
824
|
+
i0.ɵɵelementStart(6, "div", 126)(7, "span", 127);
|
|
825
|
+
i0.ɵɵtext(8, "Remote Browser");
|
|
772
826
|
i0.ɵɵelementEnd();
|
|
827
|
+
i0.ɵɵelementStart(9, "span", 128);
|
|
828
|
+
i0.ɵɵtext(10, "Shared live browser workspace");
|
|
829
|
+
i0.ɵɵelementEnd()()();
|
|
830
|
+
i0.ɵɵelementStart(11, "div", 129)(12, "input", 138);
|
|
831
|
+
i0.ɵɵtwoWayListener("ngModelChange", function ConversationChatAreaComponent_Conditional_17_Template_input_ngModelChange_12_listener($event) { i0.ɵɵrestoreView(_r34); const ctx_r0 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r0.RemoteBrowserUrlInput, $event) || (ctx_r0.RemoteBrowserUrlInput = $event); return i0.ɵɵresetView($event); });
|
|
832
|
+
i0.ɵɵlistener("keydown.enter", function ConversationChatAreaComponent_Conditional_17_Template_input_keydown_enter_12_listener($event) { i0.ɵɵrestoreView(_r34); const ctx_r0 = i0.ɵɵnextContext(); $event.preventDefault(); return i0.ɵɵresetView(ctx_r0.NavigateRemoteBrowserFromInput()); });
|
|
833
|
+
i0.ɵɵelementEnd();
|
|
834
|
+
i0.ɵɵelementStart(13, "button", 139);
|
|
835
|
+
i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_17_Template_button_click_13_listener() { i0.ɵɵrestoreView(_r34); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.NavigateRemoteBrowserFromInput()); });
|
|
836
|
+
i0.ɵɵelement(14, "i", 131);
|
|
837
|
+
i0.ɵɵelementStart(15, "span");
|
|
838
|
+
i0.ɵɵtext(16, "Go");
|
|
839
|
+
i0.ɵɵelementEnd()();
|
|
840
|
+
i0.ɵɵelementStart(17, "button", 132);
|
|
841
|
+
i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_17_Template_button_click_17_listener() { i0.ɵɵrestoreView(_r34); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.toggleMaximizeArtifactPane()); });
|
|
842
|
+
i0.ɵɵelement(18, "i", 131);
|
|
843
|
+
i0.ɵɵelementEnd();
|
|
844
|
+
i0.ɵɵelementStart(19, "button", 140);
|
|
845
|
+
i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_17_Template_button_click_19_listener() { i0.ɵɵrestoreView(_r34); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.CloseRemoteBrowserPanel()); });
|
|
846
|
+
i0.ɵɵelement(20, "i", 134);
|
|
847
|
+
i0.ɵɵelementEnd()()();
|
|
848
|
+
i0.ɵɵelementStart(21, "div", 135);
|
|
849
|
+
i0.ɵɵelement(22, "mj-realtime-remote-browser-surface", null, 9);
|
|
850
|
+
i0.ɵɵelementEnd()();
|
|
773
851
|
} if (rf & 2) {
|
|
774
852
|
const ctx_r0 = i0.ɵɵnextContext();
|
|
775
|
-
i0.ɵɵ
|
|
853
|
+
i0.ɵɵconditional(!ctx_r0.isArtifactPaneMaximized ? 0 : -1);
|
|
854
|
+
i0.ɵɵadvance();
|
|
855
|
+
i0.ɵɵstyleProp("width", ctx_r0.artifactPaneWidth, "%");
|
|
856
|
+
i0.ɵɵclassProp("maximized", ctx_r0.isArtifactPaneMaximized);
|
|
857
|
+
i0.ɵɵadvance(11);
|
|
858
|
+
i0.ɵɵtwoWayProperty("ngModel", ctx_r0.RemoteBrowserUrlInput);
|
|
859
|
+
i0.ɵɵadvance();
|
|
860
|
+
i0.ɵɵproperty("disabled", ctx_r0.IsRemoteBrowserNavigating || !ctx_r0.RemoteBrowserUrlInput.trim());
|
|
861
|
+
i0.ɵɵadvance();
|
|
862
|
+
i0.ɵɵclassProp("fa-spinner", ctx_r0.IsRemoteBrowserNavigating)("fa-spin", ctx_r0.IsRemoteBrowserNavigating)("fa-arrow-right", !ctx_r0.IsRemoteBrowserNavigating);
|
|
863
|
+
i0.ɵɵadvance(3);
|
|
864
|
+
i0.ɵɵproperty("title", ctx_r0.isArtifactPaneMaximized ? "Restore panel size" : "Maximize panel");
|
|
865
|
+
i0.ɵɵadvance();
|
|
866
|
+
i0.ɵɵclassProp("fa-compress", ctx_r0.isArtifactPaneMaximized)("fa-expand", !ctx_r0.isArtifactPaneMaximized);
|
|
776
867
|
} }
|
|
777
868
|
function ConversationChatAreaComponent_Conditional_19_Template(rf, ctx) { if (rf & 1) {
|
|
778
|
-
const
|
|
779
|
-
i0.ɵɵelementStart(0, "mj-
|
|
780
|
-
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()); });
|
|
781
881
|
i0.ɵɵelementEnd();
|
|
782
882
|
} if (rf & 2) {
|
|
783
883
|
const ctx_r0 = i0.ɵɵnextContext();
|
|
784
884
|
i0.ɵɵproperty("PanelID", ctx_r0.ForksPopoverID)("Summaries", ctx_r0.ForkSummaries)("CurrentUserID", ctx_r0.CurrentUser.ID);
|
|
785
885
|
} }
|
|
786
|
-
function
|
|
787
|
-
const
|
|
788
|
-
i0.ɵɵelementStart(0, "button",
|
|
789
|
-
i0.ɵɵlistener("click", function
|
|
790
|
-
i0.ɵɵelement(1, "span",
|
|
791
|
-
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);
|
|
792
892
|
i0.ɵɵtext(5);
|
|
793
893
|
i0.ɵɵelementEnd();
|
|
794
|
-
i0.ɵɵelementStart(6, "span",
|
|
894
|
+
i0.ɵɵelementStart(6, "span", 150);
|
|
795
895
|
i0.ɵɵtext(7, "Tap to return");
|
|
796
896
|
i0.ɵɵelementEnd()()();
|
|
797
897
|
} if (rf & 2) {
|
|
@@ -799,13 +899,13 @@ function ConversationChatAreaComponent_Conditional_20_Conditional_2_Template(rf,
|
|
|
799
899
|
i0.ɵɵadvance(5);
|
|
800
900
|
i0.ɵɵtextInterpolate1("On call \u00B7 ", ctx_r0.RealtimeSession.CurrentAgentName);
|
|
801
901
|
} }
|
|
802
|
-
function
|
|
803
|
-
const
|
|
804
|
-
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);
|
|
805
905
|
i0.ɵɵpipe(1, "async");
|
|
806
|
-
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()); });
|
|
807
907
|
i0.ɵɵelementEnd();
|
|
808
|
-
i0.ɵɵconditionalCreate(2,
|
|
908
|
+
i0.ɵɵconditionalCreate(2, ConversationChatAreaComponent_Conditional_21_Conditional_2_Template, 8, 1, "button", 144);
|
|
809
909
|
i0.ɵɵpipe(3, "async");
|
|
810
910
|
} if (rf & 2) {
|
|
811
911
|
const ctx_r0 = i0.ɵɵnextContext();
|
|
@@ -813,32 +913,32 @@ function ConversationChatAreaComponent_Conditional_20_Template(rf, ctx) { if (rf
|
|
|
813
913
|
i0.ɵɵadvance(2);
|
|
814
914
|
i0.ɵɵconditional(i0.ɵɵpipeBind1(3, 13, ctx_r0.RealtimeSession.Minimized$) ? 2 : -1);
|
|
815
915
|
} }
|
|
816
|
-
function
|
|
817
|
-
const
|
|
818
|
-
i0.ɵɵelementStart(0, "div",
|
|
819
|
-
i0.ɵɵlistener("click", function
|
|
820
|
-
i0.ɵɵelementStart(1, "div",
|
|
821
|
-
i0.ɵɵlistener("click", function
|
|
822
|
-
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");
|
|
823
923
|
i0.ɵɵtext(4, "Assign Project");
|
|
824
924
|
i0.ɵɵelementEnd();
|
|
825
|
-
i0.ɵɵelementStart(5, "button",
|
|
826
|
-
i0.ɵɵlistener("click", function
|
|
827
|
-
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);
|
|
828
928
|
i0.ɵɵelementEnd()();
|
|
829
|
-
i0.ɵɵelementStart(7, "div",
|
|
830
|
-
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)); });
|
|
831
931
|
i0.ɵɵelementEnd()()()();
|
|
832
932
|
} if (rf & 2) {
|
|
833
933
|
const ctx_r0 = i0.ɵɵnextContext();
|
|
834
934
|
i0.ɵɵadvance(8);
|
|
835
935
|
i0.ɵɵproperty("environmentId", ctx_r0.environmentId)("currentUser", ctx_r0.currentUser)("selectedProjectId", ctx_r0.conversation.ProjectID);
|
|
836
936
|
} }
|
|
837
|
-
function
|
|
838
|
-
const
|
|
839
|
-
i0.ɵɵelementStart(0, "button",
|
|
840
|
-
i0.ɵɵlistener("click", function
|
|
841
|
-
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);
|
|
842
942
|
i0.ɵɵelementStart(2, "span");
|
|
843
943
|
i0.ɵɵtext(3);
|
|
844
944
|
i0.ɵɵelementEnd()();
|
|
@@ -848,106 +948,106 @@ function ConversationChatAreaComponent_Conditional_26_Conditional_6_Template(rf,
|
|
|
848
948
|
i0.ɵɵadvance(3);
|
|
849
949
|
i0.ɵɵtextInterpolate1("", ctx_r0.showSystemArtifacts ? "Hide" : "Show", " System");
|
|
850
950
|
} }
|
|
851
|
-
function
|
|
852
|
-
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);
|
|
853
953
|
} }
|
|
854
|
-
function
|
|
954
|
+
function ConversationChatAreaComponent_Conditional_27_For_12_Conditional_8_Template(rf, ctx) { if (rf & 1) {
|
|
855
955
|
i0.ɵɵtext(0);
|
|
856
956
|
} if (rf & 2) {
|
|
857
|
-
const
|
|
858
|
-
i0.ɵɵtextInterpolate1(" ",
|
|
957
|
+
const artifact_r44 = i0.ɵɵnextContext().$implicit;
|
|
958
|
+
i0.ɵɵtextInterpolate1(" ", artifact_r44.versionCount, " versions ");
|
|
859
959
|
} }
|
|
860
|
-
function
|
|
960
|
+
function ConversationChatAreaComponent_Conditional_27_For_12_Conditional_9_Template(rf, ctx) { if (rf & 1) {
|
|
861
961
|
i0.ɵɵtext(0, " 1 version ");
|
|
862
962
|
} }
|
|
863
|
-
function
|
|
864
|
-
const
|
|
865
|
-
i0.ɵɵelementStart(0, "button",
|
|
866
|
-
i0.ɵɵlistener("click", function
|
|
867
|
-
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);
|
|
868
968
|
i0.ɵɵelementEnd();
|
|
869
969
|
} if (rf & 2) {
|
|
870
|
-
const
|
|
970
|
+
const artifact_r44 = i0.ɵɵnextContext().$implicit;
|
|
871
971
|
const ctx_r0 = i0.ɵɵnextContext(2);
|
|
872
972
|
i0.ɵɵadvance();
|
|
873
|
-
i0.ɵɵclassProp("fa-chevron-down", ctx_r0.expandedArtifactId !==
|
|
973
|
+
i0.ɵɵclassProp("fa-chevron-down", ctx_r0.expandedArtifactId !== artifact_r44.artifactId)("fa-chevron-up", ctx_r0.expandedArtifactId === artifact_r44.artifactId);
|
|
874
974
|
} }
|
|
875
|
-
function
|
|
876
|
-
const
|
|
877
|
-
i0.ɵɵelementStart(0, "div",
|
|
878
|
-
i0.ɵɵlistener("click", function
|
|
879
|
-
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);
|
|
880
980
|
i0.ɵɵtext(2);
|
|
881
981
|
i0.ɵɵelementEnd();
|
|
882
|
-
i0.ɵɵelementStart(3, "span",
|
|
982
|
+
i0.ɵɵelementStart(3, "span", 182);
|
|
883
983
|
i0.ɵɵtext(4, "Open this version");
|
|
884
984
|
i0.ɵɵelementEnd();
|
|
885
|
-
i0.ɵɵelement(5, "i",
|
|
985
|
+
i0.ɵɵelement(5, "i", 183);
|
|
886
986
|
i0.ɵɵelementEnd();
|
|
887
987
|
} if (rf & 2) {
|
|
888
|
-
const
|
|
988
|
+
const version_r47 = ctx.$implicit;
|
|
889
989
|
i0.ɵɵadvance(2);
|
|
890
|
-
i0.ɵɵtextInterpolate1("v",
|
|
990
|
+
i0.ɵɵtextInterpolate1("v", version_r47.versionNumber);
|
|
891
991
|
} }
|
|
892
|
-
function
|
|
893
|
-
i0.ɵɵelementStart(0, "div",
|
|
894
|
-
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);
|
|
895
995
|
i0.ɵɵelementEnd();
|
|
896
996
|
} if (rf & 2) {
|
|
897
|
-
const
|
|
997
|
+
const artifact_r44 = i0.ɵɵnextContext().$implicit;
|
|
898
998
|
i0.ɵɵadvance();
|
|
899
|
-
i0.ɵɵrepeater(
|
|
999
|
+
i0.ɵɵrepeater(artifact_r44.versions);
|
|
900
1000
|
} }
|
|
901
|
-
function
|
|
902
|
-
const
|
|
903
|
-
i0.ɵɵelementStart(0, "div",
|
|
904
|
-
i0.ɵɵlistener("click", function
|
|
905
|
-
i0.ɵɵelementStart(2, "div",
|
|
906
|
-
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);
|
|
907
1007
|
i0.ɵɵelementEnd();
|
|
908
|
-
i0.ɵɵelementStart(4, "div",
|
|
1008
|
+
i0.ɵɵelementStart(4, "div", 170)(5, "div", 171);
|
|
909
1009
|
i0.ɵɵtext(6);
|
|
910
1010
|
i0.ɵɵelementEnd();
|
|
911
|
-
i0.ɵɵelementStart(7, "div",
|
|
912
|
-
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);
|
|
913
1013
|
i0.ɵɵelementEnd()();
|
|
914
|
-
i0.ɵɵconditionalCreate(10,
|
|
915
|
-
i0.ɵɵelementStart(11, "div",
|
|
916
|
-
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);
|
|
917
1017
|
i0.ɵɵelementEnd()();
|
|
918
|
-
i0.ɵɵconditionalCreate(13,
|
|
1018
|
+
i0.ɵɵconditionalCreate(13, ConversationChatAreaComponent_Conditional_27_For_12_Conditional_13_Template, 3, 0, "div", 176);
|
|
919
1019
|
i0.ɵɵelementEnd();
|
|
920
1020
|
} if (rf & 2) {
|
|
921
|
-
const
|
|
1021
|
+
const artifact_r44 = ctx.$implicit;
|
|
922
1022
|
const ctx_r0 = i0.ɵɵnextContext(2);
|
|
923
|
-
i0.ɵɵclassProp("expanded", ctx_r0.expandedArtifactId ===
|
|
1023
|
+
i0.ɵɵclassProp("expanded", ctx_r0.expandedArtifactId === artifact_r44.artifactId)("system-artifact", artifact_r44.visibility === "System Only");
|
|
924
1024
|
i0.ɵɵadvance(6);
|
|
925
|
-
i0.ɵɵtextInterpolate(
|
|
1025
|
+
i0.ɵɵtextInterpolate(artifact_r44.name);
|
|
926
1026
|
i0.ɵɵadvance(2);
|
|
927
|
-
i0.ɵɵconditional(
|
|
1027
|
+
i0.ɵɵconditional(artifact_r44.versionCount > 1 ? 8 : 9);
|
|
928
1028
|
i0.ɵɵadvance(2);
|
|
929
|
-
i0.ɵɵconditional(
|
|
1029
|
+
i0.ɵɵconditional(artifact_r44.versionCount > 1 ? 10 : -1);
|
|
930
1030
|
i0.ɵɵadvance(3);
|
|
931
|
-
i0.ɵɵconditional(ctx_r0.expandedArtifactId ===
|
|
1031
|
+
i0.ɵɵconditional(ctx_r0.expandedArtifactId === artifact_r44.artifactId && artifact_r44.versionCount > 1 ? 13 : -1);
|
|
932
1032
|
} }
|
|
933
|
-
function
|
|
934
|
-
const
|
|
935
|
-
i0.ɵɵelementStart(0, "div",
|
|
936
|
-
i0.ɵɵlistener("click", function
|
|
937
|
-
i0.ɵɵelementStart(1, "div",
|
|
938
|
-
i0.ɵɵlistener("click", function
|
|
939
|
-
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");
|
|
940
1040
|
i0.ɵɵtext(4, "Conversation Artifacts");
|
|
941
1041
|
i0.ɵɵelementEnd();
|
|
942
|
-
i0.ɵɵelementStart(5, "div",
|
|
943
|
-
i0.ɵɵconditionalCreate(6,
|
|
944
|
-
i0.ɵɵelementStart(7, "button",
|
|
945
|
-
i0.ɵɵlistener("click", function
|
|
946
|
-
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);
|
|
947
1047
|
i0.ɵɵelementEnd()()();
|
|
948
|
-
i0.ɵɵelementStart(9, "div",
|
|
949
|
-
i0.ɵɵconditionalCreate(10,
|
|
950
|
-
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);
|
|
951
1051
|
i0.ɵɵelementEnd()()();
|
|
952
1052
|
} if (rf & 2) {
|
|
953
1053
|
const ctx_r0 = i0.ɵɵnextContext();
|
|
@@ -958,28 +1058,28 @@ function ConversationChatAreaComponent_Conditional_26_Template(rf, ctx) { if (rf
|
|
|
958
1058
|
i0.ɵɵadvance();
|
|
959
1059
|
i0.ɵɵrepeater(ctx_r0.getArtifactsArray());
|
|
960
1060
|
} }
|
|
961
|
-
function
|
|
962
|
-
const
|
|
963
|
-
i0.ɵɵelementStart(0, "mj-artifact-collection-picker-modal",
|
|
964
|
-
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()); });
|
|
965
1065
|
i0.ɵɵelementEnd();
|
|
966
1066
|
} if (rf & 2) {
|
|
967
1067
|
const ctx_r0 = i0.ɵɵnextContext();
|
|
968
1068
|
i0.ɵɵproperty("isOpen", ctx_r0.showCollectionPicker)("environmentId", ctx_r0.environmentId)("currentUser", ctx_r0.currentUser)("excludeCollectionIds", ctx_r0.collectionPickerExcludedIds)("artifactVersionId", ctx_r0.collectionPickerVersionId)("artifactName", ctx_r0.collectionPickerArtifactName)("artifactVersionNumber", ctx_r0.collectionPickerVersionNumber);
|
|
969
1069
|
} }
|
|
970
|
-
function
|
|
971
|
-
const
|
|
972
|
-
i0.ɵɵelementStart(0, "mj-test-feedback-dialog",
|
|
973
|
-
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)); });
|
|
974
1074
|
i0.ɵɵelementEnd();
|
|
975
1075
|
} if (rf & 2) {
|
|
976
1076
|
const ctx_r0 = i0.ɵɵnextContext();
|
|
977
1077
|
i0.ɵɵproperty("data", ctx_r0.testFeedbackDialogData)("visible", ctx_r0.showTestFeedbackDialog);
|
|
978
1078
|
} }
|
|
979
|
-
function
|
|
980
|
-
const
|
|
981
|
-
i0.ɵɵelementStart(0, "mj-image-viewer",
|
|
982
|
-
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()); });
|
|
983
1083
|
i0.ɵɵelementEnd();
|
|
984
1084
|
} if (rf & 2) {
|
|
985
1085
|
const ctx_r0 = i0.ɵɵnextContext();
|
|
@@ -987,6 +1087,7 @@ function ConversationChatAreaComponent_Conditional_29_Template(rf, ctx) { if (rf
|
|
|
987
1087
|
} }
|
|
988
1088
|
/** `MJ: Resource Types.ID` for Conversations. */
|
|
989
1089
|
const CONVERSATIONS_RESOURCE_TYPE_ID = '81D4BC3D-9FEB-EF11-B01A-286B35C04427';
|
|
1090
|
+
const EMPTY_THREAD_REPLY_ROOTS = new UUIDMap();
|
|
990
1091
|
/** Run statuses that mean the run is over, for the run-list fallback. `Paused` is still working. */
|
|
991
1092
|
const RUN_LIST_TERMINAL_STATUSES = ['Completed', 'AwaitingFeedback', 'Failed', 'Cancelled'];
|
|
992
1093
|
/** Default width (percentage) for the artifact viewer pane */
|
|
@@ -1084,7 +1185,16 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
1084
1185
|
set conversationId(value) {
|
|
1085
1186
|
this.ConversationId = value;
|
|
1086
1187
|
}
|
|
1087
|
-
|
|
1188
|
+
_conversation = null;
|
|
1189
|
+
set Conversation(value) {
|
|
1190
|
+
this._conversation = value;
|
|
1191
|
+
if (value?.ID && value.Name) {
|
|
1192
|
+
this.syncCachedMessageInputName(value.ID, value.Name);
|
|
1193
|
+
}
|
|
1194
|
+
}
|
|
1195
|
+
get Conversation() {
|
|
1196
|
+
return this._conversation;
|
|
1197
|
+
}
|
|
1088
1198
|
/** @deprecated Use {@link Conversation}. */
|
|
1089
1199
|
set conversation(value) {
|
|
1090
1200
|
this.Conversation = value;
|
|
@@ -1211,6 +1321,12 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
1211
1321
|
* that authorization to a role to stop the server creating forks as well.
|
|
1212
1322
|
*/
|
|
1213
1323
|
AllowForking = true;
|
|
1324
|
+
/**
|
|
1325
|
+
* Host-level opt-in for the conversation's Remote Browser: the header's Browser button, its drawer,
|
|
1326
|
+
* and the `browser_*` tools that let this conversation's agents drive it. Defaults false; a host
|
|
1327
|
+
* that wants an agent-driven browser beside the chat sets true.
|
|
1328
|
+
*/
|
|
1329
|
+
AllowRemoteBrowser = false;
|
|
1214
1330
|
/**
|
|
1215
1331
|
* Host-level cap for stopping and continuing agent runs: the composer's Stop and Stop all, the
|
|
1216
1332
|
* Stop pill on an in-progress reply, the Continue button on a stopped reply, and the "Continue,
|
|
@@ -1805,11 +1921,100 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
1805
1921
|
return this.ShowAgentModePicker && !!this.ModePickerTargetAgentId;
|
|
1806
1922
|
}
|
|
1807
1923
|
get ModePickerTargetAgentId() {
|
|
1808
|
-
return this.
|
|
1924
|
+
return this.CurrentOwnerAgent?.ID
|
|
1925
|
+
?? this.Conversation?.DefaultAgentID
|
|
1809
1926
|
?? this.DefaultAgentId
|
|
1810
1927
|
?? this.conversationManagerAgent?.ID
|
|
1811
1928
|
?? null;
|
|
1812
1929
|
}
|
|
1930
|
+
_cachedOwnerAgentKey;
|
|
1931
|
+
_cachedOwnerAgent = null;
|
|
1932
|
+
/**
|
|
1933
|
+
* Current conversation owner agent for the header `.with-chip` and composer
|
|
1934
|
+
* placeholder: continuity (last non-Sage reply not preceded by a newer
|
|
1935
|
+
* `@Sage` user message) -> pinned/default agent -> conversation manager.
|
|
1936
|
+
* Memoized by message count and active routing inputs so template evaluation
|
|
1937
|
+
* does not scan `messages` on every change-detection cycle.
|
|
1938
|
+
*/
|
|
1939
|
+
get CurrentOwnerAgent() {
|
|
1940
|
+
const managerId = this.conversationManagerAgent?.ID ?? null;
|
|
1941
|
+
const rows = this.DisplayMessages?.length ? this.DisplayMessages : this.messages ?? [];
|
|
1942
|
+
const lastRow = rows.length > 0 ? rows[rows.length - 1] : null;
|
|
1943
|
+
const defaultId = this.Conversation?.DefaultAgentID ?? this.DefaultAgentId ?? null;
|
|
1944
|
+
const floorMs = this.AgentHistoryFrom ? new Date(this.AgentHistoryFrom).getTime() : '';
|
|
1945
|
+
const allowedKey = this.AllowedAgentIDs ? this.AllowedAgentIDs.join(',') : '';
|
|
1946
|
+
const cacheKey = `${rows.length}|${lastRow?.ID ?? ''}|${lastRow?.AgentID ?? ''}|${defaultId ?? ''}|${managerId ?? ''}|${floorMs}|${allowedKey}`;
|
|
1947
|
+
if (this._cachedOwnerAgentKey === cacheKey) {
|
|
1948
|
+
return this._cachedOwnerAgent ?? null;
|
|
1949
|
+
}
|
|
1950
|
+
const continuity = FindContinuityAgentMessage(rows, managerId, {
|
|
1951
|
+
conversationManagerName: this.conversationManagerAgent?.Name ?? 'Sage',
|
|
1952
|
+
isWithinFloor: msg => !this.AgentHistoryFrom || msg.__mj_CreatedAt >= this.AgentHistoryFrom,
|
|
1953
|
+
});
|
|
1954
|
+
let targetId = null;
|
|
1955
|
+
if (continuity?.AgentID && this.isOwnerAgentAllowed(continuity.AgentID)) {
|
|
1956
|
+
targetId = continuity.AgentID;
|
|
1957
|
+
}
|
|
1958
|
+
else {
|
|
1959
|
+
const fallbackId = defaultId ?? managerId;
|
|
1960
|
+
if (fallbackId && this.isOwnerAgentAllowed(fallbackId)) {
|
|
1961
|
+
targetId = fallbackId;
|
|
1962
|
+
}
|
|
1963
|
+
}
|
|
1964
|
+
if (!targetId) {
|
|
1965
|
+
this._cachedOwnerAgentKey = cacheKey;
|
|
1966
|
+
this._cachedOwnerAgent = null;
|
|
1967
|
+
return null;
|
|
1968
|
+
}
|
|
1969
|
+
const meta = this.resolveHandoffAgentMeta(targetId);
|
|
1970
|
+
const isManager = managerId ? UUIDsEqual(targetId, managerId) : false;
|
|
1971
|
+
const owner = {
|
|
1972
|
+
ID: targetId,
|
|
1973
|
+
Name: meta?.Name || (isManager ? (this.conversationManagerAgent?.Name || 'Sage') : 'Agent'),
|
|
1974
|
+
IsConversationManager: isManager,
|
|
1975
|
+
};
|
|
1976
|
+
this._cachedOwnerAgentKey = cacheKey;
|
|
1977
|
+
this._cachedOwnerAgent = owner;
|
|
1978
|
+
return owner;
|
|
1979
|
+
}
|
|
1980
|
+
get CurrentOwnerAgentName() {
|
|
1981
|
+
return this.CurrentOwnerAgent?.Name || this.conversationManagerAgent?.Name || 'Sage';
|
|
1982
|
+
}
|
|
1983
|
+
get CurrentOwnerAccentVar() {
|
|
1984
|
+
return AgentAccentVar(this.CurrentOwnerAgent?.ID);
|
|
1985
|
+
}
|
|
1986
|
+
isOwnerAgentAllowed(agentId) {
|
|
1987
|
+
if (!agentId) {
|
|
1988
|
+
return false;
|
|
1989
|
+
}
|
|
1990
|
+
if (this.AllowedAgentIDs == null) {
|
|
1991
|
+
return true;
|
|
1992
|
+
}
|
|
1993
|
+
return this.AllowedAgentIDs.some(allowed => UUIDsEqual(allowed, agentId));
|
|
1994
|
+
}
|
|
1995
|
+
resolveHandoffAgentMeta(agentId) {
|
|
1996
|
+
if (this.conversationManagerAgent && UUIDsEqual(this.conversationManagerAgent.ID, agentId)) {
|
|
1997
|
+
return {
|
|
1998
|
+
Name: this.conversationManagerAgent.Name,
|
|
1999
|
+
LogoURL: this.conversationManagerAgent.LogoURL,
|
|
2000
|
+
IconClass: this.conversationManagerAgent.IconClass,
|
|
2001
|
+
};
|
|
2002
|
+
}
|
|
2003
|
+
const agents = AIEngineBase.Instance?.Agents;
|
|
2004
|
+
const found = agents?.find(a => UUIDsEqual(a.ID, agentId));
|
|
2005
|
+
if (found) {
|
|
2006
|
+
return {
|
|
2007
|
+
Name: found.Name,
|
|
2008
|
+
LogoURL: found.LogoURL,
|
|
2009
|
+
IconClass: found.IconClass,
|
|
2010
|
+
};
|
|
2011
|
+
}
|
|
2012
|
+
const msg = this.messages?.find(m => UUIDsEqual(m.AgentID, agentId) && m.Agent);
|
|
2013
|
+
if (msg) {
|
|
2014
|
+
return { Name: msg.Agent };
|
|
2015
|
+
}
|
|
2016
|
+
return null;
|
|
2017
|
+
}
|
|
1813
2018
|
/**
|
|
1814
2019
|
* Mode picker emitted a new selection. Store it; the next message's
|
|
1815
2020
|
* route picks it up via `<mj-message-input>`'s
|
|
@@ -2268,7 +2473,7 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
2268
2473
|
*/
|
|
2269
2474
|
initialDraftSnapshots = new Map();
|
|
2270
2475
|
GetInitialDraftFor(conversationId) {
|
|
2271
|
-
const key = conversationId ? conversationId
|
|
2476
|
+
const key = conversationId ? NormalizeUUID(conversationId) : 'new';
|
|
2272
2477
|
if (!this.initialDraftSnapshots.has(key)) {
|
|
2273
2478
|
let snapshot;
|
|
2274
2479
|
if (this._composerAgentMention) {
|
|
@@ -2303,14 +2508,17 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
2303
2508
|
}
|
|
2304
2509
|
// New/unsaved conversations render the empty-state composer; established ones
|
|
2305
2510
|
// use the active cached input. Both resolve the agent to a pill.
|
|
2306
|
-
const
|
|
2511
|
+
const activeInput = this.getActiveMessageInputComponent() ??
|
|
2512
|
+
this.messageInputComponents?.last ??
|
|
2513
|
+
this.messageInputComponents?.first;
|
|
2514
|
+
const target = this.emptyStateComponent ? 'empty-state' : activeInput ? 'active-input' : null;
|
|
2307
2515
|
if (attempt === 0 || attempt % 10 === 0 || target) {
|
|
2308
2516
|
console.log(`[Omnibar→Chat] chat-area apply('${agentName}') attempt ${attempt}: target=${target ?? 'none-mounted'}`);
|
|
2309
2517
|
}
|
|
2310
2518
|
const insert = this.emptyStateComponent
|
|
2311
2519
|
? this.emptyStateComponent.InsertAgentMention(agentName, true)
|
|
2312
|
-
:
|
|
2313
|
-
?
|
|
2520
|
+
: activeInput
|
|
2521
|
+
? activeInput.InsertAgentMention(agentName, true)
|
|
2314
2522
|
: null;
|
|
2315
2523
|
if (insert) {
|
|
2316
2524
|
void insert.then((applied) => {
|
|
@@ -2421,6 +2629,13 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
2421
2629
|
reconcileInFlight = null;
|
|
2422
2630
|
/** Reason for one more reconcile pass, requested while a pass was running. */
|
|
2423
2631
|
reconcileRerunReason = null;
|
|
2632
|
+
/**
|
|
2633
|
+
* Set when a TRANSPORT reconnect asks for a pass; consumed by the next pass that starts. Held as a
|
|
2634
|
+
* flag rather than read off the pass's reason because {@link ReconcileNow} folds requests that
|
|
2635
|
+
* arrive mid-pass into one follow-up carrying only the LAST reason — a reconnect followed by a
|
|
2636
|
+
* tab-visible would otherwise lose the window refresh the reconnect needs.
|
|
2637
|
+
*/
|
|
2638
|
+
reconcileWindowRefreshPending = false;
|
|
2424
2639
|
IsProcessing = false;
|
|
2425
2640
|
/** @deprecated Use {@link IsProcessing}. */
|
|
2426
2641
|
get isProcessing() {
|
|
@@ -2551,6 +2766,44 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
2551
2766
|
}
|
|
2552
2767
|
ShowArtifactPanel = false;
|
|
2553
2768
|
SelectedTaskGraphPanel = null;
|
|
2769
|
+
ShowRemoteBrowserPanel = false;
|
|
2770
|
+
RemoteBrowserUrlInput = '';
|
|
2771
|
+
IsRemoteBrowserNavigating = false;
|
|
2772
|
+
/** Whether this conversation's browser is running, shown or not (the header button stays lit while it is). */
|
|
2773
|
+
get IsRemoteBrowserLive() {
|
|
2774
|
+
return this.remoteBrowser?.ConversationId != null;
|
|
2775
|
+
}
|
|
2776
|
+
/** The conversation's browser, built on first open so a chat area that never opens one pays nothing. */
|
|
2777
|
+
remoteBrowser = null;
|
|
2778
|
+
ensureRemoteBrowser() {
|
|
2779
|
+
if (!this.remoteBrowser) {
|
|
2780
|
+
const browser = new ConversationRemoteBrowserController({
|
|
2781
|
+
OnAutoOpenSurface: () => this.OpenRemoteBrowserPanel(),
|
|
2782
|
+
// Fires on open, close and a real URL change, never per screencast frame.
|
|
2783
|
+
OnStateChange: () => {
|
|
2784
|
+
this.RemoteBrowserUrlInput = browser.CurrentUrl ?? '';
|
|
2785
|
+
this.cdr.detectChanges();
|
|
2786
|
+
},
|
|
2787
|
+
OnSessionRefused: (message) => {
|
|
2788
|
+
this.ShowRemoteBrowserPanel = false;
|
|
2789
|
+
MJNotificationService.Instance.CreateSimpleNotification(message, 'error', 6000);
|
|
2790
|
+
this.cdr.detectChanges();
|
|
2791
|
+
},
|
|
2792
|
+
});
|
|
2793
|
+
const provider = this.ProviderToUse;
|
|
2794
|
+
browser.Initialize(this.agentClientService, provider instanceof GraphQLDataProvider ? provider : null);
|
|
2795
|
+
this.remoteBrowser = browser;
|
|
2796
|
+
}
|
|
2797
|
+
return this.remoteBrowser;
|
|
2798
|
+
}
|
|
2799
|
+
set ConversationRemoteBrowserSurface(surface) {
|
|
2800
|
+
if (surface) {
|
|
2801
|
+
this.remoteBrowser?.BindSurface(surface);
|
|
2802
|
+
}
|
|
2803
|
+
else {
|
|
2804
|
+
this.remoteBrowser?.UnbindSurface();
|
|
2805
|
+
}
|
|
2806
|
+
}
|
|
2554
2807
|
/** @deprecated Use {@link ShowArtifactPanel}. */
|
|
2555
2808
|
get showArtifactPanel() {
|
|
2556
2809
|
return this.ShowArtifactPanel;
|
|
@@ -2767,6 +3020,12 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
2767
3020
|
set agentRunsByDetailId(value) {
|
|
2768
3021
|
this.AgentRunsByDetailId = value;
|
|
2769
3022
|
}
|
|
3023
|
+
/**
|
|
3024
|
+
* Handoff metadata by source conversation detail ID, built from the source
|
|
3025
|
+
* run's `Handoff` step (`MJ: AI Agent Run Steps`) and subsequent target reply.
|
|
3026
|
+
*/
|
|
3027
|
+
HandoffsByDetailId = new Map();
|
|
3028
|
+
handoffStepsByRunId = new Map();
|
|
2770
3029
|
/**
|
|
2771
3030
|
* Ratings by conversation detail ID (parsed from RatingsJSON)
|
|
2772
3031
|
*/
|
|
@@ -2803,6 +3062,8 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
2803
3062
|
this.syncSendSlot();
|
|
2804
3063
|
}
|
|
2805
3064
|
_inProgressMessageIds = [];
|
|
3065
|
+
/** Tracks the ID each in-progress reply entity was last registered under so adopting the server's row ID drops the local placeholder UUID. */
|
|
3066
|
+
inProgressIdByEntity;
|
|
2806
3067
|
// ── The composer's send slot as the stop control ──────────────────────────────────────
|
|
2807
3068
|
// While replies are in flight the composer's send slot is the stop control (one run: "Stop
|
|
2808
3069
|
// {agent}"; several: "Stop all N", and each reply shows its own pill as well). The slot's mode,
|
|
@@ -3631,6 +3892,11 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
3631
3892
|
namedThisSession = false;
|
|
3632
3893
|
this.onRealtimeSessionStarted();
|
|
3633
3894
|
});
|
|
3895
|
+
// A call that ends over a failure (a failed start, a dropped connection, a time limit) is ended by the
|
|
3896
|
+
// runtime itself, which closes the call surface with it: say why, or the call just vanishes.
|
|
3897
|
+
this.RealtimeSession.SessionEnded$
|
|
3898
|
+
.pipe(takeUntil(this.destroy$))
|
|
3899
|
+
.subscribe((ended) => this.notifyIfCallFailed(ended.reason));
|
|
3634
3900
|
let voiceWasActive = false;
|
|
3635
3901
|
this.RealtimeSession.Active$
|
|
3636
3902
|
.pipe(takeUntil(this.destroy$))
|
|
@@ -3780,7 +4046,7 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
3780
4046
|
this.resetComponentState(conversationId);
|
|
3781
4047
|
await this.decideAndApplyArtifactPanel(artifactBaseline, conversationId);
|
|
3782
4048
|
this.messages = [...this.messages];
|
|
3783
|
-
this.followTranscript('new');
|
|
4049
|
+
this.followTranscript('new', newlyLoaded);
|
|
3784
4050
|
this.cdr.detectChanges();
|
|
3785
4051
|
}
|
|
3786
4052
|
else {
|
|
@@ -3951,11 +4217,19 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
3951
4217
|
for (const id of [...(this._stopFallbackTimers?.keys() ?? [])]) {
|
|
3952
4218
|
this.clearStopFallbackTimer(id);
|
|
3953
4219
|
}
|
|
4220
|
+
// Leaving the chat surface altogether ends any live voice call (including
|
|
4221
|
+
// minimized calls or calls minted from the empty state).
|
|
4222
|
+
if (this.RealtimeSession?.IsActive) {
|
|
4223
|
+
void this.RealtimeSession.EndRealtimeSession();
|
|
4224
|
+
}
|
|
3954
4225
|
// Remove resize listeners
|
|
3955
|
-
window
|
|
3956
|
-
|
|
3957
|
-
|
|
3958
|
-
|
|
4226
|
+
if (typeof window !== 'undefined') {
|
|
4227
|
+
window.removeEventListener('mousemove', this.boundOnResizeMove);
|
|
4228
|
+
window.removeEventListener('mouseup', this.boundOnResizeEnd);
|
|
4229
|
+
window.removeEventListener('touchmove', this.boundOnResizeTouchMove);
|
|
4230
|
+
window.removeEventListener('touchend', this.boundOnResizeTouchEnd);
|
|
4231
|
+
}
|
|
4232
|
+
this.remoteBrowser?.Dispose();
|
|
3959
4233
|
}
|
|
3960
4234
|
isActiveConversation(conversationId) {
|
|
3961
4235
|
return UUIDsEqual(conversationId, this.ConversationId);
|
|
@@ -3972,6 +4246,13 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
3972
4246
|
this.clearTurnTracking();
|
|
3973
4247
|
this.ShowArtifactPanel = false;
|
|
3974
4248
|
this.SelectedTaskGraphPanel = null;
|
|
4249
|
+
// A conversation's browser ends with it: the next conversation starts without one. Reloading the SAME
|
|
4250
|
+
// conversation (the overlay-to-workspace handoff) keeps it.
|
|
4251
|
+
const browserConversation = this.remoteBrowser?.ConversationId;
|
|
4252
|
+
if (!browserConversation || !UUIDsEqual(browserConversation, this._conversationId)) {
|
|
4253
|
+
this.ShowRemoteBrowserPanel = false;
|
|
4254
|
+
void this.remoteBrowser?.Close();
|
|
4255
|
+
}
|
|
3975
4256
|
this.SelectedArtifactId = null;
|
|
3976
4257
|
this.SelectedVersionNumber = undefined;
|
|
3977
4258
|
this.CanShareSelectedArtifact = false;
|
|
@@ -4012,6 +4293,8 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
4012
4293
|
this.ForkSummaries = [];
|
|
4013
4294
|
this.ShowForksPopover = false;
|
|
4014
4295
|
this.IsRenamingTitle = false;
|
|
4296
|
+
this.HandoffsByDetailId = new Map();
|
|
4297
|
+
this.handoffStepsByRunId?.clear();
|
|
4015
4298
|
if (this.forkSummaryRefreshTimer) {
|
|
4016
4299
|
clearTimeout(this.forkSummaryRefreshTimer);
|
|
4017
4300
|
this.forkSummaryRefreshTimer = null;
|
|
@@ -4045,12 +4328,7 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
4045
4328
|
if ((this.ArtifactsByDetailId?.size ?? 0) === 0 && this.artifactMapConversationId === null) {
|
|
4046
4329
|
this.artifactMapConversationId = conversationId;
|
|
4047
4330
|
}
|
|
4048
|
-
|
|
4049
|
-
this.messageInputMetadataCache.set(conversationId, {
|
|
4050
|
-
conversationId: conversationId,
|
|
4051
|
-
conversationName: this.Conversation?.Name || null
|
|
4052
|
-
});
|
|
4053
|
-
}
|
|
4331
|
+
this.touchMessageInputCache(conversationId);
|
|
4054
4332
|
// Only show loading spinner if the engine doesn't have cached data for this conversation.
|
|
4055
4333
|
// This prevents the "no messages" flash when switching between conversations.
|
|
4056
4334
|
const hasCachedMessages = this.engine.HasCachedDetails(conversationId);
|
|
@@ -4112,13 +4390,129 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
4112
4390
|
this.conversationLoadEnded$?.next();
|
|
4113
4391
|
}
|
|
4114
4392
|
}
|
|
4393
|
+
_cachedInputsArray = [];
|
|
4394
|
+
_cachedInputsKey = '';
|
|
4395
|
+
/** Max hidden composers kept mounted for draft/state preservation; older idle ones are unmounted. */
|
|
4396
|
+
static MAX_CACHED_MESSAGE_INPUTS = 10;
|
|
4397
|
+
/** Stable case-normalized track key for `@for` so case-only UUID changes reuse the mounted composer. */
|
|
4398
|
+
NormalizeCachedInputId(conversationId) {
|
|
4399
|
+
return NormalizeUUID(conversationId);
|
|
4400
|
+
}
|
|
4401
|
+
findMessageInputCacheEntry(conversationId) {
|
|
4402
|
+
const exact = this.messageInputMetadataCache.get(conversationId);
|
|
4403
|
+
if (exact) {
|
|
4404
|
+
return { key: conversationId, meta: exact };
|
|
4405
|
+
}
|
|
4406
|
+
for (const [key, meta] of this.messageInputMetadataCache.entries()) {
|
|
4407
|
+
if (UUIDsEqual(key, conversationId)) {
|
|
4408
|
+
return { key, meta };
|
|
4409
|
+
}
|
|
4410
|
+
}
|
|
4411
|
+
return undefined;
|
|
4412
|
+
}
|
|
4413
|
+
resolveConversationNameForCache(conversationId) {
|
|
4414
|
+
const activeConv = this.Conversation;
|
|
4415
|
+
if (activeConv?.Name && (!activeConv.ID || UUIDsEqual(activeConv.ID, conversationId))) {
|
|
4416
|
+
return activeConv.Name;
|
|
4417
|
+
}
|
|
4418
|
+
return this.engine?.GetConversation?.(conversationId)?.Name || null;
|
|
4419
|
+
}
|
|
4420
|
+
syncCachedMessageInputName(conversationId, name) {
|
|
4421
|
+
if (!this.messageInputMetadataCache || !conversationId || !name) {
|
|
4422
|
+
return;
|
|
4423
|
+
}
|
|
4424
|
+
const found = this.findMessageInputCacheEntry(conversationId);
|
|
4425
|
+
if (found && found.meta.conversationName !== name) {
|
|
4426
|
+
this.messageInputMetadataCache.set(found.key, {
|
|
4427
|
+
...found.meta,
|
|
4428
|
+
conversationName: name,
|
|
4429
|
+
});
|
|
4430
|
+
}
|
|
4431
|
+
}
|
|
4432
|
+
findMessageInputComponent(conversationId) {
|
|
4433
|
+
if (!this.messageInputComponents || !conversationId) {
|
|
4434
|
+
return undefined;
|
|
4435
|
+
}
|
|
4436
|
+
return this.messageInputComponents.find(component => UUIDsEqual(component.ConversationId ?? component.conversationId, conversationId));
|
|
4437
|
+
}
|
|
4438
|
+
/**
|
|
4439
|
+
* True when a cached hidden composer for `candidateId` is idle and safe to unmount.
|
|
4440
|
+
* Never evicts the newly-activated conversation, a conversation awaiting auto-send of
|
|
4441
|
+
* `PendingMessage`, a conversation hosting a live voice session, a conversation with
|
|
4442
|
+
* running tasks in `ActiveTasksService`, or a mounted composer with in-flight streaming
|
|
4443
|
+
* callbacks / DB watches / unsent file attachments (`HasActiveWork`).
|
|
4444
|
+
*/
|
|
4445
|
+
canEvictCachedMessageInput(candidateId, activeConversationId) {
|
|
4446
|
+
if (UUIDsEqual(candidateId, activeConversationId) || UUIDsEqual(candidateId, this.ConversationId)) {
|
|
4447
|
+
return false;
|
|
4448
|
+
}
|
|
4449
|
+
if (this._pendingMessage && this.ShouldDeliverPendingMessageTo(candidateId)) {
|
|
4450
|
+
return false;
|
|
4451
|
+
}
|
|
4452
|
+
if (this.RealtimeSession?.IsActiveFor?.(candidateId)) {
|
|
4453
|
+
return false;
|
|
4454
|
+
}
|
|
4455
|
+
if (this.activeTasks?.HasActiveTasksForConversation?.(candidateId)) {
|
|
4456
|
+
return false;
|
|
4457
|
+
}
|
|
4458
|
+
const mounted = this.findMessageInputComponent(candidateId);
|
|
4459
|
+
if (mounted?.HasActiveWork) {
|
|
4460
|
+
return false;
|
|
4461
|
+
}
|
|
4462
|
+
return true;
|
|
4463
|
+
}
|
|
4464
|
+
/**
|
|
4465
|
+
* Registers `conversationId` as the most-recently-used composer and unmounts the
|
|
4466
|
+
* least-recently-used idle ones beyond the cap. Each cache entry keeps a live
|
|
4467
|
+
* `mj-message-input` component, so without a bound memory grows with every
|
|
4468
|
+
* conversation visited. Composers actively running an agent turn, holding unsent
|
|
4469
|
+
* file attachments, or hosting a live voice call are skipped until idle. Drafts
|
|
4470
|
+
* live in the draft store, so an evicted composer's frozen restore snapshot is
|
|
4471
|
+
* dropped to let a remount re-read the latest draft.
|
|
4472
|
+
*/
|
|
4473
|
+
touchMessageInputCache(conversationId) {
|
|
4474
|
+
const existing = this.findMessageInputCacheEntry(conversationId);
|
|
4475
|
+
if (existing) {
|
|
4476
|
+
this.messageInputMetadataCache.delete(existing.key); // re-insert to refresh recency & align casing
|
|
4477
|
+
}
|
|
4478
|
+
const conversationName = existing?.meta.conversationName ?? this.resolveConversationNameForCache(conversationId);
|
|
4479
|
+
this.messageInputMetadataCache.set(conversationId, {
|
|
4480
|
+
conversationId,
|
|
4481
|
+
conversationName,
|
|
4482
|
+
});
|
|
4483
|
+
if (this.messageInputMetadataCache.size <= ConversationChatAreaComponent.MAX_CACHED_MESSAGE_INPUTS) {
|
|
4484
|
+
return;
|
|
4485
|
+
}
|
|
4486
|
+
for (const [candidateKey, entry] of [...this.messageInputMetadataCache.entries()]) {
|
|
4487
|
+
if (this.messageInputMetadataCache.size <= ConversationChatAreaComponent.MAX_CACHED_MESSAGE_INPUTS) {
|
|
4488
|
+
break;
|
|
4489
|
+
}
|
|
4490
|
+
if (!this.canEvictCachedMessageInput(entry.conversationId, conversationId)) {
|
|
4491
|
+
continue;
|
|
4492
|
+
}
|
|
4493
|
+
this.messageInputMetadataCache.delete(candidateKey);
|
|
4494
|
+
this.initialDraftSnapshots?.delete(NormalizeUUID(entry.conversationId));
|
|
4495
|
+
}
|
|
4496
|
+
}
|
|
4115
4497
|
/**
|
|
4116
|
-
* Returns array of cached message-input metadata for rendering
|
|
4498
|
+
* Returns array of cached message-input metadata for rendering.
|
|
4117
4499
|
* This allows multiple message-input components to exist simultaneously (hidden)
|
|
4118
|
-
* preserving their state when switching conversations
|
|
4500
|
+
* preserving their state when switching conversations.
|
|
4501
|
+
* Memoized on cache contents so template `@for` loops receive a stable array reference across CD ticks.
|
|
4119
4502
|
*/
|
|
4120
4503
|
GetCachedInputs() {
|
|
4121
|
-
|
|
4504
|
+
if (this.messageInputMetadataCache.size === 0) {
|
|
4505
|
+
return this._cachedInputsArray.length === 0 ? this._cachedInputsArray : (this._cachedInputsArray = []);
|
|
4506
|
+
}
|
|
4507
|
+
let key = '';
|
|
4508
|
+
for (const [id, meta] of this.messageInputMetadataCache.entries()) {
|
|
4509
|
+
key += `${id}:${meta.conversationName ?? ''}|`;
|
|
4510
|
+
}
|
|
4511
|
+
if (key !== this._cachedInputsKey) {
|
|
4512
|
+
this._cachedInputsKey = key;
|
|
4513
|
+
this._cachedInputsArray = Array.from(this.messageInputMetadataCache.values());
|
|
4514
|
+
}
|
|
4515
|
+
return this._cachedInputsArray;
|
|
4122
4516
|
}
|
|
4123
4517
|
/** @deprecated Use {@link GetCachedInputs}. */
|
|
4124
4518
|
getCachedInputs() {
|
|
@@ -4141,10 +4535,10 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
4141
4535
|
* we need to find the one that matches the current conversationId.
|
|
4142
4536
|
*/
|
|
4143
4537
|
getActiveMessageInputComponent() {
|
|
4144
|
-
if (!this.
|
|
4538
|
+
if (!this.ConversationId) {
|
|
4145
4539
|
return undefined;
|
|
4146
4540
|
}
|
|
4147
|
-
return this.
|
|
4541
|
+
return this.findMessageInputComponent(this.ConversationId);
|
|
4148
4542
|
}
|
|
4149
4543
|
async loadMessages(conversationId, loadToken) {
|
|
4150
4544
|
try {
|
|
@@ -4298,7 +4692,7 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
4298
4692
|
if (!this.isActiveConversationLoad(conversationId, loadToken)) {
|
|
4299
4693
|
return;
|
|
4300
4694
|
}
|
|
4301
|
-
this.windowStore.SetPinnedCount(result.Success ? result.TotalRowCount : 0);
|
|
4695
|
+
this.windowStore.SetPinnedCount(result.Success ? result.TotalRowCount ?? 0 : 0);
|
|
4302
4696
|
}
|
|
4303
4697
|
/**
|
|
4304
4698
|
* Hydrates the pins panel's rows — first panel open only.
|
|
@@ -4419,6 +4813,18 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
4419
4813
|
if (sessionMeta.size > 0) {
|
|
4420
4814
|
this.RealtimeSessionMetaMap = new Map([...this.RealtimeSessionMetaMap, ...sessionMeta]);
|
|
4421
4815
|
}
|
|
4816
|
+
const newRunIds = newIds
|
|
4817
|
+
.map(id => this.AgentRunsByDetailId.get(id)?.ID)
|
|
4818
|
+
.filter((id) => !!id);
|
|
4819
|
+
if (newRunIds.length > 0) {
|
|
4820
|
+
await this.loadHandoffStepsForRunIds(newRunIds, conversationId);
|
|
4821
|
+
if (!this.isActiveConversation(conversationId)) {
|
|
4822
|
+
return;
|
|
4823
|
+
}
|
|
4824
|
+
}
|
|
4825
|
+
else {
|
|
4826
|
+
this.rebuildHandoffsMap();
|
|
4827
|
+
}
|
|
4422
4828
|
// A page of OLDER artifacts just entered the map. Any artifact-panel baseline taken before
|
|
4423
4829
|
// this point can no longer be diffed against the map for creations — these arrived from
|
|
4424
4830
|
// history, not from a run. See snapshotArtifactPanelBaseline.
|
|
@@ -4460,6 +4866,7 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
4460
4866
|
this.ArtifactsByDetailId.clear();
|
|
4461
4867
|
this.SystemArtifactsByDetailId.clear();
|
|
4462
4868
|
this.RatingsByDetailId.clear();
|
|
4869
|
+
this.handoffStepsByRunId.clear();
|
|
4463
4870
|
// Copy agent runs from engine (cast to extended type for UI compatibility)
|
|
4464
4871
|
for (const [detailId, agentRun] of cacheEntry.AgentRunsByDetailId) {
|
|
4465
4872
|
this.AgentRunsByDetailId.set(detailId, agentRun);
|
|
@@ -4491,6 +4898,13 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
4491
4898
|
if (!this.isCurrentConversationContext(conversationId, loadToken)) {
|
|
4492
4899
|
return;
|
|
4493
4900
|
}
|
|
4901
|
+
const runIds = Array.from(this.AgentRunsByDetailId.values())
|
|
4902
|
+
.map(r => r?.ID)
|
|
4903
|
+
.filter((id) => !!id);
|
|
4904
|
+
await this.loadHandoffStepsForRunIds(runIds, conversationId, loadToken);
|
|
4905
|
+
if (!this.isCurrentConversationContext(conversationId, loadToken)) {
|
|
4906
|
+
return;
|
|
4907
|
+
}
|
|
4494
4908
|
// Create new Map references to trigger Angular change detection
|
|
4495
4909
|
this.AgentRunsByDetailId = new Map(this.AgentRunsByDetailId);
|
|
4496
4910
|
this.ArtifactsByDetailId = new Map(this.ArtifactsByDetailId);
|
|
@@ -4513,6 +4927,42 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
4513
4927
|
this.artifactMapConversationId = null;
|
|
4514
4928
|
}
|
|
4515
4929
|
}
|
|
4930
|
+
async loadHandoffStepsForRunIds(runIds, conversationId, loadToken) {
|
|
4931
|
+
if (runIds.length > 0) {
|
|
4932
|
+
const steps = await LoadHandoffStepsForRuns(this.ProviderToUse, runIds);
|
|
4933
|
+
if (conversationId != null &&
|
|
4934
|
+
!this.isCurrentConversationContext(conversationId, loadToken)) {
|
|
4935
|
+
return;
|
|
4936
|
+
}
|
|
4937
|
+
for (const step of steps) {
|
|
4938
|
+
if (step && step.ID && step.AgentRunID && (!step.StepType || step.StepType === 'Handoff')) {
|
|
4939
|
+
this.handoffStepsByRunId.set(step.ID, step);
|
|
4940
|
+
}
|
|
4941
|
+
}
|
|
4942
|
+
}
|
|
4943
|
+
this.rebuildHandoffsMap();
|
|
4944
|
+
}
|
|
4945
|
+
rebuildHandoffsMap() {
|
|
4946
|
+
const stepsMap = this.handoffStepsByRunId;
|
|
4947
|
+
if (!stepsMap || stepsMap.size === 0 || !this.AgentRunsByDetailId || this.AgentRunsByDetailId.size === 0) {
|
|
4948
|
+
if (!this.HandoffsByDetailId || this.HandoffsByDetailId.size > 0) {
|
|
4949
|
+
this.HandoffsByDetailId = new Map();
|
|
4950
|
+
}
|
|
4951
|
+
return;
|
|
4952
|
+
}
|
|
4953
|
+
const engineAgents = AIEngineBase.Instance?.Agents ?? [];
|
|
4954
|
+
const agents = this.conversationManagerAgent &&
|
|
4955
|
+
!engineAgents.some(a => UUIDsEqual(a.ID, this.conversationManagerAgent?.ID))
|
|
4956
|
+
? [this.conversationManagerAgent, ...engineAgents]
|
|
4957
|
+
: engineAgents;
|
|
4958
|
+
this.HandoffsByDetailId = BuildHandoffsByDetailId({
|
|
4959
|
+
Messages: this.messages ?? [],
|
|
4960
|
+
AgentRunsByDetailId: this.AgentRunsByDetailId,
|
|
4961
|
+
HandoffSteps: Array.from(stepsMap.values()),
|
|
4962
|
+
Agents: agents,
|
|
4963
|
+
Presets: AIEngineBase.Instance?.AgentConfigurations ?? [],
|
|
4964
|
+
});
|
|
4965
|
+
}
|
|
4516
4966
|
/**
|
|
4517
4967
|
* Loads the `MJ: AI Agent Sessions` rows referenced by the conversation's
|
|
4518
4968
|
* session-stamped details (one batched lookup, narrow fields, only when stamped rows
|
|
@@ -4607,12 +5057,25 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
4607
5057
|
this.replaceDisplayedRow(message);
|
|
4608
5058
|
this.windowStore.ApplyLocalDetail(message);
|
|
4609
5059
|
}
|
|
5060
|
+
const rootId = this.collapsedThreadRootId(message);
|
|
5061
|
+
if (rootId !== null) {
|
|
5062
|
+
if (index < 0) {
|
|
5063
|
+
// A hidden reply's first frame: the full path adds the row once; later frames patch it in place above.
|
|
5064
|
+
this.ngZone.run(() => void this.OnMessageSent(message));
|
|
5065
|
+
return;
|
|
5066
|
+
}
|
|
5067
|
+
const root = (this.messages ?? []).find(m => UUIDsEqual(m.ID, rootId));
|
|
5068
|
+
if (root) {
|
|
5069
|
+
this.messageListComponent?.RefreshRenderedMessage(root);
|
|
5070
|
+
}
|
|
5071
|
+
return;
|
|
5072
|
+
}
|
|
4610
5073
|
if (!this.messageListComponent?.RefreshRenderedMessage(message)) {
|
|
4611
5074
|
// The first delta can beat the bubble's own render; the full path handles that one update.
|
|
4612
5075
|
this.ngZone.run(() => void this.OnMessageSent(message));
|
|
4613
5076
|
return;
|
|
4614
5077
|
}
|
|
4615
|
-
this.followTranscript('stream');
|
|
5078
|
+
this.followTranscript('stream', message);
|
|
4616
5079
|
}
|
|
4617
5080
|
/** Drops a landing still queued or retrying, so it cannot resolve after a newer one. */
|
|
4618
5081
|
cancelPendingLanding() {
|
|
@@ -4655,18 +5118,11 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
4655
5118
|
this.windowStore.ApplyLocalDetail(message);
|
|
4656
5119
|
// Check if message already exists in the array (by ID) to prevent duplicates
|
|
4657
5120
|
// Messages can be emitted multiple times as they're updated (e.g., status changes)
|
|
4658
|
-
|
|
4659
|
-
|
|
4660
|
-
|
|
4661
|
-
|
|
4662
|
-
|
|
4663
|
-
message,
|
|
4664
|
-
...this.messages.slice(existingIndex + 1)
|
|
4665
|
-
];
|
|
4666
|
-
}
|
|
4667
|
-
else {
|
|
4668
|
-
// Add new message to the list
|
|
4669
|
-
this.messages = [...this.messages, message];
|
|
5121
|
+
// An agent reply's placeholder takes the server row's ID when the run is acknowledged; a refresh may already have
|
|
5122
|
+
// brought that row in, so other copies of the ID are dropped.
|
|
5123
|
+
const upsert = UpsertMessageById(this.messages, message);
|
|
5124
|
+
this.messages = upsert.Messages;
|
|
5125
|
+
if (!upsert.Existed) {
|
|
4670
5126
|
// Ensure current user is in the avatar map for new messages
|
|
4671
5127
|
this.ensureCurrentUserInAvatarMap();
|
|
4672
5128
|
// Invalidate cache when new message is added.
|
|
@@ -4687,8 +5143,17 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
4687
5143
|
// row does not stay In-Progress until the conversation is opened again. Register the row
|
|
4688
5144
|
// for the live callback either way — an update of an existing In-Progress row included.
|
|
4689
5145
|
if (message.Status === 'In-Progress' && message.ID) {
|
|
4690
|
-
|
|
4691
|
-
|
|
5146
|
+
const entityMap = (this.inProgressIdByEntity ??= new WeakMap());
|
|
5147
|
+
const previousId = entityMap.get(message);
|
|
5148
|
+
entityMap.set(message, message.ID);
|
|
5149
|
+
const withoutPrevious = previousId && !UUIDsEqual(previousId, message.ID)
|
|
5150
|
+
? this.InProgressMessageIds.filter((id) => !UUIDsEqual(id, previousId))
|
|
5151
|
+
: this.InProgressMessageIds;
|
|
5152
|
+
if (!withoutPrevious.some((id) => UUIDsEqual(id, message.ID))) {
|
|
5153
|
+
this.InProgressMessageIds = [...withoutPrevious, message.ID];
|
|
5154
|
+
}
|
|
5155
|
+
else if (withoutPrevious !== this.InProgressMessageIds) {
|
|
5156
|
+
this.InProgressMessageIds = withoutPrevious;
|
|
4692
5157
|
}
|
|
4693
5158
|
const recentCompletion = this.streamingService.GetRecentCompletion(message.ID);
|
|
4694
5159
|
if (recentCompletion) {
|
|
@@ -4698,9 +5163,16 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
4698
5163
|
}
|
|
4699
5164
|
}
|
|
4700
5165
|
}
|
|
5166
|
+
else if (this.isSettled(message)) {
|
|
5167
|
+
// The final frame of a reply can arrive as a plain send; it leaves the in-flight list here.
|
|
5168
|
+
this.dropSettledFromInFlight();
|
|
5169
|
+
}
|
|
4701
5170
|
// Where the viewport goes: a fresh send follows — an in-place update of a message that
|
|
4702
|
-
// is already on screen must not re-run the send path's scroll.
|
|
4703
|
-
|
|
5171
|
+
// is already on screen must not re-run the send path's scroll or rebuild the handoffs map.
|
|
5172
|
+
if (!upsert.Existed) {
|
|
5173
|
+
this.rebuildHandoffsMap();
|
|
5174
|
+
}
|
|
5175
|
+
this.followTranscript(upsert.Existed ? 'update' : 'new', message);
|
|
4704
5176
|
// Force change detection — zone.js 0.15 no longer patches graphql-ws WebSocket callbacks,
|
|
4705
5177
|
// so progress updates that arrive via PubSub run outside Angular's zone. Without this,
|
|
4706
5178
|
// the UI does not update when the messages array is modified from a streaming callback.
|
|
@@ -4825,10 +5297,17 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
4825
5297
|
ConversationEngine.Instance.SetAgentRunForDetail(event.conversationId, event.conversationDetailId, newEntity);
|
|
4826
5298
|
}
|
|
4827
5299
|
}
|
|
5300
|
+
await this.loadHandoffStepsForRunIds([existingAgentRun.ID], event.conversationId);
|
|
5301
|
+
if (!this.isActiveConversation(event.conversationId)) {
|
|
5302
|
+
return;
|
|
5303
|
+
}
|
|
4828
5304
|
// Trigger re-render to show updated status
|
|
4829
5305
|
this.messages = [...this.messages];
|
|
4830
5306
|
this.cdr.detectChanges();
|
|
4831
5307
|
}
|
|
5308
|
+
else {
|
|
5309
|
+
this.rebuildHandoffsMap();
|
|
5310
|
+
}
|
|
4832
5311
|
// Reload attachments for this message to pick up newly created media attachments
|
|
4833
5312
|
// (e.g., images generated by agent via Generate Image action)
|
|
4834
5313
|
// This must be done after agent completion because attachments are created by AgentRunner
|
|
@@ -4864,6 +5343,9 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
4864
5343
|
ConversationEngine.Instance.SetAgentRunForDetail(event.conversationId, event.conversationDetailId, event.agentRun);
|
|
4865
5344
|
}
|
|
4866
5345
|
}
|
|
5346
|
+
if (!existingRun || !UUIDsEqual(existingRun.ID, event.agentRun.ID)) {
|
|
5347
|
+
this.rebuildHandoffsMap();
|
|
5348
|
+
}
|
|
4867
5349
|
}
|
|
4868
5350
|
else {
|
|
4869
5351
|
// no agent run, should have agentRunId
|
|
@@ -4919,7 +5401,7 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
4919
5401
|
// Track existing message IDs before reload to identify new messages
|
|
4920
5402
|
const existingMessageIds = new Set(this.messages.map(m => m.ID));
|
|
4921
5403
|
// Merge the refreshed window with existing client-side messages.
|
|
4922
|
-
// Preserves messages added client-side (e.g.,
|
|
5404
|
+
// Preserves messages added client-side (e.g., server-followed handoff rows)
|
|
4923
5405
|
// that haven't been picked up by entity events yet due to timing.
|
|
4924
5406
|
const merged = new Map();
|
|
4925
5407
|
for (const msg of engineDetails) {
|
|
@@ -4931,20 +5413,24 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
4931
5413
|
merged.set(msg.ID, msg);
|
|
4932
5414
|
}
|
|
4933
5415
|
}
|
|
4934
|
-
this.messages = Array.from(merged.values())
|
|
4935
|
-
.sort((a, b) => (a.__mj_CreatedAt?.getTime() || 0) - (b.__mj_CreatedAt?.getTime() || 0));
|
|
5416
|
+
this.messages = Array.from(merged.values()).sort(CompareMessagesByCreatedAt);
|
|
4936
5417
|
// Find newly discovered messages (delegated agents)
|
|
4937
5418
|
const newMessages = engineDetails.filter(m => !existingMessageIds.has(m.ID));
|
|
4938
5419
|
// Check engine cache for agent runs on new messages
|
|
5420
|
+
const discoveredRunIds = [];
|
|
4939
5421
|
for (const message of newMessages) {
|
|
4940
5422
|
if (message.AgentID && message.ID) {
|
|
4941
5423
|
const agentRun = this.engine.GetAgentRunForDetail(conversationId, message.ID);
|
|
4942
5424
|
if (agentRun) {
|
|
4943
5425
|
this.AgentRunsByDetailId.set(message.ID, agentRun);
|
|
5426
|
+
if (agentRun.ID) {
|
|
5427
|
+
discoveredRunIds.push(agentRun.ID);
|
|
5428
|
+
}
|
|
4944
5429
|
LogStatusEx({ message: `✅ Found cached agent run for new delegated message ${message.ID}`, verboseOnly: true });
|
|
4945
5430
|
}
|
|
4946
5431
|
}
|
|
4947
5432
|
}
|
|
5433
|
+
await this.loadHandoffStepsForRunIds(discoveredRunIds, conversationId);
|
|
4948
5434
|
LogStatusEx({ message: `✅ Refreshed ${engineDetails.length} messages from engine cache (${newMessages.length} new)`, verboseOnly: true });
|
|
4949
5435
|
}
|
|
4950
5436
|
catch (error) {
|
|
@@ -5584,22 +6070,36 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
5584
6070
|
const view = this.WindowView;
|
|
5585
6071
|
const branches = UUIDsEqual(this.branchRowsConversationId, this.ConversationId) ? (this.branches ?? NO_BRANCHES) : NO_BRANCHES;
|
|
5586
6072
|
const canFork = this.CanFork;
|
|
6073
|
+
const collapseThreads = Boolean(this.CollapseThreadReplies);
|
|
5587
6074
|
const cache = this.inPlaceTurnCache;
|
|
5588
|
-
if (cache &&
|
|
6075
|
+
if (cache &&
|
|
6076
|
+
cache.Messages === messages &&
|
|
6077
|
+
cache.View === view &&
|
|
6078
|
+
cache.Branches === branches &&
|
|
6079
|
+
cache.CanFork === canFork &&
|
|
6080
|
+
cache.CollapseThreads === collapseThreads) {
|
|
5589
6081
|
return cache.Turn;
|
|
5590
6082
|
}
|
|
5591
6083
|
const turn = canFork ? null : this.unblockedLatestTurn(messages, view, branches);
|
|
5592
|
-
this.inPlaceTurnCache = {
|
|
6084
|
+
this.inPlaceTurnCache = {
|
|
6085
|
+
Messages: messages,
|
|
6086
|
+
View: view,
|
|
6087
|
+
Branches: branches,
|
|
6088
|
+
CanFork: canFork,
|
|
6089
|
+
CollapseThreads: collapseThreads,
|
|
6090
|
+
Turn: turn,
|
|
6091
|
+
};
|
|
5593
6092
|
return turn;
|
|
5594
6093
|
}
|
|
5595
6094
|
/** The latest turn of the rows, or null when there is none or a fork depends on its answer rows. */
|
|
5596
6095
|
unblockedLatestTurn(messages, view, branches) {
|
|
5597
|
-
const
|
|
5598
|
-
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;
|
|
5599
6099
|
if (!turn || !user) {
|
|
5600
6100
|
return null;
|
|
5601
6101
|
}
|
|
5602
|
-
return ForkDependsOnRows(user.BranchID ?? null,
|
|
6102
|
+
return ForkDependsOnRows(user.BranchID ?? null, this.turnRowsAfter(messages, user), branches) ? null : turn;
|
|
5603
6103
|
}
|
|
5604
6104
|
/** "Save and resend": the message item saved the new text of the latest user message; reruns its turn in place. */
|
|
5605
6105
|
async OnResendInPlaceRequested(userMessage) {
|
|
@@ -5623,7 +6123,7 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
5623
6123
|
if (!input) {
|
|
5624
6124
|
return;
|
|
5625
6125
|
}
|
|
5626
|
-
const answerRows =
|
|
6126
|
+
const answerRows = this.turnRowsAfter(this.messages ?? [], userMessage);
|
|
5627
6127
|
if (answerRows.some(r => r.Status === 'In-Progress')) {
|
|
5628
6128
|
MJNotificationService.Instance.CreateSimpleNotification('Wait for the current reply to finish', 'error', 3000);
|
|
5629
6129
|
return;
|
|
@@ -5667,6 +6167,23 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
5667
6167
|
this.inPlaceRerunInFlight = false;
|
|
5668
6168
|
}
|
|
5669
6169
|
}
|
|
6170
|
+
/**
|
|
6171
|
+
* The rows of `userMessage`'s turn that an in-place rerun replaces: when thread replies are
|
|
6172
|
+
* collapsed, the main-flow rows after `userMessage` plus any thread replies rooted on those rows.
|
|
6173
|
+
*/
|
|
6174
|
+
turnRowsAfter(messages, userMessage) {
|
|
6175
|
+
if (!this.CollapseThreadReplies) {
|
|
6176
|
+
return TurnRowsAfter(messages, userMessage);
|
|
6177
|
+
}
|
|
6178
|
+
const roots = GetThreadReplyRoots(messages);
|
|
6179
|
+
const mainFlow = messages.filter(m => !roots.Has(m.ID));
|
|
6180
|
+
const mainAfter = TurnRowsAfter(mainFlow, userMessage);
|
|
6181
|
+
const afterRoots = new UUIDSet(mainAfter.map(m => m.ID));
|
|
6182
|
+
return TurnRowsAfter(messages, userMessage).filter(m => {
|
|
6183
|
+
const rootId = roots.Get(m.ID);
|
|
6184
|
+
return afterRoots.Has(m.ID) || (rootId !== undefined && afterRoots.Has(rootId));
|
|
6185
|
+
});
|
|
6186
|
+
}
|
|
5670
6187
|
/**
|
|
5671
6188
|
* Marks each row replaced, one save at a time (parallel saves race on the server's transaction
|
|
5672
6189
|
* counter): `ReplacedAt` set and `HiddenToUser` true; the rows are kept for audit. Takes the saved rows
|
|
@@ -5756,7 +6273,7 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
5756
6273
|
}
|
|
5757
6274
|
/** The nearest earlier User row in the loaded window; null when the window holds none. */
|
|
5758
6275
|
findUserMessageBefore(aiMessage) {
|
|
5759
|
-
const sorted = [...this.
|
|
6276
|
+
const sorted = [...this.displayState().MainFlow].sort((a, b) => a.Sequence - b.Sequence);
|
|
5760
6277
|
const index = sorted.findIndex(m => UUIDsEqual(m.ID, aiMessage.ID));
|
|
5761
6278
|
for (let i = index - 1; i >= 0; i--) {
|
|
5762
6279
|
if (sorted[i].Role === 'User') {
|
|
@@ -5869,6 +6386,17 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
5869
6386
|
get WindowView() {
|
|
5870
6387
|
return this.windowView ?? MAIN_OPEN_VIEW;
|
|
5871
6388
|
}
|
|
6389
|
+
/**
|
|
6390
|
+
* When true, thread replies in the loaded window are omitted from top-level `DisplayMessages` so
|
|
6391
|
+
* they can be rendered inside a collapsed thread under their root message (see
|
|
6392
|
+
* {@link GetThreadReplyRoots}).
|
|
6393
|
+
*/
|
|
6394
|
+
CollapseThreadReplies = false;
|
|
6395
|
+
/**
|
|
6396
|
+
* Emits when a jump targets a collapsed thread reply, after scrolling to its top-level root
|
|
6397
|
+
* message, so the host can open the thread and reveal the reply.
|
|
6398
|
+
*/
|
|
6399
|
+
ThreadReplyRevealRequested = new EventEmitter();
|
|
5872
6400
|
/**
|
|
5873
6401
|
* The rows the message list shows for the window view; the same array until the rows or the view
|
|
5874
6402
|
* change. Main shows every loaded row; a fork shows every inherited row, then its own rows; a draft
|
|
@@ -5881,16 +6409,45 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
5881
6409
|
displayState() {
|
|
5882
6410
|
const messages = this.messages ?? [];
|
|
5883
6411
|
const view = this.WindowView;
|
|
6412
|
+
const collapseThreads = Boolean(this.CollapseThreadReplies);
|
|
5884
6413
|
const cache = this.displayCache;
|
|
5885
|
-
if (cache && cache.Messages === messages && cache.View === view) {
|
|
6414
|
+
if (cache && cache.Messages === messages && cache.View === view && cache.CollapseThreads === collapseThreads) {
|
|
5886
6415
|
return cache;
|
|
5887
6416
|
}
|
|
5888
|
-
const
|
|
5889
|
-
const
|
|
5890
|
-
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
|
+
};
|
|
5891
6430
|
this.displayCache = next;
|
|
5892
6431
|
return next;
|
|
5893
6432
|
}
|
|
6433
|
+
/**
|
|
6434
|
+
* Top-level root ID for `message` when {@link CollapseThreadReplies} is on and `message` is a
|
|
6435
|
+
* thread reply; null when thread collapsing is off or `message` belongs in the main flow.
|
|
6436
|
+
*/
|
|
6437
|
+
collapsedThreadRootId(message) {
|
|
6438
|
+
if (!this.CollapseThreadReplies) {
|
|
6439
|
+
return null;
|
|
6440
|
+
}
|
|
6441
|
+
const fromLoaded = this.displayState().ThreadReplyRoots.Get(message.ID);
|
|
6442
|
+
if (fromLoaded) {
|
|
6443
|
+
return fromLoaded;
|
|
6444
|
+
}
|
|
6445
|
+
const loaded = this.messages ?? [];
|
|
6446
|
+
if (loaded.some((m) => UUIDsEqual(m.ID, message.ID))) {
|
|
6447
|
+
return null;
|
|
6448
|
+
}
|
|
6449
|
+
return GetThreadReplyRoots([...loaded, message]).Get(message.ID) ?? null;
|
|
6450
|
+
}
|
|
5894
6451
|
/**
|
|
5895
6452
|
* Puts `message` in place of the row with its id in the displayed rows and their split, keeping those
|
|
5896
6453
|
* arrays. They are copies of `messages`, so an entity replaced in place there is replaced here too.
|
|
@@ -5900,6 +6457,7 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
5900
6457
|
if (!cache || cache.Messages !== this.messages) {
|
|
5901
6458
|
return;
|
|
5902
6459
|
}
|
|
6460
|
+
this.replaceRowIn(cache.MainFlow, message);
|
|
5903
6461
|
this.replaceRowIn(cache.Rows, message);
|
|
5904
6462
|
this.replaceRowIn(cache.Split.Inherited, message);
|
|
5905
6463
|
this.replaceRowIn(cache.Split.Own, message);
|
|
@@ -5960,6 +6518,13 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
5960
6518
|
if (stoppedAgent !== undefined) {
|
|
5961
6519
|
return `Continue, or tell ${stoppedAgent ?? 'the agent'} what to do differently`;
|
|
5962
6520
|
}
|
|
6521
|
+
const owner = this.CurrentOwnerAgent;
|
|
6522
|
+
if (owner && !owner.IsConversationManager) {
|
|
6523
|
+
if (owner.Name.trim().toLowerCase() === 'video studio') {
|
|
6524
|
+
return `Ask ${owner.Name} for changes, like "make the opening faster"`;
|
|
6525
|
+
}
|
|
6526
|
+
return `Ask ${owner.Name} for changes or a follow-up...`;
|
|
6527
|
+
}
|
|
5963
6528
|
}
|
|
5964
6529
|
return MAIN_COMPOSER_PLACEHOLDER;
|
|
5965
6530
|
}
|
|
@@ -6076,7 +6641,8 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
6076
6641
|
if (anchor) {
|
|
6077
6642
|
return anchor;
|
|
6078
6643
|
}
|
|
6079
|
-
const
|
|
6644
|
+
const state = this.displayState();
|
|
6645
|
+
const inherited = view === this.WindowView ? state.Split.Inherited : SplitForkRows(state.MainFlow, view).Inherited;
|
|
6080
6646
|
return inherited.length > 0 ? inherited[inherited.length - 1] : null;
|
|
6081
6647
|
}
|
|
6082
6648
|
/** A short date and time for fork text, in the person's locale. */
|
|
@@ -6262,6 +6828,10 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
6262
6828
|
if (!isCurrent()) {
|
|
6263
6829
|
return;
|
|
6264
6830
|
}
|
|
6831
|
+
await this.loadHandoffStepsForRunIds([agentRun.ID], expectedConversationId, loadToken);
|
|
6832
|
+
if (!isCurrent()) {
|
|
6833
|
+
return;
|
|
6834
|
+
}
|
|
6265
6835
|
}
|
|
6266
6836
|
}
|
|
6267
6837
|
// Reload artifacts for this completed message
|
|
@@ -6300,6 +6870,7 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
6300
6870
|
// The completed message was mutated in place — refresh the window's copy too.
|
|
6301
6871
|
this.windowStore.ApplyLocalDetail(message);
|
|
6302
6872
|
// Force re-render with updated agent run and artifacts
|
|
6873
|
+
this.rebuildHandoffsMap();
|
|
6303
6874
|
this.messages = [...this.messages];
|
|
6304
6875
|
this.cdr.detectChanges();
|
|
6305
6876
|
LogStatusEx({ message: `✅ Completion handled for message ${message.ID}`, verboseOnly: true });
|
|
@@ -6314,6 +6885,8 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
6314
6885
|
if (!finished && completionId) {
|
|
6315
6886
|
this.handledCompletionIds?.delete(completionId);
|
|
6316
6887
|
}
|
|
6888
|
+
// The row was loaded above whatever happened after; if it settled, it is no longer in flight.
|
|
6889
|
+
this.dropSettledFromInFlight();
|
|
6317
6890
|
}
|
|
6318
6891
|
}
|
|
6319
6892
|
async OnAgentResponse(event) {
|
|
@@ -6406,6 +6979,10 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
6406
6979
|
ConversationEngine.Instance.SetAgentRunForDetail(conversationId, conversationDetailId, existingRun);
|
|
6407
6980
|
}
|
|
6408
6981
|
}
|
|
6982
|
+
await this.loadHandoffStepsForRunIds([agentRunId], conversationId);
|
|
6983
|
+
if (!this.isActiveConversation(conversationId)) {
|
|
6984
|
+
return agentRun;
|
|
6985
|
+
}
|
|
6409
6986
|
// Refresh the target message in place when already rendered; fall back to
|
|
6410
6987
|
// shallow array copy only when the message is not yet mounted in the list.
|
|
6411
6988
|
const targetMessage = this.messages.find(m => UUIDsEqual(m.ID, conversationDetailId));
|
|
@@ -6680,17 +7257,30 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
6680
7257
|
get hasSystemArtifacts() {
|
|
6681
7258
|
return this.HasSystemArtifacts;
|
|
6682
7259
|
}
|
|
7260
|
+
_artifactsArrayCache = [];
|
|
7261
|
+
_artifactsArrayKey = '';
|
|
6683
7262
|
/**
|
|
6684
|
-
* Get unique artifacts grouped by artifact ID (not by conversation detail)
|
|
6685
|
-
* Returns the latest version info for each unique artifact with all versions
|
|
6686
|
-
* Works with LazyArtifactInfo - uses display data without loading full entities
|
|
6687
|
-
* Respects showSystemArtifacts toggle
|
|
7263
|
+
* Get unique artifacts grouped by artifact ID (not by conversation detail).
|
|
7264
|
+
* Returns the latest version info for each unique artifact with all versions.
|
|
7265
|
+
* Works with LazyArtifactInfo - uses display data without loading full entities.
|
|
7266
|
+
* Respects showSystemArtifacts toggle and memoizes the result across CD passes.
|
|
6688
7267
|
*/
|
|
6689
7268
|
GetArtifactsArray() {
|
|
7269
|
+
const effectiveMap = this.EffectiveArtifactsMap;
|
|
7270
|
+
let sig = `${this.ShowSystemArtifacts ? 1 : 0}|${effectiveMap.size}|`;
|
|
7271
|
+
for (const artifactList of effectiveMap.values()) {
|
|
7272
|
+
for (const info of artifactList) {
|
|
7273
|
+
sig += `${info.artifactVersionId}:${info.artifactName ?? ''};`;
|
|
7274
|
+
}
|
|
7275
|
+
}
|
|
7276
|
+
if (sig === this._artifactsArrayKey) {
|
|
7277
|
+
return this._artifactsArrayCache;
|
|
7278
|
+
}
|
|
7279
|
+
this._artifactsArrayKey = sig;
|
|
6690
7280
|
const artifactMap = new Map();
|
|
6691
7281
|
// Group by artifactId, collecting all version details
|
|
6692
7282
|
// Use effectiveArtifactsMap to respect showSystemArtifacts toggle
|
|
6693
|
-
for (const artifactList of
|
|
7283
|
+
for (const artifactList of effectiveMap.values()) {
|
|
6694
7284
|
for (const info of artifactList) {
|
|
6695
7285
|
const artifactId = info.artifactId;
|
|
6696
7286
|
const versionId = info.artifactVersionId;
|
|
@@ -6717,7 +7307,7 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
6717
7307
|
}
|
|
6718
7308
|
}
|
|
6719
7309
|
// Convert to array with version count, sorted by version number descending
|
|
6720
|
-
|
|
7310
|
+
this._artifactsArrayCache = Array.from(artifactMap.values()).map(item => ({
|
|
6721
7311
|
artifactId: item.artifactId,
|
|
6722
7312
|
versionId: item.versionId,
|
|
6723
7313
|
name: item.name,
|
|
@@ -6725,6 +7315,7 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
6725
7315
|
versionCount: item.versions.length,
|
|
6726
7316
|
versions: item.versions.sort((a, b) => b.versionNumber - a.versionNumber)
|
|
6727
7317
|
}));
|
|
7318
|
+
return this._artifactsArrayCache;
|
|
6728
7319
|
}
|
|
6729
7320
|
/** @deprecated Use {@link GetArtifactsArray}. */
|
|
6730
7321
|
getArtifactsArray() {
|
|
@@ -6969,14 +7560,13 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
6969
7560
|
// region the list unmounts into spacers — so this button silently did nothing for any pin
|
|
6970
7561
|
// that wasn't already on screen. The list resolves through the timeline key, which a
|
|
6971
7562
|
// spacer shares with the item it stands in for.
|
|
6972
|
-
if (this.
|
|
6973
|
-
this.beaconMessage(messageId);
|
|
7563
|
+
if (this.scrollToMessageOrThreadRoot(messageId)) {
|
|
6974
7564
|
return;
|
|
6975
7565
|
}
|
|
6976
7566
|
// Not in the loaded window. Pins are fetched by their own query precisely so the panel can
|
|
6977
7567
|
// list pins older than the transcript, so this is the EXPECTED case for an old pin, not an
|
|
6978
7568
|
// error — page back until it is loaded, the same way a date jump does.
|
|
6979
|
-
const reached = await this.loadUntilMessageIsWindowed(messageId);
|
|
7569
|
+
const reached = (await this.loadUntilMessageIsWindowed(messageId)) && (await this.loadUntilThreadRootIsWindowed(messageId));
|
|
6980
7570
|
if (!reached) {
|
|
6981
7571
|
MJNotificationService.Instance.CreateSimpleNotification('Could not reach that message — it is further back than this jump loads.', 'info', 3000);
|
|
6982
7572
|
return;
|
|
@@ -6984,10 +7574,7 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
6984
7574
|
// The paging loop deliberately skipped the per-page peripheral rebuild — pay it once,
|
|
6985
7575
|
// here, before asking the list for element positions.
|
|
6986
7576
|
await this.refreshAfterPaging(this.ConversationId);
|
|
6987
|
-
if (this.
|
|
6988
|
-
this.beaconMessage(messageId);
|
|
6989
|
-
}
|
|
6990
|
-
else {
|
|
7577
|
+
if (!this.scrollToMessageOrThreadRoot(messageId)) {
|
|
6991
7578
|
MJNotificationService.Instance.CreateSimpleNotification('Could not find that message in this conversation', 'info', 3000);
|
|
6992
7579
|
}
|
|
6993
7580
|
}
|
|
@@ -7019,6 +7606,10 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
7019
7606
|
return false;
|
|
7020
7607
|
}
|
|
7021
7608
|
await this.loadUntilSequenceIsWindowed(sequence);
|
|
7609
|
+
const hit = this.windowStore.GetSnapshot().Details.find(m => m.Sequence === sequence && UUIDsEqual(m.BranchID ?? null, branchId));
|
|
7610
|
+
if (hit) {
|
|
7611
|
+
await this.loadUntilThreadRootIsWindowed(hit.ID);
|
|
7612
|
+
}
|
|
7022
7613
|
if (!this.isActiveConversation(conversationId)) {
|
|
7023
7614
|
return false;
|
|
7024
7615
|
}
|
|
@@ -7029,13 +7620,43 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
7029
7620
|
this.scrollToBottom = false;
|
|
7030
7621
|
this.bottomFollowSuppressedUntil = Date.now() + 1500;
|
|
7031
7622
|
}
|
|
7032
|
-
if (!row || !this.
|
|
7623
|
+
if (!row || !this.scrollToMessageOrThreadRoot(row.ID, 'search-hit-highlight', 2000)) {
|
|
7033
7624
|
MJNotificationService.Instance.CreateSimpleNotification('Could not find that message in this conversation', 'info', 3000);
|
|
7034
7625
|
return false;
|
|
7035
7626
|
}
|
|
7036
|
-
this.beaconMessage(row.ID, 'search-hit-highlight', 2000);
|
|
7037
7627
|
return true;
|
|
7038
7628
|
}
|
|
7629
|
+
/**
|
|
7630
|
+
* Scrolls to `messageId`, or when {@link CollapseThreadReplies} hides `messageId` under a thread
|
|
7631
|
+
* root, scrolls to that root and emits {@link ThreadReplyRevealRequested} so the host can open
|
|
7632
|
+
* the thread. False when the row (or its root) is not loaded, so the caller can page back for it.
|
|
7633
|
+
*/
|
|
7634
|
+
scrollToMessageOrThreadRoot(messageId, cssClass = 'pin-beacon', durationMs = 1500) {
|
|
7635
|
+
const rootId = this.CollapseThreadReplies
|
|
7636
|
+
? this.displayState().ThreadReplyRoots.Get(messageId)
|
|
7637
|
+
: undefined;
|
|
7638
|
+
if (rootId) {
|
|
7639
|
+
if (!this.messageListComponent?.ScrollToMessage(rootId)) {
|
|
7640
|
+
return false;
|
|
7641
|
+
}
|
|
7642
|
+
this.beaconMessage(rootId, cssClass, durationMs);
|
|
7643
|
+
this.emitThreadReplyReveal(messageId, rootId);
|
|
7644
|
+
return true;
|
|
7645
|
+
}
|
|
7646
|
+
if (this.messageListComponent?.ScrollToMessage(messageId)) {
|
|
7647
|
+
this.beaconMessage(messageId, cssClass, durationMs);
|
|
7648
|
+
return true;
|
|
7649
|
+
}
|
|
7650
|
+
return false;
|
|
7651
|
+
}
|
|
7652
|
+
emitThreadReplyReveal(replyId, rootId) {
|
|
7653
|
+
const loadedReply = (this.messages ?? []).find(m => UUIDsEqual(m.ID, replyId));
|
|
7654
|
+
const loadedRoot = (this.messages ?? []).find(m => UUIDsEqual(m.ID, rootId));
|
|
7655
|
+
this.ThreadReplyRevealRequested.emit({
|
|
7656
|
+
ReplyID: loadedReply?.ID ?? replyId,
|
|
7657
|
+
RootID: loadedRoot?.ID ?? rootId,
|
|
7658
|
+
});
|
|
7659
|
+
}
|
|
7039
7660
|
/**
|
|
7040
7661
|
* Waits until the load of `conversationId` has ended. False when another conversation
|
|
7041
7662
|
* becomes active first or the component is destroyed.
|
|
@@ -7051,12 +7672,39 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
7051
7672
|
}
|
|
7052
7673
|
/** Pages older history until the pinned message `messageId` falls inside the loaded window. */
|
|
7053
7674
|
async loadUntilMessageIsWindowed(messageId) {
|
|
7054
|
-
const target = this.PinnedMessages
|
|
7675
|
+
const target = this.PinnedMessages?.find(p => UUIDsEqual(p.ID, messageId));
|
|
7055
7676
|
if (!target) {
|
|
7056
7677
|
return false; // not a loaded pin — nothing tells us how far back to page
|
|
7057
7678
|
}
|
|
7058
7679
|
return this.loadUntilSequenceIsWindowed(target.Sequence);
|
|
7059
7680
|
}
|
|
7681
|
+
/**
|
|
7682
|
+
* With {@link CollapseThreadReplies} on, pages older history until the top-level root of the loaded
|
|
7683
|
+
* thread reply `messageId` is loaded too, since the jump lands on the root. True when nothing more is
|
|
7684
|
+
* needed (collapsing off, `messageId` not a loaded thread reply, or its root loaded).
|
|
7685
|
+
*/
|
|
7686
|
+
async loadUntilThreadRootIsWindowed(messageId) {
|
|
7687
|
+
if (!this.CollapseThreadReplies) {
|
|
7688
|
+
return true;
|
|
7689
|
+
}
|
|
7690
|
+
const conversationId = this.ConversationId;
|
|
7691
|
+
for (let page = 0; page < DATE_JUMP_MAX_PAGES; page++) {
|
|
7692
|
+
const snapshot = this.windowStore.GetSnapshot();
|
|
7693
|
+
// Recomputed per page: a loaded parent that is itself a reply moves the root further up.
|
|
7694
|
+
const rootId = GetThreadReplyRoots(snapshot.Details).Get(messageId);
|
|
7695
|
+
if (!rootId || new UUIDSet(snapshot.Details.map(m => m.ID)).Has(rootId)) {
|
|
7696
|
+
return true;
|
|
7697
|
+
}
|
|
7698
|
+
if (!snapshot.Cursor.HasMoreAbove) {
|
|
7699
|
+
return false;
|
|
7700
|
+
}
|
|
7701
|
+
await this.windowStore.LoadOlder(this.CurrentUser);
|
|
7702
|
+
if (!this.isActiveConversation(conversationId)) {
|
|
7703
|
+
return false;
|
|
7704
|
+
}
|
|
7705
|
+
}
|
|
7706
|
+
return false;
|
|
7707
|
+
}
|
|
7060
7708
|
/**
|
|
7061
7709
|
* Pages older history until the loaded window reaches back to `sequence`.
|
|
7062
7710
|
*
|
|
@@ -7111,7 +7759,9 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
7111
7759
|
message.IsPinned = false;
|
|
7112
7760
|
this.cdr.detectChanges();
|
|
7113
7761
|
try {
|
|
7114
|
-
await message.
|
|
7762
|
+
if (!(await SavePinState(this.ProviderToUse, message.ID, false))) {
|
|
7763
|
+
throw new Error(`the pin on message ${message.ID} could not be saved`);
|
|
7764
|
+
}
|
|
7115
7765
|
this.OnMessagePinToggled(message);
|
|
7116
7766
|
}
|
|
7117
7767
|
catch (err) {
|
|
@@ -7180,10 +7830,9 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
7180
7830
|
}
|
|
7181
7831
|
// Find this message and all messages after it sorted by Sequence
|
|
7182
7832
|
const sortedMessages = [...this.messages].sort((a, b) => a.Sequence - b.Sequence);
|
|
7183
|
-
const
|
|
7184
|
-
if (
|
|
7833
|
+
const toHide = this.rowsToDeleteFrom(sortedMessages, message.ID);
|
|
7834
|
+
if (toHide.length === 0)
|
|
7185
7835
|
return;
|
|
7186
|
-
const toHide = sortedMessages.slice(targetIndex);
|
|
7187
7836
|
const count = toHide.length;
|
|
7188
7837
|
const confirmed = await this.confirmDialog.confirm({
|
|
7189
7838
|
title: 'Delete Messages',
|
|
@@ -7216,15 +7865,52 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
7216
7865
|
console.error(`Failed to delete ConversationDetail ${e.ID}: ${last?.Message ?? 'unknown error'}`, last?.Error ?? '');
|
|
7217
7866
|
}
|
|
7218
7867
|
}
|
|
7219
|
-
const hideIds = new
|
|
7868
|
+
const hideIds = new UUIDSet(toHide.map(m => m.ID));
|
|
7220
7869
|
// Drop them from the window too, or the next RefreshLatest merge reinstates them.
|
|
7221
|
-
for (const
|
|
7222
|
-
this.windowStore.RemoveDetail(
|
|
7870
|
+
for (const m of toHide) {
|
|
7871
|
+
this.windowStore.RemoveDetail(m.ID);
|
|
7223
7872
|
}
|
|
7224
|
-
this.messages = this.messages.filter(m => !hideIds.
|
|
7873
|
+
this.messages = this.messages.filter(m => !hideIds.Has(m.ID));
|
|
7225
7874
|
this.resetComponentState(this.ConversationId);
|
|
7226
7875
|
this.cdr.detectChanges();
|
|
7227
7876
|
}
|
|
7877
|
+
/**
|
|
7878
|
+
* The rows removed by "delete this and everything after": when thread replies are collapsed,
|
|
7879
|
+
* the target, every main-flow row after it, and any thread replies whose root is among those rows.
|
|
7880
|
+
* When the target is itself a thread reply, only the target and the replies under it.
|
|
7881
|
+
*/
|
|
7882
|
+
rowsToDeleteFrom(sortedMessages, targetId) {
|
|
7883
|
+
const targetIndex = sortedMessages.findIndex(m => UUIDsEqual(m.ID, targetId));
|
|
7884
|
+
if (targetIndex === -1) {
|
|
7885
|
+
return [];
|
|
7886
|
+
}
|
|
7887
|
+
if (!this.CollapseThreadReplies) {
|
|
7888
|
+
return sortedMessages.slice(targetIndex);
|
|
7889
|
+
}
|
|
7890
|
+
const roots = GetThreadReplyRoots(sortedMessages);
|
|
7891
|
+
if (roots.Has(targetId)) {
|
|
7892
|
+
// Sorted by Sequence, so a reply always follows its parent: one pass collects the subtree.
|
|
7893
|
+
const subtree = new UUIDSet([sortedMessages[targetIndex].ID]);
|
|
7894
|
+
for (let i = targetIndex + 1; i < sortedMessages.length; i++) {
|
|
7895
|
+
const parentId = sortedMessages[i].ParentID;
|
|
7896
|
+
if (parentId && subtree.Has(parentId)) {
|
|
7897
|
+
subtree.Add(sortedMessages[i].ID);
|
|
7898
|
+
}
|
|
7899
|
+
}
|
|
7900
|
+
return sortedMessages.filter(m => subtree.Has(m.ID));
|
|
7901
|
+
}
|
|
7902
|
+
const removedRoots = new UUIDSet();
|
|
7903
|
+
for (let i = targetIndex; i < sortedMessages.length; i++) {
|
|
7904
|
+
const id = sortedMessages[i].ID;
|
|
7905
|
+
if (!roots.Has(id) || i === targetIndex) {
|
|
7906
|
+
removedRoots.Add(id);
|
|
7907
|
+
}
|
|
7908
|
+
}
|
|
7909
|
+
return sortedMessages.filter(m => {
|
|
7910
|
+
const rootId = roots.Get(m.ID);
|
|
7911
|
+
return removedRoots.Has(m.ID) || (rootId !== undefined && removedRoots.Has(rootId));
|
|
7912
|
+
});
|
|
7913
|
+
}
|
|
7228
7914
|
/** @deprecated Use {@link OnDeleteMessage}. */
|
|
7229
7915
|
async onDeleteMessage(message) {
|
|
7230
7916
|
return this.OnDeleteMessage(message);
|
|
@@ -7331,6 +8017,7 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
7331
8017
|
this.SelectedVersionNumber = undefined;
|
|
7332
8018
|
}
|
|
7333
8019
|
this.SelectedTaskGraphPanel = null;
|
|
8020
|
+
this.ShowRemoteBrowserPanel = false;
|
|
7334
8021
|
this.ShowArtifactPanel = true;
|
|
7335
8022
|
// Load permissions for the selected artifact
|
|
7336
8023
|
await this.loadArtifactPermissions(data.artifactId, conversationId, data.artifactId);
|
|
@@ -7355,6 +8042,7 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
7355
8042
|
return;
|
|
7356
8043
|
}
|
|
7357
8044
|
this.ShowArtifactPanel = false;
|
|
8045
|
+
this.ShowRemoteBrowserPanel = false;
|
|
7358
8046
|
this.SelectedArtifactId = null;
|
|
7359
8047
|
this.SelectedTaskGraphPanel = {
|
|
7360
8048
|
parentTaskId: data.parentTaskId,
|
|
@@ -7368,6 +8056,73 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
7368
8056
|
this.resetArtifactPaneSizing();
|
|
7369
8057
|
this.cdr.detectChanges();
|
|
7370
8058
|
}
|
|
8059
|
+
ToggleRemoteBrowserPanel() {
|
|
8060
|
+
if (this.ShowRemoteBrowserPanel) {
|
|
8061
|
+
this.CloseRemoteBrowserPanel();
|
|
8062
|
+
}
|
|
8063
|
+
else {
|
|
8064
|
+
this.OpenRemoteBrowserPanel();
|
|
8065
|
+
}
|
|
8066
|
+
}
|
|
8067
|
+
OpenRemoteBrowserPanel() {
|
|
8068
|
+
if (this.ShowRemoteBrowserPanel || !this.AllowRemoteBrowser || !this.ConversationId) {
|
|
8069
|
+
return;
|
|
8070
|
+
}
|
|
8071
|
+
// Open before the drawer renders: binding its surface starts the screencast for this conversation.
|
|
8072
|
+
this.ensureRemoteBrowser().Open(this.ConversationId);
|
|
8073
|
+
this.ShowArtifactPanel = false;
|
|
8074
|
+
this.SelectedTaskGraphPanel = null;
|
|
8075
|
+
this.SelectedArtifactId = null;
|
|
8076
|
+
this.ShowRemoteBrowserPanel = true;
|
|
8077
|
+
this.cdr.detectChanges();
|
|
8078
|
+
}
|
|
8079
|
+
/** Closing the drawer ends the browser (hiding it behind an artifact does not). */
|
|
8080
|
+
CloseRemoteBrowserPanel() {
|
|
8081
|
+
if (!this.ShowRemoteBrowserPanel) {
|
|
8082
|
+
return;
|
|
8083
|
+
}
|
|
8084
|
+
this.ShowRemoteBrowserPanel = false;
|
|
8085
|
+
this.resetArtifactPaneSizing();
|
|
8086
|
+
void this.remoteBrowser?.Close();
|
|
8087
|
+
this.cdr.detectChanges();
|
|
8088
|
+
}
|
|
8089
|
+
async NavigateRemoteBrowserFromInput() {
|
|
8090
|
+
const rawUrl = this.RemoteBrowserUrlInput?.trim();
|
|
8091
|
+
if (!rawUrl || this.IsRemoteBrowserNavigating) {
|
|
8092
|
+
return;
|
|
8093
|
+
}
|
|
8094
|
+
this.IsRemoteBrowserNavigating = true;
|
|
8095
|
+
this.cdr.detectChanges();
|
|
8096
|
+
try {
|
|
8097
|
+
const result = await this.remoteBrowser?.Navigate(rawUrl);
|
|
8098
|
+
// A refused session already said why (OnSessionRefused) and closed the browser.
|
|
8099
|
+
if (result && !result.Success && this.IsRemoteBrowserLive) {
|
|
8100
|
+
MJNotificationService.Instance.CreateSimpleNotification(result.ErrorMessage ?? 'The page could not be opened.', 'error', 5000);
|
|
8101
|
+
}
|
|
8102
|
+
}
|
|
8103
|
+
finally {
|
|
8104
|
+
this.IsRemoteBrowserNavigating = false;
|
|
8105
|
+
this.cdr.detectChanges();
|
|
8106
|
+
}
|
|
8107
|
+
}
|
|
8108
|
+
/**
|
|
8109
|
+
* `AppContext` plus the conversation's open browser (its URL, and the `browser_*` tools while this
|
|
8110
|
+
* chat area owns them). Cached: it is bound to an input, so a fresh object per check would re-fire it.
|
|
8111
|
+
*/
|
|
8112
|
+
get EffectiveAppContext() {
|
|
8113
|
+
const controller = this.remoteBrowser;
|
|
8114
|
+
if (!controller) {
|
|
8115
|
+
return this.AppContext;
|
|
8116
|
+
}
|
|
8117
|
+
const owns = controller.ConversationId !== null && controller.OwnsTools;
|
|
8118
|
+
let memo = this.effectiveAppContextMemo;
|
|
8119
|
+
if (!memo || memo.Base !== this.AppContext || memo.Version !== controller.StateVersion || memo.Owns !== owns) {
|
|
8120
|
+
memo = { Base: this.AppContext, Version: controller.StateVersion, Owns: owns, Value: controller.WithBrowserContext(this.AppContext) };
|
|
8121
|
+
this.effectiveAppContextMemo = memo;
|
|
8122
|
+
}
|
|
8123
|
+
return memo.Value;
|
|
8124
|
+
}
|
|
8125
|
+
effectiveAppContextMemo = null;
|
|
7371
8126
|
/**
|
|
7372
8127
|
* Persists the currently displayed Task Graph in the chat side-panel as a reusable
|
|
7373
8128
|
* Draft Flow Agent workflow via {@link WorkflowSaveOperation} and opens the new
|
|
@@ -7648,6 +8403,9 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
7648
8403
|
}
|
|
7649
8404
|
OnConversationRenamed(event) {
|
|
7650
8405
|
LogStatusEx({ message: '🎉 Conversation renamed', verboseOnly: true, additionalArgs: [event] });
|
|
8406
|
+
if (event?.conversationId && event.name) {
|
|
8407
|
+
this.syncCachedMessageInputName(event.conversationId, event.name);
|
|
8408
|
+
}
|
|
7651
8409
|
// Pass the event up to workspace component for animation
|
|
7652
8410
|
this.ConversationRenamed.emit(event);
|
|
7653
8411
|
}
|
|
@@ -7918,6 +8676,17 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
7918
8676
|
void this.engine.EnsureConversationLoaded(created, this.CurrentUser);
|
|
7919
8677
|
this.RealtimeConversationReady.emit({ conversationId: created, select: false });
|
|
7920
8678
|
}
|
|
8679
|
+
/**
|
|
8680
|
+
* Says why a call ended only when it ended over a failure. A `'deadline'` end (the runtime's time-limit auto-end) is
|
|
8681
|
+
* a normal end: the call surface closes on its own and the visitor needs no error toast.
|
|
8682
|
+
*/
|
|
8683
|
+
notifyIfCallFailed(reason) {
|
|
8684
|
+
if (reason !== 'error') {
|
|
8685
|
+
return;
|
|
8686
|
+
}
|
|
8687
|
+
const notice = DescribeCallFailureNotice(this.RealtimeSession.LastStartError, this.RealtimeSession.LastSessionError);
|
|
8688
|
+
MJNotificationService.Instance.CreateSimpleNotification(notice, 'error', 6000);
|
|
8689
|
+
}
|
|
7921
8690
|
/**
|
|
7922
8691
|
* Post-call hook. Two responsibilities:
|
|
7923
8692
|
* 1. Reload the ACTIVE conversation's timeline so the session that just ended — whose
|
|
@@ -8688,6 +9457,9 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
8688
9457
|
* in flight.
|
|
8689
9458
|
*/
|
|
8690
9459
|
followTranscript(change, message) {
|
|
9460
|
+
if (message && this.collapsedThreadRootId(message) !== null) {
|
|
9461
|
+
return;
|
|
9462
|
+
}
|
|
8691
9463
|
if (change === 'load') {
|
|
8692
9464
|
this.scrollToBottom = true;
|
|
8693
9465
|
return;
|
|
@@ -8731,6 +9503,27 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
8731
9503
|
isSettled(message) {
|
|
8732
9504
|
return message.Status === 'Complete' || message.Status === 'Error';
|
|
8733
9505
|
}
|
|
9506
|
+
/**
|
|
9507
|
+
* Drops every in-flight ID whose loaded row has settled. A settled reply is never in flight:
|
|
9508
|
+
* the list drives the composer's Stop slot and its ticker, and every reconcile path scans the
|
|
9509
|
+
* rows for `In-Progress`, so an ID left behind after its row settled would never be looked at
|
|
9510
|
+
* again (the overlay's Stop button ticked for hours after Regenerate-as-fork this way). An ID
|
|
9511
|
+
* with no loaded row is kept; the row may simply not be on screen yet.
|
|
9512
|
+
*/
|
|
9513
|
+
dropSettledFromInFlight() {
|
|
9514
|
+
const ids = this.InProgressMessageIds;
|
|
9515
|
+
if (ids.length === 0) {
|
|
9516
|
+
return;
|
|
9517
|
+
}
|
|
9518
|
+
const byID = IndexByUUID(this.messages ?? []);
|
|
9519
|
+
const stillInFlight = ids.filter((id) => {
|
|
9520
|
+
const row = byID.Get(id);
|
|
9521
|
+
return !row || !this.isSettled(row);
|
|
9522
|
+
});
|
|
9523
|
+
if (stillInFlight.length !== ids.length) {
|
|
9524
|
+
this.InProgressMessageIds = stillInFlight;
|
|
9525
|
+
}
|
|
9526
|
+
}
|
|
8734
9527
|
/**
|
|
8735
9528
|
* Where the viewport goes on a streamed delta, in the same frame as the DOM change so growth and
|
|
8736
9529
|
* scroll paint together. Without ReadReplyFromTop, or for a turn this component never saw open
|
|
@@ -8900,6 +9693,7 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
8900
9693
|
// (prioritizing ParentRunID == null and ContinuationDepth == 0 over continuation
|
|
8901
9694
|
// synthesis runs, and newest __mj_CreatedAt among ties so retried messages use their latest run).
|
|
8902
9695
|
const chosenByDetailId = new Map();
|
|
9696
|
+
const refreshedRunIds = [];
|
|
8903
9697
|
for (const run of result.Results || []) {
|
|
8904
9698
|
const detailId = run.ConversationDetailID;
|
|
8905
9699
|
if (!detailId) {
|
|
@@ -8912,9 +9706,13 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
8912
9706
|
}
|
|
8913
9707
|
for (const [detailId, run] of chosenByDetailId.entries()) {
|
|
8914
9708
|
this.AgentRunsByDetailId.set(detailId, run);
|
|
9709
|
+
if (run.ID) {
|
|
9710
|
+
refreshedRunIds.push(run.ID);
|
|
9711
|
+
}
|
|
8915
9712
|
}
|
|
8916
9713
|
// New map reference so OnPush children re-read it.
|
|
8917
9714
|
this.AgentRunsByDetailId = new Map(this.AgentRunsByDetailId);
|
|
9715
|
+
await this.loadHandoffStepsForRunIds(refreshedRunIds, conversationId, loadToken);
|
|
8918
9716
|
}
|
|
8919
9717
|
/**
|
|
8920
9718
|
* Reconcile in-progress messages against durable server state, on demand.
|
|
@@ -8929,6 +9727,9 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
8929
9727
|
* @param reason What prompted it — carried only for logging.
|
|
8930
9728
|
*/
|
|
8931
9729
|
async ReconcileNow(reason) {
|
|
9730
|
+
if (ConversationChatAreaComponent.TRANSPORT_RECONNECT_REASONS.includes(reason)) {
|
|
9731
|
+
this.reconcileWindowRefreshPending = true;
|
|
9732
|
+
}
|
|
8932
9733
|
if (this.reconcileInFlight) {
|
|
8933
9734
|
this.reconcileRerunReason = reason;
|
|
8934
9735
|
return this.reconcileInFlight;
|
|
@@ -8950,6 +9751,49 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
8950
9751
|
this.reconcileInFlight = null;
|
|
8951
9752
|
}
|
|
8952
9753
|
}
|
|
9754
|
+
/**
|
|
9755
|
+
* Supervisor reasons that mean the transport itself was down, so anything published meanwhile
|
|
9756
|
+
* was dropped. Only these pay for {@link refreshNewestWindow}; the other triggers
|
|
9757
|
+
* (tab-visible, browser-online, message-liveness, completion-for-unloaded-message) keep the
|
|
9758
|
+
* narrow run-row refresh alone.
|
|
9759
|
+
*/
|
|
9760
|
+
static TRANSPORT_RECONNECT_REASONS = ['socket-reconnected', 'stream-reconnected'];
|
|
9761
|
+
/**
|
|
9762
|
+
* After a transport reconnect, re-read the newest window page before reconciling, when any AI
|
|
9763
|
+
* message is still unsettled.
|
|
9764
|
+
*
|
|
9765
|
+
* Two things {@link refreshAgentRunsForInProgress} alone does not cover:
|
|
9766
|
+
*
|
|
9767
|
+
* - **Error-status messages.** {@link correctStaleErrorMessages} can repair a message the client
|
|
9768
|
+
* marked Error while the server went on to complete the run — but only against a fresh run
|
|
9769
|
+
* row, and the narrow refresh reads runs for In-Progress messages only. Rebuilding the
|
|
9770
|
+
* peripherals from the refreshed window gives it current runs for every message in view.
|
|
9771
|
+
* - **Rows written while the socket was down.** Their events were dropped, so only a re-read
|
|
9772
|
+
* brings them into the window.
|
|
9773
|
+
*
|
|
9774
|
+
* Newest page only, the same choice the poll-completion path makes: a full-history refresh
|
|
9775
|
+
* would replace the loaded window with every row. Only called when
|
|
9776
|
+
* {@link hasUnsettledAgentReplies} is true, so a quiet conversation costs one array scan.
|
|
9777
|
+
*
|
|
9778
|
+
* @returns false when the conversation changed underneath, so the caller abandons the pass.
|
|
9779
|
+
*/
|
|
9780
|
+
async refreshNewestWindow(conversationId, loadToken) {
|
|
9781
|
+
await this.windowStore.RefreshLatest(this.currentUser);
|
|
9782
|
+
if (!this.isActiveConversationLoad(conversationId, loadToken)) {
|
|
9783
|
+
return false;
|
|
9784
|
+
}
|
|
9785
|
+
const refreshed = this.windowStore.GetSnapshot();
|
|
9786
|
+
this.messages = refreshed.Details;
|
|
9787
|
+
// loadPeripheralData short-circuits when it has already run for this conversation; clearing
|
|
9788
|
+
// the marker is what lets it rebuild the run map from the fresh window.
|
|
9789
|
+
this.lastLoadedConversationId = null;
|
|
9790
|
+
await this.loadPeripheralData(conversationId, refreshed, loadToken);
|
|
9791
|
+
return this.isActiveConversationLoad(conversationId, loadToken);
|
|
9792
|
+
}
|
|
9793
|
+
/** Whether any agent reply is still In-Progress, or is Error and may have completed server-side. */
|
|
9794
|
+
hasUnsettledAgentReplies() {
|
|
9795
|
+
return (this.messages ?? []).some(m => m.Role === 'AI' && (m.Status === 'In-Progress' || m.Status === 'Error'));
|
|
9796
|
+
}
|
|
8953
9797
|
/** One reconcile pass over the in-progress messages of the active conversation. */
|
|
8954
9798
|
async reconcileOnce(reason) {
|
|
8955
9799
|
const conversationId = this.conversationId;
|
|
@@ -8962,6 +9806,16 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
8962
9806
|
const loadToken = this.conversationLoadToken;
|
|
8963
9807
|
LogStatusEx({ message: `🔁 Reconciling in-progress runs (${reason})`, verboseOnly: true });
|
|
8964
9808
|
try {
|
|
9809
|
+
if (this.reconcileWindowRefreshPending) {
|
|
9810
|
+
this.reconcileWindowRefreshPending = false;
|
|
9811
|
+
// Decided synchronously so a pass with nothing unsettled adds no await to next's path.
|
|
9812
|
+
if (this.hasUnsettledAgentReplies()) {
|
|
9813
|
+
const stillActive = await this.refreshNewestWindow(conversationId, loadToken);
|
|
9814
|
+
if (!stillActive) {
|
|
9815
|
+
return;
|
|
9816
|
+
}
|
|
9817
|
+
}
|
|
9818
|
+
}
|
|
8965
9819
|
await this.refreshAgentRunsForInProgress(conversationId, loadToken);
|
|
8966
9820
|
if (!this.isActiveConversationLoad(conversationId, loadToken)) {
|
|
8967
9821
|
return;
|
|
@@ -9062,6 +9916,8 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
9062
9916
|
* Reconnect to in-progress agent runs whose completion events were missed.
|
|
9063
9917
|
*/
|
|
9064
9918
|
async reconnectInProgressRuns(conversationId, loadToken) {
|
|
9919
|
+
// An ID whose row settled while its completion was missed would never be found by the scan below.
|
|
9920
|
+
this.dropSettledFromInFlight();
|
|
9065
9921
|
const inProgressMessages = this.messages.filter(m => m.Status === 'In-Progress' && m.Role === 'AI');
|
|
9066
9922
|
if (inProgressMessages.length === 0) {
|
|
9067
9923
|
return;
|
|
@@ -9165,7 +10021,7 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
9165
10021
|
scrollToMessage(messageId) {
|
|
9166
10022
|
// Wait for DOM to update, then scroll
|
|
9167
10023
|
setTimeout(() => {
|
|
9168
|
-
if (this.
|
|
10024
|
+
if (this.scrollToMessageOrThreadRoot(messageId)) {
|
|
9169
10025
|
return;
|
|
9170
10026
|
}
|
|
9171
10027
|
const messageElement = document.querySelector(`[data-message-id="${messageId}"]`);
|
|
@@ -9241,52 +10097,54 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
9241
10097
|
let _t;
|
|
9242
10098
|
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.chatSlotChildren = _t);
|
|
9243
10099
|
} }, viewQuery: function ConversationChatAreaComponent_Query(rf, ctx) { if (rf & 1) {
|
|
9244
|
-
i0.ɵɵviewQuery(_c0, 5)(ArtifactViewerPanelComponent, 5)(ConversationEmptyStateComponent, 5)(
|
|
10100
|
+
i0.ɵɵviewQuery(_c0, 5)(ArtifactViewerPanelComponent, 5)(ConversationEmptyStateComponent, 5)(_c1, 5)(MessageListComponent, 5)(_c2, 5)(_c3, 5, ElementRef)(_c4, 5, ElementRef)(_c5, 5);
|
|
9245
10101
|
} if (rf & 2) {
|
|
9246
10102
|
let _t;
|
|
9247
10103
|
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.scrollContainerRef = _t.first);
|
|
9248
10104
|
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.artifactViewerComponent = _t.first);
|
|
9249
10105
|
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.emptyStateComponent = _t.first);
|
|
10106
|
+
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.ConversationRemoteBrowserSurface = _t.first);
|
|
9250
10107
|
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.messageListComponent = _t.first);
|
|
9251
10108
|
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.titleNameInput = _t.first);
|
|
9252
10109
|
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.titleRenameButton = _t.first);
|
|
9253
10110
|
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.forksButton = _t.first);
|
|
9254
10111
|
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.messageInputComponents = _t);
|
|
9255
|
-
} }, inputs: { EnvironmentId: "EnvironmentId", environmentId: "environmentId", CurrentUser: "CurrentUser", currentUser: "currentUser", ConversationId: "ConversationId", conversationId: "conversationId", Conversation: "Conversation", conversation: "conversation", SuppressNewConversationEmptyState: "SuppressNewConversationEmptyState", suppressNewConversationEmptyState: "suppressNewConversationEmptyState", AllowMentions: "AllowMentions", allowMentions: "allowMentions", AllowAgentMentions: "AllowAgentMentions", allowAgentMentions: "allowAgentMentions", AllowEntityMentions: "AllowEntityMentions", allowEntityMentions: "allowEntityMentions", AllowSkillCommands: "AllowSkillCommands", allowSkillCommands: "allowSkillCommands", AllowAttachments: "AllowAttachments", allowAttachments: "allowAttachments", AllowPlanMode: "AllowPlanMode", allowPlanMode: "allowPlanMode", AllowRealtime: "AllowRealtime", allowRealtime: "allowRealtime", AllowForking: "AllowForking", AllowStopRun: "AllowStopRun", ShowEmptyFill: "ShowEmptyFill", showEmptyFill: "showEmptyFill", ShowLoadingState: "ShowLoadingState", showLoadingState: "showLoadingState", ReadReplyFromTop: "ReadReplyFromTop", readReplyFromTop: "readReplyFromTop", ShowAgentRunDetails: "ShowAgentRunDetails", showAgentRunDetails: "showAgentRunDetails", ShowReactions: "ShowReactions", showReactions: "showReactions", ShowMessageRating: "ShowMessageRating", showMessageRating: "showMessageRating", AllowPinning: "AllowPinning", allowPinning: "allowPinning", AllowMessageEdit: "AllowMessageEdit", allowMessageEdit: "allowMessageEdit", AllowMessageDelete: "AllowMessageDelete", allowMessageDelete: "allowMessageDelete", ReadOnly: "ReadOnly", ReadOnlyMessage: "ReadOnlyMessage", ShowSuggestedPrompts: "ShowSuggestedPrompts", showSuggestedPrompts: "showSuggestedPrompts", ShowDateNavigation: "ShowDateNavigation", showDateNavigation: "showDateNavigation", AssistantDisplayName: "AssistantDisplayName", assistantDisplayName: "assistantDisplayName", AssistantAvatarUrl: "AssistantAvatarUrl", assistantAvatarUrl: "assistantAvatarUrl", IsNewConversation: "IsNewConversation", isNewConversation: "isNewConversation", PendingMessage: "PendingMessage", pendingMessage: "pendingMessage", PendingMessageConversationId: "PendingMessageConversationId", pendingMessageConversationId: "pendingMessageConversationId", PendingAttachments: "PendingAttachments", pendingAttachments: "pendingAttachments", PendingArtifactId: "PendingArtifactId", pendingArtifactId: "pendingArtifactId", PendingArtifactVersionNumber: "PendingArtifactVersionNumber", pendingArtifactVersionNumber: "pendingArtifactVersionNumber", PendingArtifactConversationId: "PendingArtifactConversationId", pendingArtifactConversationId: "pendingArtifactConversationId", OverlayMode: "OverlayMode", overlayMode: "overlayMode", ShowExportButton: "ShowExportButton", showExportButton: "showExportButton", ExportButtonLabel: "ExportButtonLabel", exportButtonLabel: "exportButtonLabel", ExportButtonIcon: "ExportButtonIcon", exportButtonIcon: "exportButtonIcon", ExportBranding: "ExportBranding", exportBranding: "exportBranding", ShowShareButton: "ShowShareButton", showShareButton: "showShareButton", ShowArtifactIndicator: "ShowArtifactIndicator", showArtifactIndicator: "showArtifactIndicator", AppContext: "AppContext", appContext: "appContext", DefaultAgentId: "DefaultAgentId", defaultAgentId: "defaultAgentId", AgentReplyMode: "AgentReplyMode", AllowedAgentIDs: "AllowedAgentIDs", MentionPeople: "MentionPeople", AgentHistoryFrom: "AgentHistoryFrom", AgentTurnHandler: "AgentTurnHandler", AutoNameConversation: "AutoNameConversation", EnableDecisionRouting: "EnableDecisionRouting", ApplicationScope: "ApplicationScope", applicationScope: "applicationScope", ApplicationId: "ApplicationId", applicationId: "applicationId", LinkedEntityId: "LinkedEntityId", linkedEntityId: "linkedEntityId", LinkedRecordId: "LinkedRecordId", linkedRecordId: "linkedRecordId", ShowAgentPicker: "ShowAgentPicker", showAgentPicker: "showAgentPicker", ShowAgentModePicker: "ShowAgentModePicker", showAgentModePicker: "showAgentModePicker", EmptyStateGreeting: "EmptyStateGreeting", emptyStateGreeting: "emptyStateGreeting", ShowSidebarToggle: "ShowSidebarToggle", showSidebarToggle: "showSidebarToggle", ShowAgentCharacter: "ShowAgentCharacter", showAgentCharacter: "showAgentCharacter", AgentCharacterConfig: "AgentCharacterConfig", agentCharacterConfig: "agentCharacterConfig", EmptyStateConfig: "EmptyStateConfig", emptyStateConfig: "emptyStateConfig", ShowDemonstrationSurface: "ShowDemonstrationSurface", showDemonstrationSurface: "showDemonstrationSurface", DemonstrationSurfaceContent: "DemonstrationSurfaceContent", demonstrationSurfaceContent: "demonstrationSurfaceContent", ComposerDraft: "ComposerDraft", composerDraft: "composerDraft", ComposerAgentMention: "ComposerAgentMention", composerAgentMention: "composerAgentMention" }, outputs: { BeforeAgentTurn: "BeforeAgentTurn", beforeAgentTurn: "beforeAgentTurn", AfterAgentTurn: "AfterAgentTurn", afterAgentTurn: "afterAgentTurn", BeforeToolInvoked: "BeforeToolInvoked", beforeToolInvoked: "beforeToolInvoked", AfterToolInvoked: "AfterToolInvoked", afterToolInvoked: "afterToolInvoked", BeforeResponseFormSubmitted: "BeforeResponseFormSubmitted", beforeResponseFormSubmitted: "beforeResponseFormSubmitted", AfterResponseFormSubmitted: "AfterResponseFormSubmitted", afterResponseFormSubmitted: "afterResponseFormSubmitted", BeforeStopClicked: "BeforeStopClicked", AfterStopClicked: "AfterStopClicked", SessionStarted: "SessionStarted", sessionStarted: "sessionStarted", SessionChannelStateChanged: "SessionChannelStateChanged", sessionChannelStateChanged: "sessionChannelStateChanged", SessionEnded: "SessionEnded", sessionEnded: "sessionEnded", ConversationRenamed: "ConversationRenamed", conversationRenamed: "conversationRenamed", OpenEntityRecord: "OpenEntityRecord", openEntityRecord: "openEntityRecord", RealtimeConversationReady: "RealtimeConversationReady", realtimeConversationReady: "realtimeConversationReady", navigationRequest: "navigationRequest", TaskClicked: "TaskClicked", taskClicked: "taskClicked", ArtifactLinkClicked: "ArtifactLinkClicked", artifactLinkClicked: "artifactLinkClicked", SidebarToggleClicked: "SidebarToggleClicked", sidebarToggleClicked: "sidebarToggleClicked", ConversationCreated: "ConversationCreated", conversationCreated: "conversationCreated", PendingArtifactConsumed: "PendingArtifactConsumed", pendingArtifactConsumed: "pendingArtifactConsumed", PendingMessageConsumed: "PendingMessageConsumed", pendingMessageConsumed: "pendingMessageConsumed", PendingMessageRequested: "PendingMessageRequested", pendingMessageRequested: "pendingMessageRequested", ComposerDraftConsumed: "ComposerDraftConsumed", composerDraftConsumed: "composerDraftConsumed", ComposerAgentMentionConsumed: "ComposerAgentMentionConsumed", composerAgentMentionConsumed: "composerAgentMentionConsumed" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 30, vars: 36, consts: [["titleBar", ""], ["titleName", ""], ["forksButton", ""], ["titleNameInput", ""], ["titleRenameButton", ""], ["emptyStateInput", ""], ["scrollContainer", ""], ["messageInput", ""], ["taskGraphRunView", ""], [1, "chat-area"], [1, "chat-agent-presence", 3, "chat-agent-presence--prominent"], [1, "chat-header"], [1, "chat-content-area"], [1, "chat-demonstration-stage"], [1, "chat-messages-pane"], [1, "chat-messages-wrapper"], [3, "saved", "cancelled", "isOpen", "artifact", "currentUser"], [3, "pinnedMessages", "isLoading", "AllowUnpin"], [3, "PanelID", "Summaries", "CurrentUserID"], [3, "cancelled", "exported", "branding", "isVisible", "conversation", "Scope", "currentUser"], [3, "Result", "Visible", "Context", "Adapter"], [3, "cancelled", "membersChanged", "isVisible", "conversation", "currentUser"], [1, "modal-overlay"], [3, "isOpen", "environmentId", "currentUser", "excludeCollectionIds", "artifactVersionId", "artifactName", "artifactVersionNumber"], [3, "data", "visible"], [3, "imageUrl", "alt", "fileName", "visible"], [1, "chat-agent-presence"], [3, "State", "AgentName", "AvatarUrl", "Mode"], [4, "ngTemplateOutlet", "ngTemplateOutletContext"], [1, "chat-header", 3, "keydown.escape"], [1, "chat-info"], ["title", "Show conversations", 1, "sidebar-toggle-btn"], [1, "shared-by-badge", 3, "title"], [1, "project-tag"], ["title", "View Test Run", 1, "test-indicator"], [1, "chat-actions", "chat-actions-buttons"], ["mjButton", "", "Variant", "flat", "Size", "sm", "aria-haspopup", "dialog", "title", "Forks in this conversation", 1, "forks-button", 3, "active"], ["title", "View pinned messages", 1, "pin-chip", 3, "active"], ["title", "View artifacts", 1, "artifact-indicator"], ["title", "View members", 1, "chat-members"], [3, "AgentID", "Disabled"], [3, "Conversation", "CurrentUser", "AllowedAgentIDs", "Disabled"], ["mjButton", "", "variant", "flat", "size", "sm", 3, "title"], ["mjButton", "", "variant", "flat", "size", "sm", 3, "shared", "title"], ["title", "Show conversations", 1, "sidebar-toggle-btn", 3, "click"], [1, "fas", "fa-table-columns"], [4, "ngTemplateOutlet"], [1, "fas", "fa-share-nodes"], [1, "project-tag", 3, "click"], [1, "fas", "fa-folder"], ["title", "View Test Run", 1, "test-indicator", 3, "click"], [1, "fas", "fa-flask"], ["mjButton", "", "Variant", "flat", "Size", "sm", "aria-haspopup", "dialog", "title", "Forks in this conversation", 1, "forks-button", 3, "click"], [1, "fa-solid", "fa-code-branch"], [1, "btn-label"], [1, "forks-count"], ["title", "View pinned messages", 1, "pin-chip", 3, "click"], [1, "fas", "fa-thumbtack"], [1, "pin-chip-count"], ["title", "View artifacts", 1, "artifact-indicator", 3, "click"], [1, "fas", "fa-cube"], [1, "artifact-badge"], ["title", "View members", 1, "chat-members", 3, "click"], [1, "fas", "fa-users"], [1, "members-badge"], [3, "PresetChanged", "AgentID", "Disabled"], ["mjButton", "", "variant", "flat", "size", "sm", 3, "click", "title"], [1, "chat-title-bar"], ["aria-label", "Breadcrumb", 1, "chat-title-path"], [1, "chat-title-crumbs"], ["aria-current", "page", 1, "chat-title-current"], ["aria-hidden", "true"], [1, "chat-title-crumb", "chat-title-ellipsis", 3, "collapses-wide"], [1, "chat-title-crumb"], ["mjButton", "", "Variant", "flat", "Size", "sm", "type", "button", 3, "click", "title"], [1, "chat-title-crumb-label"], ["aria-hidden", "true", 1, "fa-solid", "fa-chevron-right", "chat-title-sep"], [1, "chat-title-crumb", "chat-title-ellipsis"], ["mjButton", "", "Variant", "flat", "Size", "sm", "type", "button", "aria-label", "Show the whole path", "title", "Show the whole path", 3, "click"], ["type", "text", "maxlength", "255", 1, "chat-title-input", 3, "ngModel"], ["type", "text", "maxlength", "255", 1, "chat-title-input", 3, "ngModelChange", "keydown.enter", "keydown.escape", "blur", "ngModel"], [1, "chat-title", 3, "title"], ["mjButton", "", "Variant", "icon", "Size", "sm", "type", "button", 1, "chat-title-rename", 3, "title"], ["mjButton", "", "Variant", "icon", "Size", "sm", "type", "button", 1, "chat-title-rename", 3, "click", "title"], ["aria-hidden", "true", 1, "fa-solid", "fa-pen"], [1, "conversation-loading-state"], ["text", "Loading conversation...", "size", "large"], ["role", "status", 1, "read-only-banner"], [3, "currentUser", "initialDraft", "disabled", "showSidebarToggle", "overlayMode", "greeting", "showSuggestedPrompts", "enableAttachments", "enableMentions", "enableAgentMentions", "enableEntityMentions", "enableSkillCommands", "AllowedAgentIDs", "MentionPeople", "ComposerExtraTemplate", "maxAttachments", "maxAttachmentSizeBytes", "acceptedFileTypes"], [1, "fas", "fa-eye"], [3, "initialDraftApplied", "DraftStateChanged", "ComposerBlurred", "sidebarToggleClicked", "messageSent", "currentUser", "initialDraft", "disabled", "showSidebarToggle", "overlayMode", "greeting", "showSuggestedPrompts", "enableAttachments", "enableMentions", "enableAgentMentions", "enableEntityMentions", "enableSkillCommands", "AllowedAgentIDs", "MentionPeople", "ComposerExtraTemplate", "maxAttachments", "maxAttachmentSizeBytes", "acceptedFileTypes"], [1, "chat-messages-container"], [1, "chat-input-container"], [1, "chat-composer-extra"], [1, "message-input-container-wrapper"], [3, "initialDraftApplied", "DraftStateChanged", "ComposerBlurred", "emptyStateSubmit", "emptyStateMode", "initialDraft", "currentUser", "disabled", "ReadOnly", "appContext", "applicationId", "defaultAgentId", "enableAttachments", "enableMentions", "enableAgentMentions", "enableEntityMentions", "enableSkillCommands", "enablePlanMode", "enableRealtime", "AllowedAgentIDs", "MentionPeople", "maxAttachments", "maxAttachmentSizeBytes", "acceptedFileTypes"], ["role", "region", "aria-label", "Fork", 1, "fork-view-bar"], [1, "upload-indicator-overlay"], [1, "chat-messages-container", 3, "scroll", "keydown.escape"], [3, "OlderRequested", "DateJumpRequested", "ForkOpenRequested", "EditResendRequested", "RegenerateRequested", "ResendInPlaceRequested", "ForkRequested", "realtimeSessionOpenRequested", "deleteMessage", "BeforeStopClicked", "StopMessage", "testFeedbackMessage", "artifactClicked", "messageEdited", "openEntityRecord", "suggestedResponseSelected", "attachmentClicked", "diagnosticRequested", "LivenessCheckRequested", "messagePinToggled", "beforeResponseFormSubmitted", "afterResponseFormSubmitted", "TaskGraphPanelRequested", "ScrollToMessageRequested", "showEmptyFill", "showDateNavigation", "showAgentRunDetails", "showReactions", "showMessageRating", "allowPinning", "allowMessageEdit", "allowMessageDelete", "ReadOnly", "AllowStopRun", "InFlightCount", "assistantDisplayName", "assistantAvatarUrl", "messages", "HasMoreAbove", "IsLoadingOlder", "ScrollRoot", "conversation", "currentUser", "isProcessing", "artifactMap", "agentRunMap", "ratingsMap", "userAvatarMap", "attachmentsMap", "messageRendererTemplate", "messageExtraTemplate", "sessionMetaMap", "ForkChipMap", "ForkLayout", "CanFork", "InPlaceTurn"], [1, "scroll-to-bottom-icon", 2, "left", "50%"], [1, "loading-peripheral-placeholder"], ["role", "region", "aria-label", "Fork", 1, "fork-view-bar", 3, "keydown.escape"], ["size", "medium", 3, "text"], [1, "scroll-to-bottom-icon", 2, "left", "50%", 3, "click"], [1, "fas", "fa-arrow-down"], ["text", "Loading conversation data...", "size", "medium"], [3, "hidden", "initialDraft", "conversationId", "conversationName", "currentUser", "conversationHistory", "artifactsByDetailId", "systemArtifactsByDetailId", "agentRunsByDetailId", "appContext", "applicationId", "defaultAgentId", "conversationDefaultAgentId", "agentConfigurationPresetId", "AgentReplyMode", "AllowedAgentIDs", "MentionPeople", "AgentHistoryFrom", "TargetBranchID", "ResolveTargetBranch", "AgentTurnHandler", "AutoNameConversation", "EnableDecisionRouting", "inProgressMessageIds", "disabled", "ReadOnly", "enableAttachments", "enableMentions", "enableAgentMentions", "enableEntityMentions", "enableSkillCommands", "enablePlanMode", "enableRealtime", "Placeholder", "SendSlotMode", "StopCount", "StopLabel", "StatusText", "StatusElapsed", "maxAttachments", "maxAttachmentSizeBytes", "acceptedFileTypes", "initialMessage", "initialAttachments"], [1, "fork-composer-hint"], [3, "DraftStateChanged", "ComposerBlurred", "StopClicked", "initialMessageAutoSendStarted", "initialMessageAutoSendFailed", "messageSent", "MessageStreamed", "agentResponse", "agentRunDetected", "agentRunUpdate", "messageComplete", "artifactCreated", "conversationRenamed", "intentCheckStarted", "intentCheckCompleted", "beforeAgentTurn", "afterAgentTurn", "uploadStateChanged", "hidden", "initialDraft", "conversationId", "conversationName", "currentUser", "conversationHistory", "artifactsByDetailId", "systemArtifactsByDetailId", "agentRunsByDetailId", "appContext", "applicationId", "defaultAgentId", "conversationDefaultAgentId", "agentConfigurationPresetId", "AgentReplyMode", "AllowedAgentIDs", "MentionPeople", "AgentHistoryFrom", "TargetBranchID", "ResolveTargetBranch", "AgentTurnHandler", "AutoNameConversation", "EnableDecisionRouting", "inProgressMessageIds", "disabled", "ReadOnly", "enableAttachments", "enableMentions", "enableAgentMentions", "enableEntityMentions", "enableSkillCommands", "enablePlanMode", "enableRealtime", "Placeholder", "SendSlotMode", "StopCount", "StopLabel", "StatusText", "StatusElapsed", "maxAttachments", "maxAttachmentSizeBytes", "acceptedFileTypes", "initialMessage", "initialAttachments"], [1, "resize-handle"], [1, "chat-artifact-pane"], [3, "closed", "saveToCollectionRequested", "navigateToLink", "shareRequested", "maximizeToggled", "openEntityRecord", "navigationRequest", "analyzeRequested", "applyFormRequested", "artifactId", "currentUser", "environmentId", "versionNumber", "viewContext", "Scope", "canShare", "canEdit", "isMaximized", "refreshTrigger"], [1, "resize-handle", 3, "mousedown", "touchstart"], [1, "chat-artifact-pane", "chat-task-graph-pane"], [1, "task-graph-pane-header"], [1, "task-graph-pane-title-group"], [1, "task-graph-pane-icon"], [1, "fa-solid", "fa-diagram-project"], [1, "task-graph-pane-titles"], [1, "task-graph-pane-title"], [1, "task-graph-pane-subtitle"], [1, "task-graph-pane-actions"], ["type", "button", "title", "Save this task graph as a reusable Draft Flow Agent workflow", 1, "task-graph-pane-save-btn", 3, "click", "disabled"], [1, "fa-solid"], ["type", "button", 1, "task-graph-pane-btn", 3, "click", "title"], ["type", "button", "title", "Close Task Graph panel", 1, "task-graph-pane-btn", 3, "click"], [1, "fa-solid", "fa-xmark"], [1, "task-graph-pane-body"], [3, "ParentTaskID", "WorkflowName", "LiveUpdates", "ShowVariables", "Height"], [3, "closed", "jumpRequested", "unpinRequested", "pinnedMessages", "isLoading", "AllowUnpin"], [3, "ForkSelected", "Closed", "PanelID", "Summaries", "CurrentUserID"], [3, "NavigateRequest", "StartLiveRequested", "ReviewClosed", "AgentName", "Hidden", "CurrentUser", "EnvironmentID", "ReviewData", "AllowStartLive", "Chrome", "Compact", "ShowDevLinks", "ShowDensityPicker"], ["type", "button", "title", "Return to the live call", "aria-label", "Return to the live call", 1, "voice-call-pill"], ["type", "button", "title", "Return to the live call", "aria-label", "Return to the live call", 1, "voice-call-pill", 3, "click"], ["aria-hidden", "true", 1, "voice-call-pill__pulse"], ["aria-hidden", "true", 1, "fa-solid", "fa-phone-volume"], [1, "voice-call-pill__text"], [1, "voice-call-pill__name"], [1, "voice-call-pill__hint"], [1, "modal-overlay", 3, "click"], [1, "modal-content", "project-selector-modal", 3, "click"], [1, "modal-header"], [1, "modal-close-btn", 3, "click"], [1, "fas", "fa-times"], [1, "modal-body"], [3, "projectSelected", "environmentId", "currentUser", "selectedProjectId"], [1, "modal-content", "artifacts-modal", 3, "click"], [1, "modal-header-actions"], ["title", "Toggle system artifacts visibility", 1, "toggle-system-btn", 3, "active"], [1, "modal-body", "artifacts-grid"], ["Icon", "fa-solid fa-cube", "Title", "No artifacts in this conversation yet", 1, "artifacts-empty-fill"], [1, "artifact-modal-card", 3, "expanded", "system-artifact"], ["title", "Toggle system artifacts visibility", 1, "toggle-system-btn", 3, "click"], [1, "fas", "fa-cog"], [1, "artifact-modal-card"], [1, "artifact-card-header", 3, "click"], [1, "artifact-modal-icon"], [1, "fas", "fa-file-code"], [1, "artifact-modal-info"], [1, "artifact-modal-title"], [1, "artifact-modal-meta"], [1, "expand-btn"], [1, "artifact-modal-action"], [1, "fas", "fa-external-link-alt"], [1, "artifact-versions-list"], [1, "expand-btn", 3, "click"], [1, "fas"], [1, "artifact-version-item"], [1, "artifact-version-item", 3, "click"], [1, "version-badge"], [1, "version-open-text"], [1, "fas", "fa-arrow-right"], [3, "completed", "cancelled", "isOpen", "environmentId", "currentUser", "excludeCollectionIds", "artifactVersionId", "artifactName", "artifactVersionNumber"], [3, "closed", "data", "visible"], [3, "closed", "imageUrl", "alt", "fileName", "visible"]], template: function ConversationChatAreaComponent_Template(rf, ctx) { if (rf & 1) {
|
|
9256
|
-
i0.ɵɵelementStart(0, "div",
|
|
9257
|
-
i0.ɵɵconditionalCreate(1, ConversationChatAreaComponent_Conditional_1_Template, 3, 3, "div",
|
|
9258
|
-
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);
|
|
9259
10116
|
i0.ɵɵtemplate(4, ConversationChatAreaComponent_ng_template_4_Template, 3, 1, "ng-template", null, 0, i0.ɵɵtemplateRefExtractor)(6, ConversationChatAreaComponent_ng_template_6_Template, 2, 1, "ng-template", null, 1, i0.ɵɵtemplateRefExtractor);
|
|
9260
|
-
i0.ɵɵelementStart(8, "div",
|
|
9261
|
-
i0.ɵɵconditionalCreate(9, ConversationChatAreaComponent_Conditional_9_Template, 2, 6, "div",
|
|
9262
|
-
i0.ɵɵelementStart(10, "div",
|
|
9263
|
-
i0.ɵɵconditionalCreate(11, ConversationChatAreaComponent_Conditional_11_Template, 1, 1)(12, ConversationChatAreaComponent_Conditional_12_Template, 3, 1)(13, ConversationChatAreaComponent_Conditional_13_Template, 5, 1, "div",
|
|
10117
|
+
i0.ɵɵelementStart(8, "div", 13);
|
|
10118
|
+
i0.ɵɵconditionalCreate(9, ConversationChatAreaComponent_Conditional_9_Template, 2, 6, "div", 14);
|
|
10119
|
+
i0.ɵɵelementStart(10, "div", 15);
|
|
10120
|
+
i0.ɵɵconditionalCreate(11, ConversationChatAreaComponent_Conditional_11_Template, 1, 1)(12, ConversationChatAreaComponent_Conditional_12_Template, 3, 1)(13, ConversationChatAreaComponent_Conditional_13_Template, 5, 1, "div", 16)(14, ConversationChatAreaComponent_Conditional_14_Template, 11, 37, "div", 16);
|
|
9264
10121
|
i0.ɵɵelementEnd();
|
|
9265
10122
|
i0.ɵɵconditionalCreate(15, ConversationChatAreaComponent_Conditional_15_Template, 3, 15);
|
|
9266
10123
|
i0.ɵɵconditionalCreate(16, ConversationChatAreaComponent_Conditional_16_Template, 23, 24);
|
|
9267
|
-
i0.ɵɵ
|
|
9268
|
-
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(); });
|
|
9269
10127
|
i0.ɵɵelementEnd();
|
|
9270
|
-
i0.ɵɵconditionalCreate(
|
|
9271
|
-
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);
|
|
9272
10130
|
i0.ɵɵelementEnd();
|
|
9273
|
-
i0.ɵɵconditionalCreate(
|
|
9274
|
-
i0.ɵɵpipe(
|
|
10131
|
+
i0.ɵɵconditionalCreate(21, ConversationChatAreaComponent_Conditional_21_Template, 4, 15);
|
|
10132
|
+
i0.ɵɵpipe(22, "async");
|
|
9275
10133
|
i0.ɵɵelementEnd();
|
|
9276
|
-
i0.ɵɵelementStart(
|
|
9277
|
-
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(); });
|
|
9278
10136
|
i0.ɵɵelementEnd();
|
|
9279
|
-
i0.ɵɵelementStart(
|
|
9280
|
-
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); });
|
|
9281
10139
|
i0.ɵɵelementEnd();
|
|
9282
|
-
i0.ɵɵelementStart(
|
|
9283
|
-
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; });
|
|
9284
10142
|
i0.ɵɵelementEnd();
|
|
9285
|
-
i0.ɵɵconditionalCreate(
|
|
9286
|
-
i0.ɵɵconditionalCreate(
|
|
9287
|
-
i0.ɵɵconditionalCreate(
|
|
9288
|
-
i0.ɵɵconditionalCreate(
|
|
9289
|
-
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);
|
|
9290
10148
|
} if (rf & 2) {
|
|
9291
10149
|
let tmp_3_0;
|
|
9292
10150
|
i0.ɵɵadvance();
|
|
@@ -9298,7 +10156,7 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
9298
10156
|
i0.ɵɵadvance();
|
|
9299
10157
|
i0.ɵɵconditional(ctx.isDemonstrationActive ? 9 : -1);
|
|
9300
10158
|
i0.ɵɵadvance();
|
|
9301
|
-
i0.ɵɵclassProp("full-width", !ctx.showArtifactPanel && !ctx.SelectedTaskGraphPanel)("hidden", ctx.isArtifactPaneMaximized);
|
|
10159
|
+
i0.ɵɵclassProp("full-width", !ctx.showArtifactPanel && !ctx.SelectedTaskGraphPanel && !ctx.ShowRemoteBrowserPanel)("hidden", ctx.isArtifactPaneMaximized);
|
|
9302
10160
|
i0.ɵɵadvance();
|
|
9303
10161
|
i0.ɵɵconditional(ctx.isLoadingConversation ? 11 : (ctx.isNewConversation || !ctx.conversationId) && !ctx.suppressNewConversationEmptyState ? 12 : (ctx.isNewConversation || !ctx.conversationId) && ctx.suppressNewConversationEmptyState ? 13 : 14);
|
|
9304
10162
|
i0.ɵɵadvance(4);
|
|
@@ -9306,13 +10164,15 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
9306
10164
|
i0.ɵɵadvance();
|
|
9307
10165
|
i0.ɵɵconditional(ctx.SelectedTaskGraphPanel ? 16 : -1);
|
|
9308
10166
|
i0.ɵɵadvance();
|
|
10167
|
+
i0.ɵɵconditional(ctx.ShowRemoteBrowserPanel ? 17 : -1);
|
|
10168
|
+
i0.ɵɵadvance();
|
|
9309
10169
|
i0.ɵɵproperty("isOpen", ctx.isArtifactShareModalOpen)("artifact", ctx.artifactToShare)("currentUser", ctx.currentUser);
|
|
9310
10170
|
i0.ɵɵadvance();
|
|
9311
|
-
i0.ɵɵconditional(ctx.allowPinning && ctx.showPinsPanel ?
|
|
10171
|
+
i0.ɵɵconditional(ctx.allowPinning && ctx.showPinsPanel ? 19 : -1);
|
|
9312
10172
|
i0.ɵɵadvance();
|
|
9313
|
-
i0.ɵɵconditional(ctx.ShowForksPopover ?
|
|
10173
|
+
i0.ɵɵconditional(ctx.ShowForksPopover ? 20 : -1);
|
|
9314
10174
|
i0.ɵɵadvance();
|
|
9315
|
-
i0.ɵɵconditional(i0.ɵɵpipeBind1(
|
|
10175
|
+
i0.ɵɵconditional(i0.ɵɵpipeBind1(22, 35, ctx.RealtimeSession.Active$) || ctx.RealtimeReview ? 21 : -1);
|
|
9316
10176
|
i0.ɵɵadvance(2);
|
|
9317
10177
|
i0.ɵɵproperty("branding", ctx.exportBranding)("isVisible", ctx.showExportModal)("conversation", ctx.conversation || undefined)("Scope", ctx.ExportScope)("currentUser", ctx.currentUser);
|
|
9318
10178
|
i0.ɵɵadvance();
|
|
@@ -9320,20 +10180,20 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
9320
10180
|
i0.ɵɵadvance();
|
|
9321
10181
|
i0.ɵɵproperty("isVisible", ctx.showMembersModal)("conversation", ctx.conversation || undefined)("currentUser", ctx.currentUser);
|
|
9322
10182
|
i0.ɵɵadvance();
|
|
9323
|
-
i0.ɵɵconditional(ctx.showProjectSelector && ctx.conversation ?
|
|
10183
|
+
i0.ɵɵconditional(ctx.showProjectSelector && ctx.conversation ? 26 : -1);
|
|
9324
10184
|
i0.ɵɵadvance();
|
|
9325
|
-
i0.ɵɵconditional(ctx.showArtifactsModal ?
|
|
10185
|
+
i0.ɵɵconditional(ctx.showArtifactsModal ? 27 : -1);
|
|
9326
10186
|
i0.ɵɵadvance();
|
|
9327
|
-
i0.ɵɵconditional(ctx.showCollectionPicker ?
|
|
10187
|
+
i0.ɵɵconditional(ctx.showCollectionPicker ? 28 : -1);
|
|
9328
10188
|
i0.ɵɵadvance();
|
|
9329
|
-
i0.ɵɵconditional(ctx.testFeedbackDialogData ?
|
|
10189
|
+
i0.ɵɵconditional(ctx.testFeedbackDialogData ? 29 : -1);
|
|
9330
10190
|
i0.ɵɵadvance();
|
|
9331
|
-
i0.ɵɵconditional(ctx.showImageViewer ?
|
|
9332
|
-
} }, dependencies: [i13.NgTemplateOutlet, i14.DefaultValueAccessor, i14.NgControlStatus, i14.MaxLengthValidator, i14.NgModel, i15.TaskGraphRunViewComponent, i16.MJButtonDirective, i16.MJEmptyStateComponent, i10.ArtifactViewerPanelComponent, i17.TestFeedbackDialogComponent, i18.LoadingComponent, i19.GenericShareDialogComponent, i20.ArtifactCollectionPickerModalComponent, i21.ArtifactShareModalComponent, i22.MJChatAgentPresenceDefaultComponent, i23.RealtimeSessionOverlayComponent, i24.MessageListComponent, i25.MessageInputComponent, i26.ConversationEmptyStateComponent, i27.ConversationAgentPickerComponent, i28.ConversationModePickerComponent, i29.ProjectSelectorComponent, i30.MembersModalComponent, i31.ExportModalComponent, i32.ImageViewerComponent, i33.PinnedMessagesPanelComponent, i34.ForksPopoverComponent, i13.AsyncPipe], styles: ["[_nghost-%COMP%] {\n display: flex;\n width: 100%;\n height: 100%;\n}\n\n.chat-area[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n overflow: hidden;\n \n position: relative;\n}\n\n.chat-header[_ngcontent-%COMP%] {\n flex-shrink: 0;\n padding: 12px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n display: flex;\n justify-content: space-between;\n align-items: center;\n gap: 16px;\n background: var(--mj-bg-surface-card);\n z-index: 10;\n box-shadow: var(--mj-shadow-sm);\n}\n\n\n\n\n\n\n.chat-agent-presence[_ngcontent-%COMP%] {\n flex-shrink: 0;\n padding: 8px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-card);\n display: flex;\n align-items: center;\n z-index: 11;\n}\n\n.chat-agent-presence--prominent[_ngcontent-%COMP%] {\n padding: 16px 20px;\n justify-content: center;\n}\n\n.chat-info[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n flex: 1;\n min-width: 0;\n}\n\n\n.sidebar-toggle-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n background: transparent;\n border: none;\n border-radius: 6px;\n cursor: pointer;\n transition: all 0.15s ease;\n flex-shrink: 0;\n}\n\n.sidebar-toggle-btn[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-text-primary) 8%, transparent);\n}\n\n.sidebar-toggle-btn[_ngcontent-%COMP%]:active {\n background: color-mix(in srgb, var(--mj-text-primary) 12%, transparent);\n}\n\n.sidebar-toggle-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary);\n font-size: 18px;\n transition: color 0.15s ease;\n}\n\n.sidebar-toggle-btn[_ngcontent-%COMP%]:hover i[_ngcontent-%COMP%] {\n color: var(--mj-text-primary);\n}\n\n\n.chat-title-bar[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: var(--mj-space-1);\n flex: 0 1 auto;\n min-width: 0;\n}\n\n.chat-title[_ngcontent-%COMP%] {\n flex: 0 1 auto;\n min-width: 0;\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.chat-title-path[_ngcontent-%COMP%] {\n min-width: 0;\n}\n\n.chat-title-crumbs[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: var(--mj-space-1);\n min-width: 0;\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n\n.chat-title-crumb[_ngcontent-%COMP%] {\n display: flex;\n flex: 0 100 auto;\n align-items: center;\n gap: var(--mj-space-1);\n min-width: 80px;\n}\n\n.chat-title-crumb.chat-title-ellipsis[_ngcontent-%COMP%] {\n flex: 0 0 auto;\n min-width: 0;\n}\n\n.chat-title-crumb[_ngcontent-%COMP%] > button[_ngcontent-%COMP%] {\n min-width: 0;\n color: var(--mj-text-muted);\n font-size: var(--mj-text-sm);\n font-weight: 500;\n}\n\n.chat-title-crumb-label[_ngcontent-%COMP%] {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n\n.chat-title-crumb.collapsed-wide[_ngcontent-%COMP%], \n.chat-title-ellipsis[_ngcontent-%COMP%]:not(.collapses-wide) {\n display: none;\n}\n\n.chat-title-sep[_ngcontent-%COMP%] {\n flex-shrink: 0;\n font-size: 12px;\n color: var(--mj-border-strong);\n}\n\n.chat-title-current[_ngcontent-%COMP%] {\n display: flex;\n flex: 0 1 auto;\n align-items: center;\n gap: var(--mj-space-1);\n min-width: 120px;\n}\n\n.chat-title-kind[_ngcontent-%COMP%] {\n flex-shrink: 0;\n margin: 0 var(--mj-space-1);\n color: var(--mj-status-info);\n}\n\n.chat-title-kind[data-kind='Edit'][_ngcontent-%COMP%] {\n color: var(--mj-status-warning);\n}\n\n.chat-title-kind[data-kind='Regenerate'][_ngcontent-%COMP%] {\n color: var(--mj-brand-tertiary);\n}\n\n.chat-title-bar[_ngcontent-%COMP%] .chat-title-rename[_ngcontent-%COMP%] {\n flex-shrink: 0;\n color: var(--mj-text-muted);\n opacity: 0.6;\n transition: opacity 0.15s ease, color 0.15s ease;\n}\n\n.chat-title-bar[_ngcontent-%COMP%]:hover .chat-title-rename[_ngcontent-%COMP%], \n.chat-title-bar[_ngcontent-%COMP%] .chat-title-rename[_ngcontent-%COMP%]:focus-visible {\n color: var(--mj-text-primary);\n opacity: 1;\n}\n\n.chat-title-input[_ngcontent-%COMP%] {\n flex: 0 1 360px;\n min-width: 120px;\n padding: var(--mj-space-1) var(--mj-space-2);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font: inherit;\n font-size: 16px;\n font-weight: 600;\n}\n\n.chat-title-input[_ngcontent-%COMP%]:focus-visible {\n outline: none;\n border-color: var(--mj-brand-primary);\n box-shadow: var(--mj-focus-ring);\n}\n\n.shared-by-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 3px 10px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n color: var(--mj-brand-primary);\n border-radius: 999px;\n font-size: 12px;\n font-weight: 500;\n flex-shrink: 0;\n max-width: 240px;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.shared-by-badge[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 10px;\n}\n\n.shared-by-badge[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.project-tag[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n border-radius: 16px;\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-text-muted);\n cursor: pointer;\n transition: all 0.2s;\n height: 28px;\n margin-left: 12px;\n}\n\n.project-tag[_ngcontent-%COMP%]:hover {\n background: var(--mj-border-default);\n border-color: var(--mj-text-muted);\n}\n\n.project-tag[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 10px;\n}\n\n.test-indicator[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n background: color-mix(in srgb, var(--mj-status-warning) 10%, var(--mj-bg-surface));\n border: 1px solid var(--mj-status-warning);\n border-radius: 16px;\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-status-warning);\n cursor: pointer;\n transition: all 0.2s;\n height: 28px;\n margin-left: 8px;\n}\n\n.test-indicator[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-status-warning) 20%, var(--mj-bg-surface));\n border-color: var(--mj-status-warning);\n}\n\n.test-indicator[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 10px;\n}\n\n\n.pin-chip[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 5px;\n padding: 5px 10px;\n background: color-mix(in srgb, var(--mj-status-warning) 12%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-status-warning) 45%, transparent);\n border-radius: 20px;\n color: var(--mj-status-warning-text, var(--mj-status-warning));\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s;\n}\n\n.pin-chip[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 11px;\n}\n\n.pin-chip[_ngcontent-%COMP%]:hover, \n.pin-chip.active[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 20%, var(--mj-bg-surface));\n border-color: var(--mj-status-warning);\n}\n\n.pin-chip-count[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 700;\n}\n\n.chat-members[_ngcontent-%COMP%], \n.artifact-indicator[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n position: relative;\n padding: 6px 8px;\n background: transparent;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n font-size: 14px;\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: all 150ms ease;\n}\n\n.chat-members[_ngcontent-%COMP%]:hover, \n.artifact-indicator[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n}\n\n\n.artifact-badge[_ngcontent-%COMP%], \n.members-badge[_ngcontent-%COMP%] {\n position: absolute;\n top: -6px;\n right: -6px;\n min-width: 16px;\n height: 16px;\n padding: 0 4px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n font-size: 10px;\n font-weight: 600;\n border-radius: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n line-height: 1;\n}\n\n.members-badge[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n}\n\n.ambient-agent-indicator[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n font-size: 13px;\n color: var(--mj-text-secondary);\n animation: _ngcontent-%COMP%_pulse 2s ease-in-out infinite;\n}\n\n.ambient-agent-indicator[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n@keyframes _ngcontent-%COMP%_pulse {\n 0%, 100% {\n opacity: 1;\n }\n 50% {\n opacity: 0.7;\n }\n}\n.chat-actions[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.action-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 12px;\n background: transparent;\n border: 1px solid var(--mj-border-default);\n cursor: pointer;\n border-radius: 6px;\n font-size: 13px;\n color: var(--mj-text-secondary);\n transition: all 150ms ease;\n}\n\n.action-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n}\n\n.share-btn.shared[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-color: var(--mj-brand-primary-hover);\n color: var(--mj-brand-primary-hover);\n}\n\n.share-btn.shared[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary-hover);\n}\n\n.chat-content-area[_ngcontent-%COMP%] {\n flex: 1;\n min-height: 0;\n overflow: hidden;\n display: flex;\n flex-direction: row;\n position: relative;\n}\n\n.chat-messages-pane[_ngcontent-%COMP%] {\n height: 100%;\n display: flex;\n flex-direction: column;\n min-width: min(300px, 100%); \n overflow: hidden;\n transition: width 0.3s ease;\n}\n\n.chat-messages-pane.full-width[_ngcontent-%COMP%] {\n width: 100%;\n}\n\n.chat-messages-pane[_ngcontent-%COMP%]:not(.full-width) {\n flex: 1;\n}\n\n.chat-messages-pane.hidden[_ngcontent-%COMP%] {\n display: none;\n}\n\n.resize-handle[_ngcontent-%COMP%] {\n width: 4px;\n background: transparent;\n cursor: col-resize;\n flex-shrink: 0;\n position: relative;\n transition: background-color 0.2s;\n}\n\n.resize-handle[_ngcontent-%COMP%]:hover {\n background: var(--mj-brand-primary);\n}\n\n.resize-handle[_ngcontent-%COMP%]::before {\n content: \"\";\n position: absolute;\n left: -4px;\n right: -4px;\n top: 0;\n bottom: 0;\n}\n\n.chat-artifact-pane[_ngcontent-%COMP%] {\n height: 100%;\n display: flex;\n flex-direction: column;\n background: var(--mj-bg-surface-sunken);\n overflow: hidden;\n flex-shrink: 0;\n}\n\n.chat-artifact-pane.maximized[_ngcontent-%COMP%] {\n width: 100% !important;\n}\n\n.chat-artifact-pane[_ngcontent-%COMP%] > mj-artifact-viewer-panel[_ngcontent-%COMP%] {\n display: flex;\n flex: 1;\n min-height: 0;\n overflow: hidden;\n}\n\n.chat-task-graph-pane[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border-left: 1px solid var(--mj-border-default);\n}\n\n.task-graph-pane-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n padding: 12px 16px;\n background: var(--mj-bg-surface-card);\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n\n.task-graph-pane-title-group[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n min-width: 0;\n}\n\n.task-graph-pane-icon[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n border-radius: 8px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, transparent);\n color: var(--mj-brand-primary);\n font-size: 14px;\n flex-shrink: 0;\n}\n\n.task-graph-pane-titles[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 1px;\n min-width: 0;\n}\n\n.task-graph-pane-title[_ngcontent-%COMP%] {\n font-size: 13.5px;\n font-weight: 600;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.task-graph-pane-subtitle[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-muted);\n}\n\n.task-graph-pane-actions[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n flex-shrink: 0;\n}\n\n.task-graph-pane-save-btn[_ngcontent-%COMP%] {\n height: 30px;\n padding: 0 10px;\n border-radius: 6px;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n font-weight: 500;\n border: 1px solid var(--mj-brand-primary);\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse, #ffffff);\n cursor: pointer;\n transition: opacity 0.15s ease, filter 0.15s ease;\n}\n\n.task-graph-pane-save-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n filter: brightness(1.06);\n}\n\n.task-graph-pane-save-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.55;\n cursor: not-allowed;\n}\n\n.task-graph-pane-btn[_ngcontent-%COMP%] {\n width: 30px;\n height: 30px;\n border-radius: 6px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border: 1px solid var(--mj-border-subtle);\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease;\n}\n\n.task-graph-pane-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n border-color: var(--mj-border-default);\n}\n\n.task-graph-pane-body[_ngcontent-%COMP%] {\n flex: 1;\n width: 100%;\n min-height: 0;\n min-width: 0;\n padding: 12px 16px 16px;\n box-sizing: border-box;\n overflow: hidden;\n display: flex;\n flex-direction: column;\n}\n\n.task-graph-pane-body[_ngcontent-%COMP%] > mj-task-graph-run-view[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n flex: 1;\n width: 100%;\n min-height: 0;\n min-width: 0;\n overflow: hidden;\n}\n\n.chat-messages-wrapper[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n min-height: 0;\n overflow: hidden;\n position: relative; \n}\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n.chat-demonstration-stage[_ngcontent-%COMP%] {\n height: 100%;\n display: flex;\n flex-direction: column;\n overflow: auto;\n background: var(--mj-bg-surface);\n border-right: 1px solid var(--mj-border-default);\n flex: 1;\n min-width: 0;\n}\n\n.chat-content-area.demonstration-mode[_ngcontent-%COMP%] .chat-messages-pane[_ngcontent-%COMP%], \n.chat-content-area.demonstration-mode[_ngcontent-%COMP%] .chat-messages-pane.full-width[_ngcontent-%COMP%] {\n flex: 0 0 320px;\n width: 320px;\n min-width: 0;\n}\n\n@media (max-width: 768px) {\n .chat-content-area.demonstration-mode[_ngcontent-%COMP%] {\n flex-direction: column;\n }\n\n .chat-content-area.demonstration-mode[_ngcontent-%COMP%] .chat-demonstration-stage[_ngcontent-%COMP%] {\n flex: 1 1 60%;\n border-right: none;\n border-bottom: 1px solid var(--mj-border-default);\n height: auto;\n }\n\n .chat-content-area.demonstration-mode[_ngcontent-%COMP%] .chat-messages-pane[_ngcontent-%COMP%], \n .chat-content-area.demonstration-mode[_ngcontent-%COMP%] .chat-messages-pane.full-width[_ngcontent-%COMP%] {\n flex: 1 1 40%;\n width: 100%;\n height: auto;\n }\n}\n\n\n.upload-indicator-overlay[_ngcontent-%COMP%] {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 1rem 1.5rem;\n background: color-mix(in srgb, var(--mj-bg-surface-card) 95%, transparent);\n border-radius: 12px;\n box-shadow: var(--mj-shadow-md);\n z-index: 100;\n pointer-events: none;\n}\n\n.chat-messages-container[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n background: var(--mj-bg-surface-card);\n min-height: 0;\n position: relative;\n}\n\n.scroll-to-bottom-icon[_ngcontent-%COMP%] {\n position: sticky;\n bottom: 21px;\n left: 50%;\n transform: translateX(-50%);\n width: 40px;\n height: 40px;\n margin-top: -40px;\n margin-left: auto;\n margin-right: auto;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n box-shadow: var(--mj-shadow-md);\n transition: all 0.2s ease;\n z-index: 100;\n pointer-events: auto;\n}\n\n.scroll-to-bottom-icon[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-brand-primary);\n transform: translateX(-50%) translateY(-2px);\n box-shadow: color-mix(in srgb, var(--mj-brand-primary) 20%, transparent) 0 4px 12px;\n}\n\n.scroll-to-bottom-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary);\n font-size: 16px;\n transition: color 0.2s;\n}\n\n.scroll-to-bottom-icon[_ngcontent-%COMP%]:hover i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.chat-input-container[_ngcontent-%COMP%] {\n flex-shrink: 0;\n background: var(--mj-bg-surface-card);\n padding: 0 1.25rem 1.25rem 1.25rem;\n overflow: visible;\n}\n\n\n.chat-composer-extra[_ngcontent-%COMP%] {\n margin-bottom: 0.5rem;\n}\n\n.read-only-banner[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n margin: 0 1.25rem 0.5rem 1.25rem;\n padding: 8px 12px;\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, transparent);\n color: var(--mj-text-secondary);\n border-radius: 6px;\n font-size: 12px;\n}\n\n.read-only-banner[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n font-size: 12px;\n}\n\n.loading-peripheral-placeholder[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: 140px;\n padding: 24px;\n background: color-mix(in srgb, var(--mj-bg-surface-card) 50%, transparent);\n backdrop-filter: blur(2px);\n border-radius: 12px;\n margin: 12px;\n animation: _ngcontent-%COMP%_fadeIn 0.2s ease-in-out;\n}\n\n.modal-overlay[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: var(--mj-bg-overlay);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n}\n\n.modal-content[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-card);\n border-radius: 8px;\n box-shadow: var(--mj-shadow-md);\n max-width: 90vw;\n max-height: 90vh;\n display: flex;\n flex-direction: column;\n}\n\n.project-selector-modal[_ngcontent-%COMP%] {\n width: 600px;\n height: 500px;\n}\n\n.modal-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.modal-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 18px;\n font-weight: 600;\n}\n\n.modal-header-actions[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.toggle-system-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n cursor: pointer;\n color: var(--mj-text-secondary);\n padding: 6px 12px;\n border-radius: 6px;\n font-size: 13px;\n font-weight: 500;\n transition: all 0.2s;\n}\n\n.toggle-system-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-border-default);\n border-color: var(--mj-border-default);\n color: var(--mj-text-primary);\n}\n\n.toggle-system-btn.active[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.toggle-system-btn.active[_ngcontent-%COMP%]:hover {\n background: var(--mj-brand-primary-hover);\n border-color: var(--mj-brand-primary-hover);\n}\n\n.toggle-system-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n}\n\n.modal-close-btn[_ngcontent-%COMP%] {\n background: none;\n border: none;\n cursor: pointer;\n color: var(--mj-text-secondary);\n padding: 4px 8px;\n border-radius: 4px;\n transition: all 0.2s;\n}\n\n.modal-close-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n}\n\n.modal-body[_ngcontent-%COMP%] {\n flex: 1;\n overflow: auto;\n padding: 20px;\n}\n\n.artifacts-modal[_ngcontent-%COMP%] {\n width: 700px;\n max-height: 600px;\n}\n\n.artifacts-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));\n gap: 16px;\n}\n\n\n.artifacts-empty-fill[_ngcontent-%COMP%] {\n grid-column: 1/-1;\n}\n\n.artifact-modal-card[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n background: var(--mj-bg-surface-card);\n border: 1.5px solid var(--mj-border-default);\n border-radius: 12px;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n overflow: hidden;\n}\n\n.artifact-modal-card.expanded[_ngcontent-%COMP%] {\n border-color: var(--mj-brand-primary);\n}\n\n.artifact-modal-card.system-artifact[_ngcontent-%COMP%] {\n opacity: 0.85;\n border-color: var(--mj-border-default);\n border-style: dashed;\n position: relative;\n}\n\n.artifact-modal-card.system-artifact[_ngcontent-%COMP%]::before {\n content: \"SYSTEM\";\n position: absolute;\n top: 8px;\n right: 8px;\n font-size: 9px;\n font-weight: 600;\n color: var(--mj-text-muted);\n background: var(--mj-bg-surface-sunken);\n padding: 2px 6px;\n border-radius: 3px;\n letter-spacing: 0.5px;\n z-index: 10;\n}\n\n.artifact-modal-card.system-artifact[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-text-muted);\n box-shadow: var(--mj-shadow-md);\n}\n\n.artifact-card-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 16px;\n cursor: pointer;\n}\n\n.artifact-card-header[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.artifact-modal-card[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-brand-primary);\n box-shadow: var(--mj-shadow-md);\n transform: translateY(-2px);\n}\n\n.artifact-modal-icon[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-radius: 10px;\n color: var(--mj-brand-primary);\n flex-shrink: 0;\n}\n\n.artifact-modal-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 18px;\n}\n\n.artifact-modal-info[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.artifact-modal-title[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin-bottom: 4px;\n}\n\n.artifact-modal-meta[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-secondary);\n}\n\n.artifact-modal-action[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n transition: color 0.2s;\n}\n\n.artifact-modal-card[_ngcontent-%COMP%]:hover .artifact-modal-action[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.expand-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n border: none;\n background: transparent;\n color: var(--mj-text-secondary);\n cursor: pointer;\n border-radius: 6px;\n transition: all 0.2s;\n}\n.expand-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-brand-primary);\n}\n\n.artifact-versions-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n padding: 0 1rem 1rem 1rem;\n background: var(--mj-bg-surface-sunken);\n}\n\n.artifact-version-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 16px 12px 68px;\n cursor: pointer;\n transition: background 0.15s;\n}\n.artifact-version-item[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n}\n.artifact-version-item[_ngcontent-%COMP%] .version-badge[_ngcontent-%COMP%] {\n display: inline-block;\n padding: 4px 8px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n font-size: 12px;\n font-weight: 600;\n font-family: monospace;\n border-radius: 4px;\n}\n.artifact-version-item[_ngcontent-%COMP%] .version-open-text[_ngcontent-%COMP%] {\n flex: 1;\n font-size: 13px;\n color: var(--mj-text-secondary);\n}\n.artifact-version-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n font-size: 12px;\n}\n.artifact-version-item[_ngcontent-%COMP%]:hover .version-badge[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n.artifact-version-item[_ngcontent-%COMP%]:hover .version-open-text[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n.artifact-version-item[_ngcontent-%COMP%]:hover i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.loading-peripheral-content[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 16px 24px;\n background: var(--mj-bg-surface-card);\n border: 2px solid var(--mj-border-default);\n border-radius: 12px;\n box-shadow: var(--mj-shadow-md);\n color: var(--mj-text-secondary);\n font-size: 14px;\n font-weight: 500;\n}\n.loading-peripheral-content[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 20px;\n color: var(--mj-brand-primary);\n}\n\n@keyframes _ngcontent-%COMP%_fadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n.conversation-loading-state[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n height: 100%;\n width: 100%;\n}\n\n.loading-content[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n padding-top: 20px;\n gap: 16px;\n color: var(--mj-text-secondary);\n font-size: 15px;\n}\n.loading-content[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 32px;\n color: var(--mj-brand-primary);\n}\n.loading-content[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n font-weight: 500;\n}\n\n\n@media (max-width: 768px) {\n .chat-header[_ngcontent-%COMP%] {\n padding: 8px 12px;\n gap: 6px;\n flex-direction: row;\n flex-wrap: wrap;\n align-items: center;\n position: relative;\n }\n .chat-info[_ngcontent-%COMP%] {\n flex-direction: row;\n align-items: center;\n gap: 8px;\n flex: 1;\n min-width: 0;\n order: 1;\n }\n .chat-title-bar[_ngcontent-%COMP%] {\n flex: 1;\n }\n .chat-title[_ngcontent-%COMP%] {\n font-size: 15px;\n font-weight: 700;\n }\n \n .chat-title-crumb.path-middle[_ngcontent-%COMP%] {\n display: none;\n }\n .chat-title-ellipsis[_ngcontent-%COMP%]:not(.collapses-wide) {\n display: flex;\n }\n .project-tag[_ngcontent-%COMP%] {\n margin-left: 0;\n font-size: 10px;\n padding: 3px 8px;\n height: 24px;\n display: none; \n }\n .test-indicator[_ngcontent-%COMP%] {\n margin-left: 0;\n font-size: 10px;\n padding: 3px 8px;\n height: 24px;\n }\n \n .chat-actions-buttons[_ngcontent-%COMP%] {\n order: 2;\n flex-shrink: 0;\n }\n .chat-actions-buttons[_ngcontent-%COMP%] .action-btn[_ngcontent-%COMP%] {\n padding: 6px 8px;\n min-width: auto;\n }\n .chat-actions-buttons[_ngcontent-%COMP%] .action-btn[_ngcontent-%COMP%] .btn-label[_ngcontent-%COMP%] {\n display: none;\n }\n .chat-actions[_ngcontent-%COMP%] {\n flex-wrap: nowrap;\n }\n .chat-members[_ngcontent-%COMP%], \n .artifact-indicator[_ngcontent-%COMP%] {\n padding: 5px 7px;\n font-size: 13px;\n }\n .action-btn[_ngcontent-%COMP%] {\n padding: 6px 8px;\n font-size: 12px;\n }\n .ambient-agent-indicator[_ngcontent-%COMP%] {\n font-size: 12px;\n padding: 4px 8px;\n }\n .project-selector-modal[_ngcontent-%COMP%] {\n width: min(95vw, 600px);\n height: auto;\n }\n .artifacts-modal[_ngcontent-%COMP%] {\n width: min(95vw, 700px);\n }\n .artifacts-grid[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n }\n .chat-input-container[_ngcontent-%COMP%] {\n padding: 0 0.75rem 0.75rem 0.75rem;\n }\n .scroll-to-bottom-icon[_ngcontent-%COMP%] {\n bottom: 16px;\n width: 36px;\n height: 36px;\n }\n \n .chat-content-area[_ngcontent-%COMP%] {\n position: relative;\n }\n .chat-artifact-pane[_ngcontent-%COMP%] {\n position: fixed;\n left: 0;\n right: 0;\n top: 56px; \n bottom: 0;\n width: 100% !important;\n z-index: 100;\n background: var(--mj-bg-surface-card);\n }\n .resize-handle[_ngcontent-%COMP%] {\n display: none;\n }\n}\n\n@media (max-width: 480px) {\n .chat-header[_ngcontent-%COMP%] {\n padding: 6px 8px;\n gap: 4px;\n }\n .chat-title[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 700;\n }\n .project-tag[_ngcontent-%COMP%] {\n font-size: 9px;\n padding: 2px 6px;\n height: 20px;\n display: none;\n }\n .test-indicator[_ngcontent-%COMP%] {\n font-size: 9px;\n padding: 2px 6px;\n height: 20px;\n }\n .chat-members[_ngcontent-%COMP%], \n .artifact-indicator[_ngcontent-%COMP%] {\n padding: 4px 8px;\n font-size: 11px;\n }\n .action-btn[_ngcontent-%COMP%] {\n padding: 5px 7px;\n font-size: 11px;\n }\n .ambient-agent-indicator[_ngcontent-%COMP%] {\n font-size: 11px;\n padding: 3px 6px;\n }\n .project-selector-modal[_ngcontent-%COMP%], \n .artifacts-modal[_ngcontent-%COMP%] {\n width: 100vw;\n height: 100vh;\n border-radius: 0;\n }\n .chat-input-container[_ngcontent-%COMP%] {\n padding: 0 0.5rem 0.5rem 0.5rem;\n }\n .scroll-to-bottom-icon[_ngcontent-%COMP%] {\n bottom: 12px;\n width: 32px;\n height: 32px;\n }\n .scroll-to-bottom-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n }\n}\n\n\n.artifact-picker-overlay[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background: var(--mj-bg-overlay);\n z-index: 999;\n}\n\n.artifact-picker-panel[_ngcontent-%COMP%] {\n position: fixed;\n right: 0;\n top: 0;\n width: 360px;\n height: 100%;\n background: var(--mj-bg-surface);\n border-left: 1px solid var(--mj-border-default);\n z-index: 1000;\n display: flex;\n flex-direction: column;\n box-shadow: -4px 0 12px rgba(0, 0, 0, 0.1);\n animation: _ngcontent-%COMP%_slideInRight 0.2s ease-out;\n}\n\n@keyframes _ngcontent-%COMP%_slideInRight {\n from { transform: translateX(100%); }\n to { transform: translateX(0); }\n}\n\n.artifact-picker-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.artifact-picker-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.artifact-picker-close[_ngcontent-%COMP%] {\n background: none;\n border: none;\n cursor: pointer;\n padding: 4px 8px;\n color: var(--mj-text-muted);\n border-radius: 4px;\n}\n\n.artifact-picker-close[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n\n.artifact-picker-body[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n padding: 12px;\n}\n\n.artifact-picker-empty[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 40px 20px;\n text-align: center;\n color: var(--mj-text-muted);\n gap: 8px;\n}\n\n.artifact-picker-hint[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-disabled);\n}\n\n.artifact-picker-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.artifact-picker-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 10px 12px;\n border: 1px solid var(--mj-border-subtle);\n border-radius: 6px;\n background: var(--mj-bg-surface-card);\n cursor: pointer;\n text-align: left;\n width: 100%;\n transition: background 0.15s, border-color 0.15s;\n}\n\n.artifact-picker-item[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n border-color: var(--mj-brand-primary);\n}\n\n.artifact-picker-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 20px;\n width: 24px;\n text-align: center;\n flex-shrink: 0;\n}\n\n.artifact-picker-item[_ngcontent-%COMP%] i.fa-file-pdf[_ngcontent-%COMP%] { color: var(--mj-status-error); }\n.artifact-picker-item[_ngcontent-%COMP%] i.fa-file-excel[_ngcontent-%COMP%] { color: var(--mj-status-success); }\n.artifact-picker-item[_ngcontent-%COMP%] i.fa-file-word[_ngcontent-%COMP%] { color: var(--mj-brand-primary); }\n.artifact-picker-item[_ngcontent-%COMP%] i.fa-file[_ngcontent-%COMP%] { color: var(--mj-text-muted); }\n\n.artifact-picker-item-info[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n min-width: 0;\n}\n\n.artifact-picker-item-name[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.artifact-picker-item-meta[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-muted);\n}\n\n\n\n\n\n.voice-call-pill[_ngcontent-%COMP%] {\n position: absolute;\n right: 18px;\n bottom: 18px;\n z-index: 49; \n display: flex;\n align-items: center;\n gap: 10px;\n padding: 9px 16px 9px 13px;\n border-radius: var(--mj-radius-full, 9999px);\n border: 1px solid var(--mj-border-strong);\n background: var(--mj-bg-surface-elevated, var(--mj-bg-surface));\n color: var(--mj-text-primary);\n font-family: inherit;\n cursor: pointer;\n box-shadow: 0 8px 24px color-mix(in srgb, var(--mj-brand-primary) 18%, transparent);\n transition: border-color 150ms ease, box-shadow 150ms ease, transform 150ms ease;\n}\n.voice-call-pill[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 10px 28px color-mix(in srgb, var(--mj-brand-primary) 28%, transparent);\n transform: translateY(-1px);\n}\n.voice-call-pill[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n color: var(--mj-brand-primary);\n}\n.voice-call-pill__pulse[_ngcontent-%COMP%] {\n width: 9px;\n height: 9px;\n border-radius: 50%;\n background: var(--mj-status-success);\n flex-shrink: 0;\n animation: _ngcontent-%COMP%_voice-pill-pulse 1.6s ease-in-out infinite;\n}\n.voice-call-pill__text[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n line-height: 1.25;\n}\n.voice-call-pill__name[_ngcontent-%COMP%] {\n font-size: 12.5px;\n font-weight: 700;\n}\n.voice-call-pill__hint[_ngcontent-%COMP%] {\n font-size: 10.5px;\n color: var(--mj-text-muted);\n}\n@keyframes _ngcontent-%COMP%_voice-pill-pulse {\n 0%, 100% {\n box-shadow: 0 0 0 0 color-mix(in srgb, var(--mj-status-success) 45%, transparent);\n }\n 50% {\n box-shadow: 0 0 0 5px color-mix(in srgb, var(--mj-status-success) 0%, transparent);\n }\n}\n\n\n.fork-view-bar[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n padding: var(--mj-space-2) var(--mj-space-4);\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n}\n.fork-composer-hint[_ngcontent-%COMP%] {\n padding: var(--mj-space-1) var(--mj-space-4) 0;\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n}\n.chat-actions-buttons[_ngcontent-%COMP%] > .forks-button[_ngcontent-%COMP%] .forks-count[_ngcontent-%COMP%] {\n margin-left: var(--mj-space-1);\n padding: 0 var(--mj-space-2);\n border-radius: var(--mj-radius-full);\n background: var(--mj-brand-primary);\n color: var(--mj-brand-on-primary);\n font-size: var(--mj-text-xs);\n font-weight: 600;\n}\n.chat-actions-buttons[_ngcontent-%COMP%] > .forks-button.active[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}"] });
|
|
10191
|
+
i0.ɵɵconditional(ctx.showImageViewer ? 30 : -1);
|
|
10192
|
+
} }, dependencies: [i13.NgTemplateOutlet, i14.DefaultValueAccessor, i14.NgControlStatus, i14.MaxLengthValidator, i14.NgModel, i15.TaskGraphRunViewComponent, i16.MJButtonDirective, i16.MJEmptyStateComponent, i10.ArtifactViewerPanelComponent, i17.TestFeedbackDialogComponent, i18.LoadingComponent, i19.GenericShareDialogComponent, i20.ArtifactCollectionPickerModalComponent, i21.ArtifactShareModalComponent, i22.MJChatAgentPresenceDefaultComponent, i23.RealtimeSessionOverlayComponent, i24.RemoteBrowserSurfaceComponent, i25.MessageListComponent, i26.MessageInputComponent, i27.ConversationEmptyStateComponent, i28.ConversationAgentPickerComponent, i29.ConversationModePickerComponent, i30.ProjectSelectorComponent, i31.MembersModalComponent, i32.ExportModalComponent, i33.ImageViewerComponent, i34.PinnedMessagesPanelComponent, i35.ForksPopoverComponent, i13.AsyncPipe], styles: ["[_nghost-%COMP%] {\n display: flex;\n width: 100%;\n height: 100%;\n}\n\n.chat-area[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n overflow: hidden;\n \n position: relative;\n}\n\n.chat-header[_ngcontent-%COMP%] {\n flex-shrink: 0;\n padding: 12px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n display: flex;\n justify-content: space-between;\n align-items: center;\n gap: 16px;\n background: var(--mj-bg-surface-card);\n z-index: 10;\n box-shadow: var(--mj-shadow-sm);\n}\n\n\n\n\n\n\n.chat-agent-presence[_ngcontent-%COMP%] {\n flex-shrink: 0;\n padding: 8px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-card);\n display: flex;\n align-items: center;\n z-index: 11;\n}\n\n.chat-agent-presence--prominent[_ngcontent-%COMP%] {\n padding: 16px 20px;\n justify-content: center;\n}\n\n.chat-info[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n flex: 1;\n min-width: 0;\n}\n\n\n.sidebar-toggle-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n background: transparent;\n border: none;\n border-radius: 6px;\n cursor: pointer;\n transition: all 0.15s ease;\n flex-shrink: 0;\n}\n\n.sidebar-toggle-btn[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-text-primary) 8%, transparent);\n}\n\n.sidebar-toggle-btn[_ngcontent-%COMP%]:active {\n background: color-mix(in srgb, var(--mj-text-primary) 12%, transparent);\n}\n\n.sidebar-toggle-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary);\n font-size: 18px;\n transition: color 0.15s ease;\n}\n\n.sidebar-toggle-btn[_ngcontent-%COMP%]:hover i[_ngcontent-%COMP%] {\n color: var(--mj-text-primary);\n}\n\n\n.chat-title-bar[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: var(--mj-space-1);\n flex: 0 1 auto;\n min-width: 0;\n}\n\n.chat-title[_ngcontent-%COMP%] {\n flex: 0 1 auto;\n min-width: 0;\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.chat-title-path[_ngcontent-%COMP%] {\n min-width: 0;\n}\n\n.chat-title-crumbs[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: var(--mj-space-1);\n min-width: 0;\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n\n.chat-title-crumb[_ngcontent-%COMP%] {\n display: flex;\n flex: 0 100 auto;\n align-items: center;\n gap: var(--mj-space-1);\n min-width: 80px;\n}\n\n.chat-title-crumb.chat-title-ellipsis[_ngcontent-%COMP%] {\n flex: 0 0 auto;\n min-width: 0;\n}\n\n.chat-title-crumb[_ngcontent-%COMP%] > button[_ngcontent-%COMP%] {\n min-width: 0;\n color: var(--mj-text-muted);\n font-size: var(--mj-text-sm);\n font-weight: 500;\n}\n\n.chat-title-crumb-label[_ngcontent-%COMP%] {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n\n.chat-title-crumb.collapsed-wide[_ngcontent-%COMP%], \n.chat-title-ellipsis[_ngcontent-%COMP%]:not(.collapses-wide) {\n display: none;\n}\n\n.chat-title-sep[_ngcontent-%COMP%] {\n flex-shrink: 0;\n font-size: 12px;\n color: var(--mj-border-strong);\n}\n\n.chat-title-current[_ngcontent-%COMP%] {\n display: flex;\n flex: 0 1 auto;\n align-items: center;\n gap: var(--mj-space-1);\n min-width: 120px;\n}\n\n.chat-title-kind[_ngcontent-%COMP%] {\n flex-shrink: 0;\n margin: 0 var(--mj-space-1);\n color: var(--mj-status-info);\n}\n\n.chat-title-kind[data-kind='Edit'][_ngcontent-%COMP%] {\n color: var(--mj-status-warning);\n}\n\n.chat-title-kind[data-kind='Regenerate'][_ngcontent-%COMP%] {\n color: var(--mj-brand-tertiary);\n}\n\n.chat-title-bar[_ngcontent-%COMP%] .chat-title-rename[_ngcontent-%COMP%] {\n flex-shrink: 0;\n color: var(--mj-text-muted);\n opacity: 0.6;\n transition: opacity 0.15s ease, color 0.15s ease;\n}\n\n.chat-title-bar[_ngcontent-%COMP%]:hover .chat-title-rename[_ngcontent-%COMP%], \n.chat-title-bar[_ngcontent-%COMP%] .chat-title-rename[_ngcontent-%COMP%]:focus-visible {\n color: var(--mj-text-primary);\n opacity: 1;\n}\n\n.chat-title-input[_ngcontent-%COMP%] {\n flex: 0 1 360px;\n min-width: 120px;\n padding: var(--mj-space-1) var(--mj-space-2);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font: inherit;\n font-size: 16px;\n font-weight: 600;\n}\n\n.chat-title-input[_ngcontent-%COMP%]:focus-visible {\n outline: none;\n border-color: var(--mj-brand-primary);\n box-shadow: var(--mj-focus-ring);\n}\n\n.with-chip[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: var(--mj-space-1-5);\n padding: 2px var(--mj-space-2);\n border-radius: var(--mj-radius-full);\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-subtle);\n color: var(--mj-text-secondary);\n font-size: var(--mj-text-xs);\n line-height: var(--mj-leading-tight);\n flex-shrink: 0;\n}\n\n.with-chip[_ngcontent-%COMP%] .dot[_ngcontent-%COMP%] {\n width: 6px;\n height: 6px;\n border-radius: var(--mj-radius-full);\n background: var(--agent-accent, var(--mj-brand-primary));\n transition: background-color 240ms cubic-bezier(0.22, 1, 0.36, 1);\n flex-shrink: 0;\n}\n\n.with-chip[_ngcontent-%COMP%] b[_ngcontent-%COMP%] {\n color: var(--mj-text-primary);\n font-weight: var(--mj-font-semibold);\n}\n\n@media (prefers-reduced-motion: reduce) {\n .with-chip[_ngcontent-%COMP%] .dot[_ngcontent-%COMP%] {\n transition: none;\n }\n}\n\n.shared-by-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 3px 10px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n color: var(--mj-brand-primary);\n border-radius: 999px;\n font-size: 12px;\n font-weight: 500;\n flex-shrink: 0;\n max-width: 240px;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.shared-by-badge[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 10px;\n}\n\n.shared-by-badge[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.project-tag[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n border-radius: 16px;\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-text-muted);\n cursor: pointer;\n transition: all 0.2s;\n height: 28px;\n margin-left: 12px;\n}\n\n.project-tag[_ngcontent-%COMP%]:hover {\n background: var(--mj-border-default);\n border-color: var(--mj-text-muted);\n}\n\n.project-tag[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 10px;\n}\n\n.test-indicator[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n background: color-mix(in srgb, var(--mj-status-warning) 10%, var(--mj-bg-surface));\n border: 1px solid var(--mj-status-warning);\n border-radius: 16px;\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-status-warning);\n cursor: pointer;\n transition: all 0.2s;\n height: 28px;\n margin-left: 8px;\n}\n\n.test-indicator[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-status-warning) 20%, var(--mj-bg-surface));\n border-color: var(--mj-status-warning);\n}\n\n.test-indicator[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 10px;\n}\n\n\n.pin-chip[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 5px;\n padding: 5px 10px;\n background: color-mix(in srgb, var(--mj-status-warning) 12%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-status-warning) 45%, transparent);\n border-radius: 20px;\n color: var(--mj-status-warning-text, var(--mj-status-warning));\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s;\n}\n\n.pin-chip[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 11px;\n}\n\n.pin-chip[_ngcontent-%COMP%]:hover, \n.pin-chip.active[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 20%, var(--mj-bg-surface));\n border-color: var(--mj-status-warning);\n}\n\n.pin-chip-count[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 700;\n}\n\n.chat-members[_ngcontent-%COMP%], \n.artifact-indicator[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n position: relative;\n padding: 6px 8px;\n background: transparent;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n font-size: 14px;\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: all 150ms ease;\n}\n\n.chat-members[_ngcontent-%COMP%]:hover, \n.artifact-indicator[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n}\n\n\n.artifact-badge[_ngcontent-%COMP%], \n.members-badge[_ngcontent-%COMP%] {\n position: absolute;\n top: -6px;\n right: -6px;\n min-width: 16px;\n height: 16px;\n padding: 0 4px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n font-size: 10px;\n font-weight: 600;\n border-radius: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n line-height: 1;\n}\n\n.members-badge[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n}\n\n.ambient-agent-indicator[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n font-size: 13px;\n color: var(--mj-text-secondary);\n animation: _ngcontent-%COMP%_pulse 2s ease-in-out infinite;\n}\n\n.ambient-agent-indicator[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n@keyframes _ngcontent-%COMP%_pulse {\n 0%, 100% {\n opacity: 1;\n }\n 50% {\n opacity: 0.7;\n }\n}\n.chat-actions[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.action-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 12px;\n background: transparent;\n border: 1px solid var(--mj-border-default);\n cursor: pointer;\n border-radius: 6px;\n font-size: 13px;\n color: var(--mj-text-secondary);\n transition: all 150ms ease;\n}\n\n.action-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n}\n\n.share-btn.shared[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-color: var(--mj-brand-primary-hover);\n color: var(--mj-brand-primary-hover);\n}\n\n.share-btn.shared[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary-hover);\n}\n\n.chat-content-area[_ngcontent-%COMP%] {\n flex: 1;\n min-height: 0;\n overflow: hidden;\n display: flex;\n flex-direction: row;\n position: relative;\n}\n\n.chat-messages-pane[_ngcontent-%COMP%] {\n height: 100%;\n display: flex;\n flex-direction: column;\n min-width: min(300px, 100%); \n overflow: hidden;\n transition: width 0.3s ease;\n}\n\n.chat-messages-pane.full-width[_ngcontent-%COMP%] {\n width: 100%;\n}\n\n.chat-messages-pane[_ngcontent-%COMP%]:not(.full-width) {\n flex: 1;\n}\n\n.chat-messages-pane.hidden[_ngcontent-%COMP%] {\n display: none;\n}\n\n.resize-handle[_ngcontent-%COMP%] {\n width: 4px;\n background: transparent;\n cursor: col-resize;\n flex-shrink: 0;\n position: relative;\n transition: background-color 0.2s;\n}\n\n.resize-handle[_ngcontent-%COMP%]:hover {\n background: var(--mj-brand-primary);\n}\n\n.resize-handle[_ngcontent-%COMP%]::before {\n content: \"\";\n position: absolute;\n left: -4px;\n right: -4px;\n top: 0;\n bottom: 0;\n}\n\n.chat-artifact-pane[_ngcontent-%COMP%] {\n height: 100%;\n display: flex;\n flex-direction: column;\n background: var(--mj-bg-surface-sunken);\n overflow: hidden;\n flex-shrink: 0;\n}\n\n.chat-artifact-pane.maximized[_ngcontent-%COMP%] {\n width: 100% !important;\n}\n\n.chat-artifact-pane[_ngcontent-%COMP%] > mj-artifact-viewer-panel[_ngcontent-%COMP%] {\n display: flex;\n flex: 1;\n min-height: 0;\n overflow: hidden;\n}\n\n.chat-task-graph-pane[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border-left: 1px solid var(--mj-border-default);\n}\n\n.task-graph-pane-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n padding: 12px 16px;\n background: var(--mj-bg-surface-card);\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n\n.task-graph-pane-title-group[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n min-width: 0;\n}\n\n.task-graph-pane-icon[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n border-radius: 8px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, transparent);\n color: var(--mj-brand-primary);\n font-size: 14px;\n flex-shrink: 0;\n}\n\n.task-graph-pane-titles[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 1px;\n min-width: 0;\n}\n\n.task-graph-pane-title[_ngcontent-%COMP%] {\n font-size: 13.5px;\n font-weight: 600;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.task-graph-pane-subtitle[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-muted);\n}\n\n.task-graph-pane-actions[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n flex-shrink: 0;\n}\n\n.task-graph-pane-save-btn[_ngcontent-%COMP%] {\n height: 30px;\n padding: 0 10px;\n border-radius: 6px;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n font-weight: 500;\n border: 1px solid var(--mj-brand-primary);\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse, #ffffff);\n cursor: pointer;\n transition: opacity 0.15s ease, filter 0.15s ease;\n}\n\n.task-graph-pane-save-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n filter: brightness(1.06);\n}\n\n.task-graph-pane-save-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.55;\n cursor: not-allowed;\n}\n\n.task-graph-pane-btn[_ngcontent-%COMP%] {\n width: 30px;\n height: 30px;\n border-radius: 6px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border: 1px solid var(--mj-border-subtle);\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease;\n}\n\n.task-graph-pane-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n border-color: var(--mj-border-default);\n}\n\n.task-graph-pane-body[_ngcontent-%COMP%] {\n flex: 1;\n width: 100%;\n min-height: 0;\n min-width: 0;\n padding: 12px 16px 16px;\n box-sizing: border-box;\n overflow: hidden;\n display: flex;\n flex-direction: column;\n}\n\n.task-graph-pane-body[_ngcontent-%COMP%] > mj-task-graph-run-view[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n flex: 1;\n width: 100%;\n min-height: 0;\n min-width: 0;\n overflow: hidden;\n}\n\n.chat-messages-wrapper[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n min-height: 0;\n overflow: hidden;\n position: relative; \n}\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n.chat-demonstration-stage[_ngcontent-%COMP%] {\n height: 100%;\n display: flex;\n flex-direction: column;\n overflow: auto;\n background: var(--mj-bg-surface);\n border-right: 1px solid var(--mj-border-default);\n flex: 1;\n min-width: 0;\n}\n\n.chat-content-area.demonstration-mode[_ngcontent-%COMP%] .chat-messages-pane[_ngcontent-%COMP%], \n.chat-content-area.demonstration-mode[_ngcontent-%COMP%] .chat-messages-pane.full-width[_ngcontent-%COMP%] {\n flex: 0 0 320px;\n width: 320px;\n min-width: 0;\n}\n\n@media (max-width: 768px) {\n .chat-content-area.demonstration-mode[_ngcontent-%COMP%] {\n flex-direction: column;\n }\n\n .chat-content-area.demonstration-mode[_ngcontent-%COMP%] .chat-demonstration-stage[_ngcontent-%COMP%] {\n flex: 1 1 60%;\n border-right: none;\n border-bottom: 1px solid var(--mj-border-default);\n height: auto;\n }\n\n .chat-content-area.demonstration-mode[_ngcontent-%COMP%] .chat-messages-pane[_ngcontent-%COMP%], \n .chat-content-area.demonstration-mode[_ngcontent-%COMP%] .chat-messages-pane.full-width[_ngcontent-%COMP%] {\n flex: 1 1 40%;\n width: 100%;\n height: auto;\n }\n}\n\n\n.upload-indicator-overlay[_ngcontent-%COMP%] {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 1rem 1.5rem;\n background: color-mix(in srgb, var(--mj-bg-surface-card) 95%, transparent);\n border-radius: 12px;\n box-shadow: var(--mj-shadow-md);\n z-index: 100;\n pointer-events: none;\n}\n\n.chat-messages-container[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n background: var(--mj-bg-surface-card);\n min-height: 0;\n position: relative;\n}\n\n.scroll-to-bottom-icon[_ngcontent-%COMP%] {\n position: sticky;\n bottom: 21px;\n left: 50%;\n transform: translateX(-50%);\n width: 40px;\n height: 40px;\n margin-top: -40px;\n margin-left: auto;\n margin-right: auto;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n box-shadow: var(--mj-shadow-md);\n transition: all 0.2s ease;\n z-index: 100;\n pointer-events: auto;\n}\n\n.scroll-to-bottom-icon[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-brand-primary);\n transform: translateX(-50%) translateY(-2px);\n box-shadow: color-mix(in srgb, var(--mj-brand-primary) 20%, transparent) 0 4px 12px;\n}\n\n.scroll-to-bottom-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary);\n font-size: 16px;\n transition: color 0.2s;\n}\n\n.scroll-to-bottom-icon[_ngcontent-%COMP%]:hover i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.chat-input-container[_ngcontent-%COMP%] {\n flex-shrink: 0;\n background: var(--mj-bg-surface-card);\n padding: 0 1.25rem 1.25rem 1.25rem;\n overflow: visible;\n}\n\n\n.chat-composer-extra[_ngcontent-%COMP%] {\n margin-bottom: 0.5rem;\n}\n\n.read-only-banner[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n margin: 0 1.25rem 0.5rem 1.25rem;\n padding: 8px 12px;\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, transparent);\n color: var(--mj-text-secondary);\n border-radius: 6px;\n font-size: 12px;\n}\n\n.read-only-banner[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n font-size: 12px;\n}\n\n.loading-peripheral-placeholder[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: 140px;\n padding: 24px;\n background: color-mix(in srgb, var(--mj-bg-surface-card) 50%, transparent);\n backdrop-filter: blur(2px);\n border-radius: 12px;\n margin: 12px;\n animation: _ngcontent-%COMP%_fadeIn 0.2s ease-in-out;\n}\n\n.modal-overlay[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: var(--mj-bg-overlay);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n}\n\n.modal-content[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-card);\n border-radius: 8px;\n box-shadow: var(--mj-shadow-md);\n max-width: 90vw;\n max-height: 90vh;\n display: flex;\n flex-direction: column;\n}\n\n.project-selector-modal[_ngcontent-%COMP%] {\n width: 600px;\n height: 500px;\n}\n\n.modal-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.modal-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 18px;\n font-weight: 600;\n}\n\n.modal-header-actions[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.toggle-system-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n cursor: pointer;\n color: var(--mj-text-secondary);\n padding: 6px 12px;\n border-radius: 6px;\n font-size: 13px;\n font-weight: 500;\n transition: all 0.2s;\n}\n\n.toggle-system-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-border-default);\n border-color: var(--mj-border-default);\n color: var(--mj-text-primary);\n}\n\n.toggle-system-btn.active[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.toggle-system-btn.active[_ngcontent-%COMP%]:hover {\n background: var(--mj-brand-primary-hover);\n border-color: var(--mj-brand-primary-hover);\n}\n\n.toggle-system-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n}\n\n.modal-close-btn[_ngcontent-%COMP%] {\n background: none;\n border: none;\n cursor: pointer;\n color: var(--mj-text-secondary);\n padding: 4px 8px;\n border-radius: 4px;\n transition: all 0.2s;\n}\n\n.modal-close-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n}\n\n.modal-body[_ngcontent-%COMP%] {\n flex: 1;\n overflow: auto;\n padding: 20px;\n}\n\n.artifacts-modal[_ngcontent-%COMP%] {\n width: 700px;\n max-height: 600px;\n}\n\n.artifacts-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));\n gap: 16px;\n}\n\n\n.artifacts-empty-fill[_ngcontent-%COMP%] {\n grid-column: 1/-1;\n}\n\n.artifact-modal-card[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n background: var(--mj-bg-surface-card);\n border: 1.5px solid var(--mj-border-default);\n border-radius: 12px;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n overflow: hidden;\n}\n\n.artifact-modal-card.expanded[_ngcontent-%COMP%] {\n border-color: var(--mj-brand-primary);\n}\n\n.artifact-modal-card.system-artifact[_ngcontent-%COMP%] {\n opacity: 0.85;\n border-color: var(--mj-border-default);\n border-style: dashed;\n position: relative;\n}\n\n.artifact-modal-card.system-artifact[_ngcontent-%COMP%]::before {\n content: \"SYSTEM\";\n position: absolute;\n top: 8px;\n right: 8px;\n font-size: 9px;\n font-weight: 600;\n color: var(--mj-text-muted);\n background: var(--mj-bg-surface-sunken);\n padding: 2px 6px;\n border-radius: 3px;\n letter-spacing: 0.5px;\n z-index: 10;\n}\n\n.artifact-modal-card.system-artifact[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-text-muted);\n box-shadow: var(--mj-shadow-md);\n}\n\n.artifact-card-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 16px;\n cursor: pointer;\n}\n\n.artifact-card-header[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.artifact-modal-card[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-brand-primary);\n box-shadow: var(--mj-shadow-md);\n transform: translateY(-2px);\n}\n\n.artifact-modal-icon[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-radius: 10px;\n color: var(--mj-brand-primary);\n flex-shrink: 0;\n}\n\n.artifact-modal-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 18px;\n}\n\n.artifact-modal-info[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.artifact-modal-title[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin-bottom: 4px;\n}\n\n.artifact-modal-meta[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-secondary);\n}\n\n.artifact-modal-action[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n transition: color 0.2s;\n}\n\n.artifact-modal-card[_ngcontent-%COMP%]:hover .artifact-modal-action[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.expand-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n border: none;\n background: transparent;\n color: var(--mj-text-secondary);\n cursor: pointer;\n border-radius: 6px;\n transition: all 0.2s;\n}\n.expand-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-brand-primary);\n}\n\n.artifact-versions-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n padding: 0 1rem 1rem 1rem;\n background: var(--mj-bg-surface-sunken);\n}\n\n.artifact-version-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 16px 12px 68px;\n cursor: pointer;\n transition: background 0.15s;\n}\n.artifact-version-item[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n}\n.artifact-version-item[_ngcontent-%COMP%] .version-badge[_ngcontent-%COMP%] {\n display: inline-block;\n padding: 4px 8px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n font-size: 12px;\n font-weight: 600;\n font-family: monospace;\n border-radius: 4px;\n}\n.artifact-version-item[_ngcontent-%COMP%] .version-open-text[_ngcontent-%COMP%] {\n flex: 1;\n font-size: 13px;\n color: var(--mj-text-secondary);\n}\n.artifact-version-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n font-size: 12px;\n}\n.artifact-version-item[_ngcontent-%COMP%]:hover .version-badge[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n.artifact-version-item[_ngcontent-%COMP%]:hover .version-open-text[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n.artifact-version-item[_ngcontent-%COMP%]:hover i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.loading-peripheral-content[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 16px 24px;\n background: var(--mj-bg-surface-card);\n border: 2px solid var(--mj-border-default);\n border-radius: 12px;\n box-shadow: var(--mj-shadow-md);\n color: var(--mj-text-secondary);\n font-size: 14px;\n font-weight: 500;\n}\n.loading-peripheral-content[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 20px;\n color: var(--mj-brand-primary);\n}\n\n@keyframes _ngcontent-%COMP%_fadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n.conversation-loading-state[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n height: 100%;\n width: 100%;\n}\n\n.loading-content[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n padding-top: 20px;\n gap: 16px;\n color: var(--mj-text-secondary);\n font-size: 15px;\n}\n.loading-content[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 32px;\n color: var(--mj-brand-primary);\n}\n.loading-content[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n font-weight: 500;\n}\n\n\n@media (max-width: 768px) {\n .chat-header[_ngcontent-%COMP%] {\n padding: 8px 12px;\n gap: 6px;\n flex-direction: row;\n flex-wrap: wrap;\n align-items: center;\n position: relative;\n }\n .chat-info[_ngcontent-%COMP%] {\n flex-direction: row;\n align-items: center;\n gap: 8px;\n flex: 1;\n min-width: 0;\n order: 1;\n }\n .chat-title-bar[_ngcontent-%COMP%] {\n flex: 1;\n }\n .chat-title[_ngcontent-%COMP%] {\n font-size: 15px;\n font-weight: 700;\n }\n \n .chat-title-crumb.path-middle[_ngcontent-%COMP%] {\n display: none;\n }\n .chat-title-ellipsis[_ngcontent-%COMP%]:not(.collapses-wide) {\n display: flex;\n }\n .project-tag[_ngcontent-%COMP%] {\n margin-left: 0;\n font-size: 10px;\n padding: 3px 8px;\n height: 24px;\n display: none; \n }\n .test-indicator[_ngcontent-%COMP%] {\n margin-left: 0;\n font-size: 10px;\n padding: 3px 8px;\n height: 24px;\n }\n \n .chat-actions-buttons[_ngcontent-%COMP%] {\n order: 2;\n flex-shrink: 0;\n }\n .chat-actions-buttons[_ngcontent-%COMP%] .action-btn[_ngcontent-%COMP%] {\n padding: 6px 8px;\n min-width: auto;\n }\n .chat-actions-buttons[_ngcontent-%COMP%] .action-btn[_ngcontent-%COMP%] .btn-label[_ngcontent-%COMP%] {\n display: none;\n }\n .chat-actions[_ngcontent-%COMP%] {\n flex-wrap: nowrap;\n }\n .chat-members[_ngcontent-%COMP%], \n .artifact-indicator[_ngcontent-%COMP%] {\n padding: 5px 7px;\n font-size: 13px;\n }\n .action-btn[_ngcontent-%COMP%] {\n padding: 6px 8px;\n font-size: 12px;\n }\n .ambient-agent-indicator[_ngcontent-%COMP%] {\n font-size: 12px;\n padding: 4px 8px;\n }\n .project-selector-modal[_ngcontent-%COMP%] {\n width: min(95vw, 600px);\n height: auto;\n }\n .artifacts-modal[_ngcontent-%COMP%] {\n width: min(95vw, 700px);\n }\n .artifacts-grid[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n }\n .chat-input-container[_ngcontent-%COMP%] {\n padding: 0 0.75rem 0.75rem 0.75rem;\n }\n .scroll-to-bottom-icon[_ngcontent-%COMP%] {\n bottom: 16px;\n width: 36px;\n height: 36px;\n }\n \n .chat-content-area[_ngcontent-%COMP%] {\n position: relative;\n }\n .chat-artifact-pane[_ngcontent-%COMP%] {\n position: fixed;\n left: 0;\n right: 0;\n top: 56px; \n bottom: 0;\n width: 100% !important;\n z-index: 100;\n background: var(--mj-bg-surface-card);\n }\n .resize-handle[_ngcontent-%COMP%] {\n display: none;\n }\n}\n\n@media (max-width: 480px) {\n .chat-header[_ngcontent-%COMP%] {\n padding: 6px 8px;\n gap: 4px;\n }\n .chat-title[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 700;\n }\n .project-tag[_ngcontent-%COMP%] {\n font-size: 9px;\n padding: 2px 6px;\n height: 20px;\n display: none;\n }\n .test-indicator[_ngcontent-%COMP%] {\n font-size: 9px;\n padding: 2px 6px;\n height: 20px;\n }\n .chat-members[_ngcontent-%COMP%], \n .artifact-indicator[_ngcontent-%COMP%] {\n padding: 4px 8px;\n font-size: 11px;\n }\n .action-btn[_ngcontent-%COMP%] {\n padding: 5px 7px;\n font-size: 11px;\n }\n .ambient-agent-indicator[_ngcontent-%COMP%] {\n font-size: 11px;\n padding: 3px 6px;\n }\n .project-selector-modal[_ngcontent-%COMP%], \n .artifacts-modal[_ngcontent-%COMP%] {\n width: 100vw;\n height: 100vh;\n border-radius: 0;\n }\n .chat-input-container[_ngcontent-%COMP%] {\n padding: 0 0.5rem 0.5rem 0.5rem;\n }\n .scroll-to-bottom-icon[_ngcontent-%COMP%] {\n bottom: 12px;\n width: 32px;\n height: 32px;\n }\n .scroll-to-bottom-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n }\n}\n\n\n.artifact-picker-overlay[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background: var(--mj-bg-overlay);\n z-index: 999;\n}\n\n.artifact-picker-panel[_ngcontent-%COMP%] {\n position: fixed;\n right: 0;\n top: 0;\n width: 360px;\n height: 100%;\n background: var(--mj-bg-surface);\n border-left: 1px solid var(--mj-border-default);\n z-index: 1000;\n display: flex;\n flex-direction: column;\n box-shadow: -4px 0 12px rgba(0, 0, 0, 0.1);\n animation: _ngcontent-%COMP%_slideInRight 0.2s ease-out;\n}\n\n@keyframes _ngcontent-%COMP%_slideInRight {\n from { transform: translateX(100%); }\n to { transform: translateX(0); }\n}\n\n.artifact-picker-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.artifact-picker-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.artifact-picker-close[_ngcontent-%COMP%] {\n background: none;\n border: none;\n cursor: pointer;\n padding: 4px 8px;\n color: var(--mj-text-muted);\n border-radius: 4px;\n}\n\n.artifact-picker-close[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n\n.artifact-picker-body[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n padding: 12px;\n}\n\n.artifact-picker-empty[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 40px 20px;\n text-align: center;\n color: var(--mj-text-muted);\n gap: 8px;\n}\n\n.artifact-picker-hint[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-disabled);\n}\n\n.artifact-picker-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.artifact-picker-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 10px 12px;\n border: 1px solid var(--mj-border-subtle);\n border-radius: 6px;\n background: var(--mj-bg-surface-card);\n cursor: pointer;\n text-align: left;\n width: 100%;\n transition: background 0.15s, border-color 0.15s;\n}\n\n.artifact-picker-item[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n border-color: var(--mj-brand-primary);\n}\n\n.artifact-picker-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 20px;\n width: 24px;\n text-align: center;\n flex-shrink: 0;\n}\n\n.artifact-picker-item[_ngcontent-%COMP%] i.fa-file-pdf[_ngcontent-%COMP%] { color: var(--mj-status-error); }\n.artifact-picker-item[_ngcontent-%COMP%] i.fa-file-excel[_ngcontent-%COMP%] { color: var(--mj-status-success); }\n.artifact-picker-item[_ngcontent-%COMP%] i.fa-file-word[_ngcontent-%COMP%] { color: var(--mj-brand-primary); }\n.artifact-picker-item[_ngcontent-%COMP%] i.fa-file[_ngcontent-%COMP%] { color: var(--mj-text-muted); }\n\n.artifact-picker-item-info[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n min-width: 0;\n}\n\n.artifact-picker-item-name[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.artifact-picker-item-meta[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-muted);\n}\n\n\n\n\n\n.voice-call-pill[_ngcontent-%COMP%] {\n position: absolute;\n right: 18px;\n bottom: 18px;\n z-index: 49; \n display: flex;\n align-items: center;\n gap: 10px;\n padding: 9px 16px 9px 13px;\n border-radius: var(--mj-radius-full, 9999px);\n border: 1px solid var(--mj-border-strong);\n background: var(--mj-bg-surface-elevated, var(--mj-bg-surface));\n color: var(--mj-text-primary);\n font-family: inherit;\n cursor: pointer;\n box-shadow: 0 8px 24px color-mix(in srgb, var(--mj-brand-primary) 18%, transparent);\n transition: border-color 150ms ease, box-shadow 150ms ease, transform 150ms ease;\n}\n.voice-call-pill[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 10px 28px color-mix(in srgb, var(--mj-brand-primary) 28%, transparent);\n transform: translateY(-1px);\n}\n.voice-call-pill[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n color: var(--mj-brand-primary);\n}\n.voice-call-pill__pulse[_ngcontent-%COMP%] {\n width: 9px;\n height: 9px;\n border-radius: 50%;\n background: var(--mj-status-success);\n flex-shrink: 0;\n animation: _ngcontent-%COMP%_voice-pill-pulse 1.6s ease-in-out infinite;\n}\n.voice-call-pill__text[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n line-height: 1.25;\n}\n.voice-call-pill__name[_ngcontent-%COMP%] {\n font-size: 12.5px;\n font-weight: 700;\n}\n.voice-call-pill__hint[_ngcontent-%COMP%] {\n font-size: 10.5px;\n color: var(--mj-text-muted);\n}\n@keyframes _ngcontent-%COMP%_voice-pill-pulse {\n 0%, 100% {\n box-shadow: 0 0 0 0 color-mix(in srgb, var(--mj-status-success) 45%, transparent);\n }\n 50% {\n box-shadow: 0 0 0 5px color-mix(in srgb, var(--mj-status-success) 0%, transparent);\n }\n}\n\n\n.fork-view-bar[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n padding: var(--mj-space-2) var(--mj-space-4);\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n}\n.fork-composer-hint[_ngcontent-%COMP%] {\n padding: var(--mj-space-1) var(--mj-space-4) 0;\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n}\n.chat-actions-buttons[_ngcontent-%COMP%] > .forks-button[_ngcontent-%COMP%] .forks-count[_ngcontent-%COMP%] {\n margin-left: var(--mj-space-1);\n padding: 0 var(--mj-space-2);\n border-radius: var(--mj-radius-full);\n background: var(--mj-brand-primary);\n color: var(--mj-brand-on-primary);\n font-size: var(--mj-text-xs);\n font-weight: 600;\n}\n.chat-actions-buttons[_ngcontent-%COMP%] > .forks-button.active[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n.chat-actions-buttons[_ngcontent-%COMP%] > .remote-browser-toggle-btn.active[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n.remote-browser-url-input[_ngcontent-%COMP%] {\n width: 220px;\n max-width: 38vw;\n height: 28px;\n padding: 0 10px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font-size: 12px;\n font-family: var(--mj-font-family-mono);\n}\n.remote-browser-url-input[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--mj-border-focus);\n}"] });
|
|
9333
10193
|
}
|
|
9334
10194
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ConversationChatAreaComponent, [{
|
|
9335
10195
|
type: Component,
|
|
9336
|
-
args: [{ standalone: false, selector: 'mj-conversation-chat-area', template: "<div class=\"chat-area\">\n <!-- agentPresence slot \u2014 sticky top, anchored with the header. Per Matt's\n 06-10 design: persistent presence indicator (Sid's face + live voice\n state). Off by default; opt in via [showAgentCharacter]. When a\n consumer projects an `mjChatSlot=\"agentPresence\"` template, it\n replaces the default presence component. -->\n @if (showAgentCharacter) {\n <div class=\"chat-agent-presence\" [class.chat-agent-presence--prominent]=\"agentCharacterConfig?.voiceStateMode === 'prominent'\">\n @if (slotTemplate('agentPresence'); as t) {\n <ng-container *ngTemplateOutlet=\"t; context: {\n $implicit: agentCharacterConfig,\n state: agentCharacterConfig?.state ?? 'idle',\n agentName: agentCharacterConfig?.characterName,\n avatarUrl: agentCharacterConfig?.avatarUrl,\n mode: agentCharacterConfig?.voiceStateMode ?? 'subtle'\n }\"></ng-container>\n } @else {\n <mj-chat-agent-presence-default\n [State]=\"agentCharacterConfig?.state ?? 'idle'\"\n [AgentName]=\"agentCharacterConfig?.characterName\"\n [AvatarUrl]=\"agentCharacterConfig?.avatarUrl\"\n [Mode]=\"agentCharacterConfig?.voiceStateMode ?? 'subtle'\">\n </mj-chat-agent-presence-default>\n }\n </div>\n }\n\n <!-- header slot \u2014 replaces the entire chat-header chrome (title, badges,\n export/share/agent-picker buttons). When projected, the consumer owns\n the entire header rendering; the default chrome below is bypassed\n wholesale. Context exposes the minimal IMJChatHeaderComponent shape;\n consumers needing more app state should bind to chat-area inputs\n directly via @ViewChild or wrap the whole component. -->\n @if (slotTemplate('header'); as t) {\n <ng-container *ngTemplateOutlet=\"t; context: {\n $implicit: conversation,\n conversationTitle: conversation?.Name ?? null,\n sharedBy: sharedByBadge?.display ?? null,\n artifactCount: artifactCountDisplay,\n showArtifactIndicator: showArtifactIndicator\n }\"></ng-container>\n } @else if (conversation || HasPreConversationHeader) {\n <!-- Default header \u2014 also renders BEFORE a conversation exists when the\n embedder has pre-conversation chrome to surface (currently just the\n mode picker \u2014 agent / share / export / members / artifacts all\n require a conversation row and stay hidden). Lets embedded surfaces\n like the Form Builder cockpit show the mode picker above the\n empty-state on a fresh chat instead of waiting for the first\n message to round-trip. -->\n <div class=\"chat-header\" (keydown.escape)=\"OnViewEscape($event)\">\n <div class=\"chat-info\" [class.with-sidebar-toggle]=\"showSidebarToggle\">\n @if (showSidebarToggle) {\n <button class=\"sidebar-toggle-btn\"\n (click)=\"sidebarToggleClicked.emit()\"\n title=\"Show conversations\">\n <i class=\"fas fa-table-columns\"></i>\n </button>\n }\n @if (conversation) {\n <ng-container *ngTemplateOutlet=\"titleBar\"></ng-container>\n }\n @if (sharedByBadge) {\n <span class=\"shared-by-badge\" [title]=\"sharedByBadge.fullTooltip\">\n <i class=\"fas fa-share-nodes\"></i>\n <span>Shared by {{ sharedByBadge.display }}</span>\n </span>\n }\n @if (conversation?.ProjectID) {\n <button class=\"project-tag\" (click)=\"openProjectSelector()\" [attr.title]=\"EffectiveReadOnly ? 'Project' : 'Assign to project'\">\n <i class=\"fas fa-folder\"></i>\n <span>{{ conversation!.Project || 'Project' }}</span>\n </button>\n }\n @if (conversation?.TestRunID) {\n <button class=\"test-indicator\" (click)=\"viewTestRun(conversation!.TestRunID!)\" title=\"View Test Run\">\n <i class=\"fas fa-flask\"></i>\n <span>Test</span>\n </button>\n }\n </div>\n <div class=\"chat-actions chat-actions-buttons\">\n @if (ForkSummaries.length > 0) {\n <button mjButton #forksButton Variant=\"flat\" Size=\"sm\" class=\"forks-button\" [class.active]=\"ShowForksPopover\"\n aria-haspopup=\"dialog\" [attr.aria-expanded]=\"ShowForksPopover\" [attr.aria-controls]=\"ShowForksPopover ? ForksPopoverID : null\"\n (click)=\"ToggleForksPopover()\" title=\"Forks in this conversation\">\n <i class=\"fa-solid fa-code-branch\"></i>\n <span class=\"btn-label\">Forks</span>\n <span class=\"forks-count\">{{ ForkSummaries.length }}</span>\n </button>\n }\n @if (allowPinning && pinnedMessageCount > 0) {\n <button class=\"pin-chip\" [class.active]=\"showPinsPanel\" (click)=\"TogglePinsPanel()\" title=\"View pinned messages\">\n <i class=\"fas fa-thumbtack\"></i>\n <span class=\"pin-chip-count\">{{ pinnedMessageCount }}</span>\n </button>\n }\n @if (showArtifactIndicator && artifactCountDisplay > 0) {\n <button class=\"artifact-indicator\" (click)=\"viewArtifacts()\" title=\"View artifacts\">\n <i class=\"fas fa-cube\"></i>\n <span class=\"artifact-badge\">{{ artifactCountDisplay }}</span>\n </button>\n }\n @if (memberCount > 1) {\n <button class=\"chat-members\" (click)=\"toggleMembersModal()\" title=\"View members\">\n <i class=\"fas fa-users\"></i>\n <span class=\"members-badge\">{{ memberCount }}</span>\n </button>\n }\n @if (!overlayMode && showAgentModePicker && ModePickerTargetAgentId && !EffectiveReadOnly) {\n <!-- Per-agent mode/quality picker (Draft / Standard / High).\n Targets the agent the next non-mention message will route\n to. Auto-hides when that agent has fewer than 2 configured\n presets. Choice persists per-user, per-agent via\n UserInfoEngine; emits the picked configuration ID up so\n <mj-message-input> can forward it on the next route.\n Hidden in overlayMode (the compact chat overlay): the\n mode dropdown wastes the narrow top-right space there. -->\n <mj-conversation-mode-picker\n [AgentID]=\"ModePickerTargetAgentId\"\n [Disabled]=\"isProcessing\"\n (PresetChanged)=\"OnAgentModePresetChanged($event)\">\n </mj-conversation-mode-picker>\n }\n @if (showAgentPicker && conversation) {\n <!-- Per-conversation default-agent pin. When set, non-mention\n messages route to this agent instead of Sage. Persists to\n MJConversationEntity.DefaultAgentID. Hidden when no\n conversation is loaded or when the embedder disables it. -->\n <mj-conversation-agent-picker\n [Conversation]=\"conversation\"\n [CurrentUser]=\"currentUser\"\n [AllowedAgentIDs]=\"AllowedAgentIDs\"\n [Disabled]=\"EffectiveReadOnly\">\n </mj-conversation-agent-picker>\n }\n @if (showExportButton) {\n <button mjButton variant=\"flat\" size=\"sm\" (click)=\"exportConversation()\" [title]=\"exportButtonLabel + ' conversation'\">\n <i [class]=\"exportButtonIcon\"></i>\n <span class=\"btn-label\">{{ exportButtonLabel }}</span>\n </button>\n }\n @if (showShareButton && canShareConversation) {\n <button mjButton variant=\"flat\" size=\"sm\"\n [class.shared]=\"isShared\"\n (click)=\"shareConversation()\"\n [title]=\"isShared ? 'Manage sharing' : 'Share conversation'\">\n <i class=\"fas fa-share-nodes\"></i>\n <span class=\"btn-label\">Share</span>\n </button>\n }\n <!-- headerActions slot \u2014 ADDITIVE host buttons rendered after the stock\n actions (unlike the `header` slot, which replaces the whole header\n and therefore never reaches this branch). For visual parity,\n projected buttons should use mjButton variant=\"flat\" size=\"sm\". -->\n @if (slotTemplate('headerActions'); as t) {\n <ng-container *ngTemplateOutlet=\"t; context: {\n $implicit: conversation,\n conversationId: conversationId,\n isProcessing: isProcessing\n }\"></ng-container>\n }\n </div>\n </div>\n }\n\n <!-- Header title. Main: the conversation name. A fork: the path, the conversation and each parent fork\n (each opens its view; the parent is the way back), then the open fork with its kind icon. Past three\n entries, and on narrow screens, the middle crumbs collapse into an ellipsis that opens the forks list.\n The current name can be renamed in place. -->\n <ng-template #titleBar>\n <div class=\"chat-title-bar\">\n @if (OpenView.Kind === 'Main') {\n <ng-container *ngTemplateOutlet=\"titleName\"></ng-container>\n } @else {\n <nav class=\"chat-title-path\" aria-label=\"Breadcrumb\">\n <ol class=\"chat-title-crumbs\">\n @for (parent of HeaderPath.Parents; track $index) {\n @if ($index === 1) {\n <li class=\"chat-title-crumb chat-title-ellipsis\" [class.collapses-wide]=\"HeaderPath.CollapsesWide\">\n <button mjButton Variant=\"flat\" Size=\"sm\" type=\"button\" (click)=\"ShowWholePath()\" aria-label=\"Show the whole path\" title=\"Show the whole path\">\u2026</button>\n <i class=\"fa-solid fa-chevron-right chat-title-sep\" aria-hidden=\"true\"></i>\n </li>\n }\n <li class=\"chat-title-crumb\" [class.path-middle]=\"parent.IsMiddle\" [class.collapsed-wide]=\"parent.CollapsedWide\">\n <button mjButton Variant=\"flat\" Size=\"sm\" type=\"button\" (click)=\"OpenCrumb(parent.Crumb)\" [title]=\"'Back to ' + parent.Crumb.Label\">\n <span class=\"chat-title-crumb-label\">{{ parent.Crumb.Label }}</span>\n </button>\n <i class=\"fa-solid fa-chevron-right chat-title-sep\" aria-hidden=\"true\"></i>\n </li>\n }\n <li class=\"chat-title-current\" aria-current=\"page\">\n <i [class]=\"'chat-title-kind ' + OpenViewIcon\" [attr.data-kind]=\"OpenViewKind\" aria-hidden=\"true\"></i>\n <ng-container *ngTemplateOutlet=\"titleName\"></ng-container>\n </li>\n </ol>\n </nav>\n }\n </div>\n </ng-template>\n\n <!-- The current name and its rename button; the inline field while renaming -->\n <ng-template #titleName>\n @if (IsRenamingTitle) {\n <input\n #titleNameInput\n type=\"text\"\n class=\"chat-title-input\"\n maxlength=\"255\"\n [attr.aria-label]=\"TitleRenameLabel\"\n [(ngModel)]=\"TitleRenameText\"\n (keydown.enter)=\"$event.preventDefault(); SaveTitleRename(true)\"\n (keydown.escape)=\"$event.preventDefault(); $event.stopPropagation(); CancelTitleRename()\"\n (blur)=\"SaveTitleRename()\" />\n } @else {\n <h2 class=\"chat-title\" [title]=\"HeaderTitle\">{{ HeaderTitle }}</h2>\n @if (CanRenameTitle) {\n <button mjButton #titleRenameButton Variant=\"icon\" Size=\"sm\" type=\"button\" class=\"chat-title-rename\" (click)=\"StartTitleRename()\" [attr.aria-label]=\"TitleRenameLabel\" [title]=\"TitleRenameLabel\">\n <i class=\"fa-solid fa-pen\" aria-hidden=\"true\"></i>\n </button>\n }\n }\n </ng-template>\n\n <!-- Messages and Artifact Split Layout \u2014 restructures into [stage | rail]\n when isDemonstrationActive (per Matt's 06-10 design). The .demonstration-mode\n class drives the CSS Grid switch; the stage container renders only when the\n slot is projected AND the host opts in via [showDemonstrationSurface]. -->\n <div class=\"chat-content-area\" [class.demonstration-mode]=\"isDemonstrationActive\">\n <!-- demonstrationSurface stage \u2014 takes the main pane; messages shrink to\n a side rail (or move below on mobile). Off unless both\n [showDemonstrationSurface] is true AND a slot template is projected. -->\n @if (isDemonstrationActive) {\n <div class=\"chat-demonstration-stage\">\n <ng-container *ngTemplateOutlet=\"slotTemplate('demonstrationSurface'); context: {\n $implicit: demonstrationSurfaceContent,\n content: demonstrationSurfaceContent,\n visible: showDemonstrationSurface\n }\"></ng-container>\n </div>\n }\n\n <!-- Messages Pane -->\n <div class=\"chat-messages-pane\"\n [class.full-width]=\"!showArtifactPanel && !SelectedTaskGraphPanel\"\n [class.hidden]=\"isArtifactPaneMaximized\">\n @if (isLoadingConversation) {\n <!-- Loading State - checked FIRST to prevent empty state flash. The branch\n always short-circuits the panes below; showLoadingState only controls\n whether the built-in spinner renders (hosts with their own loading\n chrome set it false and get a blank pane instead). -->\n @if (showLoadingState) {\n <div class=\"conversation-loading-state\">\n <mj-loading text=\"Loading conversation...\" size=\"large\"></mj-loading>\n </div>\n }\n } @else if ((isNewConversation || !conversationId) && !suppressNewConversationEmptyState) {\n <!-- emptyState slot \u2014 when a consumer projects mjChatSlot=\"emptyState\",\n they take over the entire empty-state region (including any send\n affordance \u2014 the slot interface doesn't include a sendMessage\n output, so consumers handle send via their own input). When no\n slot is projected, the rich built-in <mj-conversation-empty-state>\n renders with its own greeting, prompt chips, and message input.\n emptyStateConfig (when supplied) takes precedence over the legacy\n [emptyStateGreeting] string for backwards compatibility. -->\n @if (ReadOnly) {\n <div class=\"read-only-banner\" role=\"status\">\n <i class=\"fas fa-eye\"></i>\n <span>{{ ReadOnlyMessage || 'You have view-only access to this conversation.' }}</span>\n </div>\n } @else if (slotTemplate('emptyState'); as t) {\n <ng-container *ngTemplateOutlet=\"t; context: {\n $implicit: emptyStateConfig,\n greeting: emptyStateConfig?.greeting ?? emptyStateGreeting,\n subtext: emptyStateConfig?.subtext,\n suggestedPrompts: emptyStateConfig?.suggestedPrompts ?? []\n }\"></ng-container>\n } @else {\n <mj-conversation-empty-state\n [currentUser]=\"currentUser\"\n [initialDraft]=\"GetInitialDraftFor(null)\"\n (initialDraftApplied)=\"OnComposerDraftApplied()\"\n (DraftStateChanged)=\"OnDraftStateChanged(null, $event)\"\n (ComposerBlurred)=\"OnComposerBlurred()\"\n [disabled]=\"isProcessing\"\n [showSidebarToggle]=\"showSidebarToggle\"\n [overlayMode]=\"overlayMode\"\n [greeting]=\"emptyStateConfig?.greeting ?? emptyStateGreeting\"\n [showSuggestedPrompts]=\"showSuggestedPrompts\"\n [enableAttachments]=\"enableAttachments && allowAttachments\"\n [enableMentions]=\"allowMentions\"\n [enableAgentMentions]=\"allowAgentMentions\"\n [enableEntityMentions]=\"allowEntityMentions\"\n [enableSkillCommands]=\"allowSkillCommands\"\n [AllowedAgentIDs]=\"AllowedAgentIDs\"\n [MentionPeople]=\"MentionPeople\"\n [ComposerExtraTemplate]=\"slotTemplate('composerExtra')\"\n [maxAttachments]=\"maxAttachments\"\n [maxAttachmentSizeBytes]=\"maxAttachmentSizeBytes\"\n [acceptedFileTypes]=\"acceptedFileTypes\"\n (sidebarToggleClicked)=\"sidebarToggleClicked.emit()\"\n (messageSent)=\"onEmptyStateMessageSent($event)\">\n </mj-conversation-empty-state>\n }\n } @else if ((isNewConversation || !conversationId) && suppressNewConversationEmptyState) {\n <!-- Pre-conversation normal-view: empty message list + emptyStateMode input.\n Used when host (e.g. Form Builder cockpit) wants the header + mode picker\n visible on first open instead of the centered welcome card. First send\n routes through onEmptyStateMessageSent which creates the conversation. -->\n <div class=\"chat-messages-wrapper\">\n <div class=\"chat-messages-container\"></div>\n <div class=\"chat-input-container\">\n @if (ReadOnly) {\n <div class=\"read-only-banner\" role=\"status\">\n <i class=\"fas fa-eye\"></i>\n <span>{{ ReadOnlyMessage || 'You have view-only access to this conversation.' }}</span>\n </div>\n } @else {\n <!-- composerExtra slot \u2014 host UI directly above the composer (IMJChatComposerExtraContext). -->\n @if (slotTemplate('composerExtra'); as t) {\n <div class=\"chat-composer-extra\">\n <ng-container *ngTemplateOutlet=\"t; context: {\n $implicit: conversation,\n ConversationId: conversationId,\n IsProcessing: isProcessing\n }\"></ng-container>\n </div>\n }\n <div class=\"message-input-container-wrapper\">\n <mj-message-input\n #emptyStateInput\n [emptyStateMode]=\"true\"\n [initialDraft]=\"GetInitialDraftFor(null)\"\n (initialDraftApplied)=\"OnComposerDraftApplied()\"\n (DraftStateChanged)=\"OnDraftStateChanged(null, $event)\"\n (ComposerBlurred)=\"OnComposerBlurred()\"\n [currentUser]=\"currentUser\"\n [disabled]=\"isProcessing\"\n [ReadOnly]=\"EffectiveReadOnly\"\n [appContext]=\"appContext\"\n [applicationId]=\"applicationId\"\n [defaultAgentId]=\"defaultAgentId\"\n [enableAttachments]=\"enableAttachments && allowAttachments\"\n [enableMentions]=\"allowMentions\"\n [enableAgentMentions]=\"allowAgentMentions\"\n [enableEntityMentions]=\"allowEntityMentions\"\n [enableSkillCommands]=\"allowSkillCommands\"\n [enablePlanMode]=\"allowPlanMode\"\n [enableRealtime]=\"allowRealtime\"\n [AllowedAgentIDs]=\"AllowedAgentIDs\"\n [MentionPeople]=\"MentionPeople\"\n [maxAttachments]=\"maxAttachments\"\n [maxAttachmentSizeBytes]=\"maxAttachmentSizeBytes\"\n [acceptedFileTypes]=\"acceptedFileTypes\"\n (emptyStateSubmit)=\"onEmptyStateMessageSent($event)\">\n </mj-message-input>\n </div>\n }\n </div>\n </div>\n } @else {\n <!-- Normal Message View -->\n <div class=\"chat-messages-wrapper\">\n @if (OpenView.Kind !== 'Main' && slotTemplate('header')) {\n <!-- A host header replaces the default one, so the fork title shows above the transcript. -->\n <div class=\"fork-view-bar\" role=\"region\" aria-label=\"Fork\" (keydown.escape)=\"OnViewEscape($event)\">\n <ng-container *ngTemplateOutlet=\"titleBar\"></ng-container>\n </div>\n }\n <!-- Upload Indicator Overlay (centered in conversation area) -->\n @if (isUploadingAttachments) {\n <div class=\"upload-indicator-overlay\">\n <mj-loading [text]=\"uploadingMessage\" size=\"medium\"></mj-loading>\n </div>\n }\n <div class=\"chat-messages-container\" #scrollContainer (scroll)=\"checkScroll()\" (keydown.escape)=\"OnViewEscape($event)\">\n <mj-conversation-message-list\n [showEmptyFill]=\"showEmptyFill\"\n [showDateNavigation]=\"showDateNavigation\"\n [showAgentRunDetails]=\"showAgentRunDetails\"\n [showReactions]=\"showReactions\"\n [showMessageRating]=\"showMessageRating\"\n [allowPinning]=\"allowPinning && !EffectiveReadOnly\"\n [allowMessageEdit]=\"allowMessageEdit && !EffectiveReadOnly\"\n [allowMessageDelete]=\"allowMessageDelete && !EffectiveReadOnly\"\n [ReadOnly]=\"EffectiveReadOnly\"\n [AllowStopRun]=\"AllowStopRun\"\n [InFlightCount]=\"InFlightCount\"\n [assistantDisplayName]=\"assistantDisplayName\"\n [assistantAvatarUrl]=\"assistantAvatarUrl\"\n [messages]=\"DisplayMessages\"\n [HasMoreAbove]=\"ListHasMoreAbove\"\n [IsLoadingOlder]=\"isLoadingOlderMessages\"\n [ScrollRoot]=\"messageScrollRoot\"\n (OlderRequested)=\"onOlderMessagesRequested()\"\n (DateJumpRequested)=\"onDateJumpRequested($event)\"\n [conversation]=\"conversation\"\n [currentUser]=\"currentUser\"\n [isProcessing]=\"isProcessing\"\n [artifactMap]=\"effectiveArtifactsMap\"\n [agentRunMap]=\"agentRunsByDetailId\"\n [ratingsMap]=\"ratingsByDetailId\"\n [userAvatarMap]=\"userAvatarMap\"\n [attachmentsMap]=\"attachmentsByDetailId\"\n [messageRendererTemplate]=\"slotTemplate('messageRenderer')\"\n [messageExtraTemplate]=\"slotTemplate('messageExtra')\"\n [sessionMetaMap]=\"realtimeSessionMetaMap\"\n [ForkChipMap]=\"ForkChipMap\"\n [ForkLayout]=\"ForkLayout\"\n [CanFork]=\"CanFork\"\n [InPlaceTurn]=\"InPlaceTurn\"\n (ForkOpenRequested)=\"OnForkOpenRequested($event)\"\n (EditResendRequested)=\"OnEditResendRequested($event)\"\n (RegenerateRequested)=\"OnRegenerateRequested($event)\"\n (ResendInPlaceRequested)=\"OnResendInPlaceRequested($event)\"\n (ForkRequested)=\"OnForkRequested($event)\"\n (realtimeSessionOpenRequested)=\"OpenRealtimeSessionReview($event)\"\n (deleteMessage)=\"onDeleteMessage($event)\"\n (BeforeStopClicked)=\"BeforeStopClicked.emit($event)\"\n (StopMessage)=\"OnStopMessage($event)\"\n (testFeedbackMessage)=\"onTestFeedbackMessage($event)\"\n (artifactClicked)=\"onArtifactClicked($event)\"\n (messageEdited)=\"onMessageEdited($event)\"\n (openEntityRecord)=\"onOpenEntityRecord($event)\"\n (suggestedResponseSelected)=\"onSuggestedResponseSelected($event)\"\n (attachmentClicked)=\"onAttachmentClicked($event)\"\n (diagnosticRequested)=\"onDiagnosticRequested($event)\"\n (LivenessCheckRequested)=\"OnLivenessCheckRequested($event)\"\n (messagePinToggled)=\"onMessagePinToggled($event)\"\n (beforeResponseFormSubmitted)=\"beforeResponseFormSubmitted.emit($event)\"\n (afterResponseFormSubmitted)=\"afterResponseFormSubmitted.emit($event)\"\n (TaskGraphPanelRequested)=\"OnTaskGraphPanelRequested($event)\"\n (ScrollToMessageRequested)=\"OnJumpToMessage($event)\">\n </mj-conversation-message-list>\n\n <!-- Scroll to Bottom Icon (positioned within scroll container for proper centering) -->\n @if (showScrollToBottomIcon && DisplayMessages.length > 0) {\n <span class=\"scroll-to-bottom-icon\" style=\"left: 50%;\"\n (click)=\"scrollToBottomAnimate()\">\n <i class=\"fas fa-arrow-down\"></i>\n </span>\n }\n </div>\n\n <!-- Fixed Input Area -->\n <div class=\"chat-input-container\">\n @if (isLoadingPeripheralData) {\n <!-- Loading State -->\n <div class=\"loading-peripheral-placeholder\">\n <mj-loading text=\"Loading conversation data...\" size=\"medium\"></mj-loading>\n </div>\n } @else if (ReadOnly) {\n <div class=\"read-only-banner\" role=\"status\">\n <i class=\"fas fa-eye\"></i>\n <span>{{ ReadOnlyMessage || 'You have view-only access to this conversation.' }}</span>\n </div>\n } @else {\n @if (isReadOnlyView) {\n <div class=\"read-only-banner\" role=\"status\">\n <i class=\"fas fa-eye\"></i>\n <span>You have view-only access to this conversation.</span>\n </div>\n }\n <!-- composerExtra slot \u2014 host UI directly above the composer (IMJChatComposerExtraContext). -->\n @if (slotTemplate('composerExtra'); as t) {\n <div class=\"chat-composer-extra\">\n <ng-container *ngTemplateOutlet=\"t; context: {\n $implicit: conversation,\n ConversationId: conversationId,\n IsProcessing: isProcessing\n }\"></ng-container>\n </div>\n }\n <!-- Input Component - Multiple instances cached, only one visible -->\n <div class=\"message-input-container-wrapper\">\n @for (inputRef of getCachedInputs(); track inputRef.conversationId) {\n <mj-message-input\n #messageInput\n [hidden]=\"inputRef.conversationId !== conversationId\"\n [initialDraft]=\"GetInitialDraftFor(inputRef.conversationId)\"\n (DraftStateChanged)=\"OnDraftStateChanged(inputRef.conversationId, $event)\"\n (ComposerBlurred)=\"OnComposerBlurred()\"\n [conversationId]=\"inputRef.conversationId\"\n [conversationName]=\"inputRef.conversationName\"\n [currentUser]=\"currentUser\"\n [conversationHistory]=\"inputRef.conversationId === conversationId ? messages : []\"\n [artifactsByDetailId]=\"inputRef.conversationId === conversationId ? artifactsByDetailId : emptyArtifactsMap\"\n [systemArtifactsByDetailId]=\"inputRef.conversationId === conversationId ? systemArtifactsByDetailId : emptyArtifactsMap\"\n [agentRunsByDetailId]=\"inputRef.conversationId === conversationId ? agentRunsByDetailId : emptyAgentRunsMap\"\n [appContext]=\"appContext\"\n [applicationId]=\"applicationId\"\n [defaultAgentId]=\"defaultAgentId\"\n [conversationDefaultAgentId]=\"inputRef.conversationId === conversationId ? (conversation?.DefaultAgentID ?? null) : null\"\n [agentConfigurationPresetId]=\"inputRef.conversationId === conversationId ? ActiveAgentConfigurationPresetId : null\"\n [AgentReplyMode]=\"AgentReplyMode\"\n [AllowedAgentIDs]=\"AllowedAgentIDs\"\n [MentionPeople]=\"MentionPeople\"\n [AgentHistoryFrom]=\"AgentHistoryFrom\"\n [TargetBranchID]=\"TargetBranchIdFor(inputRef.conversationId)\"\n [ResolveTargetBranch]=\"inputRef.conversationId === conversationId ? ResolveComposerBranch : null\"\n [AgentTurnHandler]=\"AgentTurnHandler\"\n [AutoNameConversation]=\"AutoNameConversation\"\n [EnableDecisionRouting]=\"EnableDecisionRouting\"\n [inProgressMessageIds]=\"inputRef.conversationId === conversationId ? inProgressMessageIds : emptyInProgressIds\"\n [disabled]=\"isProcessing || isReadOnlyView\"\n [ReadOnly]=\"EffectiveReadOnly\"\n [enableAttachments]=\"enableAttachments && allowAttachments\"\n [enableMentions]=\"allowMentions\"\n [enableAgentMentions]=\"allowAgentMentions\"\n [enableEntityMentions]=\"allowEntityMentions\"\n [enableSkillCommands]=\"allowSkillCommands\"\n [enablePlanMode]=\"allowPlanMode\"\n [enableRealtime]=\"allowRealtime && OpenView.Kind !== 'DraftFork'\"\n [Placeholder]=\"ComposerPlaceholderFor(inputRef.conversationId)\"\n [SendSlotMode]=\"inputRef.conversationId === conversationId ? SendSlotMode : 'send'\"\n [StopCount]=\"inputRef.conversationId === conversationId ? StopCount : 0\"\n [StopLabel]=\"StopLabel\"\n [StatusText]=\"inputRef.conversationId === conversationId ? StatusText : null\"\n [StatusElapsed]=\"inputRef.conversationId === conversationId ? StatusElapsed : null\"\n (StopClicked)=\"OnComposerStopClicked()\"\n [maxAttachments]=\"maxAttachments\"\n [maxAttachmentSizeBytes]=\"maxAttachmentSizeBytes\"\n [acceptedFileTypes]=\"acceptedFileTypes\"\n [initialMessage]=\"shouldDeliverPendingMessageTo(inputRef.conversationId) ? pendingMessage : null\"\n [initialAttachments]=\"shouldDeliverPendingMessageTo(inputRef.conversationId) ? pendingAttachments : null\"\n (initialMessageAutoSendStarted)=\"onInitialMessageAutoSendStarted($event)\"\n (initialMessageAutoSendFailed)=\"onInitialMessageAutoSendFailed($event)\"\n (messageSent)=\"onMessageSent($event)\"\n (MessageStreamed)=\"OnMessageStreamed($event)\"\n (agentResponse)=\"onAgentResponse($event)\"\n (agentRunDetected)=\"onAgentRunDetected($event)\"\n (agentRunUpdate)=\"onAgentRunUpdate($event)\"\n (messageComplete)=\"onMessageComplete($event)\"\n (artifactCreated)=\"onArtifactCreated($event)\"\n (conversationRenamed)=\"onConversationRenamed($event)\"\n (intentCheckStarted)=\"onIntentCheckStarted($event)\"\n (intentCheckCompleted)=\"onIntentCheckCompleted($event)\"\n (beforeAgentTurn)=\"beforeAgentTurn.emit($event)\"\n (afterAgentTurn)=\"afterAgentTurn.emit($event)\"\n (uploadStateChanged)=\"onUploadStateChanged($event)\">\n </mj-message-input>\n }\n </div>\n @if (ComposerHint) {\n <div class=\"fork-composer-hint\">{{ ComposerHint }}</div>\n }\n }\n </div>\n </div>\n }\n </div>\n\n <!-- Artifact Viewer Pane -->\n @if (showArtifactPanel && selectedArtifactId) {\n @if (!isArtifactPaneMaximized) {\n <div class=\"resize-handle\" (mousedown)=\"onResizeStart($event)\" (touchstart)=\"onResizeTouchStart($event)\"></div>\n }\n <div class=\"chat-artifact-pane\"\n [style.width.%]=\"artifactPaneWidth\"\n [class.maximized]=\"isArtifactPaneMaximized\">\n <mj-artifact-viewer-panel\n [artifactId]=\"selectedArtifactId\"\n [currentUser]=\"currentUser\"\n [environmentId]=\"environmentId\"\n [versionNumber]=\"selectedVersionNumber\"\n [viewContext]=\"'conversation'\"\n [Scope]=\"ArtifactViewerScope\"\n [canShare]=\"canShareSelectedArtifact\"\n [canEdit]=\"canEditSelectedArtifact\"\n [isMaximized]=\"isArtifactPaneMaximized\"\n [refreshTrigger]=\"artifactViewerRefresh$\"\n (closed)=\"onCloseArtifactPanel()\"\n (saveToCollectionRequested)=\"onSaveToCollectionRequested($event)\"\n (navigateToLink)=\"onArtifactLinkNavigation($event)\"\n (shareRequested)=\"onArtifactShareRequested($event)\"\n (maximizeToggled)=\"toggleMaximizeArtifactPane()\"\n (openEntityRecord)=\"onOpenEntityRecord($event)\"\n (navigationRequest)=\"onNavigationRequest($event)\"\n (analyzeRequested)=\"OnAnalyzeArtifact($event)\"\n (applyFormRequested)=\"OnApplyFormRequested($event)\">\n </mj-artifact-viewer-panel>\n </div>\n }\n\n <!-- Task Graph Run Viewer Pane -->\n @if (SelectedTaskGraphPanel) {\n @if (!isArtifactPaneMaximized) {\n <div class=\"resize-handle\" (mousedown)=\"onResizeStart($event)\" (touchstart)=\"onResizeTouchStart($event)\"></div>\n }\n <div class=\"chat-artifact-pane chat-task-graph-pane\"\n [style.width.%]=\"artifactPaneWidth\"\n [class.maximized]=\"isArtifactPaneMaximized\">\n <div class=\"task-graph-pane-header\">\n <div class=\"task-graph-pane-title-group\">\n <span class=\"task-graph-pane-icon\">\n <i class=\"fa-solid fa-diagram-project\"></i>\n </span>\n <div class=\"task-graph-pane-titles\">\n <span class=\"task-graph-pane-title\">{{ SelectedTaskGraphPanel.workflowTitle }}</span>\n <span class=\"task-graph-pane-subtitle\">Interactive Task Graph & 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"] }]
|
|
9337
10197
|
}], () => [{ type: i1.AgentStateService }, { type: i2.ConversationLivenessDomService }, { type: i3.ConversationAgentService }, { type: i4.ActiveTasksService }, { type: i0.ChangeDetectorRef }, { type: i5.ArtifactPermissionService }, { type: i6.ConversationAttachmentService }, { type: i7.ConversationStreamingService }, { type: i8.DialogService }, { type: i9.ConversationBridgeService }, { type: i10.AnalyzeArtifactService }, { type: i11.UICommandHandlerService }, { type: i10.InteractiveFormApplyService }, { type: i12.AgentClientService }], { EnvironmentId: [{
|
|
9338
10198
|
type: Input
|
|
9339
10199
|
}], environmentId: [{
|
|
@@ -9384,6 +10244,8 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
9384
10244
|
type: Input
|
|
9385
10245
|
}], AllowForking: [{
|
|
9386
10246
|
type: Input
|
|
10247
|
+
}], AllowRemoteBrowser: [{
|
|
10248
|
+
type: Input
|
|
9387
10249
|
}], AllowStopRun: [{
|
|
9388
10250
|
type: Input
|
|
9389
10251
|
}], ShowEmptyFill: [{
|
|
@@ -9685,6 +10547,9 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
9685
10547
|
}], chatSlotChildren: [{
|
|
9686
10548
|
type: ContentChildren,
|
|
9687
10549
|
args: [ChatSlotDirective]
|
|
10550
|
+
}], ConversationRemoteBrowserSurface: [{
|
|
10551
|
+
type: ViewChild,
|
|
10552
|
+
args: ['conversationRemoteBrowserSurface']
|
|
9688
10553
|
}], messageListComponent: [{
|
|
9689
10554
|
type: ViewChild,
|
|
9690
10555
|
args: [MessageListComponent]
|
|
@@ -9697,6 +10562,10 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
9697
10562
|
}], forksButton: [{
|
|
9698
10563
|
type: ViewChild,
|
|
9699
10564
|
args: ['forksButton', { read: ElementRef }]
|
|
10565
|
+
}], CollapseThreadReplies: [{
|
|
10566
|
+
type: Input
|
|
10567
|
+
}], ThreadReplyRevealRequested: [{
|
|
10568
|
+
type: Output
|
|
9700
10569
|
}] }); })();
|
|
9701
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ConversationChatAreaComponent, { className: "ConversationChatAreaComponent", filePath: "src/lib/components/conversation/conversation-chat-area.component.ts", lineNumber:
|
|
10570
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ConversationChatAreaComponent, { className: "ConversationChatAreaComponent", filePath: "src/lib/components/conversation/conversation-chat-area.component.ts", lineNumber: 217 }); })();
|
|
9702
10571
|
//# sourceMappingURL=conversation-chat-area.component.js.map
|