@memberjunction/ng-conversations 6.1.0-edge.5 → 6.1.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/README.md +9 -0
- package/dist/lib/components/active-tasks/active-tasks-panel.component.js +1 -1
- package/dist/lib/components/agent/active-agent-indicator.component.js +1 -1
- package/dist/lib/components/attachment/image-viewer.component.js +1 -1
- package/dist/lib/components/collection/artifact-collection-picker-modal.component.js +1 -1
- package/dist/lib/components/collection/collection-tree.component.js +55 -56
- package/dist/lib/components/collection/collection-tree.component.js.map +1 -1
- package/dist/lib/components/collection/collection-view.component.js +1 -1
- package/dist/lib/components/collection/collection-view.component.js.map +1 -1
- package/dist/lib/components/collection/collections-full-view.component.js +1 -1
- package/dist/lib/components/composer/ai-composer.component.d.ts +9 -1
- package/dist/lib/components/composer/ai-composer.component.d.ts.map +1 -1
- package/dist/lib/components/composer/ai-composer.component.js +16 -3
- package/dist/lib/components/composer/ai-composer.component.js.map +1 -1
- package/dist/lib/components/conversation/conversation-agent-picker.component.js +2 -2
- package/dist/lib/components/conversation/conversation-agent-picker.component.js.map +1 -1
- package/dist/lib/components/conversation/conversation-chat-area.component.d.ts +116 -11
- package/dist/lib/components/conversation/conversation-chat-area.component.d.ts.map +1 -1
- package/dist/lib/components/conversation/conversation-chat-area.component.js +309 -77
- package/dist/lib/components/conversation/conversation-chat-area.component.js.map +1 -1
- package/dist/lib/components/conversation/conversation-empty-state.component.js +1 -1
- package/dist/lib/components/conversation/conversation-list.component.js +22 -23
- package/dist/lib/components/conversation/conversation-list.component.js.map +1 -1
- package/dist/lib/components/conversation/conversation-mode-picker.component.js +10 -11
- package/dist/lib/components/conversation/conversation-mode-picker.component.js.map +1 -1
- package/dist/lib/components/conversation/pinned-messages-panel.component.js +1 -1
- package/dist/lib/components/dialogs/input-dialog.component.d.ts.map +1 -1
- package/dist/lib/components/dialogs/input-dialog.component.js +3 -3
- package/dist/lib/components/dialogs/input-dialog.component.js.map +1 -1
- package/dist/lib/components/dialogs/rating-dialog.component.js +1 -1
- package/dist/lib/components/global-tasks/global-tasks-panel.component.js +1 -1
- package/dist/lib/components/message/actionable-commands.component.js +1 -1
- package/dist/lib/components/message/message-input.component.d.ts +52 -1
- package/dist/lib/components/message/message-input.component.d.ts.map +1 -1
- package/dist/lib/components/message/message-input.component.js +117 -25
- package/dist/lib/components/message/message-input.component.js.map +1 -1
- package/dist/lib/components/message/message-item.component.d.ts +39 -1
- package/dist/lib/components/message/message-item.component.d.ts.map +1 -1
- package/dist/lib/components/message/message-item.component.js +172 -111
- package/dist/lib/components/message/message-item.component.js.map +1 -1
- package/dist/lib/components/message/message-list.component.d.ts +35 -0
- package/dist/lib/components/message/message-list.component.d.ts.map +1 -1
- package/dist/lib/components/message/message-list.component.js +107 -23
- package/dist/lib/components/message/message-list.component.js.map +1 -1
- package/dist/lib/components/message/workflow-plan-card.component.js +1 -1
- package/dist/lib/components/navigation/conversation-navigation.component.js +1 -1
- package/dist/lib/components/notification/notification-badge.component.js +1 -1
- package/dist/lib/components/overlay/chat-overlay.component.js +2 -2
- package/dist/lib/components/overlay/chat-overlay.component.js.map +1 -1
- package/dist/lib/components/project/project-form-modal.component.js +1 -1
- package/dist/lib/components/realtime/channels/channel-onboarding-panel.component.js +1 -1
- package/dist/lib/components/realtime/evidence-playback/realtime-evidence-playback.component.js +1 -1
- package/dist/lib/components/realtime/media/realtime-media-surface.component.js +1 -1
- package/dist/lib/components/realtime/realtime-activity-rail.component.d.ts +1 -1
- package/dist/lib/components/realtime/realtime-activity-rail.component.d.ts.map +1 -1
- package/dist/lib/components/realtime/realtime-activity-rail.component.js +3 -3
- package/dist/lib/components/realtime/realtime-activity-rail.component.js.map +1 -1
- package/dist/lib/components/realtime/realtime-agent-banner.component.js +2 -2
- package/dist/lib/components/realtime/realtime-agent-banner.component.js.map +1 -1
- package/dist/lib/components/realtime/realtime-agent-picker.component.d.ts +16 -1
- package/dist/lib/components/realtime/realtime-agent-picker.component.d.ts.map +1 -1
- package/dist/lib/components/realtime/realtime-agent-picker.component.js +45 -13
- package/dist/lib/components/realtime/realtime-agent-picker.component.js.map +1 -1
- package/dist/lib/components/realtime/realtime-composer.component.js +2 -2
- package/dist/lib/components/realtime/realtime-composer.component.js.map +1 -1
- package/dist/lib/components/realtime/realtime-delegation-card.component.d.ts +2 -2
- package/dist/lib/components/realtime/realtime-delegation-card.component.d.ts.map +1 -1
- package/dist/lib/components/realtime/realtime-delegation-card.component.js +159 -107
- package/dist/lib/components/realtime/realtime-delegation-card.component.js.map +1 -1
- package/dist/lib/components/realtime/realtime-session-overlay.component.js +1 -1
- package/dist/lib/components/realtime/realtime-session-state.d.ts +9 -4
- package/dist/lib/components/realtime/realtime-session-state.d.ts.map +1 -1
- package/dist/lib/components/realtime/realtime-session-state.js +95 -19
- package/dist/lib/components/realtime/realtime-session-state.js.map +1 -1
- package/dist/lib/components/realtime/realtime-session-thread.component.js +1 -1
- package/dist/lib/components/realtime/realtime-session-timeline-card.component.js +1 -1
- package/dist/lib/components/realtime/realtime-surface-tabs.component.js +1 -1
- package/dist/lib/components/realtime/remote-browser/remote-browser-surface.component.js +1 -1
- package/dist/lib/components/search/search-panel.component.js +2 -2
- package/dist/lib/components/search/search-panel.component.js.map +1 -1
- package/dist/lib/components/sidebar/routines-section.component.js +1 -1
- package/dist/lib/components/sidebar/routines-section.component.js.map +1 -1
- package/dist/lib/components/tasks/tasks-dropdown.component.js +1 -1
- package/dist/lib/components/thread/thread-panel.component.js +1 -1
- package/dist/lib/components/workspace/conversation-workspace.component.js +1 -1
- package/dist/lib/composer-plugins/base-conversation-mention.provider.d.ts +6 -0
- package/dist/lib/composer-plugins/base-conversation-mention.provider.d.ts.map +1 -1
- package/dist/lib/composer-plugins/base-conversation-mention.provider.js +7 -1
- package/dist/lib/composer-plugins/base-conversation-mention.provider.js.map +1 -1
- package/dist/lib/services/active-tasks.service.d.ts.map +1 -1
- package/dist/lib/services/active-tasks.service.js +9 -7
- package/dist/lib/services/active-tasks.service.js.map +1 -1
- package/dist/lib/services/composer-draft-store.d.ts.map +1 -1
- package/dist/lib/services/composer-draft-store.js +5 -2
- package/dist/lib/services/composer-draft-store.js.map +1 -1
- package/dist/lib/services/delegation-result-parser.d.ts +5 -0
- package/dist/lib/services/delegation-result-parser.d.ts.map +1 -1
- package/dist/lib/services/delegation-result-parser.js +12 -0
- package/dist/lib/services/delegation-result-parser.js.map +1 -1
- package/dist/lib/services/mention-autocomplete.service.d.ts +16 -2
- package/dist/lib/services/mention-autocomplete.service.d.ts.map +1 -1
- package/dist/lib/services/mention-autocomplete.service.js +38 -9
- package/dist/lib/services/mention-autocomplete.service.js.map +1 -1
- package/dist/lib/services/realtime-session-review.service.d.ts +31 -1
- package/dist/lib/services/realtime-session-review.service.d.ts.map +1 -1
- package/dist/lib/services/realtime-session-review.service.js +63 -8
- package/dist/lib/services/realtime-session-review.service.js.map +1 -1
- package/dist/lib/services/realtime-session.service.d.ts +15 -8
- package/dist/lib/services/realtime-session.service.d.ts.map +1 -1
- package/dist/lib/services/realtime-session.service.js +62 -14
- package/dist/lib/services/realtime-session.service.js.map +1 -1
- package/dist/lib/services/skill-picker-narrowing.d.ts +13 -0
- package/dist/lib/services/skill-picker-narrowing.d.ts.map +1 -0
- package/dist/lib/services/skill-picker-narrowing.js +13 -0
- package/dist/lib/services/skill-picker-narrowing.js.map +1 -0
- package/dist/lib/utils/artifact-panel-action.d.ts +89 -0
- package/dist/lib/utils/artifact-panel-action.d.ts.map +1 -0
- package/dist/lib/utils/artifact-panel-action.js +122 -0
- package/dist/lib/utils/artifact-panel-action.js.map +1 -0
- package/dist/lib/utils/distinct-artifacts.d.ts +8 -0
- package/dist/lib/utils/distinct-artifacts.d.ts.map +1 -1
- package/dist/lib/utils/distinct-artifacts.js +12 -2
- package/dist/lib/utils/distinct-artifacts.js.map +1 -1
- package/package.json +39 -39
|
@@ -20,6 +20,7 @@ import { RealtimeSessionReviewService } from '../../services/realtime-session-re
|
|
|
20
20
|
import { GenerateAndApplyConversationName } from '../../services/conversation-naming';
|
|
21
21
|
import { ResolveDateJumpTarget, CombineDateJumpOutcome, DescribeDateJumpOutcome, DATE_JUMP_MAX_PAGES } from '../../utils/date-jump';
|
|
22
22
|
import { MessageListComponent } from '../message/message-list.component';
|
|
23
|
+
import { decideArtifactPanelAction, snapshotArtifactVersions } from '../../utils/artifact-panel-action';
|
|
23
24
|
import { NormalizeUUID, UUIDsEqual } from '@memberjunction/global';
|
|
24
25
|
// PR 2c — Widget extension surface
|
|
25
26
|
import { ChatSlotDirective } from '../../directives/chat-slot.directive';
|
|
@@ -503,7 +504,7 @@ function ConversationChatAreaComponent_Conditional_20_Template(rf, ctx) { if (rf
|
|
|
503
504
|
i0.ɵɵelementStart(0, "div", 91);
|
|
504
505
|
i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_20_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r23); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.showProjectSelector = false); });
|
|
505
506
|
i0.ɵɵelementStart(1, "div", 92);
|
|
506
|
-
i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_20_Template_div_click_1_listener($event) {
|
|
507
|
+
i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_20_Template_div_click_1_listener($event) { return $event.stopPropagation(); });
|
|
507
508
|
i0.ɵɵelementStart(2, "div", 93)(3, "h3");
|
|
508
509
|
i0.ɵɵtext(4, "Assign Project");
|
|
509
510
|
i0.ɵɵelementEnd();
|
|
@@ -620,7 +621,7 @@ function ConversationChatAreaComponent_Conditional_21_Template(rf, ctx) { if (rf
|
|
|
620
621
|
i0.ɵɵelementStart(0, "div", 91);
|
|
621
622
|
i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_21_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r24); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.showArtifactsModal = false); });
|
|
622
623
|
i0.ɵɵelementStart(1, "div", 98);
|
|
623
|
-
i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_21_Template_div_click_1_listener($event) {
|
|
624
|
+
i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_21_Template_div_click_1_listener($event) { return $event.stopPropagation(); });
|
|
624
625
|
i0.ɵɵelementStart(2, "div", 93)(3, "h3");
|
|
625
626
|
i0.ɵɵtext(4, "Conversation Artifacts");
|
|
626
627
|
i0.ɵɵelementEnd();
|
|
@@ -775,6 +776,19 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
775
776
|
* set false.
|
|
776
777
|
*/
|
|
777
778
|
showLoadingState = true;
|
|
779
|
+
/**
|
|
780
|
+
* Read each reply from its top instead of its bottom.
|
|
781
|
+
*
|
|
782
|
+
* Default false (current behaviour): the pane follows the tail, so a run ends with the
|
|
783
|
+
* reader looking at the END of the answer and scrolling back up to start reading it.
|
|
784
|
+
*
|
|
785
|
+
* When true, sending and the run itself behave as before, but when the reply lands and
|
|
786
|
+
* the reader was following it, the turn — the reader's own message with the reply under
|
|
787
|
+
* it — is scrolled so it starts at the top of the pane, IF it is taller than the pane. A
|
|
788
|
+
* turn that fits stays where it is: it is all on screen anyway. A reader who scrolled up
|
|
789
|
+
* during the run is never moved; the scroll-to-bottom button is their way back.
|
|
790
|
+
*/
|
|
791
|
+
readReplyFromTop = false;
|
|
778
792
|
// --- Additional host-level feature gates (all default true; false removes the
|
|
779
793
|
// affordance entirely). Forwarded to the message list / message items / empty
|
|
780
794
|
// state so white-labeled end-user surfaces can pare the chat down through the
|
|
@@ -1193,7 +1207,8 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
1193
1207
|
}
|
|
1194
1208
|
/** Live draft persistence (store debounces the server write). */
|
|
1195
1209
|
OnDraftStateChanged(conversationId, serialized) {
|
|
1196
|
-
|
|
1210
|
+
// verboseOnly: fires on every keystroke, same as the store's own SetDraft log below it.
|
|
1211
|
+
LogStatusEx({ message: `[Drafts] chat-area: draft change for '${conversationId ?? 'new'}' (${serialized.length} chars)`, verboseOnly: true });
|
|
1197
1212
|
this.draftStore.SetDraft(conversationId, serialized);
|
|
1198
1213
|
}
|
|
1199
1214
|
/** Blur = a natural save point — persist immediately. */
|
|
@@ -1265,6 +1280,24 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
1265
1280
|
messages = [];
|
|
1266
1281
|
showScrollToBottomIcon = false;
|
|
1267
1282
|
scrollToBottom = false;
|
|
1283
|
+
/**
|
|
1284
|
+
* Whether the reader was at (within a few px of) the bottom at the last scroll event.
|
|
1285
|
+
* An in-place message update only follows the tail for a reader who is already there;
|
|
1286
|
+
* one who scrolled up to reread history is left alone, whichever mode is on.
|
|
1287
|
+
*/
|
|
1288
|
+
readerAtBottom = true;
|
|
1289
|
+
/** readReplyFromTop: the reader's message that opened the current turn. */
|
|
1290
|
+
currentTurnStartMessageId = null;
|
|
1291
|
+
/** readReplyFromTop: set when the reply lands, consumed once it has rendered. */
|
|
1292
|
+
pendingTurnStartMessageId = null;
|
|
1293
|
+
/**
|
|
1294
|
+
* readReplyFromTop: while a landing is under way, bottom-follow timers already armed by the
|
|
1295
|
+
* last progress updates must not fire and drag the reader back down.
|
|
1296
|
+
*/
|
|
1297
|
+
bottomFollowSuppressedUntil = 0;
|
|
1298
|
+
turnStartRetryHandle = null;
|
|
1299
|
+
/** Gap kept between the pane's top edge and the turn's first message. */
|
|
1300
|
+
static TURN_TOP_GAP_PX = 16;
|
|
1268
1301
|
lastLoadedConversationId = null; // Track which conversation's peripheral data was loaded
|
|
1269
1302
|
currentlyLoadingConversationId = null; // Track which conversation is currently being loaded
|
|
1270
1303
|
conversationLoadToken = 0; // Monotonic token to discard stale async conversation loads
|
|
@@ -1289,6 +1322,21 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
1289
1322
|
showSystemArtifacts = false; // Toggle for showing system-only artifacts
|
|
1290
1323
|
selectedArtifactId = null;
|
|
1291
1324
|
selectedVersionNumber = undefined; // Version to show in artifact viewer
|
|
1325
|
+
/**
|
|
1326
|
+
* Bumped whenever artifacts are MERGED into `artifactsByDetailId` by something other than the
|
|
1327
|
+
* turn in flight — today only the scroll-up paging path. A before/after diff spanning such a
|
|
1328
|
+
* merge cannot tell an artifact that arrived from an older page from one a run just created, so
|
|
1329
|
+
* the baseline records this counter and the decision refuses to infer creations when it moved.
|
|
1330
|
+
*/
|
|
1331
|
+
artifactMapGeneration = 0;
|
|
1332
|
+
/**
|
|
1333
|
+
* Bumped whenever the USER changes what the artifact panel is showing (clicks a card, opens one
|
|
1334
|
+
* from the modal or a deep link, closes the panel). An agent turn can finish while such a click
|
|
1335
|
+
* is in flight — two completion handlers run per turn, each holding its own pre-turn snapshot —
|
|
1336
|
+
* and without this the slower one would pull the panel back onto the run's artifact and discard
|
|
1337
|
+
* the selection the user just made.
|
|
1338
|
+
*/
|
|
1339
|
+
artifactSelectionEpoch = 0;
|
|
1292
1340
|
artifactPaneWidth = DEFAULT_ARTIFACT_PANE_WIDTH;
|
|
1293
1341
|
isArtifactPaneMaximized = false; // Track maximize state
|
|
1294
1342
|
artifactPaneWidthBeforeMaximize = DEFAULT_ARTIFACT_PANE_WIDTH;
|
|
@@ -1882,11 +1930,20 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
1882
1930
|
if (this.scrollToBottom) {
|
|
1883
1931
|
this.scrollToBottom = false;
|
|
1884
1932
|
setTimeout(() => {
|
|
1933
|
+
if (Date.now() < this.bottomFollowSuppressedUntil) {
|
|
1934
|
+
return;
|
|
1935
|
+
}
|
|
1885
1936
|
this.scrollToBottomNow();
|
|
1886
1937
|
// Check scroll state after scrolling to bottom
|
|
1887
1938
|
this.checkScroll();
|
|
1888
1939
|
}, 100);
|
|
1889
1940
|
}
|
|
1941
|
+
if (this.pendingTurnStartMessageId) {
|
|
1942
|
+
const messageId = this.pendingTurnStartMessageId;
|
|
1943
|
+
this.pendingTurnStartMessageId = null;
|
|
1944
|
+
// Deferred for the same reason checkScroll() is not called synchronously below.
|
|
1945
|
+
setTimeout(() => this.scrollTurnToTop(messageId), 0);
|
|
1946
|
+
}
|
|
1890
1947
|
// Removed synchronous checkScroll() from else branch to prevent
|
|
1891
1948
|
// ExpressionChangedAfterItHasBeenCheckedError. Calling detectChanges()
|
|
1892
1949
|
// inside ngAfterViewChecked re-enters change detection and causes
|
|
@@ -1901,6 +1958,7 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
1901
1958
|
// Complete destroy subject to cleanup subscriptions
|
|
1902
1959
|
this.destroy$.next();
|
|
1903
1960
|
this.destroy$.complete();
|
|
1961
|
+
this.clearTurnTracking();
|
|
1904
1962
|
// Remove resize listeners
|
|
1905
1963
|
window.removeEventListener('mousemove', this.boundOnResizeMove);
|
|
1906
1964
|
window.removeEventListener('mouseup', this.boundOnResizeEnd);
|
|
@@ -1919,6 +1977,7 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
1919
1977
|
: this.isActiveConversation(conversationId);
|
|
1920
1978
|
}
|
|
1921
1979
|
resetConversationScopedViewState() {
|
|
1980
|
+
this.clearTurnTracking();
|
|
1922
1981
|
this.showArtifactPanel = false;
|
|
1923
1982
|
this.selectedArtifactId = null;
|
|
1924
1983
|
this.selectedVersionNumber = undefined;
|
|
@@ -2133,7 +2192,7 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
2133
2192
|
}
|
|
2134
2193
|
}
|
|
2135
2194
|
}
|
|
2136
|
-
this.
|
|
2195
|
+
this.followTranscript('load');
|
|
2137
2196
|
// Process peripheral data (agent runs, artifacts, ratings, attachments) from engine cache
|
|
2138
2197
|
await this.loadPeripheralData(conversationId, snapshot, loadToken);
|
|
2139
2198
|
if (!this.isActiveConversationLoad(conversationId, loadToken)) {
|
|
@@ -2279,6 +2338,10 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
2279
2338
|
if (sessionMeta.size > 0) {
|
|
2280
2339
|
this.realtimeSessionMetaMap = new Map([...this.realtimeSessionMetaMap, ...sessionMeta]);
|
|
2281
2340
|
}
|
|
2341
|
+
// A page of OLDER artifacts just entered the map. Any artifact-panel baseline taken before
|
|
2342
|
+
// this point can no longer be diffed against the map for creations — these arrived from
|
|
2343
|
+
// history, not from a run. See snapshotArtifactPanelBaseline.
|
|
2344
|
+
this.artifactMapGeneration++;
|
|
2282
2345
|
// New references so the message list's ngOnChanges sees the extended maps.
|
|
2283
2346
|
this.agentRunsByDetailId = new Map(this.agentRunsByDetailId);
|
|
2284
2347
|
this.artifactsByDetailId = new Map(this.artifactsByDetailId);
|
|
@@ -2510,8 +2573,9 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
2510
2573
|
this.inProgressMessageIds = [...this.inProgressMessageIds, message.ID];
|
|
2511
2574
|
}
|
|
2512
2575
|
}
|
|
2513
|
-
//
|
|
2514
|
-
|
|
2576
|
+
// Where the viewport goes: a fresh send follows — an in-place update of a message that
|
|
2577
|
+
// is already on screen must not re-run the send path's scroll.
|
|
2578
|
+
this.followTranscript(existingIndex >= 0 ? 'update' : 'new', message);
|
|
2515
2579
|
// Force change detection — zone.js 0.15 no longer patches graphql-ws WebSocket callbacks,
|
|
2516
2580
|
// so progress updates that arrive via PubSub run outside Angular's zone. Without this,
|
|
2517
2581
|
// the UI does not update when the messages array is modified from a streaming callback.
|
|
@@ -2736,8 +2800,9 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
2736
2800
|
try {
|
|
2737
2801
|
const isCurrent = () => this.isCurrentConversationContext(expectedConversationId, loadToken);
|
|
2738
2802
|
LogStatusEx({ message: `🎉 Handling completion for message ${message.ID}`, verboseOnly: true });
|
|
2739
|
-
// Snapshot artifact
|
|
2740
|
-
|
|
2803
|
+
// Snapshot the artifact population before the reloads below so we can tell a NEW artifact
|
|
2804
|
+
// from a new VERSION of one already on screen (#529).
|
|
2805
|
+
const artifactBaseline = this.snapshotArtifactPanelBaseline();
|
|
2741
2806
|
// Reload message from database to get final content and status
|
|
2742
2807
|
await message.Load(message.ID);
|
|
2743
2808
|
if (!isCurrent()) {
|
|
@@ -2773,12 +2838,12 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
2773
2838
|
this.inProgressMessageIds = [...this.messages
|
|
2774
2839
|
.filter(m => m.Status === 'In-Progress')
|
|
2775
2840
|
.map(m => m.ID)];
|
|
2776
|
-
//
|
|
2841
|
+
// Open/refresh the artifact panel from the version diff (not just the triggering message).
|
|
2777
2842
|
// When Sage delegates to a sub-agent (e.g., Skip), the artifact is on the sub-agent's
|
|
2778
2843
|
// message, not Sage's. Checking only the triggering message would miss delegated artifacts.
|
|
2779
|
-
|
|
2780
|
-
|
|
2781
|
-
|
|
2844
|
+
// #529: a delegated build discovered here must surface even with the panel already open on
|
|
2845
|
+
// another artifact, so this is NOT gated on `!this.showArtifactPanel`.
|
|
2846
|
+
await this.decideAndApplyArtifactPanel(artifactBaseline, expectedConversationId);
|
|
2782
2847
|
// Remove task from ActiveTasksService (clears spinner in conversation list)
|
|
2783
2848
|
const task = this.activeTasks.getByConversationDetailId(message.ID);
|
|
2784
2849
|
if (task) {
|
|
@@ -2812,8 +2877,8 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
2812
2877
|
if (this.conversationId) {
|
|
2813
2878
|
this.resetComponentState(this.conversationId);
|
|
2814
2879
|
}
|
|
2815
|
-
//
|
|
2816
|
-
this.
|
|
2880
|
+
// Where the viewport goes when the agent responds
|
|
2881
|
+
this.followTranscript('new', event.message);
|
|
2817
2882
|
// CRITICAL FIX: Always refresh the agent run data when agent completes
|
|
2818
2883
|
// This ensures we get the final status and timestamps, replacing any stale data from when agent started
|
|
2819
2884
|
// agentResult is ExecuteAgentResult which contains agentRun property
|
|
@@ -2823,17 +2888,17 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
2823
2888
|
return;
|
|
2824
2889
|
}
|
|
2825
2890
|
}
|
|
2826
|
-
// Snapshot artifact
|
|
2827
|
-
|
|
2891
|
+
// Snapshot the artifact population before reload so we can tell a NEW artifact from a new
|
|
2892
|
+
// VERSION of one already on screen (#529).
|
|
2893
|
+
const artifactBaseline = this.snapshotArtifactPanelBaseline();
|
|
2828
2894
|
// Reload artifact mapping for this message to pick up newly created artifacts
|
|
2829
2895
|
await this.reloadArtifactsForMessage(event.message.ID, event.message.ConversationID);
|
|
2830
2896
|
if (!this.isActiveConversation(event.message.ConversationID)) {
|
|
2831
2897
|
return;
|
|
2832
2898
|
}
|
|
2833
|
-
//
|
|
2834
|
-
|
|
2835
|
-
|
|
2836
|
-
}
|
|
2899
|
+
// #529: open a newly created artifact even with the panel already open on another one, refresh
|
|
2900
|
+
// the shown artifact when it gained a version, and switch to a retargeted one.
|
|
2901
|
+
await this.decideAndApplyArtifactPanel(artifactBaseline, event.message.ConversationID);
|
|
2837
2902
|
// Force change detection to update the UI
|
|
2838
2903
|
this.cdr.detectChanges();
|
|
2839
2904
|
}
|
|
@@ -2959,42 +3024,106 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
2959
3024
|
return uniqueArtifactIds.size;
|
|
2960
3025
|
}
|
|
2961
3026
|
/**
|
|
2962
|
-
*
|
|
2963
|
-
*
|
|
3027
|
+
* Every (artifactId, versionNumber) pair currently known across all messages, with the version's
|
|
3028
|
+
* creation time so candidates can be ordered by recency rather than by whichever conversation
|
|
3029
|
+
* detail the map happened to iterate last.
|
|
2964
3030
|
*/
|
|
2965
|
-
|
|
2966
|
-
const
|
|
3031
|
+
allArtifactRefs() {
|
|
3032
|
+
const refs = [];
|
|
2967
3033
|
for (const artifactList of this.artifactsByDetailId.values()) {
|
|
2968
3034
|
for (const info of artifactList) {
|
|
2969
|
-
|
|
3035
|
+
refs.push({
|
|
3036
|
+
artifactId: info.artifactId,
|
|
3037
|
+
versionNumber: info.versionNumber,
|
|
3038
|
+
versionCreatedAt: info.versionCreatedAt,
|
|
3039
|
+
});
|
|
2970
3040
|
}
|
|
2971
3041
|
}
|
|
2972
|
-
return
|
|
3042
|
+
return refs;
|
|
2973
3043
|
}
|
|
2974
3044
|
/**
|
|
2975
|
-
*
|
|
2976
|
-
*
|
|
2977
|
-
*
|
|
2978
|
-
*
|
|
2979
|
-
*
|
|
2980
|
-
*
|
|
3045
|
+
* Captures everything {@link decideAndApplyArtifactPanel} needs to judge, at the START of a turn,
|
|
3046
|
+
* whether the artifact population changed BECAUSE of that turn.
|
|
3047
|
+
*
|
|
3048
|
+
* The version map alone is not enough. `artifactsByDetailId` is rebuilt for reasons unrelated to
|
|
3049
|
+
* any run — `resetConversationScopedViewState` does not clear it on a conversation switch, so it
|
|
3050
|
+
* still holds the previous conversation's artifacts until `loadPeripheralData` lands, and the
|
|
3051
|
+
* missed-completion path in `loadMessages` runs BEFORE that rebuild. A snapshot taken there
|
|
3052
|
+
* describes a different conversation entirely, and every artifact of the conversation being
|
|
3053
|
+
* opened would read as newly created. So the baseline also records which conversation the map
|
|
3054
|
+
* was holding, the paging generation, and the user's selection epoch.
|
|
2981
3055
|
*/
|
|
2982
|
-
|
|
2983
|
-
|
|
2984
|
-
|
|
3056
|
+
snapshotArtifactPanelBaseline() {
|
|
3057
|
+
return {
|
|
3058
|
+
versions: snapshotArtifactVersions(this.allArtifactRefs()),
|
|
3059
|
+
conversationId: this.conversationId,
|
|
3060
|
+
mapConversationId: this.lastLoadedConversationId,
|
|
3061
|
+
mapGeneration: this.artifactMapGeneration,
|
|
3062
|
+
selectionEpoch: this.artifactSelectionEpoch,
|
|
3063
|
+
};
|
|
3064
|
+
}
|
|
3065
|
+
/**
|
|
3066
|
+
* Diffs the current artifact population against a baseline and carries out the resulting panel
|
|
3067
|
+
* action. The single entry point for all three completion paths, which previously each carried
|
|
3068
|
+
* their own copy of the snapshot/decide/apply sequence.
|
|
3069
|
+
*
|
|
3070
|
+
* @param baseline - From {@link snapshotArtifactPanelBaseline}, taken before the turn's reloads.
|
|
3071
|
+
* @param conversationId - The conversation this turn belongs to.
|
|
3072
|
+
*/
|
|
3073
|
+
async decideAndApplyArtifactPanel(baseline, conversationId) {
|
|
3074
|
+
// The baseline is comparable only if the map was holding THIS conversation's artifacts when it
|
|
3075
|
+
// was taken, and nothing merged an older page in since.
|
|
3076
|
+
const baselineComparable = baseline.mapConversationId != null &&
|
|
3077
|
+
UUIDsEqual(baseline.mapConversationId, baseline.conversationId) &&
|
|
3078
|
+
this.artifactMapGeneration === baseline.mapGeneration;
|
|
3079
|
+
const action = decideArtifactPanelAction({
|
|
3080
|
+
panelOpen: this.showArtifactPanel,
|
|
3081
|
+
selectedArtifactId: this.selectedArtifactId,
|
|
3082
|
+
before: baseline.versions,
|
|
3083
|
+
after: this.allArtifactRefs(),
|
|
3084
|
+
baselineComparable,
|
|
3085
|
+
userChangedSelection: this.artifactSelectionEpoch !== baseline.selectionEpoch,
|
|
3086
|
+
});
|
|
3087
|
+
if (!baselineComparable && action.kind === 'none') {
|
|
3088
|
+
LogStatusEx({
|
|
3089
|
+
message: `🎨 Skipping artifact panel decision: the before/after snapshots describe different artifact populations (map held ${baseline.mapConversationId ?? 'nothing'}, conversation was ${baseline.conversationId})`,
|
|
3090
|
+
verboseOnly: true
|
|
3091
|
+
});
|
|
2985
3092
|
}
|
|
2986
|
-
|
|
2987
|
-
|
|
2988
|
-
|
|
2989
|
-
|
|
3093
|
+
await this.applyArtifactPanelAction(action, conversationId);
|
|
3094
|
+
}
|
|
3095
|
+
/**
|
|
3096
|
+
* Carry out the decision from {@link decideArtifactPanelAction}: open the panel on an artifact
|
|
3097
|
+
* version, refresh the already-open viewer, or do nothing.
|
|
3098
|
+
*/
|
|
3099
|
+
async applyArtifactPanelAction(action, conversationId) {
|
|
3100
|
+
switch (action.kind) {
|
|
3101
|
+
case 'open':
|
|
3102
|
+
this.selectedArtifactId = action.artifactId;
|
|
3103
|
+
this.selectedVersionNumber = action.versionNumber;
|
|
2990
3104
|
this.showArtifactPanel = true;
|
|
2991
|
-
await this.loadArtifactPermissions(
|
|
2992
|
-
|
|
3105
|
+
await this.loadArtifactPermissions(action.artifactId, conversationId, action.artifactId);
|
|
3106
|
+
// The permission load is async: the user may have switched conversations or picked a
|
|
3107
|
+
// different artifact while it was in flight, so only narrate what is still on screen.
|
|
3108
|
+
if (!this.isActiveConversation(conversationId) || !UUIDsEqual(this.selectedArtifactId, action.artifactId)) {
|
|
2993
3109
|
return;
|
|
2994
3110
|
}
|
|
2995
|
-
LogStatusEx({
|
|
3111
|
+
LogStatusEx({
|
|
3112
|
+
message: `🎨 Opening artifact ${action.artifactId} v${action.versionNumber} after agent run (decided from the conversation-wide version diff, so no single detail id applies)`,
|
|
3113
|
+
verboseOnly: true
|
|
3114
|
+
});
|
|
3115
|
+
return;
|
|
3116
|
+
case 'refresh':
|
|
3117
|
+
// ONE channel, deliberately. Writing `selectedVersionNumber` as well would change the
|
|
3118
|
+
// viewer's `[versionNumber]` input in the same change-detection pass, and its `ngOnChanges`
|
|
3119
|
+
// would load the version a second time on top of the load this emission already starts —
|
|
3120
|
+
// and that second load runs without a cancellation token, so it can also land after a newer
|
|
3121
|
+
// one. The subject path is the one to keep: it reloads the version list too, which a
|
|
3122
|
+
// brand-new version needs, and it carries a load token.
|
|
3123
|
+
this.artifactViewerRefresh$.next({ artifactId: action.artifactId, versionNumber: action.versionNumber });
|
|
3124
|
+
return;
|
|
3125
|
+
case 'none':
|
|
2996
3126
|
return;
|
|
2997
|
-
}
|
|
2998
3127
|
}
|
|
2999
3128
|
}
|
|
3000
3129
|
/**
|
|
@@ -3100,6 +3229,7 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
3100
3229
|
}
|
|
3101
3230
|
async openArtifactFromModal(artifactId, versionNumber) {
|
|
3102
3231
|
const conversationId = this.conversationId;
|
|
3232
|
+
this.artifactSelectionEpoch++;
|
|
3103
3233
|
this.selectedArtifactId = artifactId;
|
|
3104
3234
|
this.selectedVersionNumber = versionNumber;
|
|
3105
3235
|
this.showArtifactPanel = true;
|
|
@@ -3480,6 +3610,7 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
3480
3610
|
}
|
|
3481
3611
|
async onArtifactClicked(data) {
|
|
3482
3612
|
const conversationId = this.conversationId;
|
|
3613
|
+
this.artifactSelectionEpoch++;
|
|
3483
3614
|
this.selectedArtifactId = data.artifactId;
|
|
3484
3615
|
// If versionId is provided, find the version number from display data (no lazy load needed)
|
|
3485
3616
|
if (data.versionId) {
|
|
@@ -3518,39 +3649,22 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
3518
3649
|
if (!this.isActiveConversation(data.conversationId)) {
|
|
3519
3650
|
return;
|
|
3520
3651
|
}
|
|
3521
|
-
// Snapshot artifact
|
|
3522
|
-
|
|
3652
|
+
// Snapshot the artifact population across the conversation before reload so we can tell a NEW
|
|
3653
|
+
// artifact from a new VERSION of an existing one (the event itself carries placeholder ids).
|
|
3654
|
+
const artifactBaseline = this.snapshotArtifactPanelBaseline();
|
|
3523
3655
|
// Reload artifacts to get full entities (processes ALL messages in the conversation)
|
|
3524
3656
|
await this.reloadArtifactsForMessage(data.conversationDetailId, data.conversationId);
|
|
3525
3657
|
if (!this.isActiveConversation(data.conversationId)) {
|
|
3526
3658
|
return;
|
|
3527
3659
|
}
|
|
3528
|
-
//
|
|
3529
|
-
|
|
3530
|
-
|
|
3531
|
-
// When a sub-agent (e.g., Skip) creates an artifact on a different ConversationDetail
|
|
3532
|
-
// than the one specified in the event, checking only data.conversationDetailId would miss it.
|
|
3533
|
-
await this.autoOpenNewArtifact(artifactIdsBefore, data.conversationId);
|
|
3534
|
-
}
|
|
3535
|
-
else if (this.selectedArtifactId) {
|
|
3536
|
-
// Panel is already open - check if new artifact is a new version of currently displayed artifact
|
|
3537
|
-
const artifactList = this.artifactsByDetailId.get(data.conversationDetailId);
|
|
3538
|
-
if (artifactList && artifactList.length > 0) {
|
|
3539
|
-
const currentArtifact = artifactList.find(a => a.artifactId === this.selectedArtifactId);
|
|
3540
|
-
if (currentArtifact) {
|
|
3541
|
-
// New version of the same artifact - refresh to show latest version
|
|
3542
|
-
const latestVersion = artifactList[artifactList.length - 1];
|
|
3543
|
-
this.artifactViewerRefresh$.next({
|
|
3544
|
-
artifactId: latestVersion.artifactId,
|
|
3545
|
-
versionNumber: latestVersion.versionNumber
|
|
3546
|
-
});
|
|
3547
|
-
}
|
|
3548
|
-
}
|
|
3549
|
-
}
|
|
3660
|
+
// #529: a new artifact opens even over an open panel (build); a bumped version of the shown
|
|
3661
|
+
// artifact refreshes; a bumped version of another artifact switches to it (retargeting).
|
|
3662
|
+
await this.decideAndApplyArtifactPanel(artifactBaseline, data.conversationId);
|
|
3550
3663
|
// Force change detection to update the UI immediately
|
|
3551
3664
|
this.cdr.detectChanges();
|
|
3552
3665
|
}
|
|
3553
3666
|
onCloseArtifactPanel() {
|
|
3667
|
+
this.artifactSelectionEpoch++;
|
|
3554
3668
|
this.showArtifactPanel = false;
|
|
3555
3669
|
this.selectedArtifactId = null;
|
|
3556
3670
|
// Clear permissions
|
|
@@ -3822,11 +3936,9 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
3822
3936
|
}
|
|
3823
3937
|
viewTestRun(testRunId) {
|
|
3824
3938
|
// Open the test run record in the entity viewer
|
|
3825
|
-
const compositeKey = new CompositeKey();
|
|
3826
|
-
compositeKey.KeyValuePairs.push({ FieldName: 'ID', Value: testRunId });
|
|
3827
3939
|
this.openEntityRecord.emit({
|
|
3828
3940
|
entityName: 'MJ: Test Runs',
|
|
3829
|
-
compositeKey
|
|
3941
|
+
compositeKey: CompositeKey.FromID(testRunId)
|
|
3830
3942
|
});
|
|
3831
3943
|
}
|
|
3832
3944
|
/**
|
|
@@ -3837,11 +3949,10 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
3837
3949
|
* wrapper routes it through `NavigationService.OpenEntityRecord`.
|
|
3838
3950
|
*/
|
|
3839
3951
|
onRealtimeNavigateRequest(event) {
|
|
3840
|
-
|
|
3841
|
-
compositeKey.KeyValuePairs.push({ FieldName: 'ID', Value: event.RecordID });
|
|
3952
|
+
// The overlay can name any entity — resolve its key column(s) from metadata, not a hardcoded ID.
|
|
3842
3953
|
this.openEntityRecord.emit({
|
|
3843
3954
|
entityName: event.EntityName,
|
|
3844
|
-
compositeKey
|
|
3955
|
+
compositeKey: CompositeKey.FromURLSegment(this.ProviderToUse.EntityByName(event.EntityName), event.RecordID)
|
|
3845
3956
|
});
|
|
3846
3957
|
}
|
|
3847
3958
|
/**
|
|
@@ -4232,6 +4343,7 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
4232
4343
|
panelAlreadyOpen);
|
|
4233
4344
|
// Open the artifact panel so the viewer mounts (if it isn't already).
|
|
4234
4345
|
if (!panelAlreadyOpen) {
|
|
4346
|
+
this.artifactSelectionEpoch++;
|
|
4235
4347
|
this.selectedArtifactId = artifactId;
|
|
4236
4348
|
this.selectedVersionNumber = undefined;
|
|
4237
4349
|
this.showArtifactPanel = true;
|
|
@@ -4486,6 +4598,7 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
4486
4598
|
const scrollDifference = element.scrollHeight - (element.scrollTop + element.clientHeight);
|
|
4487
4599
|
const hasScrollableContent = element.scrollHeight > element.clientHeight + 50;
|
|
4488
4600
|
const atBottom = scrollDifference <= buffer;
|
|
4601
|
+
this.readerAtBottom = atBottom;
|
|
4489
4602
|
const newValue = !atBottom && hasScrollableContent;
|
|
4490
4603
|
// Only update if value changed to prevent unnecessary change detection
|
|
4491
4604
|
if (this.showScrollToBottomIcon !== newValue) {
|
|
@@ -4519,6 +4632,122 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
4519
4632
|
element.scroll({ top: element.scrollHeight, behavior: 'smooth' });
|
|
4520
4633
|
}
|
|
4521
4634
|
}
|
|
4635
|
+
/**
|
|
4636
|
+
* Decides where the viewport goes after the transcript changed.
|
|
4637
|
+
*
|
|
4638
|
+
* - `load` — a conversation was opened: the bottom.
|
|
4639
|
+
* - `new` — a message was appended: follow the tail, as before.
|
|
4640
|
+
* - `update` — a message already on screen changed in place (progress, status, streamed
|
|
4641
|
+
* text). Never moves a reader who has scrolled away; keeps a reader who is
|
|
4642
|
+
* at the bottom there as the bubble grows. (Before this, every progress
|
|
4643
|
+
* update re-ran the send path's scroll — message-input re-emits
|
|
4644
|
+
* `messageSent` per update — and yanked the reader to the bottom.)
|
|
4645
|
+
*
|
|
4646
|
+
* With `readReplyFromTop`, the reader's own message opens a turn — whether it arrives as
|
|
4647
|
+
* `new` or, on the auto-send path where the chat area already holds it, as `update` — and
|
|
4648
|
+
* every settled AI message of that turn (Complete or Error) lands the turn instead of
|
|
4649
|
+
* following, for a reader who was still following. EVERY settled message, not the first:
|
|
4650
|
+
* the refinement path emits a settled status line ("Continuing with X…") before the reply,
|
|
4651
|
+
* and a turn that landed on the status line alone must land again when the reply arrives
|
|
4652
|
+
* (re-landing is idempotent — the same target, or nothing once the reader has been moved
|
|
4653
|
+
* off the bottom). Completion is also emitted more than once for one message; none of those
|
|
4654
|
+
* emits may fall through to the bottom follow. A `load` does not forget the turn: creating
|
|
4655
|
+
* a conversation from the composer sends the first message while the initial load is still
|
|
4656
|
+
* in flight.
|
|
4657
|
+
*/
|
|
4658
|
+
followTranscript(change, message) {
|
|
4659
|
+
if (change === 'load') {
|
|
4660
|
+
this.scrollToBottom = true;
|
|
4661
|
+
return;
|
|
4662
|
+
}
|
|
4663
|
+
if (this.readReplyFromTop) {
|
|
4664
|
+
if (message?.Role === 'User' && message.ID && message.ID !== this.currentTurnStartMessageId) {
|
|
4665
|
+
this.currentTurnStartMessageId = message.ID;
|
|
4666
|
+
}
|
|
4667
|
+
else if (this.currentTurnStartMessageId && message?.Role === 'AI' && this.isSettled(message)) {
|
|
4668
|
+
if (this.readerAtBottom) {
|
|
4669
|
+
this.pendingTurnStartMessageId = this.currentTurnStartMessageId;
|
|
4670
|
+
this.scrollToBottom = false;
|
|
4671
|
+
this.bottomFollowSuppressedUntil = Date.now() + 1500;
|
|
4672
|
+
}
|
|
4673
|
+
return;
|
|
4674
|
+
}
|
|
4675
|
+
}
|
|
4676
|
+
if (change === 'new' || this.readerAtBottom) {
|
|
4677
|
+
if (change === 'new' && message?.Role === 'User') {
|
|
4678
|
+
// The reader sending again right after a reply landed must not be swallowed by the
|
|
4679
|
+
// landing's suppression. Only THEIR message lifts it: an AI message arriving new
|
|
4680
|
+
// inside the window belongs to the turn that just landed and must not cancel it.
|
|
4681
|
+
this.bottomFollowSuppressedUntil = 0;
|
|
4682
|
+
}
|
|
4683
|
+
this.scrollToBottom = true;
|
|
4684
|
+
}
|
|
4685
|
+
}
|
|
4686
|
+
isSettled(message) {
|
|
4687
|
+
return message.Status === 'Complete' || message.Status === 'Error';
|
|
4688
|
+
}
|
|
4689
|
+
/**
|
|
4690
|
+
* readReplyFromTop: once the reply has rendered, scrolls the turn so its first message
|
|
4691
|
+
* sits at the top of the pane — but only if the turn is taller than the pane. A turn that
|
|
4692
|
+
* fits is already fully on screen at the bottom, and moving it would be motion for nothing.
|
|
4693
|
+
*/
|
|
4694
|
+
scrollTurnToTop(messageId, attempt = 0) {
|
|
4695
|
+
if (!this.readReplyFromTop) {
|
|
4696
|
+
return;
|
|
4697
|
+
}
|
|
4698
|
+
const container = this.scrollContainer?.nativeElement;
|
|
4699
|
+
// Resolved through the list's timeline, not a `[data-message-id]` query: a far-off item
|
|
4700
|
+
// is unmounted into a spacer and a session-stamped row folds into its session card, and
|
|
4701
|
+
// the list answers with the node that stands for the message in either case.
|
|
4702
|
+
const target = this.messageListComponent?.FindTimelineElement(messageId) ?? null;
|
|
4703
|
+
if (!container || !target) {
|
|
4704
|
+
// The reply's final render lands a tick or two after the array changes — the same
|
|
4705
|
+
// latency the bottom-follow path absorbs with its 100 ms timer.
|
|
4706
|
+
if (attempt < 20) {
|
|
4707
|
+
this.turnStartRetryHandle = setTimeout(() => this.scrollTurnToTop(messageId, attempt + 1), 50);
|
|
4708
|
+
}
|
|
4709
|
+
return;
|
|
4710
|
+
}
|
|
4711
|
+
this.turnStartRetryHandle = null;
|
|
4712
|
+
const turnTop = this.offsetWithinScroller(target) - this.turnTopClearance(container);
|
|
4713
|
+
const turnHeight = container.scrollHeight - turnTop; // the turn is the newest content
|
|
4714
|
+
if (turnHeight > container.clientHeight) {
|
|
4715
|
+
container.scroll({ top: turnTop, behavior: 'smooth' });
|
|
4716
|
+
}
|
|
4717
|
+
else {
|
|
4718
|
+
this.scrollToBottomNow();
|
|
4719
|
+
}
|
|
4720
|
+
this.checkScroll();
|
|
4721
|
+
}
|
|
4722
|
+
/**
|
|
4723
|
+
* How far below the pane's top edge the turn's first message lands: the standard gap, plus
|
|
4724
|
+
* room for the list's sticky date header when it is showing — it pins to this scroller's
|
|
4725
|
+
* top and would otherwise sit on the message's first line.
|
|
4726
|
+
*/
|
|
4727
|
+
turnTopClearance(container) {
|
|
4728
|
+
const stickyHeader = container.querySelector('.sticky-date-header');
|
|
4729
|
+
if (!stickyHeader || !stickyHeader.offsetParent) {
|
|
4730
|
+
return ConversationChatAreaComponent.TURN_TOP_GAP_PX;
|
|
4731
|
+
}
|
|
4732
|
+
// The header's CSS inset (`top: 12px`), NOT `offsetTop`: on a pinned sticky element
|
|
4733
|
+
// `offsetTop` reports the used position, which tracks the scroll offset.
|
|
4734
|
+
const inset = parseFloat(getComputedStyle(stickyHeader).top) || 0;
|
|
4735
|
+
return ConversationChatAreaComponent.TURN_TOP_GAP_PX + stickyHeader.offsetHeight + inset;
|
|
4736
|
+
}
|
|
4737
|
+
/** An element's top edge in the scroller's content coordinates — what scrollTop counts in. */
|
|
4738
|
+
offsetWithinScroller(el) {
|
|
4739
|
+
const container = this.scrollContainer.nativeElement;
|
|
4740
|
+
return el.getBoundingClientRect().top - container.getBoundingClientRect().top + container.scrollTop;
|
|
4741
|
+
}
|
|
4742
|
+
clearTurnTracking() {
|
|
4743
|
+
this.currentTurnStartMessageId = null;
|
|
4744
|
+
this.pendingTurnStartMessageId = null;
|
|
4745
|
+
this.bottomFollowSuppressedUntil = 0;
|
|
4746
|
+
if (this.turnStartRetryHandle) {
|
|
4747
|
+
clearTimeout(this.turnStartRetryHandle);
|
|
4748
|
+
this.turnStartRetryHandle = null;
|
|
4749
|
+
}
|
|
4750
|
+
}
|
|
4522
4751
|
/**
|
|
4523
4752
|
* Detect and reconcile agent run states against conversation detail statuses.
|
|
4524
4753
|
* Called after loading a conversation to handle two scenarios:
|
|
@@ -4628,6 +4857,7 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
4628
4857
|
return;
|
|
4629
4858
|
}
|
|
4630
4859
|
// Open the artifact panel
|
|
4860
|
+
this.artifactSelectionEpoch++;
|
|
4631
4861
|
this.selectedArtifactId = artifactIdToOpen;
|
|
4632
4862
|
this.selectedVersionNumber = versionNumberToOpen ?? undefined;
|
|
4633
4863
|
this.showArtifactPanel = true;
|
|
@@ -4683,7 +4913,7 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
4683
4913
|
// No ID means it's temporary (won't be saved)
|
|
4684
4914
|
this.intentCheckMessage = tempMessage;
|
|
4685
4915
|
this.messages = [...this.messages, tempMessage];
|
|
4686
|
-
this.
|
|
4916
|
+
this.followTranscript('new', tempMessage);
|
|
4687
4917
|
this.cdr.detectChanges();
|
|
4688
4918
|
}
|
|
4689
4919
|
/**
|
|
@@ -4719,7 +4949,7 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
4719
4949
|
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.emptyStateComponent = _t.first);
|
|
4720
4950
|
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.messageListComponent = _t.first);
|
|
4721
4951
|
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.messageInputComponents = _t);
|
|
4722
|
-
} }, inputs: { environmentId: "environmentId", currentUser: "currentUser", conversationId: "conversationId", conversation: "conversation", threadId: "threadId", suppressNewConversationEmptyState: "suppressNewConversationEmptyState", allowMentions: "allowMentions", allowAgentMentions: "allowAgentMentions", allowEntityMentions: "allowEntityMentions", allowSkillCommands: "allowSkillCommands", allowAttachments: "allowAttachments", allowPlanMode: "allowPlanMode", allowRealtime: "allowRealtime", showEmptyFill: "showEmptyFill", showLoadingState: "showLoadingState", showAgentRunDetails: "showAgentRunDetails", showReactions: "showReactions", showMessageRating: "showMessageRating", allowPinning: "allowPinning", allowMessageEdit: "allowMessageEdit", allowMessageDelete: "allowMessageDelete", showSuggestedPrompts: "showSuggestedPrompts", showDateNavigation: "showDateNavigation", assistantDisplayName: "assistantDisplayName", assistantAvatarUrl: "assistantAvatarUrl", isNewConversation: "isNewConversation", pendingMessage: "pendingMessage", pendingMessageConversationId: "pendingMessageConversationId", pendingAttachments: "pendingAttachments", pendingArtifactId: "pendingArtifactId", pendingArtifactVersionNumber: "pendingArtifactVersionNumber", pendingArtifactConversationId: "pendingArtifactConversationId", overlayMode: "overlayMode", showExportButton: "showExportButton", exportButtonLabel: "exportButtonLabel", exportButtonIcon: "exportButtonIcon", exportBranding: "exportBranding", showShareButton: "showShareButton", showArtifactIndicator: "showArtifactIndicator", appContext: "appContext", defaultAgentId: "defaultAgentId", applicationScope: "applicationScope", applicationId: "applicationId", linkedEntityId: "linkedEntityId", linkedRecordId: "linkedRecordId", showAgentPicker: "showAgentPicker", showAgentModePicker: "showAgentModePicker", emptyStateGreeting: "emptyStateGreeting", showSidebarToggle: "showSidebarToggle", showAgentCharacter: "showAgentCharacter", agentCharacterConfig: "agentCharacterConfig", emptyStateConfig: "emptyStateConfig", showDemonstrationSurface: "showDemonstrationSurface", demonstrationSurfaceContent: "demonstrationSurfaceContent", composerDraft: "composerDraft", composerAgentMention: "composerAgentMention" }, outputs: { beforeAgentTurn: "beforeAgentTurn", afterAgentTurn: "afterAgentTurn", beforeToolInvoked: "beforeToolInvoked", afterToolInvoked: "afterToolInvoked", beforeResponseFormSubmitted: "beforeResponseFormSubmitted", afterResponseFormSubmitted: "afterResponseFormSubmitted", sessionStarted: "sessionStarted", sessionChannelStateChanged: "sessionChannelStateChanged", sessionEnded: "sessionEnded", conversationRenamed: "conversationRenamed", openEntityRecord: "openEntityRecord", realtimeConversationReady: "realtimeConversationReady", navigationRequest: "navigationRequest", taskClicked: "taskClicked", artifactLinkClicked: "artifactLinkClicked", sidebarToggleClicked: "sidebarToggleClicked", conversationCreated: "conversationCreated", threadOpened: "threadOpened", threadClosed: "threadClosed", pendingArtifactConsumed: "pendingArtifactConsumed", pendingMessageConsumed: "pendingMessageConsumed", pendingMessageRequested: "pendingMessageRequested", composerDraftConsumed: "composerDraftConsumed", composerAgentMentionConsumed: "composerAgentMentionConsumed" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 25, vars: 34, consts: [["emptyStateInput", ""], ["scrollContainer", ""], ["messageInput", ""], [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"], [3, "parentMessageId", "conversationId", "currentUser"], [3, "cancelled", "exported", "branding", "isVisible", "conversation", "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-info"], ["title", "Show conversations", 1, "sidebar-toggle-btn"], [1, "chat-title"], [1, "shared-by-badge", 3, "title"], ["title", "Assign to project", 1, "project-tag"], ["title", "View Test Run", 1, "test-indicator"], [1, "chat-actions", "chat-actions-buttons"], ["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", "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"], [1, "fas", "fa-share-nodes"], ["title", "Assign to project", 1, "project-tag", 3, "click"], [1, "fas", "fa-folder"], ["title", "View Test Run", 1, "test-indicator", 3, "click"], [1, "fas", "fa-flask"], ["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, "btn-label"], [1, "conversation-loading-state"], ["text", "Loading conversation...", "size", "large"], [3, "currentUser", "initialDraft", "disabled", "showSidebarToggle", "overlayMode", "greeting", "showSuggestedPrompts", "enableAttachments", "enableMentions", "enableAgentMentions", "enableEntityMentions", "enableSkillCommands", "maxAttachments", "maxAttachmentSizeBytes", "acceptedFileTypes"], [3, "initialDraftApplied", "DraftStateChanged", "ComposerBlurred", "sidebarToggleClicked", "messageSent", "currentUser", "initialDraft", "disabled", "showSidebarToggle", "overlayMode", "greeting", "showSuggestedPrompts", "enableAttachments", "enableMentions", "enableAgentMentions", "enableEntityMentions", "enableSkillCommands", "maxAttachments", "maxAttachmentSizeBytes", "acceptedFileTypes"], [1, "chat-messages-container"], [1, "chat-input-container"], [1, "message-input-container-wrapper"], [3, "initialDraftApplied", "DraftStateChanged", "ComposerBlurred", "emptyStateSubmit", "emptyStateMode", "initialDraft", "currentUser", "disabled", "enableAttachments", "enableMentions", "enableAgentMentions", "enableEntityMentions", "enableSkillCommands", "enablePlanMode", "enableRealtime", "maxAttachments", "maxAttachmentSizeBytes", "acceptedFileTypes"], [1, "upload-indicator-overlay"], [1, "chat-messages-container", 3, "scroll"], [3, "OlderRequested", "DateJumpRequested", "realtimeSessionOpenRequested", "replyInThread", "viewThread", "deleteMessage", "retryMessage", "testFeedbackMessage", "artifactClicked", "messageEdited", "openEntityRecord", "suggestedResponseSelected", "attachmentClicked", "diagnosticRequested", "messagePinToggled", "beforeResponseFormSubmitted", "afterResponseFormSubmitted", "showEmptyFill", "showDateNavigation", "showAgentRunDetails", "showReactions", "showMessageRating", "allowPinning", "allowMessageEdit", "allowMessageDelete", "assistantDisplayName", "assistantAvatarUrl", "messages", "HasMoreAbove", "IsLoadingOlder", "ScrollRoot", "conversation", "currentUser", "isProcessing", "artifactMap", "agentRunMap", "ratingsMap", "userAvatarMap", "attachmentsMap", "messageRendererTemplate", "messageExtraTemplate", "sessionMetaMap"], [1, "scroll-to-bottom-icon", 2, "left", "50%"], [1, "loading-peripheral-placeholder"], ["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"], ["role", "status", 1, "read-only-banner"], [3, "hidden", "initialDraft", "conversationId", "conversationName", "currentUser", "conversationHistory", "artifactsByDetailId", "systemArtifactsByDetailId", "agentRunsByDetailId", "appContext", "applicationId", "defaultAgentId", "conversationDefaultAgentId", "agentConfigurationPresetId", "inProgressMessageIds", "disabled", "enableAttachments", "enableMentions", "enableAgentMentions", "enableEntityMentions", "enableSkillCommands", "enablePlanMode", "enableRealtime", "maxAttachments", "maxAttachmentSizeBytes", "acceptedFileTypes", "initialMessage", "initialAttachments"], [1, "fas", "fa-eye"], [3, "DraftStateChanged", "ComposerBlurred", "initialMessageAutoSendStarted", "initialMessageAutoSendFailed", "messageSent", "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", "inProgressMessageIds", "disabled", "enableAttachments", "enableMentions", "enableAgentMentions", "enableEntityMentions", "enableSkillCommands", "enablePlanMode", "enableRealtime", "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", "canShare", "canEdit", "isMaximized", "refreshTrigger"], [1, "resize-handle", 3, "mousedown", "touchstart"], [3, "closed", "jumpRequested", "unpinRequested", "pinnedMessages", "isLoading"], [3, "NavigateRequest", "StartLiveRequested", "ReviewClosed", "AgentName", "Hidden", "CurrentUser", "EnvironmentID", "ReviewData", "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"], [3, "closed", "replyAdded", "parentMessageId", "conversationId", "currentUser"], [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) {
|
|
4952
|
+
} }, inputs: { environmentId: "environmentId", currentUser: "currentUser", conversationId: "conversationId", conversation: "conversation", threadId: "threadId", suppressNewConversationEmptyState: "suppressNewConversationEmptyState", allowMentions: "allowMentions", allowAgentMentions: "allowAgentMentions", allowEntityMentions: "allowEntityMentions", allowSkillCommands: "allowSkillCommands", allowAttachments: "allowAttachments", allowPlanMode: "allowPlanMode", allowRealtime: "allowRealtime", showEmptyFill: "showEmptyFill", showLoadingState: "showLoadingState", readReplyFromTop: "readReplyFromTop", showAgentRunDetails: "showAgentRunDetails", showReactions: "showReactions", showMessageRating: "showMessageRating", allowPinning: "allowPinning", allowMessageEdit: "allowMessageEdit", allowMessageDelete: "allowMessageDelete", showSuggestedPrompts: "showSuggestedPrompts", showDateNavigation: "showDateNavigation", assistantDisplayName: "assistantDisplayName", assistantAvatarUrl: "assistantAvatarUrl", isNewConversation: "isNewConversation", pendingMessage: "pendingMessage", pendingMessageConversationId: "pendingMessageConversationId", pendingAttachments: "pendingAttachments", pendingArtifactId: "pendingArtifactId", pendingArtifactVersionNumber: "pendingArtifactVersionNumber", pendingArtifactConversationId: "pendingArtifactConversationId", overlayMode: "overlayMode", showExportButton: "showExportButton", exportButtonLabel: "exportButtonLabel", exportButtonIcon: "exportButtonIcon", exportBranding: "exportBranding", showShareButton: "showShareButton", showArtifactIndicator: "showArtifactIndicator", appContext: "appContext", defaultAgentId: "defaultAgentId", applicationScope: "applicationScope", applicationId: "applicationId", linkedEntityId: "linkedEntityId", linkedRecordId: "linkedRecordId", showAgentPicker: "showAgentPicker", showAgentModePicker: "showAgentModePicker", emptyStateGreeting: "emptyStateGreeting", showSidebarToggle: "showSidebarToggle", showAgentCharacter: "showAgentCharacter", agentCharacterConfig: "agentCharacterConfig", emptyStateConfig: "emptyStateConfig", showDemonstrationSurface: "showDemonstrationSurface", demonstrationSurfaceContent: "demonstrationSurfaceContent", composerDraft: "composerDraft", composerAgentMention: "composerAgentMention" }, outputs: { beforeAgentTurn: "beforeAgentTurn", afterAgentTurn: "afterAgentTurn", beforeToolInvoked: "beforeToolInvoked", afterToolInvoked: "afterToolInvoked", beforeResponseFormSubmitted: "beforeResponseFormSubmitted", afterResponseFormSubmitted: "afterResponseFormSubmitted", sessionStarted: "sessionStarted", sessionChannelStateChanged: "sessionChannelStateChanged", sessionEnded: "sessionEnded", conversationRenamed: "conversationRenamed", openEntityRecord: "openEntityRecord", realtimeConversationReady: "realtimeConversationReady", navigationRequest: "navigationRequest", taskClicked: "taskClicked", artifactLinkClicked: "artifactLinkClicked", sidebarToggleClicked: "sidebarToggleClicked", conversationCreated: "conversationCreated", threadOpened: "threadOpened", threadClosed: "threadClosed", pendingArtifactConsumed: "pendingArtifactConsumed", pendingMessageConsumed: "pendingMessageConsumed", pendingMessageRequested: "pendingMessageRequested", composerDraftConsumed: "composerDraftConsumed", composerAgentMentionConsumed: "composerAgentMentionConsumed" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 25, vars: 34, consts: [["emptyStateInput", ""], ["scrollContainer", ""], ["messageInput", ""], [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"], [3, "parentMessageId", "conversationId", "currentUser"], [3, "cancelled", "exported", "branding", "isVisible", "conversation", "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-info"], ["title", "Show conversations", 1, "sidebar-toggle-btn"], [1, "chat-title"], [1, "shared-by-badge", 3, "title"], ["title", "Assign to project", 1, "project-tag"], ["title", "View Test Run", 1, "test-indicator"], [1, "chat-actions", "chat-actions-buttons"], ["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", "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"], [1, "fas", "fa-share-nodes"], ["title", "Assign to project", 1, "project-tag", 3, "click"], [1, "fas", "fa-folder"], ["title", "View Test Run", 1, "test-indicator", 3, "click"], [1, "fas", "fa-flask"], ["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, "btn-label"], [1, "conversation-loading-state"], ["text", "Loading conversation...", "size", "large"], [3, "currentUser", "initialDraft", "disabled", "showSidebarToggle", "overlayMode", "greeting", "showSuggestedPrompts", "enableAttachments", "enableMentions", "enableAgentMentions", "enableEntityMentions", "enableSkillCommands", "maxAttachments", "maxAttachmentSizeBytes", "acceptedFileTypes"], [3, "initialDraftApplied", "DraftStateChanged", "ComposerBlurred", "sidebarToggleClicked", "messageSent", "currentUser", "initialDraft", "disabled", "showSidebarToggle", "overlayMode", "greeting", "showSuggestedPrompts", "enableAttachments", "enableMentions", "enableAgentMentions", "enableEntityMentions", "enableSkillCommands", "maxAttachments", "maxAttachmentSizeBytes", "acceptedFileTypes"], [1, "chat-messages-container"], [1, "chat-input-container"], [1, "message-input-container-wrapper"], [3, "initialDraftApplied", "DraftStateChanged", "ComposerBlurred", "emptyStateSubmit", "emptyStateMode", "initialDraft", "currentUser", "disabled", "enableAttachments", "enableMentions", "enableAgentMentions", "enableEntityMentions", "enableSkillCommands", "enablePlanMode", "enableRealtime", "maxAttachments", "maxAttachmentSizeBytes", "acceptedFileTypes"], [1, "upload-indicator-overlay"], [1, "chat-messages-container", 3, "scroll"], [3, "OlderRequested", "DateJumpRequested", "realtimeSessionOpenRequested", "replyInThread", "viewThread", "deleteMessage", "retryMessage", "testFeedbackMessage", "artifactClicked", "messageEdited", "openEntityRecord", "suggestedResponseSelected", "attachmentClicked", "diagnosticRequested", "messagePinToggled", "beforeResponseFormSubmitted", "afterResponseFormSubmitted", "showEmptyFill", "showDateNavigation", "showAgentRunDetails", "showReactions", "showMessageRating", "allowPinning", "allowMessageEdit", "allowMessageDelete", "assistantDisplayName", "assistantAvatarUrl", "messages", "HasMoreAbove", "IsLoadingOlder", "ScrollRoot", "conversation", "currentUser", "isProcessing", "artifactMap", "agentRunMap", "ratingsMap", "userAvatarMap", "attachmentsMap", "messageRendererTemplate", "messageExtraTemplate", "sessionMetaMap"], [1, "scroll-to-bottom-icon", 2, "left", "50%"], [1, "loading-peripheral-placeholder"], ["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"], ["role", "status", 1, "read-only-banner"], [3, "hidden", "initialDraft", "conversationId", "conversationName", "currentUser", "conversationHistory", "artifactsByDetailId", "systemArtifactsByDetailId", "agentRunsByDetailId", "appContext", "applicationId", "defaultAgentId", "conversationDefaultAgentId", "agentConfigurationPresetId", "inProgressMessageIds", "disabled", "enableAttachments", "enableMentions", "enableAgentMentions", "enableEntityMentions", "enableSkillCommands", "enablePlanMode", "enableRealtime", "maxAttachments", "maxAttachmentSizeBytes", "acceptedFileTypes", "initialMessage", "initialAttachments"], [1, "fas", "fa-eye"], [3, "DraftStateChanged", "ComposerBlurred", "initialMessageAutoSendStarted", "initialMessageAutoSendFailed", "messageSent", "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", "inProgressMessageIds", "disabled", "enableAttachments", "enableMentions", "enableAgentMentions", "enableEntityMentions", "enableSkillCommands", "enablePlanMode", "enableRealtime", "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", "canShare", "canEdit", "isMaximized", "refreshTrigger"], [1, "resize-handle", 3, "mousedown", "touchstart"], [3, "closed", "jumpRequested", "unpinRequested", "pinnedMessages", "isLoading"], [3, "NavigateRequest", "StartLiveRequested", "ReviewClosed", "AgentName", "Hidden", "CurrentUser", "EnvironmentID", "ReviewData", "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"], [3, "closed", "replyAdded", "parentMessageId", "conversationId", "currentUser"], [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) {
|
|
4723
4953
|
i0.ɵɵelementStart(0, "div", 3);
|
|
4724
4954
|
i0.ɵɵconditionalCreate(1, ConversationChatAreaComponent_Conditional_1_Template, 3, 3, "div", 4);
|
|
4725
4955
|
i0.ɵɵconditionalCreate(2, ConversationChatAreaComponent_Conditional_2_Template, 1, 8, "ng-container")(3, ConversationChatAreaComponent_Conditional_3_Template, 16, 15, "div", 5);
|
|
@@ -4792,7 +5022,7 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
4792
5022
|
i0.ɵɵconditional(ctx.testFeedbackDialogData ? 23 : -1);
|
|
4793
5023
|
i0.ɵɵadvance();
|
|
4794
5024
|
i0.ɵɵconditional(ctx.showImageViewer ? 24 : -1);
|
|
4795
|
-
} }, dependencies: [i12.NgTemplateOutlet, i13.MJButtonDirective, i13.MJEmptyStateComponent, i9.ArtifactViewerPanelComponent, i14.TestFeedbackDialogComponent, i15.LoadingComponent, i16.GenericShareDialogComponent, i17.ArtifactCollectionPickerModalComponent, i18.ArtifactShareModalComponent, i19.MJChatAgentPresenceDefaultComponent, i20.RealtimeSessionOverlayComponent, i21.MessageListComponent, i22.MessageInputComponent, i23.ConversationEmptyStateComponent, i24.ConversationAgentPickerComponent, i25.ConversationModePickerComponent, i26.ThreadPanelComponent, i27.ProjectSelectorComponent, i28.MembersModalComponent, i29.ExportModalComponent, i30.ImageViewerComponent, i31.PinnedMessagesPanelComponent, i12.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\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\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\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.chat-title[_ngcontent-%COMP%] {\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.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\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\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\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-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\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\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.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\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\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[_ngcontent-%COMP%] {\n font-size: 15px;\n font-weight: 700;\n width: auto;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n flex: 1;\n min-width: 0;\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 }\n .test-indicator[_ngcontent-%COMP%] {\n margin-left: 0;\n font-size: 10px;\n padding: 3px 8px;\n height: 24px;\n }\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\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\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\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\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\n.voice-call-pill[_ngcontent-%COMP%] {\n position: absolute;\n right: 18px;\n bottom: 18px;\n z-index: 49; \n\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}"] });
|
|
5025
|
+
} }, dependencies: [i12.NgTemplateOutlet, i13.MJButtonDirective, i13.MJEmptyStateComponent, i9.ArtifactViewerPanelComponent, i14.TestFeedbackDialogComponent, i15.LoadingComponent, i16.GenericShareDialogComponent, i17.ArtifactCollectionPickerModalComponent, i18.ArtifactShareModalComponent, i19.MJChatAgentPresenceDefaultComponent, i20.RealtimeSessionOverlayComponent, i21.MessageListComponent, i22.MessageInputComponent, i23.ConversationEmptyStateComponent, i24.ConversationAgentPickerComponent, i25.ConversationModePickerComponent, i26.ThreadPanelComponent, i27.ProjectSelectorComponent, i28.MembersModalComponent, i29.ExportModalComponent, i30.ImageViewerComponent, i31.PinnedMessagesPanelComponent, i12.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.chat-title[_ngcontent-%COMP%] {\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.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-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.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[_ngcontent-%COMP%] {\n font-size: 15px;\n font-weight: 700;\n width: auto;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n flex: 1;\n min-width: 0;\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}"] });
|
|
4796
5026
|
}
|
|
4797
5027
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ConversationChatAreaComponent, [{
|
|
4798
5028
|
type: Component,
|
|
@@ -4827,6 +5057,8 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
4827
5057
|
type: Input
|
|
4828
5058
|
}], showLoadingState: [{
|
|
4829
5059
|
type: Input
|
|
5060
|
+
}], readReplyFromTop: [{
|
|
5061
|
+
type: Input
|
|
4830
5062
|
}], showAgentRunDetails: [{
|
|
4831
5063
|
type: Input
|
|
4832
5064
|
}], showReactions: [{
|
|
@@ -4976,5 +5208,5 @@ export class ConversationChatAreaComponent extends BaseAngularComponent {
|
|
|
4976
5208
|
type: ViewChild,
|
|
4977
5209
|
args: [MessageListComponent]
|
|
4978
5210
|
}] }); })();
|
|
4979
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ConversationChatAreaComponent, { className: "ConversationChatAreaComponent", filePath: "src/lib/components/conversation/conversation-chat-area.component.ts", lineNumber:
|
|
5211
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ConversationChatAreaComponent, { className: "ConversationChatAreaComponent", filePath: "src/lib/components/conversation/conversation-chat-area.component.ts", lineNumber: 113 }); })();
|
|
4980
5212
|
//# sourceMappingURL=conversation-chat-area.component.js.map
|